1
0
Fork 0

Codechange: [OpenGL] Simplify loading OpenGL extension functions.

pull/8744/head
Michael Lutz 2021-02-24 22:55:36 +01:00
parent e1e8cc3851
commit a0c1a3f736
1 changed files with 147 additions and 134 deletions

View File

@ -20,6 +20,7 @@
# include <windows.h> # include <windows.h>
#endif #endif
#define GL_GLEXT_PROTOTYPES
#if defined(__APPLE__) #if defined(__APPLE__)
# include <OpenGL/gl3.h> # include <OpenGL/gl3.h>
#else #else
@ -46,54 +47,61 @@
#include "../safeguards.h" #include "../safeguards.h"
static PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl; /* Define function pointers of all OpenGL functions that we load dynamically. */
static PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback;
static PFNGLACTIVETEXTUREPROC _glActiveTexture; #define GL(function) static decltype(&function) _ ## function
static PFNGLGENBUFFERSPROC _glGenBuffers; GL(glDebugMessageControl);
static PFNGLDELETEBUFFERSPROC _glDeleteBuffers; GL(glDebugMessageCallback);
static PFNGLBINDBUFFERPROC _glBindBuffer;
static PFNGLBUFFERDATAPROC _glBufferData;
static PFNGLBUFFERSUBDATAPROC _glBufferSubData;
static PFNGLMAPBUFFERPROC _glMapBuffer;
static PFNGLUNMAPBUFFERPROC _glUnmapBuffer;
static PFNGLCLEARBUFFERSUBDATAPROC _glClearBufferSubData;
static PFNGLBUFFERSTORAGEPROC _glBufferStorage; GL(glActiveTexture);
static PFNGLMAPBUFFERRANGEPROC _glMapBufferRange;
static PFNGLCLIENTWAITSYNCPROC _glClientWaitSync;
static PFNGLFENCESYNCPROC _glFenceSync;
static PFNGLDELETESYNCPROC _glDeleteSync;
static PFNGLGENVERTEXARRAYSPROC _glGenVertexArrays; GL(glGenBuffers);
static PFNGLDELETEVERTEXARRAYSPROC _glDeleteVertexArrays; GL(glDeleteBuffers);
static PFNGLBINDVERTEXARRAYPROC _glBindVertexArray; GL(glBindBuffer);
GL(glBufferData);
GL(glBufferSubData);
GL(glMapBuffer);
GL(glUnmapBuffer);
GL(glClearBufferSubData);
static PFNGLCREATEPROGRAMPROC _glCreateProgram; GL(glBufferStorage);
static PFNGLDELETEPROGRAMPROC _glDeleteProgram; GL(glMapBufferRange);
static PFNGLLINKPROGRAMPROC _glLinkProgram; GL(glClientWaitSync);
static PFNGLUSEPROGRAMPROC _glUseProgram; GL(glFenceSync);
static PFNGLGETPROGRAMIVPROC _glGetProgramiv; GL(glDeleteSync);
static PFNGLGETPROGRAMINFOLOGPROC _glGetProgramInfoLog;
static PFNGLCREATESHADERPROC _glCreateShader; GL(glGenVertexArrays);
static PFNGLDELETESHADERPROC _glDeleteShader; GL(glDeleteVertexArrays);
static PFNGLSHADERSOURCEPROC _glShaderSource; GL(glBindVertexArray);
static PFNGLCOMPILESHADERPROC _glCompileShader;
static PFNGLATTACHSHADERPROC _glAttachShader; GL(glCreateProgram);
static PFNGLGETSHADERIVPROC _glGetShaderiv; GL(glDeleteProgram);
static PFNGLGETSHADERINFOLOGPROC _glGetShaderInfoLog; GL(glLinkProgram);
static PFNGLGETUNIFORMLOCATIONPROC _glGetUniformLocation; GL(glUseProgram);
static PFNGLUNIFORM1IPROC _glUniform1i; GL(glGetProgramiv);
static PFNGLUNIFORM1FPROC _glUniform1f; GL(glGetProgramInfoLog);
static PFNGLUNIFORM2FPROC _glUniform2f; GL(glCreateShader);
static PFNGLUNIFORM4FPROC _glUniform4f; GL(glDeleteShader);
GL(glShaderSource);
GL(glCompileShader);
GL(glAttachShader);
GL(glGetShaderiv);
GL(glGetShaderInfoLog);
GL(glGetUniformLocation);
GL(glUniform1i);
GL(glUniform1f);
GL(glUniform2f);
GL(glUniform4f);
GL(glGetAttribLocation);
GL(glEnableVertexAttribArray);
GL(glDisableVertexAttribArray);
GL(glVertexAttribPointer);
GL(glBindFragDataLocation);
#undef GL
static PFNGLGETATTRIBLOCATIONPROC _glGetAttribLocation;
static PFNGLENABLEVERTEXATTRIBARRAYPROC _glEnableVertexAttribArray;
static PFNGLDISABLEVERTEXATTRIBARRAYPROC _glDisableVertexAttribArray;
static PFNGLVERTEXATTRIBPOINTERARBPROC _glVertexAttribPointer;
static PFNGLBINDFRAGDATALOCATIONPROC _glBindFragDataLocation;
/** A simple 2D vertex with just position and texture. */ /** A simple 2D vertex with just position and texture. */
struct Simple2DVertex { struct Simple2DVertex {
@ -183,46 +191,60 @@ bool IsOpenGLVersionAtLeast(byte major, byte minor)
return (_gl_major_ver > major) || (_gl_major_ver == major && _gl_minor_ver >= minor); return (_gl_major_ver > major) || (_gl_major_ver == major && _gl_minor_ver >= minor);
} }
/**
* Try loading an OpenGL function.
* @tparam F Type of the function pointer.
* @param f Reference where to store the function pointer in.
* @param name Name of the function.
* @return True if the function could be bound.
*/
template <typename F>
static bool BindGLProc(F &f, const char *name)
{
f = reinterpret_cast<F>(GetOGLProcAddress(name));
return f != nullptr;
}
/** Bind texture-related extension functions. */ /** Bind texture-related extension functions. */
static bool BindTextureExtensions() static bool BindTextureExtensions()
{ {
if (IsOpenGLVersionAtLeast(1, 3)) { if (IsOpenGLVersionAtLeast(1, 3)) {
_glActiveTexture = (PFNGLACTIVETEXTUREPROC)GetOGLProcAddress("glActiveTexture"); if (!BindGLProc(_glActiveTexture, "glActiveTexture")) return false;
} else { } else {
_glActiveTexture = (PFNGLACTIVETEXTUREPROC)GetOGLProcAddress("glActiveTextureARB"); if (!BindGLProc(_glActiveTexture, "glActiveTextureARB")) return false;
} }
return _glActiveTexture != nullptr; return true;
} }
/** Bind vertex buffer object extension functions. */ /** Bind vertex buffer object extension functions. */
static bool BindVBOExtension() static bool BindVBOExtension()
{ {
if (IsOpenGLVersionAtLeast(1, 5)) { if (IsOpenGLVersionAtLeast(1, 5)) {
_glGenBuffers = (PFNGLGENBUFFERSPROC)GetOGLProcAddress("glGenBuffers"); if (!BindGLProc(_glGenBuffers, "glGenBuffers")) return false;
_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)GetOGLProcAddress("glDeleteBuffers"); if (!BindGLProc(_glDeleteBuffers, "glDeleteBuffers")) return false;
_glBindBuffer = (PFNGLBINDBUFFERPROC)GetOGLProcAddress("glBindBuffer"); if (!BindGLProc(_glBindBuffer, "glBindBuffer")) return false;
_glBufferData = (PFNGLBUFFERDATAPROC)GetOGLProcAddress("glBufferData"); if (!BindGLProc(_glBufferData, "glBufferData")) return false;
_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)GetOGLProcAddress("glBufferSubData"); if (!BindGLProc(_glBufferSubData, "glBufferSubData")) return false;
_glMapBuffer = (PFNGLMAPBUFFERPROC)GetOGLProcAddress("glMapBuffer"); if (!BindGLProc(_glMapBuffer, "glMapBuffer")) return false;
_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)GetOGLProcAddress("glUnmapBuffer"); if (!BindGLProc(_glUnmapBuffer, "glUnmapBuffer")) return false;
} else { } else {
_glGenBuffers = (PFNGLGENBUFFERSPROC)GetOGLProcAddress("glGenBuffersARB"); if (!BindGLProc(_glGenBuffers, "glGenBuffersARB")) return false;
_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)GetOGLProcAddress("glDeleteBuffersARB"); if (!BindGLProc(_glDeleteBuffers, "glDeleteBuffersARB")) return false;
_glBindBuffer = (PFNGLBINDBUFFERPROC)GetOGLProcAddress("glBindBufferARB"); if (!BindGLProc(_glBindBuffer, "glBindBufferARB")) return false;
_glBufferData = (PFNGLBUFFERDATAPROC)GetOGLProcAddress("glBufferDataARB"); if (!BindGLProc(_glBufferData, "glBufferDataARB")) return false;
_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)GetOGLProcAddress("glBufferSubDataARB"); if (!BindGLProc(_glBufferSubData, "glBufferSubDataARB")) return false;
_glMapBuffer = (PFNGLMAPBUFFERPROC)GetOGLProcAddress("glMapBufferARB"); if (!BindGLProc(_glMapBuffer, "glMapBufferARB")) return false;
_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)GetOGLProcAddress("glUnmapBufferARB"); if (!BindGLProc(_glUnmapBuffer, "glUnmapBufferARB")) return false;
} }
if (IsOpenGLVersionAtLeast(4, 3) || IsOpenGLExtensionSupported("GL_ARB_clear_buffer_object")) { if (IsOpenGLVersionAtLeast(4, 3) || IsOpenGLExtensionSupported("GL_ARB_clear_buffer_object")) {
_glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)GetOGLProcAddress("glClearBufferSubData"); BindGLProc(_glClearBufferSubData, "glClearBufferSubData");
} else { } else {
_glClearBufferSubData = nullptr; _glClearBufferSubData = nullptr;
} }
return _glGenBuffers != nullptr && _glDeleteBuffers != nullptr && _glBindBuffer != nullptr && _glBufferData != nullptr && _glBufferSubData != nullptr && _glMapBuffer != nullptr && _glUnmapBuffer != nullptr; return true;
} }
/** Bind vertex array object extension functions. */ /** Bind vertex array object extension functions. */
@ -232,86 +254,82 @@ static bool BindVBAExtension()
* Successfully getting pointers to one variant doesn't mean it is supported for * Successfully getting pointers to one variant doesn't mean it is supported for
* the current context. Always check the extension strings as well. */ * the current context. Always check the extension strings as well. */
if (IsOpenGLVersionAtLeast(3, 0) || IsOpenGLExtensionSupported("GL_ARB_vertex_array_object")) { if (IsOpenGLVersionAtLeast(3, 0) || IsOpenGLExtensionSupported("GL_ARB_vertex_array_object")) {
_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)GetOGLProcAddress("glGenVertexArrays"); if (!BindGLProc(_glGenVertexArrays, "glGenVertexArrays")) return false;
_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)GetOGLProcAddress("glDeleteVertexArrays"); if (!BindGLProc(_glDeleteVertexArrays, "glDeleteVertexArrays")) return false;
_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)GetOGLProcAddress("glBindVertexArray"); if (!BindGLProc(_glBindVertexArray, "glBindVertexArray")) return false;
} else if (IsOpenGLExtensionSupported("GL_APPLE_vertex_array_object")) { } else if (IsOpenGLExtensionSupported("GL_APPLE_vertex_array_object")) {
_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)GetOGLProcAddress("glGenVertexArraysAPPLE"); if (!BindGLProc(_glGenVertexArrays, "glGenVertexArraysAPPLE")) return false;
_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)GetOGLProcAddress("glDeleteVertexArraysAPPLE"); if (!BindGLProc(_glDeleteVertexArrays, "glDeleteVertexArraysAPPLE")) return false;
_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)GetOGLProcAddress("glBindVertexArrayAPPLE"); if (!BindGLProc(_glBindVertexArray, "glBindVertexArrayAPPLE")) return false;
} }
return _glGenVertexArrays != nullptr && _glDeleteVertexArrays != nullptr && _glBindVertexArray != nullptr; return true;
} }
/** Bind extension functions for shader support. */ /** Bind extension functions for shader support. */
static bool BindShaderExtensions() static bool BindShaderExtensions()
{ {
if (IsOpenGLVersionAtLeast(2, 0)) { if (IsOpenGLVersionAtLeast(2, 0)) {
_glCreateProgram = (PFNGLCREATEPROGRAMPROC)GetOGLProcAddress("glCreateProgram"); if (!BindGLProc(_glCreateProgram, "glCreateProgram")) return false;
_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)GetOGLProcAddress("glDeleteProgram"); if (!BindGLProc(_glDeleteProgram, "glDeleteProgram")) return false;
_glLinkProgram = (PFNGLLINKPROGRAMPROC)GetOGLProcAddress("glLinkProgram"); if (!BindGLProc(_glLinkProgram, "glLinkProgram")) return false;
_glUseProgram = (PFNGLUSEPROGRAMPROC)GetOGLProcAddress("glUseProgram"); if (!BindGLProc(_glUseProgram, "glUseProgram")) return false;
_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)GetOGLProcAddress("glGetProgramiv"); if (!BindGLProc(_glGetProgramiv, "glGetProgramiv")) return false;
_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)GetOGLProcAddress("glGetProgramInfoLog"); if (!BindGLProc(_glGetProgramInfoLog, "glGetProgramInfoLog")) return false;
_glCreateShader = (PFNGLCREATESHADERPROC)GetOGLProcAddress("glCreateShader"); if (!BindGLProc(_glCreateShader, "glCreateShader")) return false;
_glDeleteShader = (PFNGLDELETESHADERPROC)GetOGLProcAddress("glDeleteShader"); if (!BindGLProc(_glDeleteShader, "glDeleteShader")) return false;
_glShaderSource = (PFNGLSHADERSOURCEPROC)GetOGLProcAddress("glShaderSource"); if (!BindGLProc(_glShaderSource, "glShaderSource")) return false;
_glCompileShader = (PFNGLCOMPILESHADERPROC)GetOGLProcAddress("glCompileShader"); if (!BindGLProc(_glCompileShader, "glCompileShader")) return false;
_glAttachShader = (PFNGLATTACHSHADERPROC)GetOGLProcAddress("glAttachShader"); if (!BindGLProc(_glAttachShader, "glAttachShader")) return false;
_glGetShaderiv = (PFNGLGETSHADERIVPROC)GetOGLProcAddress("glGetShaderiv"); if (!BindGLProc(_glGetShaderiv, "glGetShaderiv")) return false;
_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)GetOGLProcAddress("glGetShaderInfoLog"); if (!BindGLProc(_glGetShaderInfoLog, "glGetShaderInfoLog")) return false;
_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)GetOGLProcAddress("glGetUniformLocation"); if (!BindGLProc(_glGetUniformLocation, "glGetUniformLocation")) return false;
_glUniform1i = (PFNGLUNIFORM1IPROC)GetOGLProcAddress("glUniform1i"); if (!BindGLProc(_glUniform1i, "glUniform1i")) return false;
_glUniform1f = (PFNGLUNIFORM1FPROC)GetOGLProcAddress("glUniform1f"); if (!BindGLProc(_glUniform1f, "glUniform1f")) return false;
_glUniform2f = (PFNGLUNIFORM2FPROC)GetOGLProcAddress("glUniform2f"); if (!BindGLProc(_glUniform2f, "glUniform2f")) return false;
_glUniform4f = (PFNGLUNIFORM4FPROC)GetOGLProcAddress("glUniform4f"); if (!BindGLProc(_glUniform4f, "glUniform4f")) return false;
_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)GetOGLProcAddress("glGetAttribLocation"); if (!BindGLProc(_glGetAttribLocation, "glGetAttribLocation")) return false;
_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)GetOGLProcAddress("glEnableVertexAttribArray"); if (!BindGLProc(_glEnableVertexAttribArray, "glEnableVertexAttribArray")) return false;
_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)GetOGLProcAddress("glDisableVertexAttribArray"); if (!BindGLProc(_glDisableVertexAttribArray, "glDisableVertexAttribArray")) return false;
_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERARBPROC)GetOGLProcAddress("glVertexAttribPointer"); if (!BindGLProc(_glVertexAttribPointer, "glVertexAttribPointer")) return false;
} else { } else {
/* In the ARB extension programs and shaders are in the same object space. */ /* In the ARB extension programs and shaders are in the same object space. */
_glCreateProgram = (PFNGLCREATEPROGRAMPROC)GetOGLProcAddress("glCreateProgramObjectARB"); if (!BindGLProc(_glCreateProgram, "glCreateProgramObjectARB")) return false;
_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)GetOGLProcAddress("glDeleteObjectARB"); if (!BindGLProc(_glDeleteProgram, "glDeleteObjectARB")) return false;
_glLinkProgram = (PFNGLLINKPROGRAMPROC)GetOGLProcAddress("glLinkProgramARB"); if (!BindGLProc(_glLinkProgram, "glLinkProgramARB")) return false;
_glUseProgram = (PFNGLUSEPROGRAMPROC)GetOGLProcAddress("glUseProgramObjectARB"); if (!BindGLProc(_glUseProgram, "glUseProgramObjectARB")) return false;
_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)GetOGLProcAddress("glGetObjectParameterivARB"); if (!BindGLProc(_glGetProgramiv, "glGetObjectParameterivARB")) return false;
_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)GetOGLProcAddress("glGetInfoLogARB"); if (!BindGLProc(_glGetProgramInfoLog, "glGetInfoLogARB")) return false;
_glCreateShader = (PFNGLCREATESHADERPROC)GetOGLProcAddress("glCreateShaderObjectARB"); if (!BindGLProc(_glCreateShader, "glCreateShaderObjectARB")) return false;
_glDeleteShader = (PFNGLDELETESHADERPROC)GetOGLProcAddress("glDeleteObjectARB"); if (!BindGLProc(_glDeleteShader, "glDeleteObjectARB")) return false;
_glShaderSource = (PFNGLSHADERSOURCEPROC)GetOGLProcAddress("glShaderSourceARB"); if (!BindGLProc(_glShaderSource, "glShaderSourceARB")) return false;
_glCompileShader = (PFNGLCOMPILESHADERPROC)GetOGLProcAddress("glCompileShaderARB"); if (!BindGLProc(_glCompileShader, "glCompileShaderARB")) return false;
_glAttachShader = (PFNGLATTACHSHADERPROC)GetOGLProcAddress("glAttachObjectARB"); if (!BindGLProc(_glAttachShader, "glAttachObjectARB")) return false;
_glGetShaderiv = (PFNGLGETSHADERIVPROC)GetOGLProcAddress("glGetObjectParameterivARB"); if (!BindGLProc(_glGetShaderiv, "glGetObjectParameterivARB")) return false;
_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)GetOGLProcAddress("glGetInfoLogARB"); if (!BindGLProc(_glGetShaderInfoLog, "glGetInfoLogARB")) return false;
_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)GetOGLProcAddress("glGetUniformLocationARB"); if (!BindGLProc(_glGetUniformLocation, "glGetUniformLocationARB")) return false;
_glUniform1i = (PFNGLUNIFORM1IPROC)GetOGLProcAddress("glUniform1iARB"); if (!BindGLProc(_glUniform1i, "glUniform1iARB")) return false;
_glUniform1f = (PFNGLUNIFORM1FPROC)GetOGLProcAddress("glUniform1fARB"); if (!BindGLProc(_glUniform1f, "glUniform1fARB")) return false;
_glUniform2f = (PFNGLUNIFORM2FPROC)GetOGLProcAddress("glUniform2fARB"); if (!BindGLProc(_glUniform2f, "glUniform2fARB")) return false;
_glUniform4f = (PFNGLUNIFORM4FPROC)GetOGLProcAddress("glUniform4fARB"); if (!BindGLProc(_glUniform4f, "glUniform4fARB")) return false;
_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)GetOGLProcAddress("glGetAttribLocationARB"); if (!BindGLProc(_glGetAttribLocation, "glGetAttribLocationARB")) return false;
_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)GetOGLProcAddress("glEnableVertexAttribArrayARB"); if (!BindGLProc(_glEnableVertexAttribArray, "glEnableVertexAttribArrayARB")) return false;
_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)GetOGLProcAddress("glDisableVertexAttribArrayARB"); if (!BindGLProc(_glDisableVertexAttribArray, "glDisableVertexAttribArrayARB")) return false;
_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERARBPROC)GetOGLProcAddress("glVertexAttribPointerARB"); if (!BindGLProc(_glVertexAttribPointer, "glVertexAttribPointerARB")) return false;
} }
/* Bind functions only needed when using GLSL 1.50 shaders. */ /* Bind functions only needed when using GLSL 1.50 shaders. */
if (IsOpenGLVersionAtLeast(3, 0)) { if (IsOpenGLVersionAtLeast(3, 0)) {
_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)GetOGLProcAddress("glBindFragDataLocation"); BindGLProc(_glBindFragDataLocation, "glBindFragDataLocation");
} else if (IsOpenGLExtensionSupported("GL_EXT_gpu_shader4")) { } else if (IsOpenGLExtensionSupported("GL_EXT_gpu_shader4")) {
_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)GetOGLProcAddress("glBindFragDataLocationEXT"); BindGLProc(_glBindFragDataLocation, "glBindFragDataLocationEXT");
} else { } else {
_glBindFragDataLocation = nullptr; _glBindFragDataLocation = nullptr;
} }
return _glCreateProgram != nullptr && _glDeleteProgram != nullptr && _glLinkProgram != nullptr && _glGetProgramiv != nullptr && _glGetProgramInfoLog != nullptr && return true;
_glCreateShader != nullptr && _glDeleteShader != nullptr && _glShaderSource != nullptr && _glCompileShader != nullptr && _glAttachShader != nullptr &&
_glGetShaderiv != nullptr && _glGetShaderInfoLog != nullptr && _glGetUniformLocation != nullptr && _glUniform1i != nullptr && _glUniform1f != nullptr &&
_glUniform2f != nullptr && _glUniform4f != nullptr && _glGetAttribLocation != nullptr && _glEnableVertexAttribArray != nullptr && _glDisableVertexAttribArray != nullptr &&
_glVertexAttribPointer != nullptr;
} }
/** Bind extension functions for persistent buffer mapping. */ /** Bind extension functions for persistent buffer mapping. */
@ -319,24 +337,20 @@ static bool BindPersistentBufferExtensions()
{ {
/* Optional functions for persistent buffer mapping. */ /* Optional functions for persistent buffer mapping. */
if (IsOpenGLVersionAtLeast(3, 0)) { if (IsOpenGLVersionAtLeast(3, 0)) {
_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)GetOGLProcAddress("glMapBufferRange"); if (!BindGLProc(_glMapBufferRange, "glMapBufferRange")) return false;
} }
if (IsOpenGLVersionAtLeast(4, 4) || IsOpenGLExtensionSupported("GL_ARB_buffer_storage")) { if (IsOpenGLVersionAtLeast(4, 4) || IsOpenGLExtensionSupported("GL_ARB_buffer_storage")) {
_glBufferStorage = (PFNGLBUFFERSTORAGEPROC)GetOGLProcAddress("glBufferStorage"); if (!BindGLProc(_glBufferStorage, "glBufferStorage")) return false;
} }
#ifndef NO_GL_BUFFER_SYNC #ifndef NO_GL_BUFFER_SYNC
if (IsOpenGLVersionAtLeast(3, 2) || IsOpenGLExtensionSupported("GL_ARB_sync")) { if (IsOpenGLVersionAtLeast(3, 2) || IsOpenGLExtensionSupported("GL_ARB_sync")) {
_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)GetOGLProcAddress("glClientWaitSync"); if (!BindGLProc(_glClientWaitSync, "glClientWaitSync")) return false;
_glFenceSync = (PFNGLFENCESYNCPROC)GetOGLProcAddress("glFenceSync"); if (!BindGLProc(_glFenceSync, "glFenceSync")) return false;
_glDeleteSync = (PFNGLDELETESYNCPROC)GetOGLProcAddress("glDeleteSync"); if (!BindGLProc(_glDeleteSync, "glDeleteSync")) return false;
} }
#endif #endif
return _glMapBufferRange != nullptr && _glBufferStorage != nullptr return true;
#ifndef NO_GL_BUFFER_SYNC
&& _glClientWaitSync != nullptr && _glFenceSync != nullptr && _glDeleteSync != nullptr
#endif
;
} }
/** Callback to receive OpenGL debug messages. */ /** Callback to receive OpenGL debug messages. */
@ -370,11 +384,11 @@ void SetupDebugOutput()
if (_debug_driver_level < 6) return; if (_debug_driver_level < 6) return;
if (IsOpenGLVersionAtLeast(4, 3)) { if (IsOpenGLVersionAtLeast(4, 3)) {
_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)GetOGLProcAddress("glDebugMessageControl"); BindGLProc(_glDebugMessageControl, "glDebugMessageControl");
_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)GetOGLProcAddress("glDebugMessageCallback"); BindGLProc(_glDebugMessageCallback, "glDebugMessageCallback");
} else if (IsOpenGLExtensionSupported("GL_ARB_debug_output")) { } else if (IsOpenGLExtensionSupported("GL_ARB_debug_output")) {
_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)GetOGLProcAddress("glDebugMessageControlARB"); BindGLProc(_glDebugMessageControl, "glDebugMessageControlARB");
_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)GetOGLProcAddress("glDebugMessageCallbackARB"); BindGLProc(_glDebugMessageCallback, "glDebugMessageCallbackARB");
} }
if (_glDebugMessageControl != nullptr && _glDebugMessageCallback != nullptr) { if (_glDebugMessageControl != nullptr && _glDebugMessageCallback != nullptr) {
@ -1376,4 +1390,3 @@ bool OpenGLSprite::BindTextures()
return this->tex[TEX_RGBA] != 0; return this->tex[TEX_RGBA] != 0;
} }