Initial sources
This commit is contained in:
137
engine/render/gl_shared.cpp
Normal file
137
engine/render/gl_shared.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#include "utils/logger.h"
|
||||
#include "render/gl_shared.h"
|
||||
#include "render/render_shared.h"
|
||||
|
||||
const char *GL_ErrorString( int err )
|
||||
{
|
||||
switch( err )
|
||||
{
|
||||
case GL_STACK_OVERFLOW:
|
||||
return "GL_STACK_OVERFLOW";
|
||||
case GL_STACK_UNDERFLOW:
|
||||
return "GL_STACK_UNDERFLOW";
|
||||
case GL_INVALID_ENUM:
|
||||
return "GL_INVALID_ENUM";
|
||||
case GL_INVALID_VALUE:
|
||||
return "GL_INVALID_VALUE";
|
||||
case GL_INVALID_OPERATION:
|
||||
return "GL_INVALID_OPERATION";
|
||||
case GL_OUT_OF_MEMORY:
|
||||
return "GL_OUT_OF_MEMORY";
|
||||
default:
|
||||
return "UNKNOWN ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
void GL_CheckError()
|
||||
{
|
||||
GLenum err;
|
||||
if ( (err = glGetError()) != GL_NO_ERROR )
|
||||
Msg( "OpenGL Error: %s", GL_ErrorString( err ) );// Msg("OpenGL Error: %s [%s]\n", GL_ErrorString(err), GL_TargetToString(tex->target));
|
||||
}
|
||||
|
||||
void GL_CheckErrorEx( const char* filename, int line )
|
||||
{
|
||||
GLenum err;
|
||||
if ( (err = glGetError()) != GL_NO_ERROR )
|
||||
Msg( "OpenGL Error: %s at %s:%i", GL_ErrorString( err ), filename, line );// Msg("OpenGL Error: %s [%s]\n", GL_ErrorString(err), GL_TargetToString(tex->target));
|
||||
}
|
||||
|
||||
void GL_CheckErrorFunction(const char* expression, const char* filename, int line)
|
||||
{
|
||||
GLenum err;
|
||||
if ( (err = glGetError()) != GL_NO_ERROR )
|
||||
Msg( "OpenGL Error: %s (%s) at %s:%i", expression, GL_ErrorString( err ), filename, line );// Msg("OpenGL Error: %s [%s]\n", GL_ErrorString(err), GL_TargetToString(tex->target));
|
||||
}
|
||||
|
||||
uint GetGLBlendFactor(BlendFactor factor)
|
||||
{
|
||||
switch (factor)
|
||||
{
|
||||
case BF_ZERO:
|
||||
return GL_ZERO;
|
||||
case BF_ONE:
|
||||
return GL_ONE;
|
||||
case BF_SRC_COLOR:
|
||||
return GL_SRC_COLOR;
|
||||
case BF_ONE_MINUS_SRC_COLOR:
|
||||
return GL_ONE_MINUS_SRC_COLOR;
|
||||
case BF_DST_COLOR:
|
||||
return GL_DST_COLOR;
|
||||
case BF_ONE_MINUS_DST_COLOR:
|
||||
return GL_ONE_MINUS_DST_COLOR;
|
||||
case BF_SRC_ALPHA:
|
||||
return GL_SRC_ALPHA;
|
||||
case BF_ONE_MINUS_SRC_ALPHA:
|
||||
return GL_ONE_MINUS_SRC_ALPHA;
|
||||
case BF_DST_ALPHA:
|
||||
return GL_DST_ALPHA;
|
||||
case BF_ONE_MINUS_DST_ALPHA:
|
||||
return GL_ONE_MINUS_DST_ALPHA;
|
||||
case BF_CONSTANT_COLOR:
|
||||
return GL_CONSTANT_COLOR;
|
||||
case BF_ONE_MINUS_CONSTANT_COLOR:
|
||||
return GL_ONE_MINUS_CONSTANT_COLOR;
|
||||
case BF_CONSTANT_ALPHA:
|
||||
return GL_CONSTANT_ALPHA;
|
||||
case BF_ONE_MINUS_CONSTANT_ALPHA:
|
||||
return GL_ONE_MINUS_CONSTANT_ALPHA;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define LOAD_GL_FUNC(functype, funcname) \
|
||||
{ \
|
||||
funcname = (functype)wglGetProcAddress(#funcname); \
|
||||
if (funcname == NULL) \
|
||||
LogMsg("Failed to load %s", #funcname); \
|
||||
}
|
||||
|
||||
void GL_Load()
|
||||
{
|
||||
// OpenGL 1.5
|
||||
LOAD_GL_FUNC(PFNGLGENQUERIESPROC, glGenQueries);
|
||||
LOAD_GL_FUNC(PFNGLDELETEQUERIESPROC, glDeleteQueries);
|
||||
LOAD_GL_FUNC(PFNGLISQUERYPROC, glIsQuery);
|
||||
LOAD_GL_FUNC(PFNGLBEGINQUERYPROC, glBeginQuery);
|
||||
LOAD_GL_FUNC(PFNGLENDQUERYPROC, glEndQuery);
|
||||
LOAD_GL_FUNC(PFNGLGETQUERYIVPROC, glGetQueryiv);
|
||||
LOAD_GL_FUNC(PFNGLGETQUERYOBJECTIVPROC, glGetQueryObjectiv);
|
||||
LOAD_GL_FUNC(PFNGLGETQUERYOBJECTUIVPROC, glGetQueryObjectuiv);
|
||||
LOAD_GL_FUNC(PFNGLBINDBUFFERPROC, glBindBuffer);
|
||||
LOAD_GL_FUNC(PFNGLDELETEBUFFERSPROC, glDeleteBuffers);
|
||||
LOAD_GL_FUNC(PFNGLGENBUFFERSPROC, glGenBuffers);
|
||||
LOAD_GL_FUNC(PFNGLISBUFFERPROC, glIsBuffer);
|
||||
LOAD_GL_FUNC(PFNGLBUFFERDATAPROC, glBufferData);
|
||||
LOAD_GL_FUNC(PFNGLBUFFERSUBDATAPROC, glBufferSubData);
|
||||
LOAD_GL_FUNC(PFNGLGETBUFFERSUBDATAPROC, glGetBufferSubData);
|
||||
LOAD_GL_FUNC(PFNGLMAPBUFFERPROC, glMapBuffer);
|
||||
LOAD_GL_FUNC(PFNGLUNMAPBUFFERPROC, glUnmapBuffer);
|
||||
LOAD_GL_FUNC(PFNGLGETBUFFERPARAMETERIVPROC, glGetBufferParameteriv);
|
||||
LOAD_GL_FUNC(PFNGLGETBUFFERPOINTERVPROC, glGetBufferPointerv);
|
||||
|
||||
}
|
||||
|
||||
PFNGLGENQUERIESPROC glGenQueries = NULL;
|
||||
PFNGLDELETEQUERIESPROC glDeleteQueries = NULL;
|
||||
PFNGLISQUERYPROC glIsQuery = NULL;
|
||||
PFNGLBEGINQUERYPROC glBeginQuery = NULL;
|
||||
PFNGLENDQUERYPROC glEndQuery = NULL;
|
||||
PFNGLGETQUERYIVPROC glGetQueryiv = NULL;
|
||||
PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv = NULL;
|
||||
PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv = NULL;
|
||||
PFNGLBINDBUFFERPROC glBindBuffer = NULL;
|
||||
PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL;
|
||||
PFNGLGENBUFFERSPROC glGenBuffers = NULL;
|
||||
PFNGLISBUFFERPROC glIsBuffer = NULL;
|
||||
PFNGLBUFFERDATAPROC glBufferData = NULL;
|
||||
PFNGLBUFFERSUBDATAPROC glBufferSubData = NULL;
|
||||
PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData = NULL;
|
||||
PFNGLMAPBUFFERPROC glMapBuffer = NULL;
|
||||
PFNGLUNMAPBUFFERPROC glUnmapBuffer = NULL;
|
||||
PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = NULL;
|
||||
PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv = NULL;
|
||||
44
engine/render/gl_shared.h
Normal file
44
engine/render/gl_shared.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef GL_SHARED_H
|
||||
#define GL_SHARED_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glext.h>
|
||||
|
||||
void GL_Load();
|
||||
|
||||
void GL_CheckError();
|
||||
void GL_CheckErrorEx(const char* filename, int line);
|
||||
void GL_CheckErrorFunction(const char* expression, const char* filename, int line);
|
||||
|
||||
#define GL_CHECK_ERROR() \
|
||||
GL_CheckErrorEx(__FILE__, __LINE__)
|
||||
|
||||
#define GL_CHECK_FUNC_ERROR(expr) \
|
||||
expr; \
|
||||
GL_CheckErrorFunction(#expr, __FILE__, __LINE__)
|
||||
|
||||
// OpenGL 1.5 Functional
|
||||
extern PFNGLGENQUERIESPROC glGenQueries;
|
||||
extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
||||
extern PFNGLISQUERYPROC glIsQuery;
|
||||
extern PFNGLBEGINQUERYPROC glBeginQuery;
|
||||
extern PFNGLENDQUERYPROC glEndQuery;
|
||||
extern PFNGLGETQUERYIVPROC glGetQueryiv;
|
||||
extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv;
|
||||
extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
|
||||
extern PFNGLBINDBUFFERPROC glBindBuffer;
|
||||
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
extern PFNGLGENBUFFERSPROC glGenBuffers;
|
||||
extern PFNGLISBUFFERPROC glIsBuffer;
|
||||
extern PFNGLBUFFERDATAPROC glBufferData;
|
||||
extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
|
||||
extern PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData;
|
||||
extern PFNGLMAPBUFFERPROC glMapBuffer;
|
||||
extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
|
||||
extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
|
||||
extern PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv;
|
||||
|
||||
#endif // !GL_SHARED_H
|
||||
56
engine/render/indexbuffer.cpp
Normal file
56
engine/render/indexbuffer.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "render/indexbuffer.h"
|
||||
#include "render/gl_shared.h"
|
||||
|
||||
IndexBuffer::IndexBuffer(void* data, size_t size, bool isStream /*= false*/)
|
||||
{
|
||||
glGenBuffers(1, &m_buffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, isStream ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
//if (isStream) {
|
||||
// Logger::msg("created dynamic index stream ...");
|
||||
//}
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer()
|
||||
{
|
||||
glDeleteBuffers(1, &m_buffer);
|
||||
}
|
||||
|
||||
void IndexBuffer::Bind()
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
|
||||
}
|
||||
|
||||
void* IndexBuffer::MapBuffer(BufferAccess access)
|
||||
{
|
||||
GLenum accessGl = 0;
|
||||
|
||||
switch (access)
|
||||
{
|
||||
case BA_READ_ONLY:
|
||||
accessGl = GL_READ_ONLY;
|
||||
break;
|
||||
case BA_WRITE_ONLY:
|
||||
accessGl = GL_WRITE_ONLY;
|
||||
break;
|
||||
case BA_READ_WRITE:
|
||||
accessGl = GL_READ_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
Bind();
|
||||
|
||||
void* ptr = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, accessGl);
|
||||
|
||||
GL_CHECK_ERROR();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void IndexBuffer::UnmapBuffer()
|
||||
{
|
||||
Bind();
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
}
|
||||
26
engine/render/indexbuffer.h
Normal file
26
engine/render/indexbuffer.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef INDEXOBJECT_H
|
||||
#define INDEXOBJECT_H
|
||||
|
||||
#include "render/render_shared.h"
|
||||
#include "render/gl_shared.h"
|
||||
|
||||
class RenderDevice;
|
||||
|
||||
class IndexBuffer
|
||||
{
|
||||
friend class RenderDevice;
|
||||
public:
|
||||
~IndexBuffer();
|
||||
|
||||
void* MapBuffer(BufferAccess access);
|
||||
void UnmapBuffer();
|
||||
|
||||
void Bind();
|
||||
|
||||
private:
|
||||
IndexBuffer(void* data, size_t size, bool isStream = false);
|
||||
|
||||
GLuint m_buffer;
|
||||
};
|
||||
|
||||
#endif // !INDEXOBJECT_H
|
||||
133
engine/render/render.cpp
Normal file
133
engine/render/render.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
#include "render/render.h"
|
||||
#include "render/renderdevice.h"
|
||||
#include "render/gl_shared.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#define RENDER_CLASS_NAME "RenderClassName"
|
||||
#define RENDER_WINDOW_NAME "UNEASE Alpha"
|
||||
|
||||
HWND hWnd = NULL;
|
||||
HDC hDC = NULL;
|
||||
HGLRC hRC = NULL;
|
||||
|
||||
LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_CREATE:
|
||||
return 0;
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage (0);
|
||||
return 0;
|
||||
|
||||
|
||||
case WM_KEYDOWN:
|
||||
switch (wParam)
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//input->OnKeyAction((int)wParam, true);
|
||||
|
||||
return 0;
|
||||
|
||||
case WM_KEYUP:
|
||||
//input->OnKeyAction((int)wParam, false);
|
||||
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return DefWindowProc (hWnd, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
void R_CreateWindow(int width, int height)
|
||||
{
|
||||
static bool wndclassRegistered = false;
|
||||
if (wndclassRegistered == false)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
/* register window class */
|
||||
wc.style = CS_OWNDC;
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = RENDER_CLASS_NAME;
|
||||
RegisterClass (&wc);
|
||||
|
||||
wndclassRegistered=true;
|
||||
}
|
||||
|
||||
/* create main window */
|
||||
hWnd = CreateWindow (
|
||||
RENDER_CLASS_NAME, RENDER_WINDOW_NAME,
|
||||
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
|
||||
0, 0, width, height,
|
||||
NULL, NULL, GetModuleHandle(0), NULL);
|
||||
|
||||
|
||||
LogMsg("Created window %ix%i", width, height);
|
||||
|
||||
// create opengl context
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
int iFormat;
|
||||
|
||||
/* get the device context (DC) */
|
||||
hDC = GetDC (hWnd);
|
||||
|
||||
/* set the pixel format for the DC */
|
||||
ZeroMemory (&pfd, sizeof (pfd));
|
||||
pfd.nSize = sizeof (pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.cDepthBits = 16;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
iFormat = ChoosePixelFormat (hDC, &pfd);
|
||||
SetPixelFormat (hDC, iFormat, &pfd);
|
||||
|
||||
LogMsg("SetPixelFormat successful");
|
||||
|
||||
/* create and enable the render context (RC) */
|
||||
hRC = wglCreateContext( hDC );
|
||||
LogMsg("wglCreateContext successful");
|
||||
|
||||
wglMakeCurrent( hDC, hRC );
|
||||
}
|
||||
|
||||
void R_Init()
|
||||
{
|
||||
LogMsg("--- R_Init ---");
|
||||
|
||||
// Create window
|
||||
R_CreateWindow(1024, 768);
|
||||
|
||||
// Load OpenGL
|
||||
GL_Load();
|
||||
|
||||
// Create render device
|
||||
g_renderDevice = new RenderDevice();
|
||||
}
|
||||
|
||||
void R_Shutdown()
|
||||
{
|
||||
if (g_renderDevice != NULL)
|
||||
{
|
||||
delete g_renderDevice;
|
||||
g_renderDevice = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void R_Present()
|
||||
{
|
||||
SwapBuffers(hDC);
|
||||
}
|
||||
11
engine/render/render.h
Normal file
11
engine/render/render.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef RENDER_H
|
||||
#define RENDER_H
|
||||
|
||||
#include "render/render_shared.h"
|
||||
|
||||
void R_Init();
|
||||
void R_Shutdown();
|
||||
|
||||
void R_Present();
|
||||
|
||||
#endif
|
||||
3
engine/render/render_shared.cpp
Normal file
3
engine/render/render_shared.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "render/render_shared.h"
|
||||
#include "render/gl_shared.h"
|
||||
|
||||
89
engine/render/render_shared.h
Normal file
89
engine/render/render_shared.h
Normal file
@@ -0,0 +1,89 @@
|
||||
// Shared header for render stuff
|
||||
#ifndef RENDER_SHARED_H
|
||||
#define RENDER_SHARED_H
|
||||
|
||||
#include "utils/maths.h"
|
||||
|
||||
enum BufferAccess
|
||||
{
|
||||
BA_READ_ONLY,
|
||||
BA_WRITE_ONLY,
|
||||
BA_READ_WRITE
|
||||
};
|
||||
|
||||
// texture format
|
||||
enum PixelFormat
|
||||
{
|
||||
PF_UNKNOWN,
|
||||
PF_R8G8B8,
|
||||
PF_R8G8B8A8,
|
||||
PF_R8G8B8F,
|
||||
PF_R8G8B8A8F,
|
||||
|
||||
// Depth formats
|
||||
PF_DEPTH32F
|
||||
};
|
||||
|
||||
// Blending functions
|
||||
enum BlendFactor
|
||||
{
|
||||
BF_ZERO,
|
||||
BF_ONE,
|
||||
BF_SRC_COLOR,
|
||||
BF_ONE_MINUS_SRC_COLOR,
|
||||
BF_DST_COLOR,
|
||||
BF_ONE_MINUS_DST_COLOR,
|
||||
BF_SRC_ALPHA,
|
||||
BF_ONE_MINUS_SRC_ALPHA,
|
||||
BF_DST_ALPHA,
|
||||
BF_ONE_MINUS_DST_ALPHA,
|
||||
BF_CONSTANT_COLOR,
|
||||
BF_ONE_MINUS_CONSTANT_COLOR,
|
||||
BF_CONSTANT_ALPHA,
|
||||
BF_ONE_MINUS_CONSTANT_ALPHA
|
||||
};
|
||||
|
||||
enum TextureSurfaceType
|
||||
{
|
||||
TST_COLOR = 1 << 0,
|
||||
TST_DEPTH = 1 << 1,
|
||||
TST_STENCIL = 1 << 2,
|
||||
};
|
||||
|
||||
enum PrimitiveType
|
||||
{
|
||||
PT_POINTS,
|
||||
PT_LINES,
|
||||
PT_TRIANGLES
|
||||
};
|
||||
|
||||
// Base structure for render view (view and projection matrices, viewport settings)
|
||||
struct View
|
||||
{
|
||||
int x, y;
|
||||
int width, height;
|
||||
|
||||
float fov;
|
||||
};
|
||||
|
||||
// Global instance of render view
|
||||
extern View g_renderView;
|
||||
|
||||
// pixel format convertion
|
||||
uint GetGLPF(PixelFormat pf);
|
||||
uint GetGLInternalPF(PixelFormat pf);
|
||||
uint GetGLTypePF(PixelFormat pf);
|
||||
|
||||
// Blending factor convertion
|
||||
uint GetGLBlendFactor(BlendFactor factor);
|
||||
|
||||
// Stretched picture vertex
|
||||
//struct StretchedVertex
|
||||
//{
|
||||
// Vec3 position;
|
||||
// Vec2 texcoord;
|
||||
//};
|
||||
|
||||
//#define MAX_STRETCH_VX 12 * sizeof(StretchedVertex)
|
||||
|
||||
#endif
|
||||
192
engine/render/renderdevice.cpp
Normal file
192
engine/render/renderdevice.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// OpenGL
|
||||
#include "render/gl_shared.h"
|
||||
|
||||
// VERTEX AND INDEX OBJECTS
|
||||
#include "render/vertexbuffer.h"
|
||||
#include "render/indexbuffer.h"
|
||||
|
||||
//#include "render/rendertarget.h"
|
||||
#include "render/renderdevice.h"
|
||||
|
||||
RenderDevice* g_renderDevice = NULL;
|
||||
|
||||
RenderDevice::RenderDevice()
|
||||
{
|
||||
m_activeVB = NULL;
|
||||
m_activeIB = NULL;
|
||||
m_blending = false;
|
||||
m_activeReadRT = NULL;
|
||||
m_activeWriteRT = NULL;
|
||||
}
|
||||
|
||||
RenderDevice::~RenderDevice()
|
||||
{
|
||||
}
|
||||
|
||||
VertexBuffer* RenderDevice::CreateVertexBuffer(void* data, size_t size, bool isStream)
|
||||
{
|
||||
return new VertexBuffer(data, size, isStream);
|
||||
}
|
||||
|
||||
IndexBuffer* RenderDevice::CreateIndexBuffer(void* data, size_t size, bool isStream)
|
||||
{
|
||||
return new IndexBuffer(data, size, isStream);
|
||||
}
|
||||
|
||||
void RenderDevice::SetVerticesBuffer(VertexBuffer* buffer)
|
||||
{
|
||||
if (buffer) {
|
||||
if (m_activeVB != buffer) {
|
||||
m_activeVB = buffer;
|
||||
m_activeVB->Bind();
|
||||
}
|
||||
} else { // unbind buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDevice::SetIndicesBuffer(IndexBuffer* buffer)
|
||||
{
|
||||
if (buffer) {
|
||||
if (m_activeIB != buffer) {
|
||||
m_activeIB = buffer;
|
||||
m_activeIB->Bind();
|
||||
}
|
||||
} else { // unbind buffer
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDevice::SetDepthTest(bool enable)
|
||||
{
|
||||
enable ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void RenderDevice::SetDepthWrite(bool enable)
|
||||
{
|
||||
glDepthMask(enable ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
//void RenderDevice::setVertexFormat(VertexFormat* format)
|
||||
//{
|
||||
// assert(format);
|
||||
//
|
||||
// if (format->count() == 0) {
|
||||
// Core::error("RenderDevice::setVertexFormat: failed to set empty vertex format");
|
||||
// }
|
||||
//
|
||||
// size_t appliedOffset = 0;
|
||||
// for (VertexAttribute* it = format->begin(); it != format->end(); ++it) {
|
||||
//
|
||||
// GLenum data_type = get_gl_vertex_attribute_type(it->m_type);
|
||||
// GLuint data_size = GLuint(get_vertex_attribute_size(it->m_type));
|
||||
//
|
||||
// if (appliedOffset > 0)
|
||||
// glVertexAttribPointer(
|
||||
// GLuint(it->m_offset),
|
||||
// GLint(it->m_size),
|
||||
// data_type,
|
||||
// GL_FALSE,
|
||||
// GLsizei(format->size() * data_size),
|
||||
// (void*)(appliedOffset * sizeof(float))
|
||||
// );
|
||||
// else
|
||||
// glVertexAttribPointer(
|
||||
// GLuint(it->m_offset),
|
||||
// GLint(it->m_size),
|
||||
// data_type,
|
||||
// GL_FALSE,
|
||||
// GLsizei(format->size() * data_size),
|
||||
// (void*)0
|
||||
// );
|
||||
//
|
||||
// glEnableVertexAttribArray(GLuint(it->m_offset));
|
||||
//
|
||||
// appliedOffset += it->m_size;
|
||||
// }
|
||||
//}
|
||||
|
||||
void RenderDevice::SetBlending(bool value)
|
||||
{
|
||||
if (m_blending != value) {
|
||||
m_blending = value;
|
||||
|
||||
value ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDevice::SetBlendingFunction(BlendFactor srcFactor, BlendFactor destFactor)
|
||||
{
|
||||
// Switch state if one of two blending factors was changed
|
||||
if (srcFactor != m_srcBlendFactor || destFactor != m_destBlendFactor)
|
||||
{
|
||||
m_srcBlendFactor = srcFactor;
|
||||
m_destBlendFactor = destFactor;
|
||||
|
||||
// push to gl state
|
||||
glBlendFunc(GetGLBlendFactor(srcFactor), GetGLBlendFactor(destFactor));
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDevice::SetReadRenderTarget(RenderTarget* renderTarget)
|
||||
{
|
||||
if (renderTarget) {
|
||||
if (m_activeReadRT != renderTarget) {
|
||||
m_activeReadRT = renderTarget;
|
||||
//glBindFramebuffer(GL_READ_FRAMEBUFFER, renderTarget->m_framebuffer);
|
||||
}
|
||||
}
|
||||
else { // set default rt
|
||||
// glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDevice::SetWriteRenderTarget(RenderTarget* renderTarget)
|
||||
{
|
||||
if (renderTarget) {
|
||||
if (m_activeWriteRT != renderTarget) {
|
||||
m_activeWriteRT = renderTarget;
|
||||
//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderTarget->m_framebuffer);
|
||||
}
|
||||
}
|
||||
else { // set default rt
|
||||
//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDevice::SetViewport(int x, int y, int w, int h)
|
||||
{
|
||||
glViewport(x, y, w, h);
|
||||
}
|
||||
|
||||
void RenderDevice::BlitRenderTarget(int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, TextureSurfaceType surfaceType)
|
||||
{
|
||||
GLbitfield mask = 0;
|
||||
if (surfaceType & TST_COLOR)
|
||||
mask |= GL_COLOR_BUFFER_BIT;
|
||||
if (surfaceType & TST_DEPTH)
|
||||
mask |= GL_DEPTH_BUFFER_BIT;
|
||||
if (surfaceType & TST_STENCIL)
|
||||
mask |= GL_STENCIL_BUFFER_BIT;
|
||||
|
||||
//glBlitFramebuffer(srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, mask, GL_LINEAR);
|
||||
}
|
||||
|
||||
static GLenum g_glPrimitiveMode[PT_TRIANGLES + 1] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
GL_TRIANGLES
|
||||
};
|
||||
|
||||
void RenderDevice::DrawArrays(PrimitiveType primType, uint startOf, size_t verticesCount)
|
||||
{
|
||||
glDrawArrays(g_glPrimitiveMode[primType], startOf, GLsizei(verticesCount));
|
||||
}
|
||||
|
||||
void RenderDevice::DrawElements(PrimitiveType primType, size_t elementsCount, bool is16bitIndices)
|
||||
{
|
||||
glDrawElements(g_glPrimitiveMode[primType], GLsizei(elementsCount), is16bitIndices ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, NULL);
|
||||
}
|
||||
59
engine/render/renderdevice.h
Normal file
59
engine/render/renderdevice.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef RENDERDEVICE_H
|
||||
#define RENDERDEVICE_H
|
||||
|
||||
#include "render/render_shared.h"
|
||||
|
||||
class VertexBuffer;
|
||||
class IndexBuffer;
|
||||
class VertexFormat;
|
||||
class RenderTarget;
|
||||
|
||||
class RenderDevice
|
||||
{
|
||||
public:
|
||||
RenderDevice();
|
||||
~RenderDevice();
|
||||
|
||||
VertexBuffer* CreateVertexBuffer(void* data, size_t size, bool isStream = false);
|
||||
IndexBuffer* CreateIndexBuffer(void* data, size_t size, bool isStream = false);
|
||||
|
||||
void SetVerticesBuffer(VertexBuffer* buffer);
|
||||
void SetIndicesBuffer(IndexBuffer* buffer);
|
||||
|
||||
void SetDepthTest(bool enable);
|
||||
void SetDepthWrite(bool enable);
|
||||
|
||||
//void setVertexFormat(VertexFormat* format);
|
||||
|
||||
void SetBlending(bool value);
|
||||
void SetBlendingFunction(BlendFactor srcFactor, BlendFactor destFactor);
|
||||
|
||||
void SetReadRenderTarget(RenderTarget* renderTarget);
|
||||
void SetWriteRenderTarget(RenderTarget* renderTarget);
|
||||
|
||||
void SetViewport(int x, int y, int w, int h);
|
||||
|
||||
// glBlitFramebuffer
|
||||
void BlitRenderTarget(int srcX, int srcY, int srcWidth, int srcHeight,
|
||||
int destX, int destY, int destWidth, int destHeight,
|
||||
TextureSurfaceType surfaceType);
|
||||
|
||||
// drawing
|
||||
void DrawArrays(PrimitiveType primType, uint startOf, size_t verticesCount);
|
||||
void DrawElements(PrimitiveType primType, size_t elementsCount, bool is16bitIndices);
|
||||
|
||||
private:
|
||||
VertexBuffer* m_activeVB;
|
||||
IndexBuffer* m_activeIB;
|
||||
|
||||
RenderTarget* m_activeReadRT;
|
||||
RenderTarget* m_activeWriteRT;
|
||||
|
||||
bool m_blending;
|
||||
BlendFactor m_srcBlendFactor;
|
||||
BlendFactor m_destBlendFactor;
|
||||
};
|
||||
|
||||
extern RenderDevice* g_renderDevice;
|
||||
|
||||
#endif // !RENDERDEVICE_H
|
||||
63
engine/render/rendertarget.cpp
Normal file
63
engine/render/rendertarget.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include <assert.h>
|
||||
#include "render/rendertarget.h"
|
||||
|
||||
#include "render/texturesmanager.h"
|
||||
#include "render/texture2d.h"
|
||||
|
||||
#include "glad/glad.h"
|
||||
|
||||
void RenderTarget::setDefaultFramebuffer()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
RenderTarget::RenderTarget()
|
||||
{
|
||||
m_framebuffer = -1;
|
||||
}
|
||||
|
||||
RenderTarget::~RenderTarget()
|
||||
{
|
||||
m_framebuffer = -1;
|
||||
}
|
||||
|
||||
void RenderTarget::create(const char* name /*= nullptr*/)
|
||||
{
|
||||
assert(g_texturesManager);
|
||||
|
||||
////////////////////////
|
||||
// Create FBO
|
||||
|
||||
// generate frame buffer
|
||||
glGenFramebuffers(1, &m_framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
|
||||
}
|
||||
|
||||
void RenderTarget::destroy()
|
||||
{
|
||||
GLint drawFboId;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &drawFboId);
|
||||
|
||||
if (drawFboId == (GLint)m_framebuffer)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &m_framebuffer);
|
||||
}
|
||||
|
||||
void RenderTarget::finialize()
|
||||
{
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
assert(0 && "RenderTarget::finialize: failed to finialize framebuffer. Framebuffer is not complete");
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTarget::attachColorTexture(int slot, Texture2D* texture)
|
||||
{
|
||||
assert(texture && "Failed to assing nullptr texture");
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + slot, GL_TEXTURE_2D, texture->GetHandle(), 0);
|
||||
}
|
||||
|
||||
void RenderTarget::attachDepthTexture(Texture2D* texture)
|
||||
{
|
||||
assert(texture && "Failed to assing nullptr texture");
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture->GetHandle(), 0);
|
||||
}
|
||||
33
engine/render/rendertarget.h
Normal file
33
engine/render/rendertarget.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef RENDERTARGET_H
|
||||
#define RENDERTARGET_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class Texture2D;
|
||||
class RenderDevice;
|
||||
|
||||
class RenderTarget
|
||||
{
|
||||
friend class RenderDevice;
|
||||
public:
|
||||
// #TODO: Little hack
|
||||
static void setDefaultFramebuffer();
|
||||
|
||||
public:
|
||||
RenderTarget();
|
||||
~RenderTarget();
|
||||
|
||||
void create(const char* name = nullptr);
|
||||
void destroy();
|
||||
|
||||
void finialize();
|
||||
|
||||
void attachColorTexture(int slot, Texture2D* texture);
|
||||
void attachDepthTexture(Texture2D* texture);
|
||||
|
||||
private:
|
||||
uint32_t m_framebuffer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
58
engine/render/vertexbuffer.cpp
Normal file
58
engine/render/vertexbuffer.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "render/vertexbuffer.h"
|
||||
#include "render/gl_shared.h"
|
||||
|
||||
VertexBuffer::VertexBuffer(void* data, size_t size, bool isStream /*= false*/)
|
||||
{
|
||||
glGenBuffers(1, &m_buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, size, data, isStream ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
glDeleteBuffers(1, &m_buffer);
|
||||
}
|
||||
|
||||
void VertexBuffer::Bind()
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
|
||||
}
|
||||
|
||||
void* VertexBuffer::MapBuffer(BufferAccess access)
|
||||
{
|
||||
GLenum accessGl = 0;
|
||||
|
||||
switch (access)
|
||||
{
|
||||
case BA_READ_ONLY:
|
||||
accessGl = GL_READ_ONLY;
|
||||
break;
|
||||
case BA_WRITE_ONLY:
|
||||
accessGl = GL_WRITE_ONLY;
|
||||
break;
|
||||
case BA_READ_WRITE:
|
||||
accessGl = GL_READ_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
Bind();
|
||||
|
||||
void* ptr = glMapBuffer(GL_ARRAY_BUFFER, accessGl);
|
||||
|
||||
GL_CHECK_ERROR();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void VertexBuffer::UnmapBuffer()
|
||||
{
|
||||
Bind();
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
void VertexBuffer::UpdateBuffer(void* data, size_t size)
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
|
||||
GL_CHECK_ERROR();
|
||||
}
|
||||
28
engine/render/vertexbuffer.h
Normal file
28
engine/render/vertexbuffer.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef VERTEXOBJECT_H
|
||||
#define VERTEXOBJECT_H
|
||||
|
||||
#include "render/render_shared.h"
|
||||
#include "render/gl_shared.h"
|
||||
|
||||
class RenderDevice;
|
||||
|
||||
class VertexBuffer
|
||||
{
|
||||
friend class RenderDevice;
|
||||
public:
|
||||
~VertexBuffer();
|
||||
|
||||
void Bind();
|
||||
|
||||
void* MapBuffer(BufferAccess access);
|
||||
void UnmapBuffer();
|
||||
|
||||
void UpdateBuffer(void* data, size_t size);
|
||||
|
||||
private:
|
||||
VertexBuffer(void* data, size_t size, bool isStream = false);
|
||||
|
||||
GLuint m_buffer;
|
||||
};
|
||||
|
||||
#endif // !VERTEXOBJECT_H
|
||||
Reference in New Issue
Block a user