From e45d21b6211d594397d1b6451e9ab777f063a4a4 Mon Sep 17 00:00:00 2001 From: Kirill Yurkin <47507219+ugozapad@users.noreply.github.com> Date: Fri, 7 Mar 2025 18:08:28 +0300 Subject: [PATCH] Shaders --- engine/render/gl_shared.cpp | 192 +++++++++++++++++++++++- engine/render/gl_shared.h | 95 ++++++++++++ engine/render/render.cpp | 3 + engine/render/renderdevice.cpp | 9 ++ engine/render/renderdevice.h | 4 + engine/render/shader.cpp | 92 ++++++++++++ engine/render/shader.h | 98 +++++++++++++ engine/render/shadersystem.cpp | 190 ++++++++++++++++++++++++ engine/render/shadersystem.h | 61 ++++++++ engine/render/ui.cpp | 260 +++++++++++++++++++++++++++++++++ engine/render/ui.h | 29 ++++ engine/utils/maths.h | 156 +++++++++++++++++++- 12 files changed, 1185 insertions(+), 4 deletions(-) create mode 100644 engine/render/shader.cpp create mode 100644 engine/render/shader.h create mode 100644 engine/render/shadersystem.cpp create mode 100644 engine/render/shadersystem.h create mode 100644 engine/render/ui.cpp create mode 100644 engine/render/ui.h diff --git a/engine/render/gl_shared.cpp b/engine/render/gl_shared.cpp index 97cf9e1..3201871 100644 --- a/engine/render/gl_shared.cpp +++ b/engine/render/gl_shared.cpp @@ -306,6 +306,101 @@ void GL_Load() LOAD_GL_FUNC(PFNGLGETBUFFERPARAMETERIVPROC, glGetBufferParameteriv); LOAD_GL_FUNC(PFNGLGETBUFFERPOINTERVPROC, glGetBufferPointerv); + // OpenGL 2.0 + LOAD_GL_FUNC(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate); + LOAD_GL_FUNC(PFNGLDRAWBUFFERSPROC, glDrawBuffers); + LOAD_GL_FUNC(PFNGLSTENCILOPSEPARATEPROC, glStencilOpSeparate); + LOAD_GL_FUNC(PFNGLSTENCILFUNCSEPARATEPROC, glStencilFuncSeparate); + LOAD_GL_FUNC(PFNGLSTENCILMASKSEPARATEPROC, glStencilMaskSeparate); + LOAD_GL_FUNC(PFNGLATTACHSHADERPROC, glAttachShader); + LOAD_GL_FUNC(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation); + LOAD_GL_FUNC(PFNGLCOMPILESHADERPROC, glCompileShader); + LOAD_GL_FUNC(PFNGLCREATEPROGRAMPROC, glCreateProgram); + LOAD_GL_FUNC(PFNGLCREATESHADERPROC, glCreateShader); + LOAD_GL_FUNC(PFNGLDELETEPROGRAMPROC, glDeleteProgram); + LOAD_GL_FUNC(PFNGLDELETESHADERPROC, glDeleteShader); + LOAD_GL_FUNC(PFNGLDETACHSHADERPROC, glDetachShader); + LOAD_GL_FUNC(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); + LOAD_GL_FUNC(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); + LOAD_GL_FUNC(PFNGLGETACTIVEATTRIBPROC, glGetActiveAttrib); + LOAD_GL_FUNC(PFNGLGETACTIVEUNIFORMPROC, glGetActiveUniform); + LOAD_GL_FUNC(PFNGLGETATTACHEDSHADERSPROC, glGetAttachedShaders); + LOAD_GL_FUNC(PFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation); + LOAD_GL_FUNC(PFNGLGETPROGRAMIVPROC, glGetProgramiv); + LOAD_GL_FUNC(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog); + LOAD_GL_FUNC(PFNGLGETSHADERIVPROC, glGetShaderiv); + LOAD_GL_FUNC(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); + LOAD_GL_FUNC(PFNGLGETSHADERSOURCEPROC, glGetShaderSource); + LOAD_GL_FUNC(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation); + LOAD_GL_FUNC(PFNGLGETUNIFORMFVPROC, glGetUniformfv); + LOAD_GL_FUNC(PFNGLGETUNIFORMIVPROC, glGetUniformiv); + LOAD_GL_FUNC(PFNGLGETVERTEXATTRIBDVPROC, glGetVertexAttribdv); + LOAD_GL_FUNC(PFNGLGETVERTEXATTRIBFVPROC, glGetVertexAttribfv); + LOAD_GL_FUNC(PFNGLGETVERTEXATTRIBIVPROC, glGetVertexAttribiv); + LOAD_GL_FUNC(PFNGLGETVERTEXATTRIBPOINTERVPROC, glGetVertexAttribPointerv); + LOAD_GL_FUNC(PFNGLISPROGRAMPROC, glIsProgram); + LOAD_GL_FUNC(PFNGLISSHADERPROC, glIsShader); + LOAD_GL_FUNC(PFNGLLINKPROGRAMPROC, glLinkProgram); + LOAD_GL_FUNC(PFNGLSHADERSOURCEPROC, glShaderSource); + LOAD_GL_FUNC(PFNGLUSEPROGRAMPROC, glUseProgram); + LOAD_GL_FUNC(PFNGLUNIFORM1FPROC, glUniform1f); + LOAD_GL_FUNC(PFNGLUNIFORM2FPROC, glUniform2f); + LOAD_GL_FUNC(PFNGLUNIFORM3FPROC, glUniform3f); + LOAD_GL_FUNC(PFNGLUNIFORM4FPROC, glUniform4f); + LOAD_GL_FUNC(PFNGLUNIFORM1IPROC, glUniform1i); + LOAD_GL_FUNC(PFNGLUNIFORM2IPROC, glUniform2i); + LOAD_GL_FUNC(PFNGLUNIFORM3IPROC, glUniform3i); + LOAD_GL_FUNC(PFNGLUNIFORM4IPROC, glUniform4i); + LOAD_GL_FUNC(PFNGLUNIFORM1FVPROC, glUniform1fv); + LOAD_GL_FUNC(PFNGLUNIFORM2FVPROC, glUniform2fv); + LOAD_GL_FUNC(PFNGLUNIFORM3FVPROC, glUniform3fv); + LOAD_GL_FUNC(PFNGLUNIFORM4FVPROC, glUniform4fv); + LOAD_GL_FUNC(PFNGLUNIFORM1IVPROC, glUniform1iv); + LOAD_GL_FUNC(PFNGLUNIFORM2IVPROC, glUniform2iv); + LOAD_GL_FUNC(PFNGLUNIFORM3IVPROC, glUniform3iv); + LOAD_GL_FUNC(PFNGLUNIFORM4IVPROC, glUniform4iv); + LOAD_GL_FUNC(PFNGLUNIFORMMATRIX2FVPROC, glUniformMatrix2fv); + LOAD_GL_FUNC(PFNGLUNIFORMMATRIX3FVPROC, glUniformMatrix3fv); + LOAD_GL_FUNC(PFNGLUNIFORMMATRIX4FVPROC, glUniformMatrix4fv); + LOAD_GL_FUNC(PFNGLVALIDATEPROGRAMPROC, glValidateProgram); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB1DPROC, glVertexAttrib1d); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB1DVPROC, glVertexAttrib1dv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB1FPROC, glVertexAttrib1f); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB1FVPROC, glVertexAttrib1fv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB1SPROC, glVertexAttrib1s); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB1SVPROC, glVertexAttrib1sv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB2DPROC, glVertexAttrib2d); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB2DVPROC, glVertexAttrib2dv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB2FPROC, glVertexAttrib2f); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB2FVPROC, glVertexAttrib2fv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB2SPROC, glVertexAttrib2s); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB2SVPROC, glVertexAttrib2sv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB3DPROC, glVertexAttrib3d); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB3DVPROC, glVertexAttrib3dv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB3FPROC, glVertexAttrib3f); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB3FVPROC, glVertexAttrib3fv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB3SPROC, glVertexAttrib3s); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB3SVPROC, glVertexAttrib3sv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4NBVPROC, glVertexAttrib4Nbv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4NIVPROC, glVertexAttrib4Niv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4NSVPROC, glVertexAttrib4Nsv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4NUBPROC, glVertexAttrib4Nub); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4NUBVPROC, glVertexAttrib4Nubv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4NUIVPROC, glVertexAttrib4Nuiv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4NUSVPROC, glVertexAttrib4Nusv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4BVPROC, glVertexAttrib4bv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4DPROC, glVertexAttrib4d); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4DVPROC, glVertexAttrib4dv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4FPROC, glVertexAttrib4f); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4FVPROC, glVertexAttrib4fv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4IVPROC, glVertexAttrib4iv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4SPROC, glVertexAttrib4s); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4SVPROC, glVertexAttrib4sv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4UBVPROC, glVertexAttrib4ubv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4UIVPROC, glVertexAttrib4uiv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIB4USVPROC, glVertexAttrib4usv); + LOAD_GL_FUNC(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); + //LogMsg("GL_Load: glActiveTexture=%i glGenBuffers=%i", !!glActiveTexture, !!glGenBuffers); g_EXTFramebufferSupport = GL_CheckExtensions("GL_EXT_framebuffer_object"); @@ -407,6 +502,101 @@ PFNGLUNMAPBUFFERPROC glUnmapBuffer = NULL; PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = NULL; PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv = NULL; +// OpenGL 2.0 +PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate = NULL; +PFNGLDRAWBUFFERSPROC glDrawBuffers = NULL; +PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate = NULL; +PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate = NULL; +PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate = NULL; +PFNGLATTACHSHADERPROC glAttachShader = NULL; +PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = NULL; +PFNGLCOMPILESHADERPROC glCompileShader = NULL; +PFNGLCREATEPROGRAMPROC glCreateProgram = NULL; +PFNGLCREATESHADERPROC glCreateShader = NULL; +PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL; +PFNGLDELETESHADERPROC glDeleteShader = NULL; +PFNGLDETACHSHADERPROC glDetachShader = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL; +PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform = NULL; +PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders = NULL; +PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL; +PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL; +PFNGLGETSHADERIVPROC glGetShaderiv = NULL; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL; +PFNGLGETSHADERSOURCEPROC glGetShaderSource = NULL; +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL; +PFNGLGETUNIFORMFVPROC glGetUniformfv = NULL; +PFNGLGETUNIFORMIVPROC glGetUniformiv = NULL; +PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv = NULL; +PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv = NULL; +PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv = NULL; +PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv = NULL; +PFNGLISPROGRAMPROC glIsProgram = NULL; +PFNGLISSHADERPROC glIsShader = NULL; +PFNGLLINKPROGRAMPROC glLinkProgram = NULL; +PFNGLSHADERSOURCEPROC glShaderSource = NULL; +PFNGLUSEPROGRAMPROC glUseProgram = NULL; +PFNGLUNIFORM1FPROC glUniform1f = NULL; +PFNGLUNIFORM2FPROC glUniform2f = NULL; +PFNGLUNIFORM3FPROC glUniform3f = NULL; +PFNGLUNIFORM4FPROC glUniform4f = NULL; +PFNGLUNIFORM1IPROC glUniform1i = NULL; +PFNGLUNIFORM2IPROC glUniform2i = NULL; +PFNGLUNIFORM3IPROC glUniform3i = NULL; +PFNGLUNIFORM4IPROC glUniform4i = NULL; +PFNGLUNIFORM1FVPROC glUniform1fv = NULL; +PFNGLUNIFORM2FVPROC glUniform2fv = NULL; +PFNGLUNIFORM3FVPROC glUniform3fv = NULL; +PFNGLUNIFORM4FVPROC glUniform4fv = NULL; +PFNGLUNIFORM1IVPROC glUniform1iv = NULL; +PFNGLUNIFORM2IVPROC glUniform2iv = NULL; +PFNGLUNIFORM3IVPROC glUniform3iv = NULL; +PFNGLUNIFORM4IVPROC glUniform4iv = NULL; +PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv = NULL; +PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = NULL; +PFNGLVALIDATEPROGRAMPROC glValidateProgram = NULL; +PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d = NULL; +PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv = NULL; +PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv = NULL; +PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s = NULL; +PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv = NULL; +PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d = NULL; +PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv = NULL; +PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s = NULL; +PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv = NULL; +PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d = NULL; +PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv = NULL; +PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s = NULL; +PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv = NULL; +PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv = NULL; +PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv = NULL; +PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv = NULL; +PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub = NULL; +PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv = NULL; +PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv = NULL; +PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv = NULL; +PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv = NULL; +PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d = NULL; +PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv = NULL; +PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv = NULL; +PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv = NULL; +PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s = NULL; +PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv = NULL; +PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv = NULL; +PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv = NULL; +PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL; + // GL_EXT_framebuffer_object PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT = NULL; PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL; @@ -424,4 +614,4 @@ PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT = PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL; PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL; PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL; -PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL; \ No newline at end of file +PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL; diff --git a/engine/render/gl_shared.h b/engine/render/gl_shared.h index a0680a4..e7b4b44 100644 --- a/engine/render/gl_shared.h +++ b/engine/render/gl_shared.h @@ -95,6 +95,101 @@ extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv; extern PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv; +// OpenGL 2.0 +extern PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate; +extern PFNGLDRAWBUFFERSPROC glDrawBuffers; +extern PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate; +extern PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate; +extern PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate; +extern PFNGLATTACHSHADERPROC glAttachShader; +extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; +extern PFNGLCOMPILESHADERPROC glCompileShader; +extern PFNGLCREATEPROGRAMPROC glCreateProgram; +extern PFNGLCREATESHADERPROC glCreateShader; +extern PFNGLDELETEPROGRAMPROC glDeleteProgram; +extern PFNGLDELETESHADERPROC glDeleteShader; +extern PFNGLDETACHSHADERPROC glDetachShader; +extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; +extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +extern PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; +extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; +extern PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders; +extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; +extern PFNGLGETPROGRAMIVPROC glGetProgramiv; +extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +extern PFNGLGETSHADERIVPROC glGetShaderiv; +extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +extern PFNGLGETSHADERSOURCEPROC glGetShaderSource; +extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; +extern PFNGLGETUNIFORMFVPROC glGetUniformfv; +extern PFNGLGETUNIFORMIVPROC glGetUniformiv; +extern PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv; +extern PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv; +extern PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv; +extern PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv; +extern PFNGLISPROGRAMPROC glIsProgram; +extern PFNGLISSHADERPROC glIsShader; +extern PFNGLLINKPROGRAMPROC glLinkProgram; +extern PFNGLSHADERSOURCEPROC glShaderSource; +extern PFNGLUSEPROGRAMPROC glUseProgram; +extern PFNGLUNIFORM1FPROC glUniform1f; +extern PFNGLUNIFORM2FPROC glUniform2f; +extern PFNGLUNIFORM3FPROC glUniform3f; +extern PFNGLUNIFORM4FPROC glUniform4f; +extern PFNGLUNIFORM1IPROC glUniform1i; +extern PFNGLUNIFORM2IPROC glUniform2i; +extern PFNGLUNIFORM3IPROC glUniform3i; +extern PFNGLUNIFORM4IPROC glUniform4i; +extern PFNGLUNIFORM1FVPROC glUniform1fv; +extern PFNGLUNIFORM2FVPROC glUniform2fv; +extern PFNGLUNIFORM3FVPROC glUniform3fv; +extern PFNGLUNIFORM4FVPROC glUniform4fv; +extern PFNGLUNIFORM1IVPROC glUniform1iv; +extern PFNGLUNIFORM2IVPROC glUniform2iv; +extern PFNGLUNIFORM3IVPROC glUniform3iv; +extern PFNGLUNIFORM4IVPROC glUniform4iv; +extern PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv; +extern PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; +extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; +extern PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d; +extern PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv; +extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; +extern PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv; +extern PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s; +extern PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv; +extern PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d; +extern PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv; +extern PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; +extern PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; +extern PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s; +extern PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv; +extern PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d; +extern PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv; +extern PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; +extern PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; +extern PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s; +extern PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv; +extern PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv; +extern PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv; +extern PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv; +extern PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub; +extern PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv; +extern PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv; +extern PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv; +extern PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv; +extern PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d; +extern PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv; +extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; +extern PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; +extern PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv; +extern PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s; +extern PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv; +extern PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv; +extern PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv; +extern PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv; +extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; + // GL_EXT_framebuffer_object extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT; extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; diff --git a/engine/render/render.cpp b/engine/render/render.cpp index a446940..9c912ae 100644 --- a/engine/render/render.cpp +++ b/engine/render/render.cpp @@ -8,6 +8,7 @@ #define RENDER_WINDOW_NAME "UNEASE Alpha" HWND hWnd = NULL; +View g_renderView; LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -80,6 +81,8 @@ void R_Init() { LogMsg("--- R_Init ---"); + memset(&g_renderView, 0, sizeof(g_renderView)); + // Create window R_CreateWindow(1024, 768); diff --git a/engine/render/renderdevice.cpp b/engine/render/renderdevice.cpp index 0798445..405b371 100644 --- a/engine/render/renderdevice.cpp +++ b/engine/render/renderdevice.cpp @@ -21,6 +21,7 @@ RenderDevice::RenderDevice() m_blending = false; m_activeReadRT = NULL; m_activeWriteRT = NULL; + m_backfaceCull = false; } RenderDevice::~RenderDevice() @@ -158,6 +159,14 @@ void RenderDevice::SetWriteRenderTarget(RenderTarget* renderTarget) } } +void RenderDevice::SetBackfaceCull(bool value) +{ + if (m_backfaceCull != value) { + m_backfaceCull = value; + value ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE); + } +} + void RenderDevice::SetViewport(int x, int y, int w, int h) { glViewport(x, y, w, h); diff --git a/engine/render/renderdevice.h b/engine/render/renderdevice.h index ca88ab8..3666480 100644 --- a/engine/render/renderdevice.h +++ b/engine/render/renderdevice.h @@ -31,6 +31,8 @@ public: void SetReadRenderTarget(RenderTarget* renderTarget); void SetWriteRenderTarget(RenderTarget* renderTarget); + void SetBackfaceCull(bool value); + void SetViewport(int x, int y, int w, int h); // glBlitFramebuffer @@ -52,6 +54,8 @@ private: bool m_blending; BlendFactor m_srcBlendFactor; BlendFactor m_destBlendFactor; + + bool m_backfaceCull; }; extern RenderDevice* g_renderDevice; diff --git a/engine/render/shader.cpp b/engine/render/shader.cpp new file mode 100644 index 0000000..8c196bc --- /dev/null +++ b/engine/render/shader.cpp @@ -0,0 +1,92 @@ +#include +#include "utils/logger.h" +#include "render/shader.h" +#include "filesystem/filemanager.h" +#include "filesystem/stream.h" + +GLuint CreateShader(GLenum shaderType, const char* filename) +{ + StreamBase* stream = g_fileManager->OpenStream( filename, FileAccess_Read ); + if ( !stream ) + { + LogMsg( "CreateShader: failed to open file %s", filename ); + assert( 0 ); + } + + stream->Seek( Seek_End, 0 ); + size_t length = stream->Tell(); + stream->Seek( Seek_Begin, 0 ); + + std::string content; + content.resize( length + 1 ); + stream->Read( (void*)content.data(), length ); + + content[length] = '\0'; + + const char* contentCStr = content.c_str(); + + GLuint shader = glCreateShader(shaderType); + glShaderSource(shader, 1, &contentCStr, NULL); + glCompileShader(shader); + + int success; + char infoLog[512]; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + + if (!success) + { + glGetShaderInfoLog(shader, 512, NULL, infoLog); + LogMsg("Failed to compile shader %s\n%s", filename, infoLog); + } + + LogMsg("created shader from file %s", filename); + return shader; +} + +Shader::Shader() : + m_name(nullptr), + m_stride(0), + m_layout_count(0) +{ + +} + +Shader::~Shader() +{ + if (m_name) + free( (void*)m_name ); + + Destroy(); +} + +void Shader::Create(const char* name, const char* vsfilepath, const char* psfilepath) +{ + //m_name = strdup( name ); + + GLuint vertexShader = CreateShader(GL_VERTEX_SHADER, vsfilepath); + GLuint fragmentShader = CreateShader(GL_FRAGMENT_SHADER, psfilepath); + + m_program = glCreateProgram(); + glAttachShader(m_program, vertexShader); + glAttachShader(m_program, fragmentShader); + AllocateAttributes(); + glLinkProgram(m_program); + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + int success; + char infoLog[512]; + glGetProgramiv(m_program, GL_LINK_STATUS, &success); + + if (!success) + { + glGetProgramInfoLog(m_program, 512, NULL, infoLog); + LogMsg("Failed to link program %s", infoLog); + } +} + +void Shader::Destroy() +{ + glDeleteProgram(m_program); +} diff --git a/engine/render/shader.h b/engine/render/shader.h new file mode 100644 index 0000000..0598e86 --- /dev/null +++ b/engine/render/shader.h @@ -0,0 +1,98 @@ +#ifndef SHADER_H +#define SHADER_H + +#include +#include "gl_shared.h" + +const int SHADERUNIFORM_MAX_COUNT = 16; +const int INPUT_LAYOUT_MAX_COUNT = 8; + +enum VertexAttribute_t { + VERTEXATTR_VEC2, + VERTEXATTR_VEC3, + VERTEXATTR_VEC4, + + VERTEXATTR_MAX +}; + +enum ShaderSemantic_t { + SHADERSEMANTIC_POSITION, + SHADERSEMANTIC_COLOR, + SHADERSEMANTIC_TEXCOORD, + SHADERSEMANTIC_TEXCOORD0, + SHADERSEMANTIC_TEXCOORD1, + SHADERSEMANTIC_NORMAL, + SHADERSEMANTIC_TANGENT, + SHADERSEMANTIC_BITANGENT, + + SHADERSEMANTIC_MAX +}; + +enum ShaderUniformType_t { + SHADERUNIFORM_FLOAT, + SHADERUNIFORM_VEC2, + SHADERUNIFORM_VEC3, + SHADERUNIFORM_VEC4, + SHADERUNIFORM_MAT4, + + SHADERUNIFORM_MAX +}; + +struct InputLayoutDesc_t { + VertexAttribute_t attribute; + ShaderSemantic_t semantic; +}; + +struct ShaderUniformDesc_t { + ShaderUniformType_t type; + const char* name; + size_t size; +}; + +class Shader +{ +public: + Shader(); + ~Shader(); + + void Create(const char* name, const char* vsfilepath, const char* psfilepath); + void Destroy(); + + void AllocateAttributes(); + +public: + // TEMP SOLUTION + ShaderUniformDesc_t m_uniform_desc[SHADERUNIFORM_MAX_COUNT]; + size_t m_uniform_count; + + InputLayoutDesc_t m_layouts[INPUT_LAYOUT_MAX_COUNT]; + size_t m_layout_count; + + GLuint m_glLayouts[INPUT_LAYOUT_MAX_COUNT]; + + // #TODO: REMOVE PLEASE + int m_stride; + + const char* m_name; + + GLuint m_program; +}; + +inline int GetVertexAttributeSize( VertexAttribute_t attrib ) +{ + switch ( attrib ) + { + case VERTEXATTR_VEC2: + return 2; + case VERTEXATTR_VEC3: + return 3; + case VERTEXATTR_VEC4: + return 4; + default: + break; + } + + return 0; +} + +#endif // !SHADER_H diff --git a/engine/render/shadersystem.cpp b/engine/render/shadersystem.cpp new file mode 100644 index 0000000..5d2f60e --- /dev/null +++ b/engine/render/shadersystem.cpp @@ -0,0 +1,190 @@ +#include +#include +#include "utils/logger.h" +#include "render/shadersystem.h" +#include "render/shader.h" +#include + +static const char* g_uniformNameTable[UNIFORM_MAX] = +{ + "u_modelMatrix", + "u_viewMatrix", + "u_projectionMatrix", + "u_modelViewProjection", + "u_customColor", + "u_sunDirection", + "u_sunColor", + "u_sunAmbientColor", +}; + +static const char* g_samplersNameTable[SAMPLER_MAX] = +{ + "u_albedoTexture", + "u_normalTexture", + "u_lightmapTexture", +}; + +ShaderSystem* g_shaderSystem = nullptr; + +ShaderSystem::ShaderSystem() +{ +} + +ShaderSystem::~ShaderSystem() +{ +} + +void ShaderSystem::Init() +{ + LogMsg("Initializing Shader System ..."); +} + +void ShaderSystem::Shutdown() +{ + for (int i = 0; i < m_shaders.size(); i++) + { + ShaderData& shaderData = m_shaders[i]; + + if (shaderData.shader) + { + delete shaderData.shader; + shaderData.shader = nullptr; + } + } + + m_shaders.clear(); +} + +Shader* ShaderSystem::CreateShader(const char* name, const char* vsfilepath, const char* psfilepath, InputLayoutDesc_t* inputLayout /*= nullptr*/, int inputLayoutCount/* = 0*/) +{ + for (int i = 0; i < m_shaders.size(); i++) + { + if (m_shaders[i].name == name) + return m_shaders[i].shader; + } + + Shader* pShader = new Shader(); + + if ( inputLayout && inputLayoutCount > 0 ) + { + memcpy( pShader->m_layouts, inputLayout, inputLayoutCount * sizeof( InputLayoutDesc_t ) ); + pShader->m_layout_count = inputLayoutCount; + } + + pShader->Create( name, vsfilepath, psfilepath ); + + ShaderData shaderData = { name, pShader }; + m_shaders.push_back(shaderData); + + return pShader; +} + +size_t g_vertex_attribs_sizetable[VERTEXATTR_MAX] = +{ + 2, // VERTEXATTR_VEC2 + 3, // VERTEXATTR_VEC3 + 4, // VERTEXATTR_VEC4 +}; + +size_t g_vertex_attribs_realsizetable[VERTEXATTR_MAX] = +{ + 8, // VERTEXATTR_VEC2 + 12, // VERTEXATTR_VEC3 + 16, // VERTEXATTR_VEC4 +}; + +void ApplyVertexFormat(const Shader* shader, size_t stride) +{ + size_t appliedOffset = 0; + for (int i = 0; i < shader->m_layout_count; i++) + { + const InputLayoutDesc_t* layoutEntry = &shader->m_layouts[i]; + + glEnableVertexAttribArray(GLuint(i)); + + glVertexAttribPointer(GLuint(i), GLint(g_vertex_attribs_sizetable[layoutEntry->attribute]), + GL_FLOAT, GL_FALSE, static_cast(stride), + (appliedOffset > 0) ? (void*)(appliedOffset * sizeof(float)) : (void*)0); + + appliedOffset += g_vertex_attribs_sizetable[layoutEntry->attribute]; + } +} + +void ShaderSystem::SetShader(const Shader* shader) +{ + assert( shader ); + glUseProgram( shader->m_program ); + + // apply input layout + + //for ( int i = 0; i < shader->m_layout_count; i++ ) + //{ + // const InputLayoutDesc_t& layout = shader->m_layouts[ i ]; + // + // //glEnableVertexAttribArray( shader->m_glLayouts[ i ] ); + // //glVertexAttribPointer( shader->m_glLayouts[ i ], GetVertexAttributeSize( layout.attribute ), GL_FLOAT, GL_FALSE, shader->m_stride, NULL ); + + // glEnableVertexAttribArray( i ); + // glVertexAttribPointer( i, GetVertexAttributeSize( layout.attribute ), GL_FLOAT, GL_FALSE, shader->m_stride, NULL ); + //} + + ApplyVertexFormat( shader, shader->m_stride ); + //for ( int i = 0; i < shader->m_layout_count; i++ ) + //{ + // const InputLayoutDesc_t& layout = shader->m_layouts[ i ]; + // + // glEnableVertexAttribArray( shader->m_glLayouts[ i ] ); + // glVertexAttribPointer( shader->m_glLayouts[ i ], GetVertexAttributeSize( layout.attribute ), GL_FLOAT, GL_FALSE, shader->m_stride, NULL ); + //} + +} + +void ShaderSystem::SetUniformSampler(const Shader* shader, ShaderSamplers_t sampler, int index) +{ + glGetError(); + + GLint uniformLocation = glGetUniformLocation(shader->m_program, g_samplersNameTable[sampler]); + glUniform1i(uniformLocation, static_cast(index)); +} + +void ShaderSystem::SetUniformFloat4(const Shader* shader, ShaderUniform_t uniform, const void* data) +{ + GLint location = glGetUniformLocation( shader->m_program, g_uniformNameTable[ uniform ] ); + glUniform4fv( location, 1, ( const GLfloat* )data ); +} + +void ShaderSystem::SetUniformMatrix( const Shader* shader, ShaderUniform_t uniform, const void* data ) +{ + GLint location = glGetUniformLocation( shader->m_program, g_uniformNameTable[ uniform ] ); + glUniformMatrix4fv( location, 1, GL_FALSE, ( const GLfloat* )data ); +} + +// #TODO: Move out + +static const char* s_attributeNameTable[SHADERSEMANTIC_MAX] = +{ + "a_position",//SHADERSEMANTIC_POSITION, + "a_color", //SHADERSEMANTIC_COLOR + "a_texcoord",//SHADERSEMANTIC_TEXCOORD, + "a_texcoord0", //SHADERSEMANTIC_TEXCOORD0, + "a_texcoord1",//SHADERSEMANTIC_TEXCOORD1, + "a_normal",//SHADERSEMANTIC_NORMAL, + "a_tangent",//SHADERSEMANTIC_TANGENT, + "a_bitangent"//SHADERSEMANTIC_BITANGENT, +}; + +void Shader::AllocateAttributes() +{ + // Allocate input layout + for ( int i = 0; i < m_layout_count; i++ ) + { + const InputLayoutDesc_t& layout = m_layouts[ i ]; + // Msg( "Shader::AllocateAttributes: Bind %i as %s", i, s_attributeNameTable[ layout.semantic ] ); + glBindAttribLocation( m_program, i, s_attributeNameTable[ layout.semantic ] ); + + GL_CHECK_ERROR(); + + // m_glLayouts[ i ] = glGetAttribLocation( m_program, s_attributeNameTable[i] ); + // assert( m_glLayouts[ i ] ); + } +} diff --git a/engine/render/shadersystem.h b/engine/render/shadersystem.h new file mode 100644 index 0000000..100c961 --- /dev/null +++ b/engine/render/shadersystem.h @@ -0,0 +1,61 @@ +#ifndef SHADERSYSTEM_H +#define SHADERSYSTEM_H + +#include +#include + +#include "render/shader.h" + +enum ShaderUniform_t +{ + UNIFORM_MODEL_MATRIX, + UNIFORM_VIEW_MATRIX, + UNIFORM_PROJ_MATRIX, + UNIFORM_MVP_MATRIX, + UNIFORM_CUSTOM_COLOR, + UNIFORM_SUN_DIRECTION, + UNIFORM_SUN_COLOR, + UNIFORM_SUN_AMBIENT, + + UNIFORM_MAX, +}; + +enum ShaderSamplers_t +{ + SAMPLER_ALBEDO, + SAMPLER_NORMAL, + SAMPLER_LIGHTMAP, + + SAMPLER_MAX +}; + +class ShaderSystem +{ +public: + ShaderSystem(); + ~ShaderSystem(); + + void Init(); + void Shutdown(); + + Shader* CreateShader(const char* name, const char* vsfilepath, const char* psfilepath, InputLayoutDesc_t* inputLayout = nullptr, int inputLayoutCount = 0); + + void SetShader(const Shader* shader); + + void SetUniformSampler( const Shader* shader, ShaderSamplers_t sampler, int index ); + void SetUniformFloat4( const Shader* shader, ShaderUniform_t uniform, const void* data ); + void SetUniformMatrix( const Shader* shader, ShaderUniform_t uniform, const void* data ); + +private: + struct ShaderData + { + std::string name; + Shader* shader; + }; + + std::vector m_shaders; +}; + +extern ShaderSystem* g_shaderSystem; + +#endif // !SHADERSYSTEM_H diff --git a/engine/render/ui.cpp b/engine/render/ui.cpp new file mode 100644 index 0000000..d114cc0 --- /dev/null +++ b/engine/render/ui.cpp @@ -0,0 +1,260 @@ +#include +#include +#include +#include "utils/logger.h" +#include "render/ui.h" +#include "render/vertexbuffer.h" +#include "render/indexbuffer.h" +#include "render/renderdevice.h" +#include "render/shadersystem.h" +#include "render/texturesmanager.h" +#include "render/texture2d.h" + +struct DrawInfo +{ + uint16_t vxcount; + uint16_t idxcount; +}; + +struct UIGlobals { + VertexBuffer* vb; + IndexBuffer* ib; + Shader* shader; + Texture2D* activetexture = nullptr; + Texture2D* defaultTexture = nullptr; + + UIVertex* vertices = nullptr; + uint16_t* indices = nullptr; + DrawInfo drawInfo[MAX_UI_VERTICES]; + uint16_t count = 0; + uint16_t position = 0; + uint16_t Indexposition = 0; + uint16_t currentIdx = 0; +} g_ui; + + +void uiInit() +{ + ////////////////////////////////////////////////////////////////////////// + // Buffer and context state + + // Buffer creation + g_ui.vb = g_renderDevice->CreateVertexBuffer(nullptr, MAX_UI_VERTICES, true); + g_ui.ib = g_renderDevice->CreateIndexBuffer(nullptr, MAX_UI_INDICES, true); + + // Create shader + + InputLayoutDesc_t inputLayout[] = + { + { VERTEXATTR_VEC2, SHADERSEMANTIC_POSITION }, + { VERTEXATTR_VEC2, SHADERSEMANTIC_TEXCOORD }, + { VERTEXATTR_VEC4, SHADERSEMANTIC_COLOR }, + }; + + g_ui.shader = g_shaderSystem->CreateShader("ui", "content/shaders/ui_base.vs", "content/shaders/ui_tex.ps", inputLayout, sizeof(inputLayout) / sizeof(inputLayout[0])); + g_ui.shader->m_stride = sizeof( UIVertex ); + + g_ui.defaultTexture = g_texturesManager->LoadTexture2D("$white$"); +} + +void uiShutdown() +{ + delete g_ui.ib; + delete g_ui.vb; +} + +void uiDumpBuffers() +{ + LogMsg( "--- UI Vertex Buffer ---" ); + + g_ui.vertices = (UIVertex*)g_ui.vb->MapBuffer(BA_WRITE_ONLY); + assert(g_ui.vertices); + + for ( int i = 0; i < g_ui.position; i++ ) + { + LogMsg( "%i: POSITION = %.2f %.2f", i, g_ui.vertices[ i ].position.x, g_ui.vertices[ i ].position.y ); + LogMsg( "%i: TEXCOORD = %.2f %.2f", i, g_ui.vertices[ i ].uv.x, g_ui.vertices[ i ].uv.y ); + LogMsg( "%i: COLOR = %.2f %.2f %.2f %.2f", i, + g_ui.vertices[ i ].color.x, + g_ui.vertices[ i ].color.y, + g_ui.vertices[ i ].color.z, + g_ui.vertices[ i ].color.w); + } + + LogMsg( "------------------------" ); + + g_ui.vb->UnmapBuffer(); +} + +void uiBeginRender() +{ + g_ui.vertices = (UIVertex*)g_ui.vb->MapBuffer(BA_WRITE_ONLY); + assert(g_ui.vertices); + + g_ui.indices = (uint16_t*)g_ui.ib->MapBuffer(BA_WRITE_ONLY); + assert(g_ui.indices); +} + +void uiDrawQuad(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d, const Vec4& color) +{ + DrawInfo& drawInfo = g_ui.drawInfo[g_ui.count]; + drawInfo.vxcount = 4; + drawInfo.idxcount = 6; + + g_ui.indices[g_ui.Indexposition + 0] = g_ui.currentIdx; + g_ui.indices[g_ui.Indexposition + 1] = g_ui.currentIdx + 1; + g_ui.indices[g_ui.Indexposition + 2] = g_ui.currentIdx + 2; + g_ui.indices[g_ui.Indexposition + 3] = g_ui.currentIdx; + g_ui.indices[g_ui.Indexposition + 4] = g_ui.currentIdx + 2; + g_ui.indices[g_ui.Indexposition + 5] = g_ui.currentIdx + 3; + g_ui.vertices[g_ui.position + 0].position = a; g_ui.vertices[g_ui.position + 0].color = color; + g_ui.vertices[g_ui.position + 1].position = b; g_ui.vertices[g_ui.position + 1].color = color; + g_ui.vertices[g_ui.position + 2].position = c; g_ui.vertices[g_ui.position + 2].color = color; + g_ui.vertices[g_ui.position + 3].position = d; g_ui.vertices[g_ui.position + 3].color = color; + + // texcoord + g_ui.vertices[g_ui.position + 0].uv = Vec2{ 0.0f, 1.0f }; + g_ui.vertices[g_ui.position + 1].uv = Vec2{ 1.0f, 1.0f }; + g_ui.vertices[g_ui.position + 2].uv = Vec2{ 1.0f, 0.0f }; + g_ui.vertices[g_ui.position + 3].uv = Vec2{ 0.0f, 0.0f }; + + g_ui.currentIdx += 4; + g_ui.Indexposition += 6; + g_ui.position += 4; + g_ui.count++; +} + +static inline float Rsqrt(float x) { return 1.0f / sqrtf(x); } +#define NORMALIZE2F_OVER_ZERO(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = Rsqrt(d2); VX *= inv_len; VY *= inv_len; } } (void)0 + +void uiDrawLines(const Vec2* drawPoints, const size_t pointsCount, bool closed, const Vec4& color) +{ + float thickness = 2.1f; + + const int count = closed ? pointsCount : pointsCount - 1; + const int vtxCount = (count) * 4; + const int idxCount = (count) * 6; + + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1 + 1) == pointsCount ? 0 : i1 + 1; + const Vec2& p1 = drawPoints[i1]; + const Vec2& p2 = drawPoints[i2]; + + float dx = p2.x - p1.x; + float dy = p2.y - p1.y; + NORMALIZE2F_OVER_ZERO(dx, dy); + dx *= (thickness * 0.5f); + dy *= (thickness * 0.5f); + + g_ui.vertices[g_ui.position + 0].position.x = p1.x + dy; g_ui.vertices[g_ui.position + 0].position.y = p1.y - dx; g_ui.vertices[g_ui.position + 0].color = color; + g_ui.vertices[g_ui.position + 1].position.x = p2.x + dy; g_ui.vertices[g_ui.position + 1].position.y = p2.y - dx; g_ui.vertices[g_ui.position + 1].color = color; + g_ui.vertices[g_ui.position + 2].position.x = p2.x - dy; g_ui.vertices[g_ui.position + 2].position.y = p2.y + dx; g_ui.vertices[g_ui.position + 2].color = color; + g_ui.vertices[g_ui.position + 3].position.x = p1.x - dy; g_ui.vertices[g_ui.position + 3].position.y = p1.y + dx; g_ui.vertices[g_ui.position + 3].color = color; + + g_ui.indices[g_ui.Indexposition + 0] = g_ui.currentIdx; + g_ui.indices[g_ui.Indexposition + 1] = g_ui.currentIdx + 1; + g_ui.indices[g_ui.Indexposition + 2] = g_ui.currentIdx + 2; + g_ui.indices[g_ui.Indexposition + 3] = g_ui.currentIdx; + g_ui.indices[g_ui.Indexposition + 4] = g_ui.currentIdx + 2; + g_ui.indices[g_ui.Indexposition + 5] = g_ui.currentIdx + 3; + g_ui.currentIdx += 4; + g_ui.Indexposition += 6; + g_ui.position += 4; + + DrawInfo& drawInfo = g_ui.drawInfo[g_ui.count]; + drawInfo.vxcount = 4; + drawInfo.idxcount = 6; + g_ui.count++; + } +} + +void uiDrawRect(const Vec2& position, const Vec2& size, const Vec4& color) +{ + Vec2 quad[4]; + quad[0] = { position.x, position.y }; + quad[1] = { position.x + size.x, position.y }; + quad[2] = { position.x + size.x, position.y + size.y }; + quad[3] = { position.x, position.y + size.y }; + uiDrawQuad(quad[0], quad[1], quad[2], quad[3], color); +} + +void uiSetTexture(Texture2D* texture) +{ + g_ui.activetexture = texture ? texture : g_ui.defaultTexture; +} + +void uiSetTextureByName(const char* filename) +{ + uiSetTexture( g_texturesManager->LoadTexture2D( filename ) ); +} + +void uiEndRender() +{ + g_ui.indices = nullptr; + g_ui.vertices = nullptr; + + g_ui.ib->UnmapBuffer(); + g_ui.vb->UnmapBuffer(); + + int x = 0, y = 0, w = g_renderView.width, h = g_renderView.height; + g_renderDevice->SetViewport(x, y, w, h); + + float L = x; + float R = x + w; + float T = y; + float B = y + h; +#if defined(GL_CLIP_ORIGIN) + if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left +#endif + const float orthoProjection[4][4] = + { + { 2.0f / (R - L), 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f / (T - B), 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { (R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f }, + }; + + if ( g_ui.activetexture == nullptr ) + g_ui.activetexture = g_ui.defaultTexture; + + g_texturesManager->SetTexture( 0, g_ui.activetexture ); + g_ui.activetexture->SetMin(TF_LINEAR); + g_ui.activetexture->SetMag(TF_LINEAR); + g_ui.activetexture->SetWrapS(TW_CLAMP_TO_EDGE); + g_ui.activetexture->SetWrapT(TW_CLAMP_TO_EDGE); + + g_shaderSystem->SetShader( g_ui.shader ); + g_shaderSystem->SetUniformMatrix( g_ui.shader, UNIFORM_PROJ_MATRIX, orthoProjection ); + + g_renderDevice->SetVerticesBuffer( g_ui.vb ); + g_renderDevice->SetIndicesBuffer( g_ui.ib ); + + // Enable blending + g_renderDevice->SetBlending( true ); + g_renderDevice->SetBlendingFunction( BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA ); + + // Disable depth + g_renderDevice->SetDepthTest( false ); + g_renderDevice->SetBackfaceCull( false ); + + g_renderDevice->DrawElements( PT_TRIANGLES, g_ui.Indexposition, true ); + + // Uncomment for UI VB debugging + //uiDumpBuffers(); + + g_ui.currentIdx = 0; + g_ui.Indexposition = 0; + g_ui.position = 0; + g_ui.count = 0; +} + +typedef struct Character { + int codePoint, x, y, width, height, originX, originY; +} Character; + +typedef struct Font { + const char* name; + int size, bold, italic, width, height, characterCount; + Character* characters; +} Font; diff --git a/engine/render/ui.h b/engine/render/ui.h new file mode 100644 index 0000000..84adcd9 --- /dev/null +++ b/engine/render/ui.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +#define MAX_UI_VERTICES 2048 * 4 +#define MAX_UI_INDICES 2048 * 4 + +class Texture2D; + +struct UIVertex +{ + Vec2 position; + Vec2 uv; + Vec4 color; +}; + +void uiInit(); +void uiShutdown(); + +void uiBeginRender(); + +void uiDrawQuad(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d, const Vec4& color); +void uiDrawLines(const Vec2* drawPoints, const size_t pointsCount, bool closed, const Vec4& color); +void uiDrawRect(const Vec2& position, const Vec2& size, const Vec4& color); + +void uiSetTexture(Texture2D* texture); +void uiSetTextureByName(const char* filename); + +void uiEndRender(); \ No newline at end of file diff --git a/engine/utils/maths.h b/engine/utils/maths.h index 39684b5..9ed4b5a 100644 --- a/engine/utils/maths.h +++ b/engine/utils/maths.h @@ -25,15 +25,165 @@ struct Point2 int y; }; +struct Vec2 +{ + float x; + float y; + + Vec2() : x(0.0f), y(0.0f) {} + Vec2(float _val) : x(_val), y(_val) {} + Vec2(float _x, float _y) : x(_x), y(_y) {} + + // Vec2 with Vec2 operations + + inline Vec2 operator+(const Vec2& rhs) const { return Vec2(x + rhs.x, y + rhs.y); } + inline Vec2 operator-(const Vec2& rhs) const { return Vec2(x - rhs.x, y - rhs.y); } + inline Vec2 operator*(const Vec2& rhs) const { return Vec2(x * rhs.x, y * rhs.y); } + inline Vec2 operator/(const Vec2& rhs) const { return Vec2(x / rhs.x, y / rhs.y); } + + inline Vec2& operator+=(const Vec2& rhs) { *this = *this + rhs; return *this; } + inline Vec2& operator*=(const Vec2& rhs) { *this = *this * rhs; return *this; } + inline Vec2& operator-=(const Vec2& rhs) { *this = *this - rhs; return *this; } + inline Vec2& operator/=(const Vec2& rhs) { *this = *this / rhs; return *this; } + + // Vec2 with Scalar operations + + inline Vec2 operator+(const float s) const { return Vec2(x + s, y + s); } + inline Vec2 operator-(const float s) const { return Vec2(x - s, y - s); } + inline Vec2 operator*(const float s) const { return Vec2(x * s, y * s); } + inline Vec2 operator/(const float s) const { return Vec2(x / s, y / s); } + + inline Vec2& operator+=(const float s) { *this = *this + s; return *this; } + inline Vec2& operator*=(const float s) { *this = *this * s; return *this; } + inline Vec2& operator-=(const float s) { *this = *this - s; return *this; } + inline Vec2& operator/=(const float s) { *this = *this / s; return *this; } +}; + struct Vec3 { float x; float y; float z; - Vec3() { x = y = z = 0.f; } - Vec3(float value) { x = y = z = value; } - Vec3(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } + Vec3() : x(0.0f), y(0.0f), z(0.0f) {} + Vec3(float _val) : x(_val), y(_val), z(_val) {} + Vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {} + + // Vec3 with Vec2 operations + + inline Vec3 operator+(const Vec2& rhs) const { return Vec3(x + rhs.x, y + rhs.y, z); } + inline Vec3 operator-(const Vec2& rhs) const { return Vec3(x - rhs.x, y - rhs.y, z); } + inline Vec3 operator*(const Vec2& rhs) const { return Vec3(x * rhs.x, y * rhs.y, z); } + inline Vec3 operator/(const Vec2& rhs) const { return Vec3(x / rhs.x, y / rhs.y, z); } + + inline Vec3& operator+=(const Vec2& rhs) { *this = *this + rhs; return *this; } + inline Vec3& operator*=(const Vec2& rhs) { *this = *this * rhs; return *this; } + inline Vec3& operator-=(const Vec2& rhs) { *this = *this - rhs; return *this; } + inline Vec3& operator/=(const Vec2& rhs) { *this = *this / rhs; return *this; } + + // Vec3 with Vec3 operations + + inline Vec3 operator+(const Vec3& rhs) const { return Vec3(x + rhs.x, y + rhs.y, z + rhs.z); } + inline Vec3 operator-(const Vec3& rhs) const { return Vec3(x - rhs.x, y - rhs.y, z - rhs.z); } + inline Vec3 operator*(const Vec3& rhs) const { return Vec3(x * rhs.x, y * rhs.y, z * rhs.z); } + inline Vec3 operator/(const Vec3& rhs) const { return Vec3(x / rhs.x, y / rhs.y, z / rhs.z); } + + inline Vec3& operator+=(const Vec3& rhs) { *this = *this + rhs; return *this; } + inline Vec3& operator*=(const Vec3& rhs) { *this = *this * rhs; return *this; } + inline Vec3& operator-=(const Vec3& rhs) { *this = *this - rhs; return *this; } + inline Vec3& operator/=(const Vec3& rhs) { *this = *this / rhs; return *this; } + + // Vec3 with Scalar operations + + inline Vec3 operator+(const float s) const { return Vec3(x + s, y + s, z + s); } + inline Vec3 operator-(const float s) const { return Vec3(x - s, y - s, z - s); } + inline Vec3 operator*(const float s) const { return Vec3(x * s, y * s, z * s); } + inline Vec3 operator/(const float s) const { return Vec3(x / s, y / s, z / s); } + + inline Vec3& operator+=(const float s) { *this = *this + s; return *this; } + inline Vec3& operator*=(const float s) { *this = *this * s; return *this; } + inline Vec3& operator-=(const float s) { *this = *this - s; return *this; } + inline Vec3& operator/=(const float s) { *this = *this / s; return *this; } }; +struct Vec4 +{ + float x; + float y; + float z; + float w; + + Vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {} + Vec4(float _val) : x(_val), y(_val), z(_val), w(_val) {} + Vec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) {} + + // Vec4 with Vec2 operations + + inline Vec4 operator+(const Vec2& rhs) const { return Vec4(x + rhs.x, y + rhs.y, z, w); } + inline Vec4 operator-(const Vec2& rhs) const { return Vec4(x - rhs.x, y - rhs.y, z, w); } + inline Vec4 operator*(const Vec2& rhs) const { return Vec4(x * rhs.x, y * rhs.y, z, w); } + inline Vec4 operator/(const Vec2& rhs) const { return Vec4(x / rhs.x, y / rhs.y, z, w); } + + inline Vec4& operator+=(const Vec2& rhs) { *this = *this + rhs; return *this; } + inline Vec4& operator*=(const Vec2& rhs) { *this = *this * rhs; return *this; } + inline Vec4& operator-=(const Vec2& rhs) { *this = *this - rhs; return *this; } + inline Vec4& operator/=(const Vec2& rhs) { *this = *this / rhs; return *this; } + + // Vec4 with Vec3 operations + + inline Vec4 operator+(const Vec3& rhs) const { return Vec4(x + rhs.x, y + rhs.y, z + rhs.z, w); } + inline Vec4 operator-(const Vec3& rhs) const { return Vec4(x - rhs.x, y - rhs.y, z - rhs.z, w); } + inline Vec4 operator*(const Vec3& rhs) const { return Vec4(x * rhs.x, y * rhs.y, z * rhs.z, w); } + inline Vec4 operator/(const Vec3& rhs) const { return Vec4(x / rhs.x, y / rhs.y, z / rhs.z, w); } + + inline Vec4& operator+=(const Vec3& rhs) { *this = *this + rhs; return *this; } + inline Vec4& operator*=(const Vec3& rhs) { *this = *this * rhs; return *this; } + inline Vec4& operator-=(const Vec3& rhs) { *this = *this - rhs; return *this; } + inline Vec4& operator/=(const Vec3& rhs) { *this = *this / rhs; return *this; } + + // Vec4 with Vec4 operations + + inline Vec4 operator+(const Vec4& rhs) const { return Vec4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w); } + inline Vec4 operator-(const Vec4& rhs) const { return Vec4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w); } + inline Vec4 operator*(const Vec4& rhs) const { return Vec4(x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w); } + inline Vec4 operator/(const Vec4& rhs) const { return Vec4(x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w); } + + inline Vec4& operator+=(const Vec4& rhs) { *this = *this + rhs; return *this; } + inline Vec4& operator*=(const Vec4& rhs) { *this = *this * rhs; return *this; } + inline Vec4& operator-=(const Vec4& rhs) { *this = *this - rhs; return *this; } + inline Vec4& operator/=(const Vec4& rhs) { *this = *this / rhs; return *this; } + + // Vec4 with Scalar operations + + inline Vec4 operator+(const float s) const { return Vec4(x + s, y + s, z + s, w + s); } + inline Vec4 operator-(const float s) const { return Vec4(x - s, y - s, z - s, w - s); } + inline Vec4 operator*(const float s) const { return Vec4(x * s, y * s, z * s, w * s); } + inline Vec4 operator/(const float s) const { return Vec4(x / s, y / s, z / s, w / s); } + + inline Vec4& operator+=(const float s) { *this = *this + s; return *this; } + inline Vec4& operator*=(const float s) { *this = *this * s; return *this; } + inline Vec4& operator-=(const float s) { *this = *this - s; return *this; } + inline Vec4& operator/=(const float s) { *this = *this / s; return *this; } +}; + +inline Vec3 operator+(const float s, const Vec3& v) +{ + return Vec3(s + v.x, s + v.y, s + v.z); +} + +inline Vec3 operator-(const float s, const Vec3& v) +{ + return Vec3(s - v.x, s - v.y, s - v.z); +} + +inline Vec3 operator*(const float s, const Vec3& v) +{ + return Vec3(s * v.x, s * v.y, s * v.z); +} + +inline Vec3 operator/(const float s, const Vec3& v) +{ + return Vec3(s / v.x, s / v.y, s / v.z); +} + #endif // !MATHS_H