diff --git a/4ed_defines.h b/4ed_defines.h index 4f53a32b..61c133d4 100644 --- a/4ed_defines.h +++ b/4ed_defines.h @@ -55,6 +55,7 @@ typedef double f64; #define STR__(s) #s #define STR_(s) STR__(s) #define LINE_STR STR_(__LINE__) +#define FNLN __FILE__ ":" LINE_STR ":" #if defined(Assert) # undef Assert diff --git a/4ed_render_opengl.cpp b/4ed_render_opengl.cpp index fd04b047..45b26b9d 100644 --- a/4ed_render_opengl.cpp +++ b/4ed_render_opengl.cpp @@ -106,8 +106,52 @@ private_draw_glyph(System_Functions *system, Render_Target *t, Render_Font *font } } +internal void CALL_CONVENTION +opengl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam){ + // TODO(allen): Fill this in with my preferred thingy. +} + internal void interpret_render_buffer(System_Functions *system, Render_Target *t){ + local_persist b32 first_opengl_call = true; + if (first_opengl_call){ + first_opengl_call = false; + + // TODO(allen): Get logging working everywhere +#if 0 + //TODO(inso): glGetStringi is required in core profile if the GL version is >= 3.0 + char *Vendor = (char *)glGetString(GL_VENDOR); + char *Renderer = (char *)glGetString(GL_RENDERER); + char *Version = (char *)glGetString(GL_VERSION); + + LOGF("GL_VENDOR: %s\n", Vendor); + LOGF("GL_RENDERER: %s\n", Renderer); + LOGF("GL_VERSION: %s\n", Version); +#endif + + // TODO(allen): Get this up and running again. +#if (defined(BUILD_X64) && 0) || (defined(BUILD_X86) && 0) + // NOTE(casey): This slows down GL but puts error messages to + // the debug console immediately whenever you do something wrong + glDebugMessageCallback_type *glDebugMessageCallback = + (glDebugMessageCallback_type *)win32_load_gl_always("glDebugMessageCallback", module); + glDebugMessageControl_type *glDebugMessageControl = + (glDebugMessageControl_type *)win32_load_gl_always("glDebugMessageControl", module); + if(glDebugMessageCallback != 0 && glDebugMessageControl != 0) + { + glDebugMessageCallback(opengl_debug_callback, 0); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + } +#endif + + glEnable(GL_TEXTURE_2D); + glEnable(GL_SCISSOR_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + char *cursor = t->push_buffer; char *cursor_end = cursor + t->size; diff --git a/platform_linux/linux_4ed.cpp b/platform_linux/linux_4ed.cpp index daaa75d3..6ea353c6 100644 --- a/platform_linux/linux_4ed.cpp +++ b/platform_linux/linux_4ed.cpp @@ -479,31 +479,13 @@ LinuxResizeTarget(i32 width, i32 height){ static bool ctxErrorOccurred = false; internal int -ctxErrorHandler( Display *dpy, XErrorEvent *ev ) -{ +ctxErrorHandler( Display *dpy, XErrorEvent *ev ){ ctxErrorOccurred = true; return 0; } -#if defined(FRED_INTERNAL) - -static void LinuxGLDebugCallback( -GLenum source, -GLenum type, -GLuint id, -GLenum severity, -GLsizei length, -const GLchar* message, -const void* userParam -){ - LOGF("GL DEBUG: %s\n", message); -} - -#endif - internal GLXContext -InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, b32 &IsLegacy) -{ +InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, b32 &IsLegacy){ IsLegacy = false; typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); @@ -589,8 +571,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, } b32 Direct; - if (!glXIsDirect(XDisplay, ctx)) - { + if (!glXIsDirect(XDisplay, ctx)){ LOG("Indirect GLX rendering context obtained\n"); Direct = false; } @@ -602,28 +583,20 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, LOG("Making context current\n"); glXMakeCurrent( XDisplay, XWindow, ctx ); - char *Vendor = (char *)glGetString(GL_VENDOR); - char *Renderer = (char *)glGetString(GL_RENDERER); - char *Version = (char *)glGetString(GL_VERSION); - //TODO(inso): glGetStringi is required in core profile if the GL version is >= 3.0 - char *Extensions = (char *)glGetString(GL_EXTENSIONS); - - LOGF("GL_VENDOR: %s\n", Vendor); - LOGF("GL_RENDERER: %s\n", Renderer); - LOGF("GL_VERSION: %s\n", Version); + //char *Extensions = (char *)glGetString(GL_EXTENSIONS); //NOTE(inso): enable vsync if available. this should probably be optional if (Direct && strstr(glxExts, "GLX_EXT_swap_control ")){ GLXLOAD(glXSwapIntervalEXT); - if (glXSwapIntervalEXT){ + if (glXSwapIntervalEXT != 0){ glXSwapIntervalEXT(XDisplay, XWindow, 1); unsigned int swap_val = 0; glXQueryDrawable(XDisplay, XWindow, GLX_SWAP_INTERVAL_EXT, &swap_val); - linuxvars.vsync = swap_val == 1; + linuxvars.vsync = (swap_val == true); LOGF("VSync enabled? %s.\n", linuxvars.vsync ? "Yes" : "No"); } @@ -633,29 +606,29 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, GLXLOAD(glXSwapIntervalMESA); GLXLOAD(glXGetSwapIntervalMESA); - if (glXSwapIntervalMESA){ + if (glXSwapIntervalMESA != 0){ glXSwapIntervalMESA(1); - if (glXGetSwapIntervalMESA){ + if (glXGetSwapIntervalMESA != 0){ linuxvars.vsync = glXGetSwapIntervalMESA(); LOGF("VSync enabled? %s (MESA)\n", linuxvars.vsync ? "Yes" : "No"); - } else { + } + else{ // NOTE(inso): assume it worked? - linuxvars.vsync = 1; + linuxvars.vsync = true; LOG("VSync enabled? possibly (MESA)\n"); } } } else if (Direct && strstr(glxExts, "GLX_SGI_swap_control ")){ - GLXLOAD(glXSwapIntervalSGI); if (glXSwapIntervalSGI){ glXSwapIntervalSGI(1); // NOTE(inso): The SGI one doesn't seem to have a way to confirm we got it... - linuxvars.vsync = 1; + linuxvars.vsync = true; LOG("VSync enabled? hopefully (SGI)\n"); } @@ -664,25 +637,6 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, LOG("VSync enabled? nope, no suitable extension\n"); } -#if defined(FRED_INTERNAL) - typedef PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackProc; - - GLXLOAD(glDebugMessageCallback); - - if (glDebugMessageCallback){ - LOG("Enabling GL Debug Callback\n"); - glDebugMessageCallback(&LinuxGLDebugCallback, 0); - glEnable(GL_DEBUG_OUTPUT); - } -#endif - - glEnable(GL_TEXTURE_2D); - glEnable(GL_SCISSOR_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - -#undef GLXLOAD - return(ctx); } diff --git a/platform_linux/linux_error_box.cpp b/platform_linux/linux_error_box.cpp index 3bedfa8e..99d8afa6 100644 --- a/platform_linux/linux_error_box.cpp +++ b/platform_linux/linux_error_box.cpp @@ -12,7 +12,7 @@ // HACK(allen): // NOTE(inso): this was a quick hack, might need some cleanup. internal void -system_error_box(char *msg){ +system_error_box(char *msg, b32 shutdown = true){ LOGF("Fatal Error: %s\n", msg); Display *dpy = XOpenDisplay(0); @@ -180,7 +180,9 @@ system_error_box(char *msg){ } #undef DRAW_STR - exit(1); + if (shutdown){ + exit(1); + } } // BOTTOM diff --git a/platform_mac/mac_4ed.m b/platform_mac/mac_4ed.m index c7d0e684..d4afa75f 100644 --- a/platform_mac/mac_4ed.m +++ b/platform_mac/mac_4ed.m @@ -213,13 +213,9 @@ static i32 did_update_for_clipboard = true; [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; NSOpenGLPixelFormatAttribute attrs[] = { - NSOpenGLPFAOpenGLProfile, - //NSOpenGLProfileVersion3_2Core, - NSOpenGLProfileVersionLegacy, - NSOpenGLPFAColorSize, - 24, - NSOpenGLPFAAlphaSize, - 8, + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy, + NSOpenGLPFAColorSize, 24, + NSOpenGLPFAAlphaSize, 8, NSOpenGLPFAAccelerated, NSOpenGLPFADoubleBuffer, 0 diff --git a/platform_mac/mac_error_box.cpp b/platform_mac/mac_error_box.cpp index 88793746..a1e53910 100644 --- a/platform_mac/mac_error_box.cpp +++ b/platform_mac/mac_error_box.cpp @@ -10,9 +10,11 @@ // TOP internal void -system_error_box(char *msg){ - osx_error_dialogue(msg); - exit(1); +system_error_box(char *msg, b32 shutdown = true){ + osx2_error_dialogue(msg); + if (shutdown){ + exit(1); + } } // BOTTOM diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index cf2a0da0..e898e193 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -172,6 +172,20 @@ global Coroutine_System_Auto_Alloc coroutines; //////////////////////////////// +internal void +win32_output_error_string(){ + DWORD error = GetLastError(); + + char *str = 0; + char *str_ptr = (char*)&str; + if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, error, 0, str_ptr, 0, 0)){ + LOGF("win32 error:\n%s\n", str); + system_error_box(str, false); + } +} + +//////////////////////////////// + internal HANDLE handle_type(Plat_Handle h){ HANDLE result; @@ -530,138 +544,135 @@ Win32Resize(i32 width, i32 height){ } } -internal void* -win32_load_gl_always(char *name, HMODULE module){ - void *p = (void *)wglGetProcAddress(name), *r = 0; - if(p == 0 || - (p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) || - (p == (void*)-1) ){ - r = (void *)GetProcAddress(module, name); - } - else{ - r = p; - } - return(r); -} +#define GLFuncGood(f) (((f)!=0)&&((f)!=(void*)1)&&((f)!=(void*)2)&&((f)!=(void*)3)&&((f)!=(void*)-11)) -internal void CALL_CONVENTION -OpenGLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam){ - OutputDebugStringA(message); - OutputDebugStringA("\n"); -} +typedef HGLRC CALL_CONVENTION (wglCreateContextAttribsARB_Function)(HDC,HGLRC,i32*); +typedef BOOL CALL_CONVENTION (wglChoosePixelFormatARB_Function)(HDC,i32*,f32*,u32,i32*,u32*); +typedef char* CALL_CONVENTION (wglGetExtensionsStringEXT_Function)(); +typedef VOID CALL_CONVENTION (wglSwapIntervalEXT_Function)(i32); + +global wglCreateContextAttribsARB_Function *wglCreateContextAttribsARB = 0; +global wglChoosePixelFormatARB_Function *wglChoosePixelFormatARB = 0; +global wglGetExtensionsStringEXT_Function *wglGetExtensionsStringEXT = 0; +global wglSwapIntervalEXT_Function *wglSwapIntervalEXT = 0; internal void -Win32InitGL(){ - // GL context initialization - PIXELFORMATDESCRIPTOR format; +win32_init_gl(HDC hdc){ + LOG("trying to load wgl extensions...\n"); + +#define GLInitFail(s) system_error_box(FNLN "\nOpenGL init fail - " s ) + + // Init First Context + WNDCLASSA wglclass = {0}; + wglclass.lpfnWndProc = DefWindowProcA; + wglclass.hInstance = GetModuleHandle(0); + wglclass.lpszClassName = "4ed-wgl-loader"; + if (RegisterClassA(&wglclass) == 0){ + GLInitFail("RegisterClassA"); + } + + HWND hwglwnd = CreateWindowExA(0, wglclass.lpszClassName, "", 0, 0, 0, 0, 0, 0, 0, wglclass.hInstance, 0); + if (hwglwnd == 0){ + GLInitFail("CreateWindowExA"); + } + + HDC hwgldc = GetDC(hwglwnd); + + PIXELFORMATDESCRIPTOR format = {0}; format.nSize = sizeof(format); format.nVersion = 1; - format.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; + format.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; format.iPixelType = PFD_TYPE_RGBA; format.cColorBits = 32; - format.cRedBits = 0; - format.cRedShift = 0; - format.cGreenBits = 0; - format.cGreenShift = 0; - format.cBlueBits = 0; - format.cBlueShift = 0; - format.cAlphaBits = 0; - format.cAlphaShift = 0; - format.cAccumBits = 0; - format.cAccumRedBits = 0; - format.cAccumGreenBits = 0; - format.cAccumBlueBits = 0; - format.cAccumAlphaBits = 0; + format.cAlphaBits = 8; format.cDepthBits = 24; - format.cStencilBits = 8; - format.cAuxBuffers = 0; format.iLayerType = PFD_MAIN_PLANE; - format.bReserved = 0; - format.dwLayerMask = 0; - format.dwVisibleMask = 0; - format.dwDamageMask = 0; + i32 suggested_format_index = ChoosePixelFormat(hwgldc, &format); + if (suggested_format_index == 0){ + win32_output_error_string(); + GLInitFail("ChoosePixelFormat"); + } - HDC dc = GetDC(win32vars.window_handle); - Assert(dc); - int format_id = ChoosePixelFormat(dc, &format); - Assert(format_id != 0); - BOOL success = SetPixelFormat(dc, format_id, &format); - Assert(success == TRUE); AllowLocal(success); + DescribePixelFormat(hwgldc, suggested_format_index, sizeof(format), &format); + if (!SetPixelFormat(hwgldc, suggested_format_index, &format)){ + win32_output_error_string(); + GLInitFail("SetPixelFormat"); + } - HGLRC glcontext = wglCreateContext(dc); - wglMakeCurrent(dc, glcontext); + HGLRC wglcontext = wglCreateContext(hwgldc); + if (wglcontext == 0){ + win32_output_error_string(); + GLInitFail("wglCreateContext"); + } - HMODULE module = LoadLibraryA("opengl32.dll"); - AllowLocal(module); + if (!wglMakeCurrent(hwgldc, wglcontext)){ + win32_output_error_string(); + GLInitFail("wglMakeCurrent"); + } - wglCreateContextAttribsARB_Function *wglCreateContextAttribsARB = 0; - wglCreateContextAttribsARB = (wglCreateContextAttribsARB_Function*) - win32_load_gl_always("wglCreateContextAttribsARB", module); + // Load wgl Extensions +#define LoadWGL(f, s) f = (f##_Function*)wglGetProcAddress(#f); b32 got_##f = GLFuncGood(f); \ + if (!got_##f) { if (s) { GLInitFail(#f " missing"); } else { f = 0; } } + LoadWGL(wglCreateContextAttribsARB, true); + LoadWGL(wglChoosePixelFormatARB, true); + LoadWGL(wglGetExtensionsStringEXT, true); - wglChoosePixelFormatARB_Function *wglChoosePixelFormatARB = 0; - wglChoosePixelFormatARB = (wglChoosePixelFormatARB_Function*) - win32_load_gl_always("wglChoosePixelFormatARB", module); + LOG("got wgl functions\n"); - if (wglCreateContextAttribsARB != 0 && wglChoosePixelFormatARB != 0){ - const int choosePixel_attribList[] = - { - WGL_DRAW_TO_WINDOW_ARB, TRUE, - WGL_SUPPORT_OPENGL_ARB, TRUE, - WGL_DOUBLE_BUFFER_ARB, GL_TRUE, - WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, - WGL_COLOR_BITS_ARB, 32, - WGL_DEPTH_BITS_ARB, 24, - WGL_STENCIL_BITS_ARB, 8, - 0, - }; - - i32 extended_format_id = 0; - u32 num_formats = 0; - BOOL result = wglChoosePixelFormatARB(dc, choosePixel_attribList, 0, 1, &extended_format_id, &num_formats); - - if (result != 0 && num_formats > 0){ - const int createContext_attribList[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 3, - WGL_CONTEXT_MINOR_VERSION_ARB, 2, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - 0 - }; - - if (extended_format_id == format_id){ - HGLRC extended_context = wglCreateContextAttribsARB(dc, 0, createContext_attribList); - if (extended_context){ - wglMakeCurrent(dc, extended_context); - wglDeleteContext(glcontext); - glcontext = extended_context; - } - } + char *extensions_c = wglGetExtensionsStringEXT(); + String extensions = make_string_slowly(extensions_c); + if (has_substr(extensions, make_lit_string("WGL_EXT_swap_interval"))){ + LoadWGL(wglSwapIntervalEXT, false); + if (wglSwapIntervalEXT != 0){ + LOG("got wglSwapIntervalEXT\n"); } } - ReleaseDC(win32vars.window_handle, dc); + // Init the Second Context + int pixel_attrib_list[] = { + WGL_DRAW_TO_WINDOW_ARB, TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + WGL_SUPPORT_OPENGL_ARB, TRUE, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, + 0, + }; -#if (defined(BUILD_X64) && 1) || (defined(BUILD_X86) && 0) -#if defined(FRED_INTERNAL) - // NOTE(casey): This slows down GL but puts error messages to - // the debug console immediately whenever you do something wrong - glDebugMessageCallback_type *glDebugMessageCallback = - (glDebugMessageCallback_type *)win32_load_gl_always("glDebugMessageCallback", module); - glDebugMessageControl_type *glDebugMessageControl = - (glDebugMessageControl_type *)win32_load_gl_always("glDebugMessageControl", module); - if(glDebugMessageCallback != 0 && glDebugMessageControl != 0) - { - glDebugMessageCallback(OpenGLDebugCallback, 0); - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); - glEnable(GL_DEBUG_OUTPUT); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + u32 ignore = 0; + if (!wglChoosePixelFormatARB(hdc, pixel_attrib_list, 0, 1, &suggested_format_index, &ignore)){ + GLInitFail("wglChoosePixelFormatARB"); } -#endif -#endif - glEnable(GL_TEXTURE_2D); - glEnable(GL_SCISSOR_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + DescribePixelFormat(hdc, suggested_format_index, sizeof(format), &format); + if (!SetPixelFormat(hdc, suggested_format_index, &format)){ + GLInitFail("SetPixelFormat"); + } + + i32 context_attrib_list[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 2, + WGL_CONTEXT_MINOR_VERSION_ARB, 1, + WGL_CONTEXT_FLAGS_ARB, 0, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0 + }; + + HGLRC context = wglCreateContextAttribsARB(hdc, 0, context_attrib_list); + if (context == 0){ + GLInitFail("wglCreateContextAttribsARB"); + } + + wglMakeCurrent(hdc, context); + + if (wglSwapIntervalEXT != 0){ + LOGF("setting swap interval %d\n", 1); + wglSwapIntervalEXT(1); + } + + ReleaseDC(hwglwnd, hwgldc); + DestroyWindow(hwglwnd); + wglDeleteContext(wglcontext); + + LOG("successfully enabled opengl\n"); } internal void @@ -1080,10 +1091,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS win32vars.dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); GetClientRect(win32vars.window_handle, &window_rect); + + win32_init_gl(hdc); + ReleaseDC(win32vars.window_handle, hdc); } - Win32InitGL(); Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); // diff --git a/platform_win32/win32_error_box.cpp b/platform_win32/win32_error_box.cpp index b83fb252..15ba6aff 100644 --- a/platform_win32/win32_error_box.cpp +++ b/platform_win32/win32_error_box.cpp @@ -3,17 +3,19 @@ * * 18.07.2017 * - * Linux fatal error message box. + * Windows fatal error message box. * */ // TOP internal void -system_error_box(char *msg){ - LOGF("Fatal Error: %s\n", msg); - MessageBox_utf8(0, (u8*)msg, (u8*)"Error",0); - exit(1); +system_error_box(char *msg, b32 shutdown = true){ + LOGF("error box: %s\n", msg); + MessageBox_utf8(0, (u8*)msg, (u8*)"Error", 0); + if (shutdown){ + exit(1); + } } // BOTTOM diff --git a/platform_win32/win32_gl.h b/platform_win32/win32_gl.h index dcb3dfb1..ebdf5a69 100644 --- a/platform_win32/win32_gl.h +++ b/platform_win32/win32_gl.h @@ -70,26 +70,7 @@ #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -typedef BOOL CALL_CONVENTION -wglChoosePixelFormatARB_Function(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); - -typedef HGLRC CALL_CONVENTION -wglCreateContextAttribsARB_Function(HDC hDC, HGLRC hshareContext, const int *attribList); - -typedef const char* CALL_CONVENTION -wglGetExtensionsStringARB_Function(HDC hdc); - -typedef void CALL_CONVENTION -GLDEBUGPROC_TYPE(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char * message, const GLvoid * userParam); - // TODO(allen): these don't belong here, but the organizational stuff is not fully in place yet. -typedef GLDEBUGPROC_TYPE * GLDEBUGPROC; -typedef void CALL_CONVENTION -glDebugMessageControl_type(GLenum source, GLenum type, GLenum severity, GLsizei count, GLuint * ids, GLboolean enabled); - -typedef void CALL_CONVENTION -glDebugMessageCallback_type(GLDEBUGPROC callback, void * userParam); - #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 #define GL_DEBUG_OUTPUT 0x92E0