diff --git a/projects/msvc/GLideN64.vcxproj b/projects/msvc/GLideN64.vcxproj
index 4daf237df..9e6a9e2a6 100644
--- a/projects/msvc/GLideN64.vcxproj
+++ b/projects/msvc/GLideN64.vcxproj
@@ -260,9 +260,16 @@ copy /Y "$(OutDir)$(TargetName).*" "$(Mupen64PluginsDir_x64)")
+
+
+
+
true
+
+ true
+
true
@@ -399,6 +406,15 @@ copy /Y "$(OutDir)$(TargetName).*" "$(Mupen64PluginsDir_x64)")
+
+
+
+
+
+
+
+ true
+
diff --git a/projects/msvc/GLideN64.vcxproj.filters b/projects/msvc/GLideN64.vcxproj.filters
index facba9173..123b08092 100644
--- a/projects/msvc/GLideN64.vcxproj.filters
+++ b/projects/msvc/GLideN64.vcxproj.filters
@@ -69,6 +69,12 @@
{77259791-9942-4601-a63f-5a0468e69e49}
+
+ {09919f83-2933-4b48-a4c7-f7bf6e790304}
+
+
+ {32e9be50-cb55-445a-9562-bbe05085bbe1}
+
@@ -260,6 +266,12 @@
Source Files\Graphics\OpenGL\windows
+
+ Source Files\Graphics\OpenGL\windows
+
+
+ Source Files\Graphics\OpenGL\windows
+
Source Files\Graphics\OpenGL\mupen64plus
@@ -392,6 +404,18 @@
Source Files\Graphics\OpenGL\GLSL
+
+ Source Files\Graphics\OpenGL\ThreadedOpenGL
+
+
+ Source Files\Graphics\OpenGL\ThreadedOpenGL
+
+
+ Source Files\Graphics\OpenGL\ThreadedOpenGL
+
+
+ Source Files\Graphics\OpenGL\ThreadedOpenGL
+
@@ -631,6 +655,9 @@
Header Files\Graphics\OpenGL
+
+ Header Files\Graphics\OpenGL\windows
+
Header Files
@@ -724,5 +751,23 @@
Header Files\Graphics\OpenGL\GLSL
+
+ Header Files\Graphics\OpenGL\ThreadedOpenGL
+
+
+ Header Files\Graphics\OpenGL\ThreadedOpenGL
+
+
+ Header Files\Graphics\OpenGL\ThreadedOpenGL
+
+
+ Header Files\Graphics\OpenGL\ThreadedOpenGL
+
+
+ Header Files\Graphics\OpenGL\ThreadedOpenGL
+
+
+ Header Files\Graphics\OpenGL\ThreadedOpenGL
+
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f634b64fb..b01db67b2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -61,6 +61,10 @@ set(GLideN64_SOURCES
Graphics/CombinerProgram.cpp
Graphics/ObjectHandle.cpp
Graphics/OpenGLContext/GLFunctions.cpp
+ Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.cpp
+ Graphics/OpenGLContext/ThreadedOpenGl/opengl_ObjectPool.cpp
+ Graphics/OpenGLContext/ThreadedOpenGl/opengl_Wrapper.cpp
+ Graphics/OpenGLContext/ThreadedOpenGl/opengl_WrappedFunctions.cpp
Graphics/OpenGLContext/opengl_Attributes.cpp
Graphics/OpenGLContext/opengl_BufferedDrawer.cpp
Graphics/OpenGLContext/opengl_BufferManipulationObjectFactory.cpp
diff --git a/src/Config.cpp b/src/Config.cpp
index 880d6e6b2..d4a3eb04e 100644
--- a/src/Config.cpp
+++ b/src/Config.cpp
@@ -25,6 +25,7 @@ void Config::resetToDefaults()
video.fxaa = 0;
video.multisampling = 0;
video.verticalSync = 0;
+ video.threadedVideo = 0;
texture.maxAnisotropy = 0;
texture.bilinearMode = BILINEAR_STANDARD;
diff --git a/src/Config.h b/src/Config.h
index 6d0db2aac..7e04d912f 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -28,6 +28,7 @@ struct Config
u32 fxaa;
u32 multisampling;
u32 verticalSync;
+ u32 threadedVideo;
} video;
struct
diff --git a/src/GLideNUI/ConfigDialog.cpp b/src/GLideNUI/ConfigDialog.cpp
index 66ff91cd0..5a25193a3 100644
--- a/src/GLideNUI/ConfigDialog.cpp
+++ b/src/GLideNUI/ConfigDialog.cpp
@@ -117,6 +117,7 @@ void ConfigDialog::_init()
ui->aliasingLabelVal->setText(QString::number(config.video.multisampling));
ui->anisotropicSlider->setValue(config.texture.maxAnisotropy);
ui->vSyncCheckBox->setChecked(config.video.verticalSync != 0);
+ ui->vThreadedVideoCheckBox->setChecked(config.video.threadedVideo != 0);
switch (config.texture.bilinearMode) {
case BILINEAR_3POINT:
@@ -426,6 +427,8 @@ void ConfigDialog::accept()
config.video.verticalSync = ui->vSyncCheckBox->isChecked() ? 1 : 0;
+ config.video.threadedVideo = ui->vThreadedVideoCheckBox->isChecked() ? 1 : 0;
+
// Emulation settings
config.generalEmulation.enableLOD = ui->emulateLodCheckBox->isChecked() ? 1 : 0;
config.generalEmulation.enableNoise = ui->emulateNoiseCheckBox->isChecked() ? 1 : 0;
diff --git a/src/GLideNUI/Settings.cpp b/src/GLideNUI/Settings.cpp
index 717876276..dd814d2fe 100644
--- a/src/GLideNUI/Settings.cpp
+++ b/src/GLideNUI/Settings.cpp
@@ -29,6 +29,7 @@ void _loadSettings(QSettings & settings)
config.video.multisampling = settings.value("multisampling", config.video.multisampling).toInt();
config.video.fxaa= settings.value("fxaa", config.video.fxaa).toInt();
config.video.verticalSync = settings.value("verticalSync", config.video.verticalSync).toInt();
+ config.video.threadedVideo = settings.value("threadedVideo", config.video.threadedVideo).toInt();
settings.endGroup();
settings.beginGroup("texture");
@@ -197,6 +198,7 @@ void writeSettings(const QString & _strIniFolder)
settings.setValue("multisampling", config.video.multisampling);
settings.setValue("fxaa", config.video.fxaa);
settings.setValue("verticalSync", config.video.verticalSync);
+ settings.setValue("threadedVideo", config.video.threadedVideo);
settings.endGroup();
settings.beginGroup("texture");
diff --git a/src/GLideNUI/configDialog.ui b/src/GLideNUI/configDialog.ui
index 4f5b73bca..2faa73105 100644
--- a/src/GLideNUI/configDialog.ui
+++ b/src/GLideNUI/configDialog.ui
@@ -160,6 +160,16 @@
+ -
+
+
+ <html><head/><body><p>Threaded video can improve performance with poor OpenGL drivers at the cost of very marginal input lag, usually less than half a frame</p><p>[Recommended: <span style=" font-style:italic;">Usually off, unless there are performance issues.</span>]</p></body></html>
+
+
+ Enable threaded video
+
+
+
-
diff --git a/src/Graphics/OpenGLContext/GLFunctions.cpp b/src/Graphics/OpenGLContext/GLFunctions.cpp
index 9b8dab4b3..e470884e8 100644
--- a/src/Graphics/OpenGLContext/GLFunctions.cpp
+++ b/src/Graphics/OpenGLContext/GLFunctions.cpp
@@ -3,16 +3,18 @@
#ifdef OS_WINDOWS
#define glGetProcAddress wglGetProcAddress
-#define GL_GET_PROC_ADR(proc_type, proc_name) g_##proc_name = (proc_type) glGetProcAddress(#proc_name)
+#define GL_GET_PROC_ADR(proc_type, proc_name) ptr##proc_name = (proc_type) glGetProcAddress("gl"#proc_name)
+#define ASSIGN_PROC_ADR(proc_type, proc_name) ptr##proc_name = gl##proc_name
#elif defined(VERO4K) || defined(ODROID) || defined(VC)
-#define GL_GET_PROC_ADR(proc_type, proc_name) g_##proc_name = (proc_type) dlsym(gles2so, #proc_name);
+#define GL_GET_PROC_ADR(proc_type, proc_name) ptr##proc_name = (proc_type) dlsym(gles2so, "gl"#proc_name);
#elif defined(EGL)
#define glGetProcAddress eglGetProcAddress
-#define GL_GET_PROC_ADR(proc_type, proc_name) g_##proc_name = (proc_type) glGetProcAddress(#proc_name)
+#define GL_GET_PROC_ADR(proc_type, proc_name) ptr##proc_name = (proc_type) glGetProcAddress("gl"#proc_name)
+#define GL_GET_PROC_ADR_EGL(proc_type, proc_name) ptr##proc_name = (proc_type) glGetProcAddress("egl"#proc_name)
#elif defined(OS_LINUX)
@@ -58,145 +60,140 @@ static void* IOSGLGetProcAddress (const char *name)
#endif
//GL Fucntions
-
-#ifdef OS_WINDOWS
-PFNGLACTIVETEXTUREPROC g_glActiveTexture;
-PFNGLBLENDCOLORPROC g_glBlendColor;
-#elif defined(EGL) || defined(OS_IOS)
-PFNGLBLENDFUNCPROC g_glBlendFunc;
-PFNGLPIXELSTOREIPROC g_glPixelStorei;
-PFNGLCLEARCOLORPROC g_glClearColor;
-PFNGLCULLFACEPROC g_glCullFace;
-PFNGLDEPTHFUNCPROC g_glDepthFunc;
-PFNGLDEPTHMASKPROC g_glDepthMask;
-PFNGLDISABLEPROC g_glDisable;
-PFNGLENABLEPROC g_glEnable;
-PFNGLPOLYGONOFFSETPROC g_glPolygonOffset;
-PFNGLSCISSORPROC g_glScissor;
-PFNGLVIEWPORTPROC g_glViewport;
-PFNGLBINDTEXTUREPROC g_glBindTexture;
-PFNGLTEXIMAGE2DPROC g_glTexImage2D;
-PFNGLTEXPARAMETERIPROC g_glTexParameteri;
-PFNGLGETINTEGERVPROC g_glGetIntegerv;
-PFNGLGETSTRINGPROC g_glGetString;
-PFNGLREADPIXELSPROC g_glReadPixels;
-PFNGLTEXSUBIMAGE2DPROC g_glTexSubImage2D;
-PFNGLDRAWARRAYSPROC g_glDrawArrays;
-PFNGLGETERRORPROC g_glGetError;
-PFNGLDRAWELEMENTSPROC g_glDrawElements;
-PFNGLLINEWIDTHPROC g_glLineWidth;
-PFNGLCLEARPROC g_glClear;
-PFNGLGETFLOATVPROC g_glGetFloatv;
-PFNGLDELETETEXTURESPROC g_glDeleteTextures;
-PFNGLGENTEXTURESPROC g_glGenTextures;
-PFNGLTEXPARAMETERFPROC g_glTexParameterf;
-PFNGLACTIVETEXTUREPROC g_glActiveTexture;
-PFNGLBLENDCOLORPROC g_glBlendColor;
-PFNGLREADBUFFERPROC g_glReadBuffer;
-PFNGLFINISHPROC g_glFinish;
+PFNGLBLENDFUNCPROC ptrBlendFunc;
+PFNGLPIXELSTOREIPROC ptrPixelStorei;
+PFNGLCLEARCOLORPROC ptrClearColor;
+PFNGLCULLFACEPROC ptrCullFace;
+PFNGLDEPTHFUNCPROC ptrDepthFunc;
+PFNGLDEPTHMASKPROC ptrDepthMask;
+PFNGLDISABLEPROC ptrDisable;
+PFNGLENABLEPROC ptrEnable;
+PFNGLPOLYGONOFFSETPROC ptrPolygonOffset;
+PFNGLSCISSORPROC ptrScissor;
+PFNGLVIEWPORTPROC ptrViewport;
+PFNGLBINDTEXTUREPROC ptrBindTexture;
+PFNGLTEXIMAGE2DPROC ptrTexImage2D;
+PFNGLTEXPARAMETERIPROC ptrTexParameteri;
+PFNGLGETINTEGERVPROC ptrGetIntegerv;
+PFNGLGETSTRINGPROC ptrGetString;
+PFNGLREADPIXELSPROC ptrReadPixels;
+PFNGLTEXSUBIMAGE2DPROC ptrTexSubImage2D;
+PFNGLDRAWARRAYSPROC ptrDrawArrays;
+PFNGLGETERRORPROC ptrGetError;
+PFNGLDRAWELEMENTSPROC ptrDrawElements;
+PFNGLLINEWIDTHPROC ptrLineWidth;
+PFNGLCLEARPROC ptrClear;
+PFNGLGETFLOATVPROC ptrGetFloatv;
+PFNGLDELETETEXTURESPROC ptrDeleteTextures;
+PFNGLGENTEXTURESPROC ptrGenTextures;
+PFNGLTEXPARAMETERFPROC ptrTexParameterf;
+PFNGLACTIVETEXTUREPROC ptrActiveTexture;
+PFNGLBLENDCOLORPROC ptrBlendColor;
+PFNGLREADBUFFERPROC ptrReadBuffer;
+PFNGLFINISHPROC ptrFinish;
#if defined(OS_ANDROID)
-PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC g_eglGetNativeClientBufferANDROID;
-#endif
+PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC ptrGetNativeClientBufferANDROID;
#endif
-PFNGLCREATESHADERPROC g_glCreateShader;
-PFNGLCOMPILESHADERPROC g_glCompileShader;
-PFNGLSHADERSOURCEPROC g_glShaderSource;
-PFNGLCREATEPROGRAMPROC g_glCreateProgram;
-PFNGLATTACHSHADERPROC g_glAttachShader;
-PFNGLLINKPROGRAMPROC g_glLinkProgram;
-PFNGLUSEPROGRAMPROC g_glUseProgram;
-PFNGLGETUNIFORMLOCATIONPROC g_glGetUniformLocation;
-PFNGLUNIFORM1IPROC g_glUniform1i;
-PFNGLUNIFORM1FPROC g_glUniform1f;
-PFNGLUNIFORM2FPROC g_glUniform2f;
-PFNGLUNIFORM2IPROC g_glUniform2i;
-PFNGLUNIFORM4IPROC g_glUniform4i;
-PFNGLUNIFORM4FPROC g_glUniform4f;
-PFNGLUNIFORM3FVPROC g_glUniform3fv;
-PFNGLUNIFORM4FVPROC g_glUniform4fv;
-PFNGLDETACHSHADERPROC g_glDetachShader;
-PFNGLDELETESHADERPROC g_glDeleteShader;
-PFNGLDELETEPROGRAMPROC g_glDeleteProgram;
-PFNGLGETPROGRAMINFOLOGPROC g_glGetProgramInfoLog;
-PFNGLGETSHADERINFOLOGPROC g_glGetShaderInfoLog;
-PFNGLGETSHADERIVPROC g_glGetShaderiv;
-PFNGLGETPROGRAMIVPROC g_glGetProgramiv;
-
-PFNGLENABLEVERTEXATTRIBARRAYPROC g_glEnableVertexAttribArray;
-PFNGLDISABLEVERTEXATTRIBARRAYPROC g_glDisableVertexAttribArray;
-PFNGLVERTEXATTRIBPOINTERPROC g_glVertexAttribPointer;
-PFNGLBINDATTRIBLOCATIONPROC g_glBindAttribLocation;
-PFNGLVERTEXATTRIB1FPROC g_glVertexAttrib1f;
-PFNGLVERTEXATTRIB4FPROC g_glVertexAttrib4f;
-PFNGLVERTEXATTRIB4FVPROC g_glVertexAttrib4fv;
+
+PFNGLCREATESHADERPROC ptrCreateShader;
+PFNGLCOMPILESHADERPROC ptrCompileShader;
+PFNGLSHADERSOURCEPROC ptrShaderSource;
+PFNGLCREATEPROGRAMPROC ptrCreateProgram;
+PFNGLATTACHSHADERPROC ptrAttachShader;
+PFNGLLINKPROGRAMPROC ptrLinkProgram;
+PFNGLUSEPROGRAMPROC ptrUseProgram;
+PFNGLGETUNIFORMLOCATIONPROC ptrGetUniformLocation;
+PFNGLUNIFORM1IPROC ptrUniform1i;
+PFNGLUNIFORM1FPROC ptrUniform1f;
+PFNGLUNIFORM2FPROC ptrUniform2f;
+PFNGLUNIFORM2IPROC ptrUniform2i;
+PFNGLUNIFORM4IPROC ptrUniform4i;
+PFNGLUNIFORM4FPROC ptrUniform4f;
+PFNGLUNIFORM3FVPROC ptrUniform3fv;
+PFNGLUNIFORM4FVPROC ptrUniform4fv;
+PFNGLDETACHSHADERPROC ptrDetachShader;
+PFNGLDELETESHADERPROC ptrDeleteShader;
+PFNGLDELETEPROGRAMPROC ptrDeleteProgram;
+PFNGLGETPROGRAMINFOLOGPROC ptrGetProgramInfoLog;
+PFNGLGETSHADERINFOLOGPROC ptrGetShaderInfoLog;
+PFNGLGETSHADERIVPROC ptrGetShaderiv;
+PFNGLGETPROGRAMIVPROC ptrGetProgramiv;
+
+PFNGLENABLEVERTEXATTRIBARRAYPROC ptrEnableVertexAttribArray;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC ptrDisableVertexAttribArray;
+PFNGLVERTEXATTRIBPOINTERPROC ptrVertexAttribPointer;
+PFNGLBINDATTRIBLOCATIONPROC ptrBindAttribLocation;
+PFNGLVERTEXATTRIB1FPROC ptrVertexAttrib1f;
+PFNGLVERTEXATTRIB4FPROC ptrVertexAttrib4f;
+PFNGLVERTEXATTRIB4FVPROC ptrVertexAttrib4fv;
// multitexture functions
-PFNGLDEPTHRANGEFPROC g_glDepthRangef;
-PFNGLCLEARDEPTHFPROC g_glClearDepthf;
-
-PFNGLDRAWBUFFERSPROC g_glDrawBuffers;
-PFNGLBINDFRAMEBUFFERPROC g_glBindFramebuffer;
-PFNGLDELETEFRAMEBUFFERSPROC g_glDeleteFramebuffers;
-PFNGLGENFRAMEBUFFERSPROC g_glGenFramebuffers;
-PFNGLFRAMEBUFFERTEXTURE2DPROC g_glFramebufferTexture2D;
-PFNGLTEXIMAGE2DMULTISAMPLEPROC g_glTexImage2DMultisample;
-PFNGLTEXSTORAGE2DMULTISAMPLEPROC g_glTexStorage2DMultisample;
-PFNGLGENRENDERBUFFERSPROC g_glGenRenderbuffers;
-PFNGLBINDRENDERBUFFERPROC g_glBindRenderbuffer;
-PFNGLRENDERBUFFERSTORAGEPROC g_glRenderbufferStorage;
-PFNGLFRAMEBUFFERRENDERBUFFERPROC g_glFramebufferRenderbuffer;
-PFNGLDELETERENDERBUFFERSPROC g_glDeleteRenderbuffers;
-PFNGLCHECKFRAMEBUFFERSTATUSPROC g_glCheckFramebufferStatus;
-PFNGLBLITFRAMEBUFFERPROC g_glBlitFramebuffer;
-PFNGLGENVERTEXARRAYSPROC g_glGenVertexArrays;
-PFNGLBINDVERTEXARRAYPROC g_glBindVertexArray;
-PFNGLDELETEVERTEXARRAYSPROC g_glDeleteVertexArrays;
-PFNGLGENBUFFERSPROC g_glGenBuffers;
-PFNGLBINDBUFFERPROC g_glBindBuffer;
-PFNGLBUFFERDATAPROC g_glBufferData;
-PFNGLMAPBUFFERPROC g_glMapBuffer;
-PFNGLMAPBUFFERRANGEPROC g_glMapBufferRange;
-PFNGLUNMAPBUFFERPROC g_glUnmapBuffer;
-PFNGLDELETEBUFFERSPROC g_glDeleteBuffers;
-PFNGLBINDIMAGETEXTUREPROC g_glBindImageTexture;
-PFNGLMEMORYBARRIERPROC g_glMemoryBarrier;
-PFNGLGETSTRINGIPROC g_glGetStringi;
-PFNGLINVALIDATEFRAMEBUFFERPROC g_glInvalidateFramebuffer;
-PFNGLBUFFERSTORAGEPROC g_glBufferStorage;
-PFNGLFENCESYNCPROC g_glFenceSync;
-PFNGLCLIENTWAITSYNCPROC g_glClientWaitSync;
-PFNGLDELETESYNCPROC g_glDeleteSync;
-
-PFNGLGETUNIFORMBLOCKINDEXPROC g_glGetUniformBlockIndex;
-PFNGLUNIFORMBLOCKBINDINGPROC g_glUniformBlockBinding;
-PFNGLGETACTIVEUNIFORMBLOCKIVPROC g_glGetActiveUniformBlockiv;
-PFNGLGETUNIFORMINDICESPROC g_glGetUniformIndices;
-PFNGLGETACTIVEUNIFORMSIVPROC g_glGetActiveUniformsiv;
-PFNGLBINDBUFFERBASEPROC g_glBindBufferBase;
-PFNGLBUFFERSUBDATAPROC g_glBufferSubData;
-
-PFNGLGETPROGRAMBINARYPROC g_glGetProgramBinary;
-PFNGLPROGRAMBINARYPROC g_glProgramBinary;
-PFNGLPROGRAMPARAMETERIPROC g_glProgramParameteri;
-
-PFNGLTEXSTORAGE2DPROC g_glTexStorage2D;
-PFNGLTEXTURESTORAGE2DPROC g_glTextureStorage2D;
-PFNGLTEXTURESUBIMAGE2DPROC g_glTextureSubImage2D;
-PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC g_glTextureStorage2DMultisample;
-PFNGLTEXTUREPARAMETERIPROC g_glTextureParameteri;
-PFNGLTEXTUREPARAMETERFPROC g_glTextureParameterf;
-PFNGLCREATETEXTURESPROC g_glCreateTextures;
-PFNGLCREATEBUFFERSPROC g_glCreateBuffers;
-PFNGLCREATEFRAMEBUFFERSPROC g_glCreateFramebuffers;
-PFNGLNAMEDFRAMEBUFFERTEXTUREPROC g_glNamedFramebufferTexture;
-PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC g_glDrawRangeElementsBaseVertex;
-PFNGLFLUSHMAPPEDBUFFERRANGEPROC g_glFlushMappedBufferRange;
-PFNGLTEXTUREBARRIERPROC g_glTextureBarrier;
-PFNGLTEXTUREBARRIERNVPROC g_glTextureBarrierNV;
-PFNGLCLEARBUFFERFVPROC g_glClearBufferfv;
-PFNGLENABLEIPROC g_glEnablei;
-PFNGLDISABLEIPROC g_glDisablei;
-PFNGLEGLIMAGETARGETTEXTURE2DOESPROC g_glEGLImageTargetTexture2DOES;
+PFNGLDEPTHRANGEFPROC ptrDepthRangef;
+PFNGLCLEARDEPTHFPROC ptrClearDepthf;
+
+PFNGLDRAWBUFFERSPROC ptrDrawBuffers;
+PFNGLBINDFRAMEBUFFERPROC ptrBindFramebuffer;
+PFNGLDELETEFRAMEBUFFERSPROC ptrDeleteFramebuffers;
+PFNGLGENFRAMEBUFFERSPROC ptrGenFramebuffers;
+PFNGLFRAMEBUFFERTEXTURE2DPROC ptrFramebufferTexture2D;
+PFNGLTEXIMAGE2DMULTISAMPLEPROC ptrTexImage2DMultisample;
+PFNGLTEXSTORAGE2DMULTISAMPLEPROC ptrTexStorage2DMultisample;
+PFNGLGENRENDERBUFFERSPROC ptrGenRenderbuffers;
+PFNGLBINDRENDERBUFFERPROC ptrBindRenderbuffer;
+PFNGLRENDERBUFFERSTORAGEPROC ptrRenderbufferStorage;
+PFNGLFRAMEBUFFERRENDERBUFFERPROC ptrFramebufferRenderbuffer;
+PFNGLDELETERENDERBUFFERSPROC ptrDeleteRenderbuffers;
+PFNGLCHECKFRAMEBUFFERSTATUSPROC ptrCheckFramebufferStatus;
+PFNGLBLITFRAMEBUFFERPROC ptrBlitFramebuffer;
+PFNGLGENVERTEXARRAYSPROC ptrGenVertexArrays;
+PFNGLBINDVERTEXARRAYPROC ptrBindVertexArray;
+PFNGLDELETEVERTEXARRAYSPROC ptrDeleteVertexArrays;
+PFNGLGENBUFFERSPROC ptrGenBuffers;
+PFNGLBINDBUFFERPROC ptrBindBuffer;
+PFNGLBUFFERDATAPROC ptrBufferData;
+PFNGLMAPBUFFERPROC ptrMapBuffer;
+PFNGLMAPBUFFERRANGEPROC ptrMapBufferRange;
+PFNGLUNMAPBUFFERPROC ptrUnmapBuffer;
+PFNGLDELETEBUFFERSPROC ptrDeleteBuffers;
+PFNGLBINDIMAGETEXTUREPROC ptrBindImageTexture;
+PFNGLMEMORYBARRIERPROC ptrMemoryBarrier;
+PFNGLGETSTRINGIPROC ptrGetStringi;
+PFNGLINVALIDATEFRAMEBUFFERPROC ptrInvalidateFramebuffer;
+PFNGLBUFFERSTORAGEPROC ptrBufferStorage;
+PFNGLFENCESYNCPROC ptrFenceSync;
+PFNGLCLIENTWAITSYNCPROC ptrClientWaitSync;
+PFNGLDELETESYNCPROC ptrDeleteSync;
+
+PFNGLGETUNIFORMBLOCKINDEXPROC ptrGetUniformBlockIndex;
+PFNGLUNIFORMBLOCKBINDINGPROC ptrUniformBlockBinding;
+PFNGLGETACTIVEUNIFORMBLOCKIVPROC ptrGetActiveUniformBlockiv;
+PFNGLGETUNIFORMINDICESPROC ptrGetUniformIndices;
+PFNGLGETACTIVEUNIFORMSIVPROC ptrGetActiveUniformsiv;
+PFNGLBINDBUFFERBASEPROC ptrBindBufferBase;
+PFNGLBUFFERSUBDATAPROC ptrBufferSubData;
+
+PFNGLGETPROGRAMBINARYPROC ptrGetProgramBinary;
+PFNGLPROGRAMBINARYPROC ptrProgramBinary;
+PFNGLPROGRAMPARAMETERIPROC ptrProgramParameteri;
+
+PFNGLTEXSTORAGE2DPROC ptrTexStorage2D;
+PFNGLTEXTURESTORAGE2DPROC ptrTextureStorage2D;
+PFNGLTEXTURESUBIMAGE2DPROC ptrTextureSubImage2D;
+PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC ptrTextureStorage2DMultisample;
+PFNGLTEXTUREPARAMETERIPROC ptrTextureParameteri;
+PFNGLTEXTUREPARAMETERFPROC ptrTextureParameterf;
+PFNGLCREATETEXTURESPROC ptrCreateTextures;
+PFNGLCREATEBUFFERSPROC ptrCreateBuffers;
+PFNGLCREATEFRAMEBUFFERSPROC ptrCreateFramebuffers;
+PFNGLNAMEDFRAMEBUFFERTEXTUREPROC ptrNamedFramebufferTexture;
+PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC ptrDrawRangeElementsBaseVertex;
+PFNGLFLUSHMAPPEDBUFFERRANGEPROC ptrFlushMappedBufferRange;
+PFNGLTEXTUREBARRIERPROC ptrTextureBarrier;
+PFNGLTEXTUREBARRIERNVPROC ptrTextureBarrierNV;
+PFNGLCLEARBUFFERFVPROC ptrClearBufferfv;
+PFNGLENABLEIPROC ptrEnablei;
+PFNGLDISABLEIPROC ptrDisablei;
+PFNGLEGLIMAGETARGETTEXTURE2DOESPROC ptrEGLImageTargetTexture2DOES;
void initGLFunctions()
{
@@ -207,143 +204,178 @@ void initGLFunctions()
#elif defined(VERO4K)
void *gles2so = dlopen("/opt/vero3/lib/libGLESv2.so", RTLD_NOW);
#endif
+
+#if defined(EGL) || defined(OS_IOS)
+ GL_GET_PROC_ADR(PFNGLBLENDFUNCPROC, BlendFunc);
+ GL_GET_PROC_ADR(PFNGLPIXELSTOREIPROC, PixelStorei);
+ GL_GET_PROC_ADR(PFNGLCLEARCOLORPROC, ClearColor);
+ GL_GET_PROC_ADR(PFNGLCULLFACEPROC, CullFace);
+ GL_GET_PROC_ADR(PFNGLDEPTHFUNCPROC, DepthFunc);
+ GL_GET_PROC_ADR(PFNGLDEPTHMASKPROC, DepthMask);
+ GL_GET_PROC_ADR(PFNGLDISABLEPROC, Disable);
+ GL_GET_PROC_ADR(PFNGLENABLEPROC, Enable);
+ GL_GET_PROC_ADR(PFNGLPOLYGONOFFSETPROC, PolygonOffset);
+ GL_GET_PROC_ADR(PFNGLSCISSORPROC, Scissor);
+ GL_GET_PROC_ADR(PFNGLVIEWPORTPROC, Viewport);
+ GL_GET_PROC_ADR(PFNGLBINDTEXTUREPROC, BindTexture);
+ GL_GET_PROC_ADR(PFNGLTEXIMAGE2DPROC, TexImage2D);
+ GL_GET_PROC_ADR(PFNGLTEXPARAMETERIPROC, TexParameteri);
+ GL_GET_PROC_ADR(PFNGLGETINTEGERVPROC, GetIntegerv);
+ GL_GET_PROC_ADR(PFNGLGETSTRINGPROC, GetString);
+ GL_GET_PROC_ADR(PFNGLREADPIXELSPROC, ReadPixels);
+ GL_GET_PROC_ADR(PFNGLTEXSUBIMAGE2DPROC, TexSubImage2D);
+ GL_GET_PROC_ADR(PFNGLDRAWARRAYSPROC, DrawArrays);
+ GL_GET_PROC_ADR(PFNGLGETERRORPROC, GetError);
+ GL_GET_PROC_ADR(PFNGLDRAWELEMENTSPROC, DrawElements);
+ GL_GET_PROC_ADR(PFNGLLINEWIDTHPROC, LineWidth);
+ GL_GET_PROC_ADR(PFNGLCLEARPROC, Clear);
+ GL_GET_PROC_ADR(PFNGLGETFLOATVPROC, GetFloatv);
+ GL_GET_PROC_ADR(PFNGLDELETETEXTURESPROC, DeleteTextures);
+ GL_GET_PROC_ADR(PFNGLGENTEXTURESPROC, GenTextures);
+ GL_GET_PROC_ADR(PFNGLTEXPARAMETERFPROC, TexParameterf);
+ GL_GET_PROC_ADR(PFNGLACTIVETEXTUREPROC, ActiveTexture);
+ GL_GET_PROC_ADR(PFNGLBLENDCOLORPROC, BlendColor);
+ GL_GET_PROC_ADR(PFNGLREADBUFFERPROC, ReadBuffer);
+ GL_GET_PROC_ADR(PFNGLFINISHPROC, Finish);
+#if defined(OS_ANDROID)
+ GL_GET_PROC_ADR_EGL(PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC, GetNativeClientBufferANDROID);
+#endif
+#else
#ifdef OS_WINDOWS
- GL_GET_PROC_ADR(PFNGLACTIVETEXTUREPROC, glActiveTexture);
- GL_GET_PROC_ADR(PFNGLBLENDCOLORPROC, glBlendColor);
-#elif defined(EGL) || defined(OS_IOS)
- GL_GET_PROC_ADR(PFNGLBLENDFUNCPROC, glBlendFunc);
- GL_GET_PROC_ADR(PFNGLPIXELSTOREIPROC, glPixelStorei);
- GL_GET_PROC_ADR(PFNGLCLEARCOLORPROC, glClearColor);
- GL_GET_PROC_ADR(PFNGLCULLFACEPROC, glCullFace);
- GL_GET_PROC_ADR(PFNGLDEPTHFUNCPROC, glDepthFunc);
- GL_GET_PROC_ADR(PFNGLDEPTHMASKPROC, glDepthMask);
- GL_GET_PROC_ADR(PFNGLDISABLEPROC, glDisable);
- GL_GET_PROC_ADR(PFNGLENABLEPROC, glEnable);
- GL_GET_PROC_ADR(PFNGLPOLYGONOFFSETPROC, glPolygonOffset);
- GL_GET_PROC_ADR(PFNGLSCISSORPROC, glScissor);
- GL_GET_PROC_ADR(PFNGLVIEWPORTPROC, glViewport);
- GL_GET_PROC_ADR(PFNGLBINDTEXTUREPROC, glBindTexture);
- GL_GET_PROC_ADR(PFNGLTEXIMAGE2DPROC, glTexImage2D);
- GL_GET_PROC_ADR(PFNGLTEXPARAMETERIPROC, glTexParameteri);
- GL_GET_PROC_ADR(PFNGLGETINTEGERVPROC, glGetIntegerv);
- GL_GET_PROC_ADR(PFNGLGETSTRINGPROC, glGetString);
- GL_GET_PROC_ADR(PFNGLREADPIXELSPROC, glReadPixels);
- GL_GET_PROC_ADR(PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D);
- GL_GET_PROC_ADR(PFNGLDRAWARRAYSPROC, glDrawArrays);
- GL_GET_PROC_ADR(PFNGLGETERRORPROC, glGetError);
- GL_GET_PROC_ADR(PFNGLDRAWELEMENTSPROC, glDrawElements);
- GL_GET_PROC_ADR(PFNGLLINEWIDTHPROC, glLineWidth);
- GL_GET_PROC_ADR(PFNGLCLEARPROC, glClear);
- GL_GET_PROC_ADR(PFNGLGETFLOATVPROC, glGetFloatv);
- GL_GET_PROC_ADR(PFNGLDELETETEXTURESPROC, glDeleteTextures);
- GL_GET_PROC_ADR(PFNGLGENTEXTURESPROC, glGenTextures);
- GL_GET_PROC_ADR(PFNGLTEXPARAMETERFPROC, glTexParameterf);
- GL_GET_PROC_ADR(PFNGLACTIVETEXTUREPROC, glActiveTexture);
- GL_GET_PROC_ADR(PFNGLBLENDCOLORPROC, glBlendColor);
- GL_GET_PROC_ADR(PFNGLREADBUFFERPROC, glReadBuffer);
- GL_GET_PROC_ADR(PFNGLFINISHPROC, glFinish);
-#ifdef OS_ANDROID
- GL_GET_PROC_ADR(PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC, eglGetNativeClientBufferANDROID);
+ GL_GET_PROC_ADR(PFNGLACTIVETEXTUREPROC, ActiveTexture);
+ GL_GET_PROC_ADR(PFNGLBLENDCOLORPROC, BlendColor);
+#else
+ ASSIGN_PROC_ADR(PFNGLACTIVETEXTUREPROC, ActiveTexture)
+ ASSIGN_PROC_ADR(PFNGLBLENDCOLORPROC, BlendColor);
#endif
+ ASSIGN_PROC_ADR(PFNGLBLENDFUNCPROC, BlendFunc);
+ ASSIGN_PROC_ADR(PFNGLPIXELSTOREIPROC, PixelStorei);
+ ASSIGN_PROC_ADR(PFNGLCLEARCOLORPROC, ClearColor);
+ ASSIGN_PROC_ADR(PFNGLCULLFACEPROC, CullFace);
+ ASSIGN_PROC_ADR(PFNGLDEPTHFUNCPROC, DepthFunc);
+ ASSIGN_PROC_ADR(PFNGLDEPTHMASKPROC, DepthMask);
+ ASSIGN_PROC_ADR(PFNGLDISABLEPROC, Disable);
+ ASSIGN_PROC_ADR(PFNGLENABLEPROC, Enable);
+ ASSIGN_PROC_ADR(PFNGLPOLYGONOFFSETPROC, PolygonOffset);
+ ASSIGN_PROC_ADR(PFNGLSCISSORPROC, Scissor);
+ ASSIGN_PROC_ADR(PFNGLVIEWPORTPROC, Viewport);
+ ASSIGN_PROC_ADR(PFNGLBINDTEXTUREPROC, BindTexture);
+ ASSIGN_PROC_ADR(PFNGLTEXIMAGE2DPROC, TexImage2D);
+ ASSIGN_PROC_ADR(PFNGLTEXPARAMETERIPROC, TexParameteri);
+ ASSIGN_PROC_ADR(PFNGLGETINTEGERVPROC, GetIntegerv);
+ ASSIGN_PROC_ADR(PFNGLGETSTRINGPROC, GetString);
+ ASSIGN_PROC_ADR(PFNGLREADPIXELSPROC, ReadPixels);
+ ASSIGN_PROC_ADR(PFNGLTEXSUBIMAGE2DPROC, TexSubImage2D);
+ ASSIGN_PROC_ADR(PFNGLDRAWARRAYSPROC, DrawArrays);
+ ASSIGN_PROC_ADR(PFNGLGETERRORPROC, GetError);
+ ASSIGN_PROC_ADR(PFNGLDRAWELEMENTSPROC, DrawElements);
+ ASSIGN_PROC_ADR(PFNGLLINEWIDTHPROC, LineWidth);
+ ASSIGN_PROC_ADR(PFNGLCLEARPROC, Clear);
+ ASSIGN_PROC_ADR(PFNGLGETFLOATVPROC, GetFloatv);
+ ASSIGN_PROC_ADR(PFNGLDELETETEXTURESPROC, DeleteTextures);
+ ASSIGN_PROC_ADR(PFNGLGENTEXTURESPROC, GenTextures);
+ ASSIGN_PROC_ADR(PFNGLTEXPARAMETERFPROC, TexParameterf);
+ ASSIGN_PROC_ADR(PFNGLREADBUFFERPROC, ReadBuffer);
+ ASSIGN_PROC_ADR(PFNGLFINISHPROC, Finish);
#endif
- GL_GET_PROC_ADR(PFNGLCREATESHADERPROC, glCreateShader);
- GL_GET_PROC_ADR(PFNGLCOMPILESHADERPROC, glCompileShader);
- GL_GET_PROC_ADR(PFNGLSHADERSOURCEPROC, glShaderSource);
- GL_GET_PROC_ADR(PFNGLCREATEPROGRAMPROC, glCreateProgram);
- GL_GET_PROC_ADR(PFNGLATTACHSHADERPROC, glAttachShader);
- GL_GET_PROC_ADR(PFNGLLINKPROGRAMPROC, glLinkProgram);
- GL_GET_PROC_ADR(PFNGLUSEPROGRAMPROC, glUseProgram);
- GL_GET_PROC_ADR(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation);
- GL_GET_PROC_ADR(PFNGLUNIFORM1IPROC, glUniform1i);
- GL_GET_PROC_ADR(PFNGLUNIFORM1FPROC, glUniform1f);
- GL_GET_PROC_ADR(PFNGLUNIFORM2FPROC, glUniform2f);
- GL_GET_PROC_ADR(PFNGLUNIFORM2IPROC, glUniform2i);
- GL_GET_PROC_ADR(PFNGLUNIFORM4IPROC, glUniform4i);
- GL_GET_PROC_ADR(PFNGLUNIFORM4FPROC, glUniform4f);
- GL_GET_PROC_ADR(PFNGLUNIFORM3FVPROC, glUniform3fv);
- GL_GET_PROC_ADR(PFNGLUNIFORM4FVPROC, glUniform4fv);
- GL_GET_PROC_ADR(PFNGLDETACHSHADERPROC, glDetachShader);
- GL_GET_PROC_ADR(PFNGLDELETESHADERPROC, glDeleteShader);
- GL_GET_PROC_ADR(PFNGLDELETEPROGRAMPROC, glDeleteProgram);
- GL_GET_PROC_ADR(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog);
- GL_GET_PROC_ADR(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog);
- GL_GET_PROC_ADR(PFNGLGETSHADERIVPROC, glGetShaderiv);
- GL_GET_PROC_ADR(PFNGLGETPROGRAMIVPROC, glGetProgramiv);
-
- GL_GET_PROC_ADR(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray);
- GL_GET_PROC_ADR(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray);
- GL_GET_PROC_ADR(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer);
- GL_GET_PROC_ADR(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation);
- GL_GET_PROC_ADR(PFNGLVERTEXATTRIB1FPROC, glVertexAttrib1f);
- GL_GET_PROC_ADR(PFNGLVERTEXATTRIB4FPROC, glVertexAttrib4f);
- GL_GET_PROC_ADR(PFNGLVERTEXATTRIB4FVPROC, glVertexAttrib4fv);
-
- GL_GET_PROC_ADR(PFNGLDEPTHRANGEFPROC, glDepthRangef);
- GL_GET_PROC_ADR(PFNGLCLEARDEPTHFPROC, glClearDepthf);
-
- GL_GET_PROC_ADR(PFNGLDRAWBUFFERSPROC, glDrawBuffers);
- GL_GET_PROC_ADR(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer);
- GL_GET_PROC_ADR(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers);
- GL_GET_PROC_ADR(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers);
- GL_GET_PROC_ADR(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D);
- GL_GET_PROC_ADR(PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample);
- GL_GET_PROC_ADR(PFNGLTEXSTORAGE2DMULTISAMPLEPROC, glTexStorage2DMultisample);
- GL_GET_PROC_ADR(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers);
- GL_GET_PROC_ADR(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer);
- GL_GET_PROC_ADR(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage);
- GL_GET_PROC_ADR(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer);
- GL_GET_PROC_ADR(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers);
- GL_GET_PROC_ADR(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus);
- GL_GET_PROC_ADR(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer);
- GL_GET_PROC_ADR(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays);
- GL_GET_PROC_ADR(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray);
- GL_GET_PROC_ADR(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays);
- GL_GET_PROC_ADR(PFNGLGENBUFFERSPROC, glGenBuffers);
- GL_GET_PROC_ADR(PFNGLBINDBUFFERPROC, glBindBuffer);
- GL_GET_PROC_ADR(PFNGLBUFFERDATAPROC, glBufferData);
- GL_GET_PROC_ADR(PFNGLMAPBUFFERPROC, glMapBuffer);
- GL_GET_PROC_ADR(PFNGLMAPBUFFERRANGEPROC, glMapBufferRange);
- GL_GET_PROC_ADR(PFNGLUNMAPBUFFERPROC, glUnmapBuffer);
- GL_GET_PROC_ADR(PFNGLDELETEBUFFERSPROC, glDeleteBuffers);
- GL_GET_PROC_ADR(PFNGLBINDIMAGETEXTUREPROC, glBindImageTexture);
- GL_GET_PROC_ADR(PFNGLMEMORYBARRIERPROC, glMemoryBarrier);
- GL_GET_PROC_ADR(PFNGLGETSTRINGIPROC, glGetStringi);
- GL_GET_PROC_ADR(PFNGLINVALIDATEFRAMEBUFFERPROC, glInvalidateFramebuffer);
- GL_GET_PROC_ADR(PFNGLBUFFERSTORAGEPROC, glBufferStorage);
- GL_GET_PROC_ADR(PFNGLFENCESYNCPROC, glFenceSync);
- GL_GET_PROC_ADR(PFNGLCLIENTWAITSYNCPROC, glClientWaitSync);
- GL_GET_PROC_ADR(PFNGLDELETESYNCPROC, glDeleteSync);
-
- GL_GET_PROC_ADR(PFNGLGETUNIFORMBLOCKINDEXPROC, glGetUniformBlockIndex);
- GL_GET_PROC_ADR(PFNGLUNIFORMBLOCKBINDINGPROC, glUniformBlockBinding);
- GL_GET_PROC_ADR(PFNGLGETACTIVEUNIFORMBLOCKIVPROC, glGetActiveUniformBlockiv);
- GL_GET_PROC_ADR(PFNGLGETUNIFORMINDICESPROC, glGetUniformIndices);
- GL_GET_PROC_ADR(PFNGLGETACTIVEUNIFORMSIVPROC, glGetActiveUniformsiv);
- GL_GET_PROC_ADR(PFNGLBINDBUFFERBASEPROC, glBindBufferBase);
- GL_GET_PROC_ADR(PFNGLBUFFERSUBDATAPROC, glBufferSubData);
-
- GL_GET_PROC_ADR(PFNGLGETPROGRAMBINARYPROC, glGetProgramBinary);
- GL_GET_PROC_ADR(PFNGLPROGRAMBINARYPROC, glProgramBinary);
- GL_GET_PROC_ADR(PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri);
-
- GL_GET_PROC_ADR(PFNGLTEXSTORAGE2DPROC, glTexStorage2D);
- GL_GET_PROC_ADR(PFNGLTEXTURESTORAGE2DPROC, glTextureStorage2D);
- GL_GET_PROC_ADR(PFNGLTEXTURESUBIMAGE2DPROC, glTextureSubImage2D);
- GL_GET_PROC_ADR(PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC, glTextureStorage2DMultisample);
-
- GL_GET_PROC_ADR(PFNGLTEXTUREPARAMETERIPROC, glTextureParameteri);
- GL_GET_PROC_ADR(PFNGLTEXTUREPARAMETERFPROC, glTextureParameterf);
- GL_GET_PROC_ADR(PFNGLCREATETEXTURESPROC, glCreateTextures);
- GL_GET_PROC_ADR(PFNGLCREATEBUFFERSPROC, glCreateBuffers);
- GL_GET_PROC_ADR(PFNGLCREATEFRAMEBUFFERSPROC, glCreateFramebuffers);
- GL_GET_PROC_ADR(PFNGLNAMEDFRAMEBUFFERTEXTUREPROC, glNamedFramebufferTexture);
- GL_GET_PROC_ADR(PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC, glDrawRangeElementsBaseVertex);
- GL_GET_PROC_ADR(PFNGLFLUSHMAPPEDBUFFERRANGEPROC, glFlushMappedBufferRange);
- GL_GET_PROC_ADR(PFNGLTEXTUREBARRIERPROC, glTextureBarrier);
- GL_GET_PROC_ADR(PFNGLTEXTUREBARRIERNVPROC, glTextureBarrierNV);
- GL_GET_PROC_ADR(PFNGLCLEARBUFFERFVPROC, glClearBufferfv);
- GL_GET_PROC_ADR(PFNGLENABLEIPROC, glEnablei);
- GL_GET_PROC_ADR(PFNGLDISABLEIPROC, glDisablei);
- GL_GET_PROC_ADR(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC, glEGLImageTargetTexture2DOES);
+ GL_GET_PROC_ADR(PFNGLCREATESHADERPROC, CreateShader);
+ GL_GET_PROC_ADR(PFNGLCOMPILESHADERPROC, CompileShader);
+ GL_GET_PROC_ADR(PFNGLSHADERSOURCEPROC, ShaderSource);
+ GL_GET_PROC_ADR(PFNGLCREATEPROGRAMPROC, CreateProgram);
+ GL_GET_PROC_ADR(PFNGLATTACHSHADERPROC, AttachShader);
+ GL_GET_PROC_ADR(PFNGLLINKPROGRAMPROC, LinkProgram);
+ GL_GET_PROC_ADR(PFNGLUSEPROGRAMPROC, UseProgram);
+ GL_GET_PROC_ADR(PFNGLGETUNIFORMLOCATIONPROC, GetUniformLocation);
+ GL_GET_PROC_ADR(PFNGLUNIFORM1IPROC, Uniform1i);
+ GL_GET_PROC_ADR(PFNGLUNIFORM1FPROC, Uniform1f);
+ GL_GET_PROC_ADR(PFNGLUNIFORM2FPROC, Uniform2f);
+ GL_GET_PROC_ADR(PFNGLUNIFORM2IPROC, Uniform2i);
+ GL_GET_PROC_ADR(PFNGLUNIFORM4IPROC, Uniform4i);
+ GL_GET_PROC_ADR(PFNGLUNIFORM4FPROC, Uniform4f);
+ GL_GET_PROC_ADR(PFNGLUNIFORM3FVPROC, Uniform3fv);
+ GL_GET_PROC_ADR(PFNGLUNIFORM4FVPROC, Uniform4fv);
+ GL_GET_PROC_ADR(PFNGLDETACHSHADERPROC, DetachShader);
+ GL_GET_PROC_ADR(PFNGLDELETESHADERPROC, DeleteShader);
+ GL_GET_PROC_ADR(PFNGLDELETEPROGRAMPROC, DeleteProgram);
+ GL_GET_PROC_ADR(PFNGLGETPROGRAMINFOLOGPROC, GetProgramInfoLog);
+ GL_GET_PROC_ADR(PFNGLGETSHADERINFOLOGPROC, GetShaderInfoLog);
+ GL_GET_PROC_ADR(PFNGLGETSHADERIVPROC, GetShaderiv);
+ GL_GET_PROC_ADR(PFNGLGETPROGRAMIVPROC, GetProgramiv);
+
+ GL_GET_PROC_ADR(PFNGLENABLEVERTEXATTRIBARRAYPROC, EnableVertexAttribArray);
+ GL_GET_PROC_ADR(PFNGLDISABLEVERTEXATTRIBARRAYPROC, DisableVertexAttribArray);
+ GL_GET_PROC_ADR(PFNGLVERTEXATTRIBPOINTERPROC, VertexAttribPointer);
+ GL_GET_PROC_ADR(PFNGLBINDATTRIBLOCATIONPROC, BindAttribLocation);
+ GL_GET_PROC_ADR(PFNGLVERTEXATTRIB1FPROC, VertexAttrib1f);
+ GL_GET_PROC_ADR(PFNGLVERTEXATTRIB4FPROC, VertexAttrib4f);
+ GL_GET_PROC_ADR(PFNGLVERTEXATTRIB4FVPROC, VertexAttrib4fv);
+
+ GL_GET_PROC_ADR(PFNGLDEPTHRANGEFPROC, DepthRangef);
+ GL_GET_PROC_ADR(PFNGLCLEARDEPTHFPROC, ClearDepthf);
+
+ GL_GET_PROC_ADR(PFNGLDRAWBUFFERSPROC, DrawBuffers);
+ GL_GET_PROC_ADR(PFNGLBINDFRAMEBUFFERPROC, BindFramebuffer);
+ GL_GET_PROC_ADR(PFNGLDELETEFRAMEBUFFERSPROC, DeleteFramebuffers);
+ GL_GET_PROC_ADR(PFNGLGENFRAMEBUFFERSPROC, GenFramebuffers);
+ GL_GET_PROC_ADR(PFNGLFRAMEBUFFERTEXTURE2DPROC, FramebufferTexture2D);
+ GL_GET_PROC_ADR(PFNGLTEXIMAGE2DMULTISAMPLEPROC, TexImage2DMultisample);
+ GL_GET_PROC_ADR(PFNGLTEXSTORAGE2DMULTISAMPLEPROC, TexStorage2DMultisample);
+ GL_GET_PROC_ADR(PFNGLGENRENDERBUFFERSPROC, GenRenderbuffers);
+ GL_GET_PROC_ADR(PFNGLBINDRENDERBUFFERPROC, BindRenderbuffer);
+ GL_GET_PROC_ADR(PFNGLRENDERBUFFERSTORAGEPROC, RenderbufferStorage);
+ GL_GET_PROC_ADR(PFNGLFRAMEBUFFERRENDERBUFFERPROC, FramebufferRenderbuffer);
+ GL_GET_PROC_ADR(PFNGLDELETERENDERBUFFERSPROC, DeleteRenderbuffers);
+ GL_GET_PROC_ADR(PFNGLCHECKFRAMEBUFFERSTATUSPROC, CheckFramebufferStatus);
+ GL_GET_PROC_ADR(PFNGLBLITFRAMEBUFFERPROC, BlitFramebuffer);
+ GL_GET_PROC_ADR(PFNGLGENVERTEXARRAYSPROC, GenVertexArrays);
+ GL_GET_PROC_ADR(PFNGLBINDVERTEXARRAYPROC, BindVertexArray);
+ GL_GET_PROC_ADR(PFNGLDELETEVERTEXARRAYSPROC, DeleteVertexArrays);
+ GL_GET_PROC_ADR(PFNGLGENBUFFERSPROC, GenBuffers);
+ GL_GET_PROC_ADR(PFNGLBINDBUFFERPROC, BindBuffer);
+ GL_GET_PROC_ADR(PFNGLBUFFERDATAPROC, BufferData);
+ GL_GET_PROC_ADR(PFNGLMAPBUFFERPROC, MapBuffer);
+ GL_GET_PROC_ADR(PFNGLMAPBUFFERRANGEPROC, MapBufferRange);
+ GL_GET_PROC_ADR(PFNGLUNMAPBUFFERPROC, UnmapBuffer);
+ GL_GET_PROC_ADR(PFNGLDELETEBUFFERSPROC, DeleteBuffers);
+ GL_GET_PROC_ADR(PFNGLBINDIMAGETEXTUREPROC, BindImageTexture);
+ GL_GET_PROC_ADR(PFNGLMEMORYBARRIERPROC, MemoryBarrier);
+ GL_GET_PROC_ADR(PFNGLGETSTRINGIPROC, GetStringi);
+ GL_GET_PROC_ADR(PFNGLINVALIDATEFRAMEBUFFERPROC, InvalidateFramebuffer);
+ GL_GET_PROC_ADR(PFNGLBUFFERSTORAGEPROC, BufferStorage);
+ GL_GET_PROC_ADR(PFNGLFENCESYNCPROC, FenceSync);
+ GL_GET_PROC_ADR(PFNGLCLIENTWAITSYNCPROC, ClientWaitSync);
+ GL_GET_PROC_ADR(PFNGLDELETESYNCPROC, DeleteSync);
+
+ GL_GET_PROC_ADR(PFNGLGETUNIFORMBLOCKINDEXPROC, GetUniformBlockIndex);
+ GL_GET_PROC_ADR(PFNGLUNIFORMBLOCKBINDINGPROC, UniformBlockBinding);
+ GL_GET_PROC_ADR(PFNGLGETACTIVEUNIFORMBLOCKIVPROC, GetActiveUniformBlockiv);
+ GL_GET_PROC_ADR(PFNGLGETUNIFORMINDICESPROC, GetUniformIndices);
+ GL_GET_PROC_ADR(PFNGLGETACTIVEUNIFORMSIVPROC, GetActiveUniformsiv);
+ GL_GET_PROC_ADR(PFNGLBINDBUFFERBASEPROC, BindBufferBase);
+ GL_GET_PROC_ADR(PFNGLBUFFERSUBDATAPROC, BufferSubData);
+
+ GL_GET_PROC_ADR(PFNGLGETPROGRAMBINARYPROC, GetProgramBinary);
+ GL_GET_PROC_ADR(PFNGLPROGRAMBINARYPROC, ProgramBinary);
+ GL_GET_PROC_ADR(PFNGLPROGRAMPARAMETERIPROC, ProgramParameteri);
+
+ GL_GET_PROC_ADR(PFNGLTEXSTORAGE2DPROC, TexStorage2D);
+ GL_GET_PROC_ADR(PFNGLTEXTURESTORAGE2DPROC, TextureStorage2D);
+ GL_GET_PROC_ADR(PFNGLTEXTURESUBIMAGE2DPROC, TextureSubImage2D);
+ GL_GET_PROC_ADR(PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC, TextureStorage2DMultisample);
+
+ GL_GET_PROC_ADR(PFNGLTEXTUREPARAMETERIPROC, TextureParameteri);
+ GL_GET_PROC_ADR(PFNGLTEXTUREPARAMETERFPROC, TextureParameterf);
+ GL_GET_PROC_ADR(PFNGLCREATETEXTURESPROC, CreateTextures);
+ GL_GET_PROC_ADR(PFNGLCREATEBUFFERSPROC, CreateBuffers);
+ GL_GET_PROC_ADR(PFNGLCREATEFRAMEBUFFERSPROC, CreateFramebuffers);
+ GL_GET_PROC_ADR(PFNGLNAMEDFRAMEBUFFERTEXTUREPROC, NamedFramebufferTexture);
+ GL_GET_PROC_ADR(PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC, DrawRangeElementsBaseVertex);
+ GL_GET_PROC_ADR(PFNGLFLUSHMAPPEDBUFFERRANGEPROC, FlushMappedBufferRange);
+ GL_GET_PROC_ADR(PFNGLTEXTUREBARRIERPROC, TextureBarrier);
+ GL_GET_PROC_ADR(PFNGLTEXTUREBARRIERNVPROC, TextureBarrierNV);
+ GL_GET_PROC_ADR(PFNGLCLEARBUFFERFVPROC, ClearBufferfv);
+ GL_GET_PROC_ADR(PFNGLENABLEIPROC, Enablei);
+ GL_GET_PROC_ADR(PFNGLDISABLEIPROC, Disablei);
+ GL_GET_PROC_ADR(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC, EGLImageTargetTexture2DOES);
}
diff --git a/src/Graphics/OpenGLContext/GLFunctions.h b/src/Graphics/OpenGLContext/GLFunctions.h
index f2673f8f9..944e23acb 100644
--- a/src/Graphics/OpenGLContext/GLFunctions.h
+++ b/src/Graphics/OpenGLContext/GLFunctions.h
@@ -4,7 +4,6 @@
#ifdef OS_WINDOWS
#include
#elif defined(OS_LINUX)
-//#define GL_GLEXT_PROTOTYPES
#include
#endif
@@ -16,7 +15,7 @@
#include
#include
#include
-//#include
+
#elif defined(OS_IOS)
#include
#include
@@ -30,6 +29,7 @@ typedef double GLdouble;
#include
#else
#include
+#include
#endif
#include
@@ -37,326 +37,296 @@ typedef double GLdouble;
#include
#include "Log.h"
-#ifdef GL_ERROR_DEBUG
-#define CHECKED_GL_FUNCTION(proc_name, ...) checked([&]() { proc_name(__VA_ARGS__);}, #proc_name)
-#define CHECKED_GL_FUNCTION_WITH_RETURN(proc_name, ReturnType, ...) checkedWithReturn([&]() { return proc_name(__VA_ARGS__);}, #proc_name)
-#else
-#define CHECKED_GL_FUNCTION(proc_name, ...) proc_name(__VA_ARGS__)
-#define CHECKED_GL_FUNCTION_WITH_RETURN(proc_name, ReturnType, ...) proc_name(__VA_ARGS__)
-#endif
+#define IS_GL_FUNCTION_VALID(proc_name) ptr##proc_name != nullptr
-#define IS_GL_FUNCTION_VALID(proc_name) g_##proc_name != nullptr
-#define GET_GL_FUNCTION(proc_name) g_##proc_name
-
-#if defined(EGL) || defined(OS_IOS)
-
-#define glGetError g_glGetError
-#define glBlendFunc(...) CHECKED_GL_FUNCTION(g_glBlendFunc, __VA_ARGS__)
-#define glPixelStorei(...) CHECKED_GL_FUNCTION(g_glPixelStorei, __VA_ARGS__)
-#define glClearColor(...) CHECKED_GL_FUNCTION(g_glClearColor, __VA_ARGS__)
-#define glCullFace(...) CHECKED_GL_FUNCTION(g_glCullFace, __VA_ARGS__)
-#define glDepthFunc(...) CHECKED_GL_FUNCTION(g_glDepthFunc, __VA_ARGS__)
-#define glDepthMask(...) CHECKED_GL_FUNCTION(g_glDepthMask, __VA_ARGS__)
-#define glDisable(...) CHECKED_GL_FUNCTION(g_glDisable, __VA_ARGS__)
-#define glEnable(...) CHECKED_GL_FUNCTION(g_glEnable, __VA_ARGS__)
-#define glPolygonOffset(...) CHECKED_GL_FUNCTION(g_glPolygonOffset, __VA_ARGS__)
-#define glScissor(...) CHECKED_GL_FUNCTION(g_glScissor, __VA_ARGS__)
-#define glViewport(...) CHECKED_GL_FUNCTION(g_glViewport, __VA_ARGS__)
-#define glBindTexture(...) CHECKED_GL_FUNCTION(g_glBindTexture, __VA_ARGS__)
-#define glTexImage2D(...) CHECKED_GL_FUNCTION(g_glTexImage2D, __VA_ARGS__)
-#define glTexParameteri(...) CHECKED_GL_FUNCTION(g_glTexParameteri, __VA_ARGS__)
-#define glGetIntegerv(...) CHECKED_GL_FUNCTION(g_glGetIntegerv, __VA_ARGS__)
-#define glGetString(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_glGetString, const GLubyte*, __VA_ARGS__)
-#define glReadPixels(...) CHECKED_GL_FUNCTION(g_glReadPixels, __VA_ARGS__)
-#define glTexSubImage2D(...) CHECKED_GL_FUNCTION(g_glTexSubImage2D, __VA_ARGS__)
-#define glDrawArrays(...) CHECKED_GL_FUNCTION(g_glDrawArrays, __VA_ARGS__)
-#define glDrawElements(...) CHECKED_GL_FUNCTION(g_glDrawElements, __VA_ARGS__)
-#define glLineWidth(...) CHECKED_GL_FUNCTION(g_glLineWidth, __VA_ARGS__)
-#define glClear(...) CHECKED_GL_FUNCTION(g_glClear, __VA_ARGS__)
-#define glGetFloatv(...) CHECKED_GL_FUNCTION(g_glGetFloatv, __VA_ARGS__)
-#define glDeleteTextures(...) CHECKED_GL_FUNCTION(g_glDeleteTextures, __VA_ARGS__)
-#define glGenTextures(...) CHECKED_GL_FUNCTION(g_glGenTextures, __VA_ARGS__)
-#define glTexParameterf(...) CHECKED_GL_FUNCTION(g_glTexParameterf, __VA_ARGS__)
-#define glActiveTexture(...) CHECKED_GL_FUNCTION(g_glActiveTexture, __VA_ARGS__)
-#define glBlendColor(...) CHECKED_GL_FUNCTION(g_glBlendColor, __VA_ARGS__)
-#define glReadBuffer(...) CHECKED_GL_FUNCTION(g_glReadBuffer, __VA_ARGS__)
-#define glFinish(...) CHECKED_GL_FUNCTION(g_glFinish, __VA_ARGS__)
-#if defined(OS_ANDROID)
-#define eglGetNativeClientBufferANDROID(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_eglGetNativeClientBufferANDROID, EGLClientBuffer, __VA_ARGS__)
+#if !defined(EGL) && !defined(OS_IOS)
+typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
+typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
+typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
+typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
#endif
-extern PFNGLBLENDFUNCPROC g_glBlendFunc;
-extern PFNGLPIXELSTOREIPROC g_glPixelStorei;
-extern PFNGLCLEARCOLORPROC g_glClearColor;
-extern PFNGLCULLFACEPROC g_glCullFace;
-extern PFNGLDEPTHFUNCPROC g_glDepthFunc;
-extern PFNGLDEPTHMASKPROC g_glDepthMask;
-extern PFNGLDISABLEPROC g_glDisable;
-extern PFNGLENABLEPROC g_glEnable;
-extern PFNGLPOLYGONOFFSETPROC g_glPolygonOffset;
-extern PFNGLSCISSORPROC g_glScissor;
-extern PFNGLVIEWPORTPROC g_glViewport;
-extern PFNGLBINDTEXTUREPROC g_glBindTexture;
-extern PFNGLTEXIMAGE2DPROC g_glTexImage2D;
-extern PFNGLTEXPARAMETERIPROC g_glTexParameteri;
-extern PFNGLGETINTEGERVPROC g_glGetIntegerv;
-extern PFNGLGETSTRINGPROC g_glGetString;
-extern PFNGLREADPIXELSPROC g_glReadPixels;
-extern PFNGLTEXSUBIMAGE2DPROC g_glTexSubImage2D;
-extern PFNGLDRAWARRAYSPROC g_glDrawArrays;
-extern PFNGLGETERRORPROC g_glGetError;
-extern PFNGLDRAWELEMENTSPROC g_glDrawElements;
-extern PFNGLLINEWIDTHPROC g_glLineWidth;
-extern PFNGLCLEARPROC g_glClear;
-extern PFNGLGETFLOATVPROC g_glGetFloatv;
-extern PFNGLDELETETEXTURESPROC g_glDeleteTextures;
-extern PFNGLGENTEXTURESPROC g_glGenTextures;
-extern PFNGLTEXPARAMETERFPROC g_glTexParameterf;
-extern PFNGLACTIVETEXTUREPROC g_glActiveTexture;
-extern PFNGLBLENDCOLORPROC g_glBlendColor;
-extern PFNGLREADBUFFERPROC g_glReadBuffer;
-extern PFNGLFINISHPROC g_glFinish;
+extern PFNGLBLENDFUNCPROC ptrBlendFunc;
+extern PFNGLPIXELSTOREIPROC ptrPixelStorei;
+extern PFNGLCLEARCOLORPROC ptrClearColor;
+extern PFNGLCULLFACEPROC ptrCullFace;
+extern PFNGLDEPTHFUNCPROC ptrDepthFunc;
+extern PFNGLDEPTHMASKPROC ptrDepthMask;
+extern PFNGLDISABLEPROC ptrDisable;
+extern PFNGLENABLEPROC ptrEnable;
+extern PFNGLPOLYGONOFFSETPROC ptrPolygonOffset;
+extern PFNGLSCISSORPROC ptrScissor;
+extern PFNGLVIEWPORTPROC ptrViewport;
+extern PFNGLBINDTEXTUREPROC ptrBindTexture;
+extern PFNGLTEXIMAGE2DPROC ptrTexImage2D;
+extern PFNGLTEXPARAMETERIPROC ptrTexParameteri;
+extern PFNGLGETINTEGERVPROC ptrGetIntegerv;
+extern PFNGLGETSTRINGPROC ptrGetString;
+extern PFNGLREADPIXELSPROC ptrReadPixels;
+extern PFNGLTEXSUBIMAGE2DPROC ptrTexSubImage2D;
+extern PFNGLDRAWARRAYSPROC ptrDrawArrays;
+extern PFNGLGETERRORPROC ptrGetError;
+extern PFNGLDRAWELEMENTSPROC ptrDrawElements;
+extern PFNGLLINEWIDTHPROC ptrLineWidth;
+extern PFNGLCLEARPROC ptrClear;
+extern PFNGLGETFLOATVPROC ptrGetFloatv;
+extern PFNGLDELETETEXTURESPROC ptrDeleteTextures;
+extern PFNGLGENTEXTURESPROC ptrGenTextures;
+extern PFNGLTEXPARAMETERFPROC ptrTexParameterf;
+extern PFNGLACTIVETEXTUREPROC ptrActiveTexture;
+extern PFNGLBLENDCOLORPROC ptrBlendColor;
+extern PFNGLREADBUFFERPROC ptrReadBuffer;
+extern PFNGLFINISHPROC ptrFinish;
#if defined(OS_ANDROID)
-extern PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC g_eglGetNativeClientBufferANDROID;
-#endif
+extern PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC ptrGetNativeClientBufferANDROID;
#endif
#ifdef OS_WINDOWS
-#define glActiveTexture g_glActiveTexture
-#define glBlendColor g_glBlendColor
-
-extern PFNGLACTIVETEXTUREPROC g_glActiveTexture;
-extern PFNGLBLENDCOLORPROC g_glBlendColor;
+extern PFNGLACTIVETEXTUREPROC ptrActiveTexture;
+extern PFNGLBLENDCOLORPROC ptrBlendColor;
#endif
-#define glCreateShader(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_glCreateShader, GLuint, __VA_ARGS__)
-#define glCompileShader(...) CHECKED_GL_FUNCTION(g_glCompileShader, __VA_ARGS__)
-#define glShaderSource(...) CHECKED_GL_FUNCTION(g_glShaderSource, __VA_ARGS__)
-#define glCreateProgram(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_glCreateProgram, GLuint, __VA_ARGS__)
-#define glAttachShader(...) CHECKED_GL_FUNCTION(g_glAttachShader, __VA_ARGS__)
-#define glLinkProgram(...) CHECKED_GL_FUNCTION(g_glLinkProgram, __VA_ARGS__)
-#define glUseProgram(...) CHECKED_GL_FUNCTION(g_glUseProgram, __VA_ARGS__)
-#define glGetUniformLocation(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_glGetUniformLocation, GLint, __VA_ARGS__)
-#define glUniform1i(...) CHECKED_GL_FUNCTION(g_glUniform1i, __VA_ARGS__)
-#define glUniform1f(...) CHECKED_GL_FUNCTION(g_glUniform1f, __VA_ARGS__)
-#define glUniform2f(...) CHECKED_GL_FUNCTION(g_glUniform2f, __VA_ARGS__)
-#define glUniform2i(...) CHECKED_GL_FUNCTION(g_glUniform2i, __VA_ARGS__)
-#define glUniform4i(...) CHECKED_GL_FUNCTION(g_glUniform4i, __VA_ARGS__)
-
-#define glUniform4f(...) CHECKED_GL_FUNCTION(g_glUniform4f, __VA_ARGS__)
-#define glUniform3fv(...) CHECKED_GL_FUNCTION(g_glUniform3fv, __VA_ARGS__)
-#define glUniform4fv(...) CHECKED_GL_FUNCTION(g_glUniform4fv, __VA_ARGS__)
-#define glDetachShader(...) CHECKED_GL_FUNCTION(g_glDetachShader, __VA_ARGS__)
-#define glDeleteShader(...) CHECKED_GL_FUNCTION(g_glDeleteShader, __VA_ARGS__)
-#define glDeleteProgram(...) CHECKED_GL_FUNCTION(g_glDeleteProgram, __VA_ARGS__)
-#define glGetProgramInfoLog(...) CHECKED_GL_FUNCTION(g_glGetProgramInfoLog, __VA_ARGS__)
-#define glGetShaderInfoLog(...) CHECKED_GL_FUNCTION(g_glGetShaderInfoLog, __VA_ARGS__)
-#define glGetShaderiv(...) CHECKED_GL_FUNCTION(g_glGetShaderiv, __VA_ARGS__)
-#define glGetProgramiv(...) CHECKED_GL_FUNCTION(g_glGetProgramiv, __VA_ARGS__)
-
-#define glEnableVertexAttribArray(...) CHECKED_GL_FUNCTION(g_glEnableVertexAttribArray, __VA_ARGS__)
-#define glDisableVertexAttribArray(...) CHECKED_GL_FUNCTION(g_glDisableVertexAttribArray, __VA_ARGS__)
-#define glVertexAttribPointer(...) CHECKED_GL_FUNCTION(g_glVertexAttribPointer, __VA_ARGS__)
-#define glBindAttribLocation(...) CHECKED_GL_FUNCTION(g_glBindAttribLocation, __VA_ARGS__)
-#define glVertexAttrib1f(...) CHECKED_GL_FUNCTION(g_glVertexAttrib1f, __VA_ARGS__)
-#define glVertexAttrib4f(...) CHECKED_GL_FUNCTION(g_glVertexAttrib4f, __VA_ARGS__)
-#define glVertexAttrib4fv(...) CHECKED_GL_FUNCTION(g_glVertexAttrib4fv, __VA_ARGS__)
-
-#define glDepthRangef(...) CHECKED_GL_FUNCTION(g_glDepthRangef, __VA_ARGS__)
-#define glClearDepthf(...) CHECKED_GL_FUNCTION(g_glClearDepthf, __VA_ARGS__)
-
-#define glBindBuffer(...) CHECKED_GL_FUNCTION(g_glBindBuffer, __VA_ARGS__)
-#define glBindFramebuffer(...) CHECKED_GL_FUNCTION(g_glBindFramebuffer, __VA_ARGS__)
-#define glBindRenderbuffer(...) CHECKED_GL_FUNCTION(g_glBindRenderbuffer, __VA_ARGS__)
-#define glDrawBuffers(...) CHECKED_GL_FUNCTION(g_glDrawBuffers, __VA_ARGS__)
-#define glGenFramebuffers(...) CHECKED_GL_FUNCTION(g_glGenFramebuffers, __VA_ARGS__)
-#define glDeleteFramebuffers(...) CHECKED_GL_FUNCTION(g_glDeleteFramebuffers, __VA_ARGS__)
-#define glFramebufferTexture2D(...) CHECKED_GL_FUNCTION(g_glFramebufferTexture2D, __VA_ARGS__)
-#define glTexImage2DMultisample(...) CHECKED_GL_FUNCTION(g_glTexImage2DMultisample, __VA_ARGS__)
-#define glTexStorage2DMultisample(...) CHECKED_GL_FUNCTION(g_glTexStorage2DMultisample, __VA_ARGS__)
-#define glGenRenderbuffers(...) CHECKED_GL_FUNCTION(g_glGenRenderbuffers, __VA_ARGS__)
-#define glRenderbufferStorage(...) CHECKED_GL_FUNCTION(g_glRenderbufferStorage, __VA_ARGS__)
-#define glDeleteRenderbuffers(...) CHECKED_GL_FUNCTION(g_glDeleteRenderbuffers, __VA_ARGS__)
-#define glFramebufferRenderbuffer(...) CHECKED_GL_FUNCTION(g_glFramebufferRenderbuffer, __VA_ARGS__)
-#define glCheckFramebufferStatus(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_glCheckFramebufferStatus, GLenum, __VA_ARGS__)
-#define glBlitFramebuffer(...) CHECKED_GL_FUNCTION(g_glBlitFramebuffer, __VA_ARGS__)
-#define glGenVertexArrays(...) CHECKED_GL_FUNCTION(g_glGenVertexArrays, __VA_ARGS__)
-#define glBindVertexArray(...) CHECKED_GL_FUNCTION(g_glBindVertexArray, __VA_ARGS__)
-#define glDeleteVertexArrays(...) CHECKED_GL_FUNCTION(g_glDeleteVertexArrays, __VA_ARGS__);
-#define glGenBuffers(...) CHECKED_GL_FUNCTION(g_glGenBuffers, __VA_ARGS__)
-#define glBufferData(...) CHECKED_GL_FUNCTION(g_glBufferData, __VA_ARGS__)
-#define glMapBuffer(...) CHECKED_GL_FUNCTION(g_glMapBuffer, __VA_ARGS__)
-#define glMapBufferRange(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_glMapBufferRange, void*, __VA_ARGS__)
-#define glUnmapBuffer(...) CHECKED_GL_FUNCTION(g_glUnmapBuffer, __VA_ARGS__)
-#define glDeleteBuffers(...) CHECKED_GL_FUNCTION(g_glDeleteBuffers, __VA_ARGS__)
-#define glBindImageTexture(...) CHECKED_GL_FUNCTION(g_glBindImageTexture, __VA_ARGS__)
-#define glMemoryBarrier(...) CHECKED_GL_FUNCTION(g_glMemoryBarrier, __VA_ARGS__)
-#define glGetStringi(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_glGetStringi, const GLubyte*, __VA_ARGS__)
-#define glInvalidateFramebuffer(...) CHECKED_GL_FUNCTION(g_glInvalidateFramebuffer, __VA_ARGS__)
-#define glBufferStorage(...) CHECKED_GL_FUNCTION(g_glBufferStorage, __VA_ARGS__)
-#define glFenceSync(...) CHECKED_GL_FUNCTION_WITH_RETURN(g_glFenceSync, GLsync, __VA_ARGS__)
-#define glClientWaitSync(...) CHECKED_GL_FUNCTION(g_glClientWaitSync, __VA_ARGS__)
-#define glDeleteSync(...) CHECKED_GL_FUNCTION(g_glDeleteSync, __VA_ARGS__)
-
-#define glGetUniformBlockIndex(...) CHECKED_GL_FUNCTION(g_glGetUniformBlockIndex, __VA_ARGS__)
-#define glUniformBlockBinding(...) CHECKED_GL_FUNCTION(g_glUniformBlockBinding, __VA_ARGS__)
-#define glGetActiveUniformBlockiv(...) CHECKED_GL_FUNCTION(g_glGetActiveUniformBlockiv, __VA_ARGS__)
-#define glGetUniformIndices(...) CHECKED_GL_FUNCTION(g_glGetUniformIndices, __VA_ARGS__)
-#define glGetActiveUniformsiv(...) CHECKED_GL_FUNCTION(g_glGetActiveUniformsiv, __VA_ARGS__)
-#define glBindBufferBase(...) CHECKED_GL_FUNCTION(g_glBindBufferBase, __VA_ARGS__)
-#define glBufferSubData(...) CHECKED_GL_FUNCTION(g_glBufferSubData, __VA_ARGS__)
-
-#define glGetProgramBinary(...) CHECKED_GL_FUNCTION(g_glGetProgramBinary, __VA_ARGS__)
-#define glProgramBinary(...) CHECKED_GL_FUNCTION(g_glProgramBinary, __VA_ARGS__)
-#define glProgramParameteri(...) CHECKED_GL_FUNCTION(g_glProgramParameteri, __VA_ARGS__)
-
-#define glTexStorage2D(...) CHECKED_GL_FUNCTION(g_glTexStorage2D, __VA_ARGS__)
-#define glTextureStorage2D(...) CHECKED_GL_FUNCTION(g_glTextureStorage2D, __VA_ARGS__)
-#define glTextureSubImage2D(...) CHECKED_GL_FUNCTION(g_glTextureSubImage2D, __VA_ARGS__)
-#define glTextureStorage2DMultisample(...) CHECKED_GL_FUNCTION(g_glTextureStorage2DMultisample, __VA_ARGS__)
-#define glTextureParameteri(...) CHECKED_GL_FUNCTION(g_glTextureParameteri, __VA_ARGS__)
-#define glTextureParameterf(...) CHECKED_GL_FUNCTION(g_glTextureParameterf, __VA_ARGS__)
-#define glCreateTextures(...) CHECKED_GL_FUNCTION(g_glCreateTextures, __VA_ARGS__)
-#define glCreateBuffers(...) CHECKED_GL_FUNCTION(g_glCreateBuffers, __VA_ARGS__)
-#define glCreateFramebuffers(...) CHECKED_GL_FUNCTION(g_glCreateFramebuffers, __VA_ARGS__)
-#define glNamedFramebufferTexture(...) CHECKED_GL_FUNCTION(g_glNamedFramebufferTexture, __VA_ARGS__)
-#define glDrawRangeElementsBaseVertex(...) CHECKED_GL_FUNCTION(g_glDrawRangeElementsBaseVertex, __VA_ARGS__)
-#define glFlushMappedBufferRange(...) CHECKED_GL_FUNCTION(g_glFlushMappedBufferRange, __VA_ARGS__)
-#define glTextureBarrier(...) CHECKED_GL_FUNCTION(g_glTextureBarrier, __VA_ARGS__)
-#define glTextureBarrierNV(...) CHECKED_GL_FUNCTION(g_glTextureBarrierNV, __VA_ARGS__)
-#define glClearBufferfv(...) CHECKED_GL_FUNCTION(g_glClearBufferfv, __VA_ARGS__)
-#define glEnablei(...) CHECKED_GL_FUNCTION(g_glEnablei, __VA_ARGS__)
-#define glDisablei(...) CHECKED_GL_FUNCTION(g_glDisablei, __VA_ARGS__)
-#define glEGLImageTargetTexture2DOES(...) CHECKED_GL_FUNCTION(g_glEGLImageTargetTexture2DOES, __VA_ARGS__)
-
-extern PFNGLCREATESHADERPROC g_glCreateShader;
-extern PFNGLCOMPILESHADERPROC g_glCompileShader;
-extern PFNGLSHADERSOURCEPROC g_glShaderSource;
-extern PFNGLCREATEPROGRAMPROC g_glCreateProgram;
-extern PFNGLATTACHSHADERPROC g_glAttachShader;
-extern PFNGLLINKPROGRAMPROC g_glLinkProgram;
-extern PFNGLUSEPROGRAMPROC g_glUseProgram;
-extern PFNGLGETUNIFORMLOCATIONPROC g_glGetUniformLocation;
-extern PFNGLUNIFORM1IPROC g_glUniform1i;
-extern PFNGLUNIFORM1FPROC g_glUniform1f;
-extern PFNGLUNIFORM2FPROC g_glUniform2f;
-extern PFNGLUNIFORM2IPROC g_glUniform2i;
-extern PFNGLUNIFORM4IPROC g_glUniform4i;
-
-extern PFNGLUNIFORM4FPROC g_glUniform4f;
-extern PFNGLUNIFORM3FVPROC g_glUniform3fv;
-extern PFNGLUNIFORM4FVPROC g_glUniform4fv;
-extern PFNGLDETACHSHADERPROC g_glDetachShader;
-extern PFNGLDELETESHADERPROC g_glDeleteShader;
-extern PFNGLDELETEPROGRAMPROC g_glDeleteProgram;
-extern PFNGLGETPROGRAMINFOLOGPROC g_glGetProgramInfoLog;
-extern PFNGLGETSHADERINFOLOGPROC g_glGetShaderInfoLog;
-extern PFNGLGETSHADERIVPROC g_glGetShaderiv;
-extern PFNGLGETPROGRAMIVPROC g_glGetProgramiv;
-
-extern PFNGLENABLEVERTEXATTRIBARRAYPROC g_glEnableVertexAttribArray;
-extern PFNGLDISABLEVERTEXATTRIBARRAYPROC g_glDisableVertexAttribArray;
-extern PFNGLVERTEXATTRIBPOINTERPROC g_glVertexAttribPointer;
-extern PFNGLBINDATTRIBLOCATIONPROC g_glBindAttribLocation;
-extern PFNGLVERTEXATTRIB1FPROC g_glVertexAttrib1f;
-extern PFNGLVERTEXATTRIB4FPROC g_glVertexAttrib4f;
-extern PFNGLVERTEXATTRIB4FVPROC g_glVertexAttrib4fv;
-
-extern PFNGLDEPTHRANGEFPROC g_glDepthRangef;
-extern PFNGLCLEARDEPTHFPROC g_glClearDepthf;
-
-extern PFNGLDRAWBUFFERSPROC g_glDrawBuffers;
-extern PFNGLGENFRAMEBUFFERSPROC g_glGenFramebuffers;
-extern PFNGLBINDFRAMEBUFFERPROC g_glBindFramebuffer;
-extern PFNGLDELETEFRAMEBUFFERSPROC g_glDeleteFramebuffers;
-extern PFNGLFRAMEBUFFERTEXTURE2DPROC g_glFramebufferTexture2D;
-extern PFNGLTEXIMAGE2DMULTISAMPLEPROC g_glTexImage2DMultisample;
-extern PFNGLTEXSTORAGE2DMULTISAMPLEPROC g_glTexStorage2DMultisample;
-extern PFNGLGENRENDERBUFFERSPROC g_glGenRenderbuffers;
-extern PFNGLBINDRENDERBUFFERPROC g_glBindRenderbuffer;
-extern PFNGLRENDERBUFFERSTORAGEPROC g_glRenderbufferStorage;
-extern PFNGLDELETERENDERBUFFERSPROC g_glDeleteRenderbuffers;
-extern PFNGLFRAMEBUFFERRENDERBUFFERPROC g_glFramebufferRenderbuffer;
-extern PFNGLCHECKFRAMEBUFFERSTATUSPROC g_glCheckFramebufferStatus;
-extern PFNGLBLITFRAMEBUFFERPROC g_glBlitFramebuffer;
-extern PFNGLGENVERTEXARRAYSPROC g_glGenVertexArrays;
-extern PFNGLBINDVERTEXARRAYPROC g_glBindVertexArray;
-extern PFNGLDELETEVERTEXARRAYSPROC g_glDeleteVertexArrays;
-extern PFNGLGENBUFFERSPROC g_glGenBuffers;
-extern PFNGLBINDBUFFERPROC g_glBindBuffer;
-extern PFNGLBUFFERDATAPROC g_glBufferData;
-extern PFNGLMAPBUFFERPROC g_glMapBuffer;
-extern PFNGLMAPBUFFERRANGEPROC g_glMapBufferRange;
-extern PFNGLUNMAPBUFFERPROC g_glUnmapBuffer;
-extern PFNGLDELETEBUFFERSPROC g_glDeleteBuffers;
-extern PFNGLBINDIMAGETEXTUREPROC g_glBindImageTexture;
-extern PFNGLMEMORYBARRIERPROC g_glMemoryBarrier;
-extern PFNGLGETSTRINGIPROC g_glGetStringi;
-extern PFNGLINVALIDATEFRAMEBUFFERPROC g_glInvalidateFramebuffer;
-extern PFNGLBUFFERSTORAGEPROC g_glBufferStorage;
-extern PFNGLFENCESYNCPROC g_glFenceSync;
-extern PFNGLCLIENTWAITSYNCPROC g_glClientWaitSync;
-extern PFNGLDELETESYNCPROC g_glDeleteSync;
-
-extern PFNGLGETUNIFORMBLOCKINDEXPROC g_glGetUniformBlockIndex;
-extern PFNGLUNIFORMBLOCKBINDINGPROC g_glUniformBlockBinding;
-extern PFNGLGETACTIVEUNIFORMBLOCKIVPROC g_glGetActiveUniformBlockiv;
-extern PFNGLGETUNIFORMINDICESPROC g_glGetUniformIndices;
-extern PFNGLGETACTIVEUNIFORMSIVPROC g_glGetActiveUniformsiv;
-extern PFNGLBINDBUFFERBASEPROC g_glBindBufferBase;
-extern PFNGLBUFFERSUBDATAPROC g_glBufferSubData;
-
-extern PFNGLGETPROGRAMBINARYPROC g_glGetProgramBinary;
-extern PFNGLPROGRAMBINARYPROC g_glProgramBinary;
-extern PFNGLPROGRAMPARAMETERIPROC g_glProgramParameteri;
-
-extern PFNGLTEXSTORAGE2DPROC g_glTexStorage2D;
-extern PFNGLTEXTURESTORAGE2DPROC g_glTextureStorage2D;
-extern PFNGLTEXTURESUBIMAGE2DPROC g_glTextureSubImage2D;
-extern PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC g_glTextureStorage2DMultisample;
-extern PFNGLTEXTUREPARAMETERIPROC g_glTextureParameteri;
-extern PFNGLTEXTUREPARAMETERFPROC g_glTextureParameterf;
-extern PFNGLCREATETEXTURESPROC g_glCreateTextures;
-extern PFNGLCREATEBUFFERSPROC g_glCreateBuffers;
-extern PFNGLCREATEFRAMEBUFFERSPROC g_glCreateFramebuffers;
-extern PFNGLNAMEDFRAMEBUFFERTEXTUREPROC g_glNamedFramebufferTexture;
-extern PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC g_glDrawRangeElementsBaseVertex;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC g_glFlushMappedBufferRange;
-extern PFNGLTEXTUREBARRIERPROC g_glTextureBarrier;
-extern PFNGLTEXTUREBARRIERNVPROC g_glTextureBarrierNV;
-extern PFNGLCLEARBUFFERFVPROC g_glClearBufferfv;
-extern PFNGLENABLEIPROC g_glEnablei;
-extern PFNGLDISABLEIPROC g_glDisablei;
+extern PFNGLCREATESHADERPROC ptrCreateShader;
+extern PFNGLCOMPILESHADERPROC ptrCompileShader;
+extern PFNGLSHADERSOURCEPROC ptrShaderSource;
+extern PFNGLCREATEPROGRAMPROC ptrCreateProgram;
+extern PFNGLATTACHSHADERPROC ptrAttachShader;
+extern PFNGLLINKPROGRAMPROC ptrLinkProgram;
+extern PFNGLUSEPROGRAMPROC ptrUseProgram;
+extern PFNGLGETUNIFORMLOCATIONPROC ptrGetUniformLocation;
+extern PFNGLUNIFORM1IPROC ptrUniform1i;
+extern PFNGLUNIFORM1FPROC ptrUniform1f;
+extern PFNGLUNIFORM2FPROC ptrUniform2f;
+extern PFNGLUNIFORM2IPROC ptrUniform2i;
+extern PFNGLUNIFORM4IPROC ptrUniform4i;
+
+extern PFNGLUNIFORM4FPROC ptrUniform4f;
+extern PFNGLUNIFORM3FVPROC ptrUniform3fv;
+extern PFNGLUNIFORM4FVPROC ptrUniform4fv;
+extern PFNGLDETACHSHADERPROC ptrDetachShader;
+extern PFNGLDELETESHADERPROC ptrDeleteShader;
+extern PFNGLDELETEPROGRAMPROC ptrDeleteProgram;
+extern PFNGLGETPROGRAMINFOLOGPROC ptrGetProgramInfoLog;
+extern PFNGLGETSHADERINFOLOGPROC ptrGetShaderInfoLog;
+extern PFNGLGETSHADERIVPROC ptrGetShaderiv;
+extern PFNGLGETPROGRAMIVPROC ptrGetProgramiv;
+
+extern PFNGLENABLEVERTEXATTRIBARRAYPROC ptrEnableVertexAttribArray;
+extern PFNGLDISABLEVERTEXATTRIBARRAYPROC ptrDisableVertexAttribArray;
+extern PFNGLVERTEXATTRIBPOINTERPROC ptrVertexAttribPointer;
+extern PFNGLBINDATTRIBLOCATIONPROC ptrBindAttribLocation;
+extern PFNGLVERTEXATTRIB1FPROC ptrVertexAttrib1f;
+extern PFNGLVERTEXATTRIB4FPROC ptrVertexAttrib4f;
+extern PFNGLVERTEXATTRIB4FVPROC ptrVertexAttrib4fv;
+
+extern PFNGLDEPTHRANGEFPROC ptrDepthRangef;
+extern PFNGLCLEARDEPTHFPROC ptrClearDepthf;
+
+extern PFNGLDRAWBUFFERSPROC ptrDrawBuffers;
+extern PFNGLGENFRAMEBUFFERSPROC ptrGenFramebuffers;
+extern PFNGLBINDFRAMEBUFFERPROC ptrBindFramebuffer;
+extern PFNGLDELETEFRAMEBUFFERSPROC ptrDeleteFramebuffers;
+extern PFNGLFRAMEBUFFERTEXTURE2DPROC ptrFramebufferTexture2D;
+extern PFNGLTEXIMAGE2DMULTISAMPLEPROC ptrTexImage2DMultisample;
+extern PFNGLTEXSTORAGE2DMULTISAMPLEPROC ptrTexStorage2DMultisample;
+extern PFNGLGENRENDERBUFFERSPROC ptrGenRenderbuffers;
+extern PFNGLBINDRENDERBUFFERPROC ptrBindRenderbuffer;
+extern PFNGLRENDERBUFFERSTORAGEPROC ptrRenderbufferStorage;
+extern PFNGLDELETERENDERBUFFERSPROC ptrDeleteRenderbuffers;
+extern PFNGLFRAMEBUFFERRENDERBUFFERPROC ptrFramebufferRenderbuffer;
+extern PFNGLCHECKFRAMEBUFFERSTATUSPROC ptrCheckFramebufferStatus;
+extern PFNGLBLITFRAMEBUFFERPROC ptrBlitFramebuffer;
+extern PFNGLGENVERTEXARRAYSPROC ptrGenVertexArrays;
+extern PFNGLBINDVERTEXARRAYPROC ptrBindVertexArray;
+extern PFNGLDELETEVERTEXARRAYSPROC ptrDeleteVertexArrays;
+extern PFNGLGENBUFFERSPROC ptrGenBuffers;
+extern PFNGLBINDBUFFERPROC ptrBindBuffer;
+extern PFNGLBUFFERDATAPROC ptrBufferData;
+extern PFNGLMAPBUFFERPROC ptrMapBuffer;
+extern PFNGLMAPBUFFERRANGEPROC ptrMapBufferRange;
+extern PFNGLUNMAPBUFFERPROC ptrUnmapBuffer;
+extern PFNGLDELETEBUFFERSPROC ptrDeleteBuffers;
+extern PFNGLBINDIMAGETEXTUREPROC ptrBindImageTexture;
+extern PFNGLMEMORYBARRIERPROC ptrMemoryBarrier;
+extern PFNGLGETSTRINGIPROC ptrGetStringi;
+extern PFNGLINVALIDATEFRAMEBUFFERPROC ptrInvalidateFramebuffer;
+extern PFNGLBUFFERSTORAGEPROC ptrBufferStorage;
+extern PFNGLFENCESYNCPROC ptrFenceSync;
+extern PFNGLCLIENTWAITSYNCPROC ptrClientWaitSync;
+extern PFNGLDELETESYNCPROC ptrDeleteSync;
+
+extern PFNGLGETUNIFORMBLOCKINDEXPROC ptrGetUniformBlockIndex;
+extern PFNGLUNIFORMBLOCKBINDINGPROC ptrUniformBlockBinding;
+extern PFNGLGETACTIVEUNIFORMBLOCKIVPROC ptrGetActiveUniformBlockiv;
+extern PFNGLGETUNIFORMINDICESPROC ptrGetUniformIndices;
+extern PFNGLGETACTIVEUNIFORMSIVPROC ptrGetActiveUniformsiv;
+extern PFNGLBINDBUFFERBASEPROC ptrBindBufferBase;
+extern PFNGLBUFFERSUBDATAPROC ptrBufferSubData;
+
+extern PFNGLGETPROGRAMBINARYPROC ptrGetProgramBinary;
+extern PFNGLPROGRAMBINARYPROC ptrProgramBinary;
+extern PFNGLPROGRAMPARAMETERIPROC ptrProgramParameteri;
+
+extern PFNGLTEXSTORAGE2DPROC ptrTexStorage2D;
+extern PFNGLTEXTURESTORAGE2DPROC ptrTextureStorage2D;
+extern PFNGLTEXTURESUBIMAGE2DPROC ptrTextureSubImage2D;
+extern PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC ptrTextureStorage2DMultisample;
+extern PFNGLTEXTUREPARAMETERIPROC ptrTextureParameteri;
+extern PFNGLTEXTUREPARAMETERFPROC ptrTextureParameterf;
+extern PFNGLCREATETEXTURESPROC ptrCreateTextures;
+extern PFNGLCREATEBUFFERSPROC ptrCreateBuffers;
+extern PFNGLCREATEFRAMEBUFFERSPROC ptrCreateFramebuffers;
+extern PFNGLNAMEDFRAMEBUFFERTEXTUREPROC ptrNamedFramebufferTexture;
+extern PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC ptrDrawRangeElementsBaseVertex;
+extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC ptrFlushMappedBufferRange;
+extern PFNGLTEXTUREBARRIERPROC ptrTextureBarrier;
+extern PFNGLTEXTUREBARRIERNVPROC ptrTextureBarrierNV;
+extern PFNGLCLEARBUFFERFVPROC ptrClearBufferfv;
+extern PFNGLENABLEIPROC ptrEnablei;
+extern PFNGLDISABLEIPROC ptrDisablei;
typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, void* image);
-extern PFNGLEGLIMAGETARGETTEXTURE2DOESPROC g_glEGLImageTargetTexture2DOES;
+extern PFNGLEGLIMAGETARGETTEXTURE2DOESPROC ptrEGLImageTargetTexture2DOES;
void initGLFunctions();
-template void checked(F fn, const char* _functionName)
-{
- fn();
- auto error = glGetError();
- if (error != GL_NO_ERROR) {
- std::stringstream errorString;
- errorString << _functionName << " OpenGL error: 0x" << std::hex << error;
- LOG(LOG_ERROR, errorString.str().c_str());
- throw std::runtime_error(errorString.str().c_str());
- }
-}
-
-template R checkedWithReturn(F fn, const char* _functionName)
-{
- R returnValue = fn();
- auto error = glGetError();
- if (error != GL_NO_ERROR) {
- std::stringstream errorString;
- errorString << _functionName << " OpenGL error: 0x" << std::hex << error;
- LOG(LOG_ERROR, errorString.str().c_str());
- throw std::runtime_error(errorString.str().c_str());
- }
-
- return returnValue;
-}
+#define glGetError(...) opengl::FunctionWrapper::wrGetError(__VA_ARGS__)
+#define glBlendFunc(...) opengl::FunctionWrapper::wrBlendFunc(__VA_ARGS__)
+#define glPixelStorei(...) opengl::FunctionWrapper::wrPixelStorei(__VA_ARGS__)
+#define glClearColor(...) opengl::FunctionWrapper::wrClearColor(__VA_ARGS__)
+#define glCullFace(...) opengl::FunctionWrapper::wrCullFace(__VA_ARGS__)
+#define glDepthFunc(...) opengl::FunctionWrapper::wrDepthFunc(__VA_ARGS__)
+#define glDepthMask(...) opengl::FunctionWrapper::wrDepthMask(__VA_ARGS__)
+#define glDisable(...) opengl::FunctionWrapper::wrDisable(__VA_ARGS__)
+#define glEnable(...) opengl::FunctionWrapper::wrEnable(__VA_ARGS__)
+#define glPolygonOffset(...) opengl::FunctionWrapper::wrPolygonOffset(__VA_ARGS__)
+#define glScissor(...) opengl::FunctionWrapper::wrScissor(__VA_ARGS__)
+#define glViewport(...) opengl::FunctionWrapper::wrViewport(__VA_ARGS__)
+#define glBindTexture(...) opengl::FunctionWrapper::wrBindTexture(__VA_ARGS__)
+#define glTexImage2D(...) opengl::FunctionWrapper::wrTexImage2D(__VA_ARGS__)
+#define glTexParameteri(...) opengl::FunctionWrapper::wrTexParameteri(__VA_ARGS__)
+#define glGetIntegerv(...) opengl::FunctionWrapper::wrGetIntegerv(__VA_ARGS__)
+#define glGetString(...) opengl::FunctionWrapper::wrGetString(__VA_ARGS__)
+#define glReadPixels(...) opengl::FunctionWrapper::wrReadPixels(__VA_ARGS__)
+#define glTexSubImage2D(...) opengl::FunctionWrapper::wrTexSubImage2D(__VA_ARGS__)
+#define glDrawArrays(...) opengl::FunctionWrapper::wrDrawArrays(__VA_ARGS__)
+#define glDrawElements(...) opengl::FunctionWrapper::wrDrawElements(__VA_ARGS__)
+#define glLineWidth(...) opengl::FunctionWrapper::wrLineWidth(__VA_ARGS__)
+#define glClear(...) opengl::FunctionWrapper::wrClear(__VA_ARGS__)
+#define glGetFloatv(...) opengl::FunctionWrapper::wrGetFloatv(__VA_ARGS__)
+#define glDeleteTextures(...) opengl::FunctionWrapper::wrDeleteTextures(__VA_ARGS__)
+#define glGenTextures(...) opengl::FunctionWrapper::wrGenTextures(__VA_ARGS__)
+#define glTexParameterf(...) opengl::FunctionWrapper::wrTexParameterf(__VA_ARGS__)
+#define glActiveTexture(...) opengl::FunctionWrapper::wrActiveTexture(__VA_ARGS__)
+#define glBlendColor(...) opengl::FunctionWrapper::wrBlendColor(__VA_ARGS__)
+#define glReadBuffer(...) opengl::FunctionWrapper::wrReadBuffer(__VA_ARGS__)
+#define glFinish(...) opengl::FunctionWrapper::wrFinish(__VA_ARGS__)
+#if defined(OS_ANDROID)
+#define eglGetNativeClientBufferANDROID(...) opengl::FunctionWrapper::ewrGetNativeClientBufferANDROID(__VA_ARGS__)
+#endif
+#define glCreateShader(...) opengl::FunctionWrapper::wrCreateShader(__VA_ARGS__)
+#define glCompileShader(...) opengl::FunctionWrapper::wrCompileShader(__VA_ARGS__)
+#define glShaderSource(...) opengl::FunctionWrapper::wrShaderSource(__VA_ARGS__)
+#define glCreateProgram(...) opengl::FunctionWrapper::wrCreateProgram(__VA_ARGS__)
+#define glAttachShader(...) opengl::FunctionWrapper::wrAttachShader(__VA_ARGS__)
+#define glLinkProgram(...) opengl::FunctionWrapper::wrLinkProgram(__VA_ARGS__)
+#define glUseProgram(...) opengl::FunctionWrapper::wrUseProgram(__VA_ARGS__)
+#define glGetUniformLocation(...) opengl::FunctionWrapper::wrGetUniformLocation(__VA_ARGS__)
+#define glUniform1i(...) opengl::FunctionWrapper::wrUniform1i(__VA_ARGS__)
+#define glUniform1f(...) opengl::FunctionWrapper::wrUniform1f(__VA_ARGS__)
+#define glUniform2f(...) opengl::FunctionWrapper::wrUniform2f(__VA_ARGS__)
+#define glUniform2i(...) opengl::FunctionWrapper::wrUniform2i(__VA_ARGS__)
+#define glUniform4i(...) opengl::FunctionWrapper::wrUniform4i(__VA_ARGS__)
+
+#define glUniform4f(...) opengl::FunctionWrapper::wrUniform4f(__VA_ARGS__)
+#define glUniform3fv(...) opengl::FunctionWrapper::wrUniform3fv(__VA_ARGS__)
+#define glUniform4fv(...) opengl::FunctionWrapper::wrUniform4fv(__VA_ARGS__)
+#define glDetachShader(...) opengl::FunctionWrapper::wrDetachShader(__VA_ARGS__)
+#define glDeleteShader(...) opengl::FunctionWrapper::wrDeleteShader(__VA_ARGS__)
+#define glDeleteProgram(...) opengl::FunctionWrapper::wrDeleteProgram(__VA_ARGS__)
+#define glGetProgramInfoLog(...) opengl::FunctionWrapper::wrGetProgramInfoLog(__VA_ARGS__)
+#define glGetShaderInfoLog(...) opengl::FunctionWrapper::wrGetShaderInfoLog(__VA_ARGS__)
+#define glGetShaderiv(...) opengl::FunctionWrapper::wrGetShaderiv(__VA_ARGS__)
+#define glGetProgramiv(...) opengl::FunctionWrapper::wrGetProgramiv(__VA_ARGS__)
+
+#define glEnableVertexAttribArray(...) opengl::FunctionWrapper::wrEnableVertexAttribArray(__VA_ARGS__)
+#define glDisableVertexAttribArray(...) opengl::FunctionWrapper::wrDisableVertexAttribArray(__VA_ARGS__)
+#define glVertexAttribPointer(...) opengl::FunctionWrapper::wrVertexAttribPointer(__VA_ARGS__)
+#define glBindAttribLocation(...) opengl::FunctionWrapper::wrBindAttribLocation(__VA_ARGS__)
+#define glVertexAttrib1f(...) opengl::FunctionWrapper::wrVertexAttrib1f(__VA_ARGS__)
+#define glVertexAttrib4f(...) opengl::FunctionWrapper::wrVertexAttrib4f(__VA_ARGS__)
+#define glVertexAttrib4fv(...) opengl::FunctionWrapper::wrVertexAttrib4fv(__VA_ARGS__)
+
+#define glDepthRangef(...) opengl::FunctionWrapper::wrDepthRangef(__VA_ARGS__)
+#define glClearDepthf(...) opengl::FunctionWrapper::wrClearDepthf(__VA_ARGS__)
+
+#define glBindBuffer(...) opengl::FunctionWrapper::wrBindBuffer(__VA_ARGS__)
+#define glBindFramebuffer(...) opengl::FunctionWrapper::wrBindFramebuffer(__VA_ARGS__)
+#define glBindRenderbuffer(...) opengl::FunctionWrapper::wrBindRenderbuffer(__VA_ARGS__)
+#define glDrawBuffers(...) opengl::FunctionWrapper::wrDrawBuffers(__VA_ARGS__)
+#define glGenFramebuffers(...) opengl::FunctionWrapper::wrGenFramebuffers(__VA_ARGS__)
+#define glDeleteFramebuffers(...) opengl::FunctionWrapper::wrDeleteFramebuffers(__VA_ARGS__)
+#define glFramebufferTexture2D(...) opengl::FunctionWrapper::wrFramebufferTexture2D(__VA_ARGS__)
+#define glTexImage2DMultisample(...) opengl::FunctionWrapper::wrTexImage2DMultisample(__VA_ARGS__)
+#define glTexStorage2DMultisample(...) opengl::FunctionWrapper::wrTexStorage2DMultisample(__VA_ARGS__)
+#define glGenRenderbuffers(...) opengl::FunctionWrapper::wrGenRenderbuffers(__VA_ARGS__)
+#define glRenderbufferStorage(...) opengl::FunctionWrapper::wrRenderbufferStorage(__VA_ARGS__)
+#define glDeleteRenderbuffers(...) opengl::FunctionWrapper::wrDeleteRenderbuffers(__VA_ARGS__)
+#define glFramebufferRenderbuffer(...) opengl::FunctionWrapper::wrFramebufferRenderbuffer(__VA_ARGS__)
+#define glCheckFramebufferStatus(...) opengl::FunctionWrapper::wrCheckFramebufferStatus(__VA_ARGS__)
+#define glBlitFramebuffer(...) opengl::FunctionWrapper::wrBlitFramebuffer(__VA_ARGS__)
+#define glGenVertexArrays(...) opengl::FunctionWrapper::wrGenVertexArrays(__VA_ARGS__)
+#define glBindVertexArray(...) opengl::FunctionWrapper::wrBindVertexArray(__VA_ARGS__)
+#define glDeleteVertexArrays(...) opengl::FunctionWrapper::wrDeleteVertexArrays(__VA_ARGS__);
+#define glGenBuffers(...) opengl::FunctionWrapper::wrGenBuffers(__VA_ARGS__)
+#define glBufferData(...) opengl::FunctionWrapper::wrBufferData(__VA_ARGS__)
+#define glMapBuffer(...) opengl::FunctionWrapper::wrMapBuffer(__VA_ARGS__)
+#define glMapBufferRange(...) opengl::FunctionWrapper::wrMapBufferRange(__VA_ARGS__)
+#define glUnmapBuffer(...) opengl::FunctionWrapper::wrUnmapBuffer(__VA_ARGS__)
+#define glDeleteBuffers(...) opengl::FunctionWrapper::wrDeleteBuffers(__VA_ARGS__)
+#define glBindImageTexture(...) opengl::FunctionWrapper::wrBindImageTexture(__VA_ARGS__)
+#define glMemoryBarrier(...) opengl::FunctionWrapper::wrMemoryBarrier(__VA_ARGS__)
+#define glGetStringi(...) opengl::FunctionWrapper::wrGetStringi(__VA_ARGS__)
+#define glInvalidateFramebuffer(...) opengl::FunctionWrapper::wrInvalidateFramebuffer(__VA_ARGS__)
+#define glBufferStorage(...) opengl::FunctionWrapper::wrBufferStorage(__VA_ARGS__)
+#define glFenceSync(...) opengl::FunctionWrapper::wrFenceSync(__VA_ARGS__)
+#define glClientWaitSync(...) opengl::FunctionWrapper::wrClientWaitSync(__VA_ARGS__)
+#define glDeleteSync(...) opengl::FunctionWrapper::wrDeleteSync(__VA_ARGS__)
+
+#define glGetUniformBlockIndex(...) opengl::FunctionWrapper::wrGetUniformBlockIndex(__VA_ARGS__)
+#define glUniformBlockBinding(...) opengl::FunctionWrapper::wrUniformBlockBinding(__VA_ARGS__)
+#define glGetActiveUniformBlockiv(...) opengl::FunctionWrapper::wrGetActiveUniformBlockiv(__VA_ARGS__)
+#define glGetUniformIndices(...) opengl::FunctionWrapper::wrGetUniformIndices(__VA_ARGS__)
+#define glGetActiveUniformsiv(...) opengl::FunctionWrapper::wrGetActiveUniformsiv(__VA_ARGS__)
+#define glBindBufferBase(...) opengl::FunctionWrapper::wrBindBufferBase(__VA_ARGS__)
+#define glBufferSubData(...) opengl::FunctionWrapper::wrBufferSubData(__VA_ARGS__)
+
+#define glGetProgramBinary(...) opengl::FunctionWrapper::wrGetProgramBinary(__VA_ARGS__)
+#define glProgramBinary(...) opengl::FunctionWrapper::wrProgramBinary(__VA_ARGS__)
+#define glProgramParameteri(...) opengl::FunctionWrapper::wrProgramParameteri(__VA_ARGS__)
+
+#define glTexStorage2D(...) opengl::FunctionWrapper::wrTexStorage2D(__VA_ARGS__)
+#define glTextureStorage2D(...) opengl::FunctionWrapper::wrTextureStorage2D(__VA_ARGS__)
+#define glTextureSubImage2D(...) opengl::FunctionWrapper::wrTextureSubImage2D(__VA_ARGS__)
+#define glTextureStorage2DMultisample(...) opengl::FunctionWrapper::wrTextureStorage2DMultisample(__VA_ARGS__)
+#define glTextureParameteri(...) opengl::FunctionWrapper::wrTextureParameteri(__VA_ARGS__)
+#define glTextureParameterf(...) opengl::FunctionWrapper::wrTextureParameterf(__VA_ARGS__)
+#define glCreateTextures(...) opengl::FunctionWrapper::wrCreateTextures(__VA_ARGS__)
+#define glCreateBuffers(...) opengl::FunctionWrapper::wrCreateBuffers(__VA_ARGS__)
+#define glCreateFramebuffers(...) opengl::FunctionWrapper::wrCreateFramebuffers(__VA_ARGS__)
+#define glNamedFramebufferTexture(...) opengl::FunctionWrapper::wrNamedFramebufferTexture(__VA_ARGS__)
+#define glDrawRangeElementsBaseVertex(...) opengl::FunctionWrapper::wrDrawRangeElementsBaseVertex(__VA_ARGS__)
+#define glFlushMappedBufferRange(...) opengl::FunctionWrapper::wrFlushMappedBufferRange(__VA_ARGS__)
+#define glTextureBarrier(...) opengl::FunctionWrapper::wrTextureBarrier(__VA_ARGS__)
+#define glTextureBarrierNV(...) opengl::FunctionWrapper::wrTextureBarrierNV(__VA_ARGS__)
+#define glClearBufferfv(...) opengl::FunctionWrapper::wrClearBufferfv(__VA_ARGS__)
+#define glEnablei(...) opengl::FunctionWrapper::wrEnablei(__VA_ARGS__)
+#define glDisablei(...) opengl::FunctionWrapper::wrDisablei(__VA_ARGS__)
+#define glEGLImageTargetTexture2DOES(...) opengl::FunctionWrapper::wrEGLImageTargetTexture2DOES(__VA_ARGS__)
+
+#include "Graphics/OpenGLContext/ThreadedOpenGl/opengl_Wrapper.h"
#endif // GLFUNCTIONS_H
diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp
index 55a6b0bd6..b87239e73 100644
--- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp
+++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp
@@ -2444,7 +2444,7 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
glAttachShader(program, bUseTextures ? m_vertexShaderTexturedTriangle : m_vertexShaderTriangle);
glAttachShader(program, fragmentShader);
if (CombinerInfo::get().isShaderCacheSupported()) {
- if (IS_GL_FUNCTION_VALID(glProgramParameteri))
+ if (IS_GL_FUNCTION_VALID(ProgramParameteri))
glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
}
glLinkProgram(program);
diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/BlockingQueue.h b/src/Graphics/OpenGLContext/ThreadedOpenGl/BlockingQueue.h
new file mode 100644
index 000000000..516f0dec0
--- /dev/null
+++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/BlockingQueue.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include
+#include
+#include
+
+template >
+class BlockingQueue
+{
+private:
+ std::mutex m_mutex;
+ std::condition_variable m_condition;
+ Container m_queue;
+public:
+ void push(T const& value) {
+ {
+ std::unique_lock lock(this->m_mutex);
+ m_queue.push_front(value);
+ }
+ this->m_condition.notify_one();
+ }
+
+ void pushBack(T const& value) {
+ {
+ std::unique_lock lock(this->m_mutex);
+ m_queue.push_back(value);
+ }
+ this->m_condition.notify_one();
+ }
+
+ T pop() {
+ std::unique_lock lock(this->m_mutex);
+ this->m_condition.wait(lock, [this]{ return !this->m_queue.empty(); });
+ T rc(std::move(this->m_queue.back()));
+ this->m_queue.pop_back();
+ return rc;
+ }
+ bool tryPop (T & v, std::chrono::milliseconds dur) {
+ std::unique_lock lock(this->m_mutex);
+ if (!this->m_condition.wait_for(lock, dur, [this]{ return !this->m_queue.empty(); })) {
+ return false;
+ }
+ v = std::move(this->m_queue.back());
+ this->m_queue.pop_back();
+ return true;
+ }
+ int size() {
+ return m_queue.size();
+ }
+};
diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.cpp b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.cpp
new file mode 100644
index 000000000..6dbf7f694
--- /dev/null
+++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.cpp
@@ -0,0 +1,60 @@
+#include "opengl_Command.h"
+#include "Graphics/OpenGLContext/GLFunctions.h"
+
+namespace opengl {
+
+void OpenGlCommand::performCommandSingleThreaded() {
+ commandToExecute();
+
+ setInUse(false);
+#ifdef GL_DEBUG
+ if (m_isGlCommand) {
+ auto error = ptrGetError();
+ if (error != GL_NO_ERROR) {
+ std::stringstream errorString;
+ errorString << " OpenGL error: 0x" << std::hex << error << ", on function: " << m_functionName;
+ LOG(LOG_ERROR, errorString.str().c_str());
+ throw std::runtime_error(errorString.str().c_str());
+ }
+ }
+#endif
+}
+
+void OpenGlCommand::performCommand() {
+ std::unique_lock lock(m_condvarMutex);
+ performCommandSingleThreaded();
+ if (m_synced) {
+#ifdef GL_DEBUG
+ if (m_logIfSynced) {
+ std::stringstream errorString;
+ errorString << " Executing synced: " << m_functionName;
+ LOG(LOG_VERBOSE, errorString.str().c_str());
+ }
+#endif
+ m_executed = true;
+ m_condition.notify_all();
+ }
+}
+
+void OpenGlCommand::waitOnCommand() {
+ std::unique_lock lock(m_condvarMutex);
+
+ if (m_synced && !m_executed) {
+ m_condition.wait(lock, [this] { return m_executed; });
+ }
+
+ m_executed = false;
+}
+
+OpenGlCommand::OpenGlCommand(bool _synced, bool _logIfSynced, const std::string &_functionName,
+ bool _isGlCommand) :
+ m_synced(_synced), m_executed(false)
+#ifdef GL_DEBUG
+, m_logIfSynced(_logIfSynced)
+ , m_functionName(std::move(_functionName))
+ , m_isGlCommand(_isGlCommand)
+#endif
+{
+}
+
+}
diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.h b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.h
new file mode 100644
index 000000000..f0202870b
--- /dev/null
+++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include
+#include
+#include
+#include "opengl_ObjectPool.h"
+#include
+
+namespace opengl {
+
+class OpenGlCommand : public PoolObject {
+public:
+ void performCommandSingleThreaded();
+
+ void performCommand();
+
+ void waitOnCommand();
+
+protected:
+ OpenGlCommand(bool _synced, bool _logIfSynced, const std::string &_functionName,
+ bool _isGlCommand = true);
+
+ virtual void commandToExecute() = 0;
+
+ template
+ static std::shared_ptr getFromPool(int _poolId) {
+ auto poolObject = OpenGlCommandPool::get().getAvailableObject(_poolId);
+ if (poolObject == nullptr) {
+ poolObject = std::shared_ptr(new CoomandType);
+ OpenGlCommandPool::get().addObjectToPool(_poolId, poolObject);
+ }
+
+ poolObject->setInUse(true);
+ return std::static_pointer_cast(poolObject);
+ }
+
+protected:
+
+#ifdef GL_DEBUG
+ const bool m_logIfSynced;
+ const std::string m_functionName;
+ const bool m_isGlCommand;
+#endif
+
+private:
+ std::atomic m_synced;
+ bool m_executed;
+ std::mutex m_condvarMutex;
+ std::condition_variable m_condition;
+};
+}
diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_ObjectPool.cpp b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_ObjectPool.cpp
new file mode 100644
index 000000000..e732ff77e
--- /dev/null
+++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_ObjectPool.cpp
@@ -0,0 +1,85 @@
+#include "opengl_ObjectPool.h"
+
+namespace opengl {
+
+
+PoolObject::PoolObject() :
+ m_inUse(false), m_poolId(0), m_objectId(0) {
+}
+
+bool PoolObject::isInUse() {
+ return m_inUse;
+}
+
+void PoolObject::setInUse(bool _inUse) {
+ m_inUse = _inUse;
+}
+
+int PoolObject::getPoolId() {
+ return m_poolId;
+}
+
+void PoolObject::setPoolId(int _poolId) {
+ m_poolId = _poolId;
+}
+
+int PoolObject::getObjectId() {
+ return m_objectId;
+}
+
+void PoolObject::setObjectId(int _objectId) {
+ m_objectId = _objectId;
+}
+
+
+OpenGlCommandPool &OpenGlCommandPool::get() {
+ static OpenGlCommandPool commandPool;
+ return commandPool;
+}
+
+int OpenGlCommandPool::getNextAvailablePool() {
+ m_objectPool.push_back(std::vector>());
+ m_objectPoolIndex.push_back(0);
+ return m_objectPool.size() - 1;
+}
+
+std::shared_ptr OpenGlCommandPool::getAvailableObject(int _poolId) {
+ auto ¤tPool = m_objectPool[_poolId];
+ auto ¤tIndex = m_objectPoolIndex[_poolId];
+
+ if (currentPool.empty()) {
+ return nullptr;
+ } else if (!currentPool[currentIndex]->isInUse()) {
+ int objectId = currentIndex;
+ ++currentIndex;
+
+ if (currentIndex == currentPool.size()) {
+ currentIndex = 0;
+ }
+
+ return currentPool[objectId];
+
+ } else {
+ bool found = false;
+ unsigned int index;
+ //Not found in most common case, so go ahead and search
+ for (index = currentIndex; index < currentPool.size() && !found; ++index) {
+ found = !currentPool[index]->isInUse();
+ }
+
+ if (found) {
+ --index;
+ currentIndex = index;
+ return currentPool[index];
+ } else {
+ return nullptr;
+ }
+ }
+}
+
+void OpenGlCommandPool::addObjectToPool(int _poolId, std::shared_ptr _object) {
+ _object->setPoolId(_poolId);
+ _object->setObjectId(m_objectPool[_poolId].size());
+ m_objectPool[_poolId].push_back(_object);
+}
+}
diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_ObjectPool.h b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_ObjectPool.h
new file mode 100644
index 000000000..f4fcd5018
--- /dev/null
+++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_ObjectPool.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include
+#include
+
+
+namespace opengl {
+
+class PoolObject {
+public:
+
+ PoolObject();
+
+ bool isInUse();
+ void setInUse(bool _inUse);
+
+ int getPoolId();
+
+ void setPoolId(int _poolId);
+
+ int getObjectId();
+
+ void setObjectId(int _objectId);
+private:
+
+ bool m_inUse;
+ int m_poolId;
+ int m_objectId;
+};
+
+class OpenGlCommandPool
+{
+public:
+ static OpenGlCommandPool& get();
+
+ int getNextAvailablePool();
+
+ std::shared_ptr getAvailableObject(int _poolId);
+
+ void addObjectToPool(int _poolId, std::shared_ptr _object);
+
+private:
+ std::vector>> m_objectPool;
+ std::vector m_objectPoolIndex;
+};
+}
diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_WrappedFunctions.cpp b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_WrappedFunctions.cpp
new file mode 100644
index 000000000..9a0075bb8
--- /dev/null
+++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_WrappedFunctions.cpp
@@ -0,0 +1,23 @@
+#include "opengl_WrappedFunctions.h"
+
+namespace opengl {
+
+ std::vector GlDrawArraysUnbufferedCommand::m_attribsData;
+ std::vector GlDrawElementsUnbufferedCommand::m_attribsData;
+ GLenum GlMapBufferRangeWriteAsyncCommand::m_targetTemp;
+ GLintptr GlMapBufferRangeWriteAsyncCommand::m_offsetTemp;
+ u32 GlMapBufferRangeWriteAsyncCommand::m_lengthTemp;
+ GLbitfield GlMapBufferRangeWriteAsyncCommand::m_accessTemp = 0;
+ std::unordered_map>> GlMapBufferRangeWriteAsyncCommand::m_TempData;
+ splicer::ObjectPool> GlMapBufferRangeWriteAsyncCommand::m_vectorPool(128);
+ std::unordered_map>> GlMapBufferRangeReadAsyncCommand::m_data;
+ std::mutex GlMapBufferRangeReadAsyncCommand::m_mapMutex;
+ std::unordered_map GlVertexAttribPointerManager::m_vertexAttributePointers;
+ const void* GlVertexAttribPointerManager::smallestDataPtr = nullptr;
+ std::unordered_map GlVertexAttribPointerManager::m_vertexAttributePointersRender;
+ const void* GlVertexAttribPointerManager::smallestDataPtrRender = nullptr;
+ splicer::ObjectPool> GlVertexAttribPointerManager::m_vectorPool(128);
+ std::unordered_map GlBindBufferCommand::m_boundBuffersRender;
+ std::unordered_map GlBindBufferCommand::m_boundBuffers;
+ GLuint GlReadPixelsAsyncCommand::m_readPixelsBoundBuffer = 0;
+}
diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_WrappedFunctions.h b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_WrappedFunctions.h
new file mode 100644
index 000000000..ed8105f1b
--- /dev/null
+++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_WrappedFunctions.h
@@ -0,0 +1,4937 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "BlockingQueue.h"
+#include "Graphics/OpenGLContext/GLFunctions.h"
+#include "Graphics/OpenGLContext/opengl_Attributes.h"
+#include
+#include
+#include
+#include "opengl_Command.h"
+#include "splice-pool.hpp"
+
+#ifdef MUPENPLUSAPI
+#include
+#else
+#include
+#endif
+
+namespace opengl {
+
+ class GlBlendFuncCommand : public OpenGlCommand
+ {
+ public:
+ GlBlendFuncCommand() :
+ OpenGlCommand(false, false, "glBlendFunc")
+ {
+ }
+
+ static std::shared_ptr get(GLenum sfactor, GLenum dfactor)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(sfactor, dfactor);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrBlendFunc(m_sfactor, m_dfactor);
+ }
+ private:
+ void set(GLenum sfactor, GLenum dfactor)
+ {
+ m_sfactor = sfactor;
+ m_dfactor = dfactor;
+ }
+
+ GLenum m_sfactor;
+ GLenum m_dfactor;
+ };
+
+ class GlPixelStoreiCommand : public OpenGlCommand
+ {
+ public:
+ GlPixelStoreiCommand() :
+ OpenGlCommand(false, false, "glPixelStorei")
+ {
+ }
+
+ static std::shared_ptr get(GLenum pname, GLint param)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(pname, param);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrPixelStorei(m_pname, m_param);
+ }
+
+ private:
+ void set(GLenum pname, GLint param)
+ {
+ m_pname = pname;
+ m_param = param;
+ }
+
+ GLenum m_pname;
+ GLint m_param;
+ };
+
+ class GlClearColorCommand : public OpenGlCommand
+ {
+ public:
+ GlClearColorCommand() :
+ OpenGlCommand(false, false, "glClearColor")
+ {
+
+ }
+
+ static std::shared_ptr get(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(red, green, blue, alpha);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrClearColor(m_red, m_green, m_blue, m_alpha);
+ }
+ private:
+ void set(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+ {
+ m_red = red;
+ m_green = green;
+ m_blue = blue;
+ m_alpha = alpha;
+ }
+
+ GLfloat m_red;
+ GLfloat m_green;
+ GLfloat m_blue;
+ GLfloat m_alpha;
+ };
+
+ class GlCullFaceCommand : public OpenGlCommand
+ {
+ public:
+ GlCullFaceCommand() :
+ OpenGlCommand(false, false, "glCullFace")
+ {
+ }
+
+ static std::shared_ptr get(GLenum mode)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(mode);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrCullFace(m_mode);
+ }
+
+ private:
+ void set(GLenum mode)
+ {
+ m_mode = mode;
+ }
+
+ GLenum m_mode;
+ };
+
+ class GlDepthFuncCommand : public OpenGlCommand
+ {
+ public:
+ GlDepthFuncCommand() :
+ OpenGlCommand(false, false, "glDepthFunc")
+ {
+ }
+
+ static std::shared_ptr get(GLenum func)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(func);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDepthFunc(m_func);
+ }
+ private:
+ void set(GLenum func)
+ {
+ m_func = func;
+ }
+
+ GLenum m_func;
+ };
+
+ class GlDepthMaskCommand : public OpenGlCommand
+ {
+ public:
+ GlDepthMaskCommand() :
+ OpenGlCommand(false, false, "glDepthMask")
+ {
+
+ }
+
+ static std::shared_ptr get(GLboolean flag)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(flag);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDepthMask(m_flag);
+ }
+ private:
+ void set(GLboolean flag)
+ {
+ m_flag = flag;
+ }
+
+ GLboolean m_flag;
+ };
+
+ class GlDisableCommand : public OpenGlCommand
+ {
+ public:
+ GlDisableCommand() :
+ OpenGlCommand(false, false, "glDisable")
+ {
+ }
+
+ static std::shared_ptr get(GLenum cap)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(cap);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDisable(m_cap);
+ }
+ private:
+ void set(GLenum cap)
+ {
+ m_cap = cap;
+ }
+
+ GLenum m_cap;
+ };
+
+ class GlEnableCommand : public OpenGlCommand
+ {
+ public:
+ GlEnableCommand() :
+ OpenGlCommand(false, false, "glEnable")
+ {
+ }
+
+ static std::shared_ptr get(GLenum cap)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(cap);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrEnable(m_cap);
+ }
+ private:
+ void set(GLenum cap)
+ {
+ m_cap = cap;
+ }
+
+ GLenum m_cap;
+ };
+
+ class GlDisableiCommand : public OpenGlCommand
+ {
+ public:
+ GlDisableiCommand() :
+ OpenGlCommand(false, false, "glDisablei")
+ {
+ }
+
+ static std::shared_ptr get(GLenum target, GLuint index)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(target, index);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDisablei(m_target, m_index);
+ }
+ private:
+ void set(GLenum target, GLuint index)
+ {
+ m_target = target;
+ m_index = index;
+ }
+
+ GLenum m_target;
+ GLuint m_index;
+ };
+
+ class GlEnableiCommand : public OpenGlCommand
+ {
+ public:
+ GlEnableiCommand() :
+ OpenGlCommand(false, false, "glEnablei")
+ {
+ }
+
+ static std::shared_ptr get(GLenum target, GLuint index)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(target, index);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrEnablei(m_target, m_index);
+ }
+ private:
+ void set(GLenum target, GLuint index)
+ {
+ m_target = target;
+ m_index = index;
+ }
+
+ GLenum m_target;
+ GLuint m_index;
+ };
+
+ class GlPolygonOffsetCommand : public OpenGlCommand
+ {
+ public:
+ GlPolygonOffsetCommand() :
+ OpenGlCommand(false, false, "glPolygonOffset")
+ {
+ }
+
+ static std::shared_ptr get(GLfloat factor, GLfloat units)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(factor, units);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrPolygonOffset(m_factor, m_units);
+ }
+ private:
+ void set(GLfloat factor, GLfloat units)
+ {
+ m_factor = factor;
+ m_units = units;
+ }
+
+ GLfloat m_factor;
+ GLfloat m_units;
+ };
+
+ class GlScissorCommand : public OpenGlCommand
+ {
+ public:
+ GlScissorCommand() :
+ OpenGlCommand(false, false, "glScissor")
+ {
+ }
+
+ static std::shared_ptr get(GLint x, GLint y, GLsizei width, GLsizei height)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(x, y, width, height);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrScissor(m_x, m_y, m_width, m_height);
+ }
+ private:
+ void set(GLint x, GLint y, GLsizei width, GLsizei height)
+ {
+ m_x = x;
+ m_y = y;
+ m_width = width;
+ m_height = height;
+ }
+
+ GLint m_x;
+ GLint m_y;
+ GLsizei m_width;
+ GLsizei m_height;
+ };
+
+ class GlViewportCommand : public OpenGlCommand
+ {
+ public:
+ GlViewportCommand() :
+ OpenGlCommand(false, false, "glViewport")
+ {
+ }
+
+ static std::shared_ptr get(GLint x, GLint y, GLsizei width, GLsizei height)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(x, y, width, height);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrViewport(m_x, m_y, m_width, m_height);
+ }
+ private:
+ void set(GLint x, GLint y, GLsizei width, GLsizei height)
+ {
+ m_x = x;
+ m_y = y;
+ m_width = width;
+ m_height = height;
+ }
+
+ GLint m_x;
+ GLint m_y;
+ GLsizei m_width;
+ GLsizei m_height;
+ };
+
+ class GlBindTextureCommand : public OpenGlCommand
+ {
+ public:
+ GlBindTextureCommand() :
+ OpenGlCommand(false, false, "glBindTexture")
+ {
+ }
+
+ static std::shared_ptr get(GLenum target, GLuint texture)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(target, texture);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrBindTexture(m_target, m_texture);
+ }
+ private:
+ void set(GLenum target, GLuint texture)
+ {
+ m_target = target;
+ m_texture = texture;
+ }
+
+ GLenum m_target;
+ GLuint m_texture;
+ };
+
+ class GlTexImage2DCommand : public OpenGlCommand
+ {
+ public:
+ GlTexImage2DCommand() :
+ OpenGlCommand(false, false, "glTexImage2D")
+ {
+ }
+
+ static std::shared_ptr get(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type, std::unique_ptr pixels)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(target, level, internalformat, width, height, border, format, type, std::move(pixels));
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrTexImage2D(m_target, m_level, m_internalformat, m_width, m_height, m_border, m_format, m_type,
+ m_pixels.get());
+ }
+ private:
+ void set(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type, std::unique_ptr pixels)
+ {
+ m_target = target;
+ m_level = level;
+ m_internalformat = internalformat;
+ m_width = width;
+ m_height = height;
+ m_border = border;
+ m_format = format;
+ m_type = type;
+ m_pixels = std::move(pixels);
+ }
+
+ GLenum m_target;
+ GLint m_level;
+ GLint m_internalformat;
+ GLsizei m_width;
+ GLsizei m_height;
+ GLint m_border;
+ GLenum m_format;
+ GLenum m_type;
+ std::unique_ptr m_pixels;
+ };
+
+ class GlTexParameteriCommand : public OpenGlCommand
+ {
+ public:
+ GlTexParameteriCommand() :
+ OpenGlCommand(false, false, "glTexParameteri")
+ {
+ }
+
+ static std::shared_ptr get(GLenum target, GLenum pname, GLint param)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(target, pname, param);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrTexParameteri(m_target, m_pname, m_param);
+ }
+ private:
+ void set(GLenum target, GLenum pname, GLint param)
+ {
+ m_target = target;
+ m_pname = pname;
+ m_param = param;
+ }
+
+ GLenum m_target;
+ GLenum m_pname;
+ GLint m_param;
+ };
+
+ class GlGetIntegervCommand : public OpenGlCommand
+ {
+ public:
+ GlGetIntegervCommand() :
+ OpenGlCommand(true, false, "glGetIntegerv")
+ {
+ }
+
+ static std::shared_ptr get(GLenum pname, GLint* data)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(pname, data);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrGetIntegerv(m_pname, m_data);
+ }
+ private:
+ void set(GLenum pname, GLint* data)
+ {
+ m_pname = pname;
+ m_data = data;
+ }
+
+ GLenum m_pname;
+ GLint* m_data;
+ };
+
+ class GlGetStringCommand : public OpenGlCommand
+ {
+ public:
+ GlGetStringCommand() :
+ OpenGlCommand(true, false, "glGetString")
+ {
+ }
+
+ static std::shared_ptr get(GLenum name, const GLubyte*& returnValue)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(name, returnValue);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ *m_returnValue = ptrGetString(m_name);
+ }
+ private:
+ void set(GLenum name, const GLubyte*& returnValue)
+ {
+ m_name = name;
+ m_returnValue = &returnValue;
+ }
+
+ GLenum m_name;
+ const GLubyte** m_returnValue;
+ };
+
+ class GlReadPixelsCommand : public OpenGlCommand
+ {
+ public:
+ GlReadPixelsCommand() :
+ OpenGlCommand(true, true, "glReadPixels")
+ {
+ }
+
+ static std::shared_ptr get(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(x, y, width, height, format, type, pixels);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrReadPixels(m_x, m_y, m_width, m_height, m_format, m_type, m_pixels);
+ }
+ private:
+ void set(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
+ {
+ m_x = x;
+ m_y = y;
+ m_width = width;
+ m_height = height;
+ m_format = format;
+ m_type = type;
+ m_pixels = pixels;
+ }
+
+ GLint m_x;
+ GLint m_y;
+ GLsizei m_width;
+ GLsizei m_height;
+ GLenum m_format;
+ GLenum m_type;
+ void* m_pixels;
+ };
+
+ class GlReadPixelsAsyncCommand : public OpenGlCommand
+ {
+ public:
+ GlReadPixelsAsyncCommand() :
+ OpenGlCommand(false, false, "GlReadPixelsAync")
+ {
+ }
+
+ static std::shared_ptr get(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(x, y, width, height, format, type);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrReadPixels(m_x, m_y, m_width, m_height, m_format, m_type, nullptr);
+ }
+
+ static GLuint getBoundBuffer()
+ {
+ return m_readPixelsBoundBuffer;
+ }
+
+ static void setBoundBuffer(GLuint buffer)
+ {
+ m_readPixelsBoundBuffer = buffer;
+ }
+
+ private:
+ void set(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type)
+ {
+ m_x = x;
+ m_y = y;
+ m_width = width;
+ m_height = height;
+ m_format = format;
+ m_type = type;
+ }
+
+ GLint m_x;
+ GLint m_y;
+ GLsizei m_width;
+ GLsizei m_height;
+ GLenum m_format;
+ GLenum m_type;
+ static GLuint m_readPixelsBoundBuffer;
+ };
+
+ class GlTexSubImage2DUnbufferedCommand : public OpenGlCommand
+ {
+ public:
+ GlTexSubImage2DUnbufferedCommand() :
+ OpenGlCommand(false, false, "glTexSubImage2D")
+ {
+ }
+
+ static std::shared_ptr get(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, std::unique_ptr pixels)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(target, level, xoffset, yoffset, width, height, format, type, std::move(pixels));
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrTexSubImage2D(m_target, m_level, m_xoffset, m_yoffset, m_width, m_height, m_format, m_type, m_pixels.get());
+ }
+ private:
+ void set(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, std::unique_ptr pixels)
+ {
+ m_target = target;
+ m_level = level;
+ m_xoffset = xoffset;
+ m_yoffset = yoffset;
+ m_width = width;
+ m_height = height;
+ m_format = format;
+ m_type = type;
+ m_pixels = std::move(pixels);
+ }
+
+ GLenum m_target;
+ GLint m_level;
+ GLint m_xoffset;
+ GLint m_yoffset;
+ GLsizei m_width;
+ GLsizei m_height;
+ GLenum m_format;
+ GLenum m_type;
+ std::unique_ptr m_pixels;
+ };
+
+ class GlDrawArraysCommand : public OpenGlCommand
+ {
+ public:
+ GlDrawArraysCommand() :
+ OpenGlCommand(false, false, "glDrawArrays")
+ {
+ }
+
+ static std::shared_ptr get(GLenum mode, GLint first, GLsizei count)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(mode, first, count);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDrawArrays(m_mode, m_first, m_count);
+ }
+ private:
+ void set(GLenum mode, GLint first, GLsizei count)
+ {
+ m_mode = mode;
+ m_first = first;
+ m_count = count;
+ }
+
+ GLenum m_mode;
+ GLint m_first;
+ GLsizei m_count;
+ };
+
+ class GlVertexAttribPointerManager
+ {
+ public:
+ struct VertexAttributeData
+ {
+ GLuint m_index;
+ GLint m_size;
+ GLenum m_type;
+ GLboolean m_normalized;
+ GLsizei m_stride;
+ const void* m_pointer;
+ bool m_enabled;
+ bool m_updated = false;
+ };
+
+ static void enableVertexAttributeIndexRender(unsigned int index)
+ {
+ VertexAttributeData& attributeData = m_vertexAttributePointersRender[index];
+ attributeData.m_enabled = true;
+
+ updatedSmallestPtrRender();
+ }
+
+ static void disableVertexAttributeIndexRender(unsigned int index)
+ {
+ VertexAttributeData& attributeData = m_vertexAttributePointersRender[index];
+ attributeData.m_enabled = false;
+
+ updatedSmallestPtrRender();
+ }
+
+ static std::unordered_map& getVertexAttributesRender()
+ {
+ return m_vertexAttributePointersRender;
+ }
+
+ static void updateRender(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
+ {
+ VertexAttributeData &vertexAttributeData = m_vertexAttributePointersRender[index];
+ vertexAttributeData.m_index = index;
+ vertexAttributeData.m_size = size;
+ vertexAttributeData.m_type = type;
+ vertexAttributeData.m_normalized = normalized;
+ vertexAttributeData.m_stride = stride;
+ vertexAttributeData.m_pointer = pointer;
+ vertexAttributeData.m_updated = true;
+
+ updatedSmallestPtrRender();
+ }
+
+ static const char* getSmallestPtrRender() {
+ return reinterpret_cast(smallestDataPtrRender);
+ }
+
+ static void enableVertexAttributeIndex(unsigned int index)
+ {
+ VertexAttributeData& attributeData = m_vertexAttributePointers[index];
+ attributeData.m_enabled = true;
+
+ updatedSmallestPtr();
+ }
+
+ static void disableVertexAttributeIndex(int index)
+ {
+ VertexAttributeData& attributeData = m_vertexAttributePointers[index];
+ attributeData.m_enabled = false;
+
+ updatedSmallestPtr();
+ }
+
+ static int getStride()
+ {
+ int stride = 0;
+ for (auto& data : m_vertexAttributePointers) {
+ if (data.second.m_pointer && data.second.m_enabled) {
+ stride = data.second.m_stride;
+ break;
+ }
+ }
+
+ return stride;
+ }
+
+ static void update(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
+ {
+ VertexAttributeData &vertexAttributeData = m_vertexAttributePointers[index];
+ vertexAttributeData.m_index = index;
+ vertexAttributeData.m_size = size;
+ vertexAttributeData.m_type = type;
+ vertexAttributeData.m_normalized = normalized;
+ vertexAttributeData.m_stride = stride;
+ vertexAttributeData.m_pointer = pointer;
+
+ updatedSmallestPtr();
+ }
+
+ static const char* getSmallestPtr() {
+ return reinterpret_cast(smallestDataPtr);
+ }
+
+ static splicer::Node>* getVectorFromPool() {
+ return m_vectorPool.acquireOne().release();
+ }
+
+ static void releaseVectorFromPool(splicer::Node>* node) {
+ m_vectorPool.release(node);
+ }
+
+ private:
+ static void updatedSmallestPtrRender()
+ {
+ smallestDataPtrRender = nullptr;
+
+ for (auto& data : m_vertexAttributePointersRender) {
+ if (data.second.m_pointer && data.second.m_enabled && (smallestDataPtrRender == nullptr || data.second.m_pointer < smallestDataPtrRender)) {
+ smallestDataPtrRender = data.second.m_pointer;
+ }
+ }
+ }
+
+ static void updatedSmallestPtr()
+ {
+ smallestDataPtr = nullptr;
+
+ for (auto& data : m_vertexAttributePointers) {
+ if (data.second.m_pointer && data.second.m_enabled && (smallestDataPtr == nullptr || data.second.m_pointer < smallestDataPtr)) {
+ smallestDataPtr = data.second.m_pointer;
+ }
+ }
+ }
+
+ static std::unordered_map m_vertexAttributePointersRender;
+ static const void* smallestDataPtrRender;
+
+ static std::unordered_map m_vertexAttributePointers;
+ static const void* smallestDataPtr;
+
+ static splicer::ObjectPool> m_vectorPool;
+ };
+
+ class GlVertexAttribPointerUnbufferedCommand : public OpenGlCommand
+ {
+ public:
+ GlVertexAttribPointerUnbufferedCommand() :
+ OpenGlCommand(false, false, "glVertexAttribPointer")
+ {
+ }
+
+ static std::shared_ptr get(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(index, size, type, normalized, stride, pointer);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ GlVertexAttribPointerManager::updateRender(m_index, m_size, m_type, m_normalized, m_stride, m_pointer);
+ }
+
+ private:
+ void set(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
+ {
+ m_index = index;
+ m_size = size;
+ m_type = type;
+ m_normalized = normalized;
+ m_stride = stride;
+ m_pointer = pointer;
+ }
+
+ GLuint m_index;
+ GLint m_size;
+ GLenum m_type;
+ GLboolean m_normalized;
+ GLsizei m_stride;
+ const void* m_pointer;
+ };
+
+ class GlDrawArraysUnbufferedCommand : public OpenGlCommand
+ {
+ public:
+ GlDrawArraysUnbufferedCommand() :
+ OpenGlCommand(false, false, "glDrawArraysUnbuffered")
+ {
+ static bool attribsDataInitialized = false;
+
+ if (!attribsDataInitialized) {
+ m_attribsData.resize(2*1024*1024, 0);
+ attribsDataInitialized = true;
+ }
+ }
+
+ static std::shared_ptr get(GLenum mode, GLint first, GLsizei count, splicer::Node>* data)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(mode, first, count, data);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ auto& vertexAttributes = GlVertexAttribPointerManager::getVertexAttributesRender();
+
+ for (auto& data : vertexAttributes) {
+ if (data.second.m_updated && data.second.m_enabled) {
+
+ unsigned long ptrOffset = reinterpret_cast(data.second.m_pointer) -
+ GlVertexAttribPointerManager::getSmallestPtrRender();
+ ptrVertexAttribPointer(data.second.m_index, data.second.m_size, data.second.m_type, data.second.m_normalized,
+ data.second.m_stride, reinterpret_cast(m_attribsData.data() + ptrOffset));
+ data.second.m_updated = false;
+ }
+ }
+ std::copy_n(m_data->val().begin(), m_data->val().size(), m_attribsData.begin());
+ ptrDrawArrays(m_mode, m_first, m_count);
+ GlVertexAttribPointerManager::releaseVectorFromPool(m_data);
+ }
+ private:
+ void set(GLenum mode, GLint first, GLsizei count, splicer::Node>* data)
+ {
+ m_mode = mode;
+ m_first = first;
+ m_count = count;
+ m_data = data;
+ }
+
+ GLenum m_mode;
+ GLint m_first;
+ GLsizei m_count;
+ splicer::Node>* m_data;
+ static std::vector m_attribsData;
+ };
+
+ class GlGetErrorCommand : public OpenGlCommand
+ {
+ public:
+ GlGetErrorCommand() :
+ OpenGlCommand(true, true, "glGetError")
+ {
+ }
+
+ static std::shared_ptr get(GLenum& returnValue)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(returnValue);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ *m_returnValue = ptrGetError();
+ }
+ private:
+ void set(GLenum& returnValue)
+ {
+ m_returnValue = &returnValue;
+ }
+
+ GLenum* m_returnValue;
+ };
+
+ class GlDrawElementsUnbufferedCommand : public OpenGlCommand
+ {
+ public:
+ GlDrawElementsUnbufferedCommand() :
+ OpenGlCommand(false, false, "glDrawElementsUnbuffered")
+ {
+ static bool attribsDataInitialized = false;
+
+ if (!attribsDataInitialized) {
+ m_attribsData.resize(2*1024*1024, 0);
+ attribsDataInitialized = true;
+ }
+ }
+
+ static std::shared_ptr get(GLenum mode, GLsizei count, GLenum type, std::unique_ptr indices,
+ splicer::Node>* data)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(mode, count, type, std::move(indices), std::move(data));
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ auto& vertexAttributes = GlVertexAttribPointerManager::getVertexAttributesRender();
+ int count = 0;
+
+ for (auto& data : vertexAttributes) {
+ if (data.second.m_updated && data.second.m_enabled) {
+ unsigned long ptrOffset = reinterpret_cast(data.second.m_pointer) -
+ GlVertexAttribPointerManager::getSmallestPtrRender();
+ ptrVertexAttribPointer(data.second.m_index, data.second.m_size, data.second.m_type, data.second.m_normalized,
+ data.second.m_stride, reinterpret_cast(m_attribsData.data() + ptrOffset));
+ data.second.m_updated = false;
+ }
+ }
+
+ std::copy_n(m_data->val().begin(), m_data->val().size(), m_attribsData.begin());
+ ptrDrawElements(m_mode, m_count, m_type, m_indices.get());
+ GlVertexAttribPointerManager::releaseVectorFromPool(m_data);
+ }
+ private:
+ void set(GLenum mode, GLsizei count, GLenum type, std::unique_ptr indices,
+ splicer::Node>* data)
+ {
+ m_mode = mode;
+ m_count = count;
+ m_type = type;
+ m_indices = std::move(indices);
+ m_data = data;
+ }
+
+ GLenum m_mode;
+ GLsizei m_count;
+ GLenum m_type;
+ std::unique_ptr m_indices;
+ splicer::Node>* m_data;
+ static std::vector m_attribsData;
+ };
+
+ class GlLineWidthCommand : public OpenGlCommand
+ {
+ public:
+ GlLineWidthCommand() :
+ OpenGlCommand(false, false, "glLineWidth")
+ {
+ }
+
+ static std::shared_ptr get(GLfloat width)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(width);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrLineWidth(m_width);
+ }
+ private:
+ void set(GLfloat width)
+ {
+ m_width = width;
+ }
+
+ GLfloat m_width;
+ };
+
+ class GlClearCommand : public OpenGlCommand
+ {
+ public:
+ GlClearCommand() :
+ OpenGlCommand(false, false, "glClear")
+ {
+ }
+
+ static std::shared_ptr get(GLbitfield mask)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(mask);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrClear(m_mask);
+ }
+ private:
+ void set(GLbitfield mask)
+ {
+ m_mask = mask;
+ }
+
+ GLbitfield m_mask;
+ };
+
+ class GlClearBufferfvCommand : public OpenGlCommand
+ {
+ public:
+ GlClearBufferfvCommand() :
+ OpenGlCommand(false, false, "glClearBufferfv")
+ {
+ }
+
+ static std::shared_ptr get(GLenum buffer, GLint drawbuffer, std::unique_ptr value)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(buffer, drawbuffer, std::move(value));
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrClearBufferfv(m_buffer, m_drawbuffer, m_value.get());
+ }
+ private:
+ void set(GLenum buffer, GLint drawbuffer, std::unique_ptr value)
+ {
+ m_buffer = buffer;
+ m_drawbuffer = drawbuffer;
+ m_value = std::move(value);
+ }
+
+ GLenum m_buffer;
+ GLint m_drawbuffer;
+ std::unique_ptr m_value;
+ };
+
+ class GlGetFloatvCommand : public OpenGlCommand
+ {
+ public:
+ GlGetFloatvCommand() :
+ OpenGlCommand(true, false, "glGetFloatv")
+ {
+ }
+
+ static std::shared_ptr get(GLenum pname, GLfloat* data)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(pname, data);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrGetFloatv(m_pname, m_data);
+ }
+ private:
+ void set(GLenum pname, GLfloat* data)
+ {
+ m_pname = pname;
+ m_data = data;
+ }
+
+ GLenum m_pname;
+ GLfloat* m_data;
+ };
+
+ class GlDeleteTexturesCommand : public OpenGlCommand
+ {
+ public:
+ GlDeleteTexturesCommand() :
+ OpenGlCommand(false, false, "glDeleteTextures")
+ {
+ }
+
+ static std::shared_ptr get(GLsizei n, std::unique_ptr textures)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(n, std::move(textures));
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDeleteTextures(m_n, m_textures.get());
+ }
+ private:
+ void set(GLsizei n, std::unique_ptr textures)
+ {
+ m_n = n;
+ m_textures = std::move(textures);
+ }
+
+ GLsizei m_n;
+ std::unique_ptr m_textures;
+ };
+
+ class GlGenTexturesCommand : public OpenGlCommand
+ {
+ public:
+ GlGenTexturesCommand() :
+ OpenGlCommand(true, false, "glGenTextures")
+ {
+ }
+
+ static std::shared_ptr get(GLsizei n, GLuint* textures)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(n, textures);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrGenTextures(m_n, m_textures);
+ }
+ private:
+ void set(GLsizei n, GLuint* textures)
+ {
+ m_n = n;
+ m_textures = textures;
+ }
+
+ GLsizei m_n;
+ GLuint* m_textures;
+ };
+
+ class GlTexParameterfCommand : public OpenGlCommand
+ {
+ public:
+ GlTexParameterfCommand() :
+ OpenGlCommand(false, false, "glTexParameterf")
+ {
+ }
+
+ static std::shared_ptr get(GLenum target, GLenum pname, GLfloat param)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(target, pname, param);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrTexParameterf(m_target, m_pname, m_param);
+ }
+ private:
+ void set(GLenum target, GLenum pname, GLfloat param)
+ {
+ m_target = target;
+ m_pname = pname;
+ m_param = param;
+ }
+
+ GLenum m_target;
+ GLenum m_pname;
+ GLfloat m_param;
+ };
+
+ class GlActiveTextureCommand : public OpenGlCommand
+ {
+ public:
+ GlActiveTextureCommand() :
+ OpenGlCommand(false, false, "glActiveTexture")
+ {
+ }
+
+ static std::shared_ptr get(GLenum texture)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(texture);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrActiveTexture(m_texture);
+ }
+ private:
+ void set(GLenum texture)
+ {
+ m_texture = texture;
+ }
+
+ GLenum m_texture;
+ };
+
+ class GlBlendColorCommand : public OpenGlCommand
+ {
+ public:
+ GlBlendColorCommand() :
+ OpenGlCommand(false, false, "glBlendColor")
+ {
+ }
+
+ static std::shared_ptr get(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(red, green, blue, alpha);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrBlendColor(m_red, m_green, m_blue, m_alpha);
+ }
+ private:
+ void set(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+ {
+ m_red = red;
+ m_green = green;
+ m_blue = blue;
+ m_alpha = alpha;
+ }
+
+ GLfloat m_red;
+ GLfloat m_green;
+ GLfloat m_blue;
+ GLfloat m_alpha;
+ };
+
+ class GlReadBufferCommand : public OpenGlCommand
+ {
+ public:
+ GlReadBufferCommand() :
+ OpenGlCommand(false, false, "glReadBuffer")
+ {
+ }
+
+ static std::shared_ptr get(GLenum src)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(src);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrReadBuffer(m_src);
+ }
+ private:
+ void set(GLenum src)
+ {
+ m_src = src;
+ }
+
+ GLenum m_src;
+ };
+
+ class GlCreateShaderCommand : public OpenGlCommand
+ {
+ public:
+ GlCreateShaderCommand() :
+ OpenGlCommand(true, true, "glCreateShader")
+ {
+ }
+
+ static std::shared_ptr get(GLenum type, GLuint& returnValue)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(type, returnValue);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ *m_returnValue = ptrCreateShader(m_type);
+ }
+ private:
+ void set(GLenum type, GLuint& returnValue)
+ {
+ m_type = type;
+ m_returnValue = &returnValue;
+ }
+
+ GLenum m_type;
+ GLuint* m_returnValue;
+ };
+
+ class GlCompileShaderCommand : public OpenGlCommand
+ {
+ public:
+ GlCompileShaderCommand() :
+ OpenGlCommand(false, false, "glCompileShader")
+ {
+ }
+
+ static std::shared_ptr get(GLuint shader)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(shader);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrCompileShader(m_shader);
+ }
+ private:
+ void set(GLuint shader)
+ {
+ m_shader = shader;
+ }
+
+ GLuint m_shader;
+ };
+
+ class GlShaderSourceCommand : public OpenGlCommand
+ {
+ public:
+ GlShaderSourceCommand() :
+ OpenGlCommand(false, false, "glShaderSource")
+ {
+ }
+
+ static std::shared_ptr get(GLuint shader, std::vector& strings)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(shader, strings);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ const GLchar **stringData = new const GLchar*[m_strings.size()];
+ for (unsigned int index = 0; index < m_strings.size(); ++index) {
+ stringData[index] = m_strings[index].data();
+ }
+
+ ptrShaderSource(m_shader, m_strings.size(), stringData, nullptr);
+ }
+ private:
+ void set(GLuint shader, std::vector& strings)
+ {
+ m_shader = shader;
+ m_strings = std::move(strings);
+ }
+
+ GLuint m_shader;
+ std::vector m_strings;
+ };
+
+ class GlCreateProgramCommand : public OpenGlCommand
+ {
+ public:
+ GlCreateProgramCommand() :
+ OpenGlCommand(true, true, "glCreateProgram")
+ {
+ }
+
+ static std::shared_ptr get(GLuint& returnValue)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(returnValue);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ *m_returnValue = ptrCreateProgram();
+ }
+ private:
+ void set(GLuint& returnValue)
+ {
+ m_returnValue = &returnValue;
+ }
+
+ GLuint* m_returnValue;
+ };
+
+ class GlAttachShaderCommand : public OpenGlCommand
+ {
+ public:
+ GlAttachShaderCommand() :
+ OpenGlCommand(false, false, "glAttachShader")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program, GLuint shader)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program, shader);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrAttachShader(m_program, m_shader);
+ }
+ private:
+ void set(GLuint program, GLuint shader)
+ {
+ m_program = program;
+ m_shader = shader;
+ }
+
+ GLuint m_program;
+ GLuint m_shader;
+ };
+
+ class GlLinkProgramCommand : public OpenGlCommand
+ {
+ public:
+ GlLinkProgramCommand() :
+ OpenGlCommand(false, false, "glLinkProgram")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrLinkProgram(m_program);
+ }
+ private:
+ void set(GLuint program)
+ {
+ m_program = program;
+ }
+
+ GLuint m_program;
+ };
+
+ class GlUseProgramCommand : public OpenGlCommand
+ {
+ public:
+ GlUseProgramCommand() :
+ OpenGlCommand(false, false, "glUseProgram")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUseProgram(m_program);
+ }
+ private:
+ void set(GLuint program)
+ {
+ m_program = program;
+ }
+
+ GLuint m_program;
+ };
+
+ class GlGetUniformLocationCommand : public OpenGlCommand
+ {
+ public:
+ GlGetUniformLocationCommand() :
+ OpenGlCommand(true, true, "glGetUniformLocation")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program, const GLchar* name, GLint& returnValue)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program, name, returnValue);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ *m_returnValue = ptrGetUniformLocation(m_program, m_name);
+ }
+ private:
+ void set(GLuint program, const GLchar* name, GLint& returnValue)
+ {
+ m_program = program;
+ m_name = name;
+ m_returnValue = &returnValue;
+ }
+
+ GLint* m_returnValue;
+ GLuint m_program;
+ const GLchar* m_name;
+ };
+
+ class GlUniform1iCommand : public OpenGlCommand
+ {
+ public:
+ GlUniform1iCommand() :
+ OpenGlCommand(false, false, "glUniform1i")
+ {
+ }
+
+ static std::shared_ptr get(GLint location, GLint v0)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(location, v0);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUniform1i(m_location, m_v0);
+ }
+ private:
+ void set(GLint location, GLint v0)
+ {
+ m_location = location;
+ m_v0 = v0;
+ }
+
+ GLint m_location;
+ GLint m_v0;
+ };
+
+ class GlUniform1fCommand : public OpenGlCommand
+ {
+ public:
+ GlUniform1fCommand() :
+ OpenGlCommand(false, false, "glUniform1f")
+ {
+ }
+
+ static std::shared_ptr get(GLint location, GLfloat v0)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(location, v0);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUniform1f(m_location, m_v0);
+ }
+ private:
+ void set(GLint location, GLfloat v0)
+ {
+ m_location = location;
+ m_v0 = v0;
+ }
+
+ GLint m_location;
+ GLfloat m_v0;
+ };
+
+ class GlUniform2fCommand : public OpenGlCommand
+ {
+ public:
+ GlUniform2fCommand() :
+ OpenGlCommand(false, false, "glUniform2f")
+ {
+ }
+
+ static std::shared_ptr get(GLint location, GLfloat v0, GLfloat v1)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(location, v0, v1);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUniform2f(m_location, m_v0, m_v1);
+ }
+ private:
+ void set(GLint location, GLfloat v0, GLfloat v1)
+ {
+ m_location = location;
+ m_v0 = v0;
+ m_v1 = v1;
+ }
+
+ GLint m_location;
+ GLfloat m_v0;
+ GLfloat m_v1;
+ };
+
+ class GlUniform2iCommand : public OpenGlCommand
+ {
+ public:
+ GlUniform2iCommand() :
+ OpenGlCommand(false, false, "glUniform2i")
+ {
+ }
+
+ static std::shared_ptr get(GLint location, GLint v0, GLint v1)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(location, v0, v1);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUniform2i(m_location, m_v0, m_v1);
+ }
+ private:
+ void set(GLint location, GLint v0, GLint v1)
+ {
+ m_location = location;
+ m_v0 = v0;
+ m_v1 = v1;
+ }
+
+ GLint m_location;
+ GLint m_v0;
+ GLint m_v1;
+ };
+
+ class GlUniform4iCommand : public OpenGlCommand
+ {
+ public:
+ GlUniform4iCommand() :
+ OpenGlCommand(false, false, "glUniform4i")
+ {
+ }
+
+ static std::shared_ptr get(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(location, v0, v1, v2, v3);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUniform4i(m_location, m_v0, m_v1, m_v2, m_v3);
+ }
+ private:
+ void set(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+ {
+ m_location = location;
+ m_v0 = v0;
+ m_v1 = v1;
+ m_v2 = v2;
+ m_v3 = v3;
+ }
+
+ GLint m_location;
+ GLint m_v0;
+ GLint m_v1;
+ GLint m_v2;
+ GLint m_v3;
+ };
+
+ class GlUniform4fCommand : public OpenGlCommand
+ {
+ public:
+ GlUniform4fCommand() :
+ OpenGlCommand(false, false, "glUniform4f")
+ {
+ }
+
+ static std::shared_ptr get(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(location, v0, v1, v2, v3);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUniform4f(m_location, m_v0, m_v1, m_v2, m_v3);
+ }
+ private:
+ void set(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+ {
+ m_location = location;
+ m_v0 = v0;
+ m_v1 = v1;
+ m_v2 = v2;
+ m_v3 = v3;
+ }
+
+ GLint m_location;
+ GLfloat m_v0;
+ GLfloat m_v1;
+ GLfloat m_v2;
+ GLfloat m_v3;
+ };
+
+ class GlUniform3fvCommand : public OpenGlCommand
+ {
+ public:
+ GlUniform3fvCommand() :
+ OpenGlCommand(false, false, "glUniform3fv")
+ {
+ }
+
+ static std::shared_ptr get(GLint location, GLsizei count, std::unique_ptr value)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(location, count, std::move(value));
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUniform3fv(m_location, m_count, m_value.get());
+ }
+ private:
+ void set(GLint location, GLsizei count, std::unique_ptr value)
+ {
+ m_location = location;
+ m_count = count;
+ m_value = std::move(value);
+ }
+
+ GLint m_location;
+ GLsizei m_count;
+ std::unique_ptr m_value;
+ };
+
+ class GlUniform4fvCommand : public OpenGlCommand
+ {
+ public:
+ GlUniform4fvCommand() :
+ OpenGlCommand(false, false, "glUniform4fv")
+ {
+ }
+
+ static std::shared_ptr get(GLint location, GLsizei count, std::unique_ptr value)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(location, count, std::move(value));
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrUniform4fv(m_location, m_count, m_value.get());
+ }
+ private:
+ void set(GLint location, GLsizei count, std::unique_ptr value)
+ {
+ m_location = location;
+ m_count = count;
+ m_value = std::move(value);
+ }
+
+ GLint m_location;
+ GLsizei m_count;
+ std::unique_ptr m_value;
+ };
+
+ class GlDetachShaderCommand : public OpenGlCommand
+ {
+ public:
+ GlDetachShaderCommand() :
+ OpenGlCommand(false, false, "glDetachShader")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program, GLuint shader)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program, shader);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDetachShader(m_program, m_shader);
+ }
+ private:
+ void set(GLuint program, GLuint shader)
+ {
+ m_program = program;
+ m_shader = shader;
+ }
+
+ GLuint m_program;
+ GLuint m_shader;
+ };
+
+ class GlDeleteShaderCommand : public OpenGlCommand
+ {
+ public:
+ GlDeleteShaderCommand() :
+ OpenGlCommand(false, false, "glDeleteShader")
+ {
+ }
+
+ static std::shared_ptr get(GLuint shader)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(shader);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDeleteShader(m_shader);
+ }
+ private:
+ void set(GLuint shader)
+ {
+ m_shader = shader;
+ }
+
+ GLuint m_shader;
+ };
+
+ class GlDeleteProgramCommand : public OpenGlCommand
+ {
+ public:
+ GlDeleteProgramCommand() :
+ OpenGlCommand(false, false, "glDeleteProgram")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDeleteProgram(m_program);
+ }
+ private:
+ void set(GLuint program)
+ {
+ m_program = program;
+ }
+
+ GLuint m_program;
+ };
+
+ class GlGetProgramInfoLogCommand : public OpenGlCommand
+ {
+ public:
+ GlGetProgramInfoLogCommand() :
+ OpenGlCommand(true, true, "glGetProgramInfoLog")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program, bufSize, length, infoLog);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrGetProgramInfoLog(m_program, m_bufSize, m_length, m_infoLog);
+ }
+ private:
+ void set(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
+ {
+ m_program = program;
+ m_bufSize = bufSize;
+ m_length = length;
+ m_infoLog = infoLog;
+ }
+
+ GLuint m_program;
+ GLsizei m_bufSize;
+ GLsizei* m_length;
+ GLchar* m_infoLog;
+ };
+
+ class GlGetShaderInfoLogCommand : public OpenGlCommand
+ {
+ public:
+ GlGetShaderInfoLogCommand() :
+ OpenGlCommand(true, true, "glGetShaderInfoLog")
+ {
+ }
+
+ static std::shared_ptr get(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(shader, bufSize, length, infoLog);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrGetShaderInfoLog(m_shader, m_bufSize, m_length, m_infoLog);
+ }
+ private:
+ void set(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog)
+ {
+ m_shader = shader;
+ m_bufSize = bufSize;
+ m_length = length;
+ m_infoLog = infoLog;
+ }
+
+ GLuint m_shader;
+ GLsizei m_bufSize;
+ GLsizei* m_length;
+ GLchar* m_infoLog;
+ };
+
+ class GlGetShaderivCommand : public OpenGlCommand
+ {
+ public:
+ GlGetShaderivCommand() :
+ OpenGlCommand(true, true, "glGetShaderiv")
+ {
+ }
+
+ static std::shared_ptr get(GLuint shader, GLenum pname, GLint* params)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(shader, pname, params);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrGetShaderiv(m_shader, m_pname, m_params);
+ }
+ private:
+ void set(GLuint shader, GLenum pname, GLint* params)
+ {
+ m_shader = shader;
+ m_pname = pname;
+ m_params = params;
+ }
+
+ GLuint m_shader;
+ GLenum m_pname;
+ GLint* m_params;
+ };
+
+ class GlGetProgramivCommand : public OpenGlCommand
+ {
+ public:
+ GlGetProgramivCommand() :
+ OpenGlCommand(true, true, "glGetProgramiv")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program, GLenum pname, GLint*& params)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program, pname, params);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrGetProgramiv(m_program, m_pname, *m_params);
+ }
+ private:
+ void set(GLuint program, GLenum pname, GLint*& params)
+ {
+ m_program = program;
+ m_pname = pname;
+ m_params = ¶ms;
+ }
+
+ GLuint m_program;
+ GLenum m_pname;
+ GLint** m_params;
+ };
+
+ class GlEnableVertexAttribArrayCommand : public OpenGlCommand
+ {
+ public:
+ GlEnableVertexAttribArrayCommand() :
+ OpenGlCommand(false, false, "glEnableVertexAttribArray")
+ {
+ }
+
+ static std::shared_ptr get(GLuint index)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(index);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ GlVertexAttribPointerManager::enableVertexAttributeIndexRender(m_index);
+ ptrEnableVertexAttribArray(m_index);
+ }
+ private:
+ void set(GLuint index)
+ {
+ m_index = index;
+ }
+
+ GLuint m_index;
+ };
+
+ class GlDisableVertexAttribArrayCommand : public OpenGlCommand
+ {
+ public:
+ GlDisableVertexAttribArrayCommand() :
+ OpenGlCommand(false, false, "glDisableVertexAttribArray")
+ {
+ }
+
+ static std::shared_ptr get(GLuint index)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(index);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ GlVertexAttribPointerManager::disableVertexAttributeIndexRender(m_index);
+ ptrDisableVertexAttribArray(m_index);
+ }
+ private:
+ void set(GLuint index)
+ {
+ m_index = index;
+ }
+
+ GLuint m_index;
+ };
+
+ class GlVertexAttribPointerBufferedCommand : public OpenGlCommand
+ {
+ public:
+ GlVertexAttribPointerBufferedCommand() :
+ OpenGlCommand(false, false, "glVertexAttribPointer")
+ {
+ }
+
+ static std::shared_ptr get(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
+ const GLvoid* offset)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(index, size, type, normalized, stride, offset);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrVertexAttribPointer(m_index, m_size, m_type, m_normalized, m_stride, m_offset);
+ }
+ private:
+ void set(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
+ const GLvoid* offset)
+ {
+ m_index = index;
+ m_size = size;
+ m_type = type;
+ m_normalized = normalized;
+ m_stride = stride;
+ m_offset = offset;
+ }
+
+ GLuint m_index;
+ GLint m_size;
+ GLenum m_type;
+ GLboolean m_normalized;
+ GLsizei m_stride;
+ const GLvoid* m_offset;
+ };
+
+ class GlBindAttribLocationCommand : public OpenGlCommand
+ {
+ public:
+ GlBindAttribLocationCommand() :
+ OpenGlCommand(false, false, "glBindAttribLocation")
+ {
+ }
+
+ static std::shared_ptr get(GLuint program, GLuint index, const std::string name)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(program, index, name);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrBindAttribLocation(m_program, m_index, m_name.data());
+ }
+ private:
+ void set(GLuint program, GLuint index, const std::string name)
+ {
+ m_program = program;
+ m_index = index;
+ m_name = name;
+ }
+
+ GLuint m_program;
+ GLuint m_index;
+ std::string m_name;
+ };
+
+ class GlVertexAttrib1fCommand : public OpenGlCommand
+ {
+ public:
+ GlVertexAttrib1fCommand() :
+ OpenGlCommand(false, false, "glVertexAttrib1f")
+ {
+ }
+
+ static std::shared_ptr get(GLuint index, GLfloat x)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(index, x);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrVertexAttrib1f(m_index, m_x);
+ }
+ private:
+ void set(GLuint index, GLfloat x)
+ {
+ m_index = index;
+ m_x = x;
+ }
+
+ GLuint m_index;
+ GLfloat m_x;
+ };
+
+ class GlVertexAttrib4fCommand : public OpenGlCommand
+ {
+ public:
+ GlVertexAttrib4fCommand() :
+ OpenGlCommand(false, false, "glVertexAttrib4f")
+ {
+ }
+
+ static std::shared_ptr get(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(index, x, y, z, w);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrVertexAttrib4f(m_index, m_x, m_y, m_z, m_w);
+ }
+ private:
+ void set(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+ {
+ m_index = index;
+ m_x = x;
+ m_y = y;
+ m_z = z;
+ m_w = w;
+ }
+
+ GLuint m_index;
+ GLfloat m_x;
+ GLfloat m_y;
+ GLfloat m_z;
+ GLfloat m_w;
+ };
+
+ class GlVertexAttrib4fvCommand : public OpenGlCommand
+ {
+ public:
+ GlVertexAttrib4fvCommand() :
+ OpenGlCommand(false, false, "glVertexAttrib4fv")
+ {
+ }
+
+ static std::shared_ptr get(GLuint index, std::unique_ptr v)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(index, std::move(v));
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrVertexAttrib4fv(m_index, m_v.get());
+ }
+ private:
+ void set(GLuint index, std::unique_ptr v)
+ {
+ m_index = index;
+ m_v = std::move(v);
+ }
+
+ GLuint m_index;
+ std::unique_ptr m_v;
+ };
+
+ class GlDepthRangefCommand : public OpenGlCommand
+ {
+ public:
+ GlDepthRangefCommand() :
+ OpenGlCommand(false, false, "glDepthRangef")
+ {
+ }
+
+ static std::shared_ptr get(GLfloat n, GLfloat f)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(n, f);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrDepthRangef(m_n,m_f);
+ }
+ private:
+ void set(GLfloat n, GLfloat f)
+ {
+ m_n = n;
+ m_f = f;
+ }
+
+ GLfloat m_n;
+ GLfloat m_f;
+ };
+
+ class GlClearDepthfCommand : public OpenGlCommand
+ {
+ public:
+ GlClearDepthfCommand() :
+ OpenGlCommand(false, false, "glClearDepthf")
+ {
+ }
+
+ static std::shared_ptr get(GLfloat d)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool(poolId);
+ ptr->set(d);
+ return ptr;
+ }
+
+ void commandToExecute() override
+ {
+ ptrClearDepthf(m_d);
+ }
+ private:
+ void set(GLfloat d)
+ {
+ m_d = d;
+ }
+
+ GLfloat m_d;
+ };
+
+ class GlDrawBuffersCommand : public OpenGlCommand
+ {
+ public:
+ GlDrawBuffersCommand() :
+ OpenGlCommand(false, false, "glDrawBuffers")
+ {
+ }
+
+ static std::shared_ptr get(GLsizei n, std::unique_ptr bufs)
+ {
+ static int poolId = OpenGlCommandPool::get().getNextAvailablePool();
+ auto ptr = getFromPool