Super 'by the book' wgl setup

This commit is contained in:
Allen Webster 2017-11-10 16:13:02 -05:00
parent 7ffa493d44
commit e43390a6c0
9 changed files with 201 additions and 206 deletions

View File

@ -55,6 +55,7 @@ typedef double f64;
#define STR__(s) #s #define STR__(s) #s
#define STR_(s) STR__(s) #define STR_(s) STR__(s)
#define LINE_STR STR_(__LINE__) #define LINE_STR STR_(__LINE__)
#define FNLN __FILE__ ":" LINE_STR ":"
#if defined(Assert) #if defined(Assert)
# undef Assert # undef Assert

View File

@ -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 internal void
interpret_render_buffer(System_Functions *system, Render_Target *t){ 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 = t->push_buffer;
char *cursor_end = cursor + t->size; char *cursor_end = cursor + t->size;

View File

@ -479,31 +479,13 @@ LinuxResizeTarget(i32 width, i32 height){
static bool ctxErrorOccurred = false; static bool ctxErrorOccurred = false;
internal int internal int
ctxErrorHandler( Display *dpy, XErrorEvent *ev ) ctxErrorHandler( Display *dpy, XErrorEvent *ev ){
{
ctxErrorOccurred = true; ctxErrorOccurred = true;
return 0; 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 internal GLXContext
InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, b32 &IsLegacy) InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc, b32 &IsLegacy){
{
IsLegacy = false; IsLegacy = false;
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
@ -589,8 +571,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
} }
b32 Direct; b32 Direct;
if (!glXIsDirect(XDisplay, ctx)) if (!glXIsDirect(XDisplay, ctx)){
{
LOG("Indirect GLX rendering context obtained\n"); LOG("Indirect GLX rendering context obtained\n");
Direct = false; Direct = false;
} }
@ -602,28 +583,20 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
LOG("Making context current\n"); LOG("Making context current\n");
glXMakeCurrent( XDisplay, XWindow, ctx ); 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 //TODO(inso): glGetStringi is required in core profile if the GL version is >= 3.0
char *Extensions = (char *)glGetString(GL_EXTENSIONS); //char *Extensions = (char *)glGetString(GL_EXTENSIONS);
LOGF("GL_VENDOR: %s\n", Vendor);
LOGF("GL_RENDERER: %s\n", Renderer);
LOGF("GL_VERSION: %s\n", Version);
//NOTE(inso): enable vsync if available. this should probably be optional //NOTE(inso): enable vsync if available. this should probably be optional
if (Direct && strstr(glxExts, "GLX_EXT_swap_control ")){ if (Direct && strstr(glxExts, "GLX_EXT_swap_control ")){
GLXLOAD(glXSwapIntervalEXT); GLXLOAD(glXSwapIntervalEXT);
if (glXSwapIntervalEXT){ if (glXSwapIntervalEXT != 0){
glXSwapIntervalEXT(XDisplay, XWindow, 1); glXSwapIntervalEXT(XDisplay, XWindow, 1);
unsigned int swap_val = 0; unsigned int swap_val = 0;
glXQueryDrawable(XDisplay, XWindow, GLX_SWAP_INTERVAL_EXT, &swap_val); 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"); LOGF("VSync enabled? %s.\n", linuxvars.vsync ? "Yes" : "No");
} }
@ -633,29 +606,29 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
GLXLOAD(glXSwapIntervalMESA); GLXLOAD(glXSwapIntervalMESA);
GLXLOAD(glXGetSwapIntervalMESA); GLXLOAD(glXGetSwapIntervalMESA);
if (glXSwapIntervalMESA){ if (glXSwapIntervalMESA != 0){
glXSwapIntervalMESA(1); glXSwapIntervalMESA(1);
if (glXGetSwapIntervalMESA){ if (glXGetSwapIntervalMESA != 0){
linuxvars.vsync = glXGetSwapIntervalMESA(); linuxvars.vsync = glXGetSwapIntervalMESA();
LOGF("VSync enabled? %s (MESA)\n", linuxvars.vsync ? "Yes" : "No"); LOGF("VSync enabled? %s (MESA)\n", linuxvars.vsync ? "Yes" : "No");
} else { }
else{
// NOTE(inso): assume it worked? // NOTE(inso): assume it worked?
linuxvars.vsync = 1; linuxvars.vsync = true;
LOG("VSync enabled? possibly (MESA)\n"); LOG("VSync enabled? possibly (MESA)\n");
} }
} }
} }
else if (Direct && strstr(glxExts, "GLX_SGI_swap_control ")){ else if (Direct && strstr(glxExts, "GLX_SGI_swap_control ")){
GLXLOAD(glXSwapIntervalSGI); GLXLOAD(glXSwapIntervalSGI);
if (glXSwapIntervalSGI){ if (glXSwapIntervalSGI){
glXSwapIntervalSGI(1); glXSwapIntervalSGI(1);
// NOTE(inso): The SGI one doesn't seem to have a way to confirm we got it... // 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"); 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"); 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); return(ctx);
} }

View File

@ -12,7 +12,7 @@
// HACK(allen): // NOTE(inso): this was a quick hack, might need some cleanup. // HACK(allen): // NOTE(inso): this was a quick hack, might need some cleanup.
internal void internal void
system_error_box(char *msg){ system_error_box(char *msg, b32 shutdown = true){
LOGF("Fatal Error: %s\n", msg); LOGF("Fatal Error: %s\n", msg);
Display *dpy = XOpenDisplay(0); Display *dpy = XOpenDisplay(0);
@ -180,7 +180,9 @@ system_error_box(char *msg){
} }
#undef DRAW_STR #undef DRAW_STR
exit(1); if (shutdown){
exit(1);
}
} }
// BOTTOM // BOTTOM

View File

@ -213,13 +213,9 @@ static i32 did_update_for_clipboard = true;
[self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy,
//NSOpenGLProfileVersion3_2Core, NSOpenGLPFAColorSize, 24,
NSOpenGLProfileVersionLegacy, NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAColorSize,
24,
NSOpenGLPFAAlphaSize,
8,
NSOpenGLPFAAccelerated, NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer, NSOpenGLPFADoubleBuffer,
0 0

View File

@ -10,9 +10,11 @@
// TOP // TOP
internal void internal void
system_error_box(char *msg){ system_error_box(char *msg, b32 shutdown = true){
osx_error_dialogue(msg); osx2_error_dialogue(msg);
exit(1); if (shutdown){
exit(1);
}
} }
// BOTTOM // BOTTOM

View File

@ -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 internal HANDLE
handle_type(Plat_Handle h){ handle_type(Plat_Handle h){
HANDLE result; HANDLE result;
@ -530,138 +544,135 @@ Win32Resize(i32 width, i32 height){
} }
} }
internal void* #define GLFuncGood(f) (((f)!=0)&&((f)!=(void*)1)&&((f)!=(void*)2)&&((f)!=(void*)3)&&((f)!=(void*)-11))
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);
}
internal void CALL_CONVENTION typedef HGLRC CALL_CONVENTION (wglCreateContextAttribsARB_Function)(HDC,HGLRC,i32*);
OpenGLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam){ typedef BOOL CALL_CONVENTION (wglChoosePixelFormatARB_Function)(HDC,i32*,f32*,u32,i32*,u32*);
OutputDebugStringA(message); typedef char* CALL_CONVENTION (wglGetExtensionsStringEXT_Function)();
OutputDebugStringA("\n"); 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 internal void
Win32InitGL(){ win32_init_gl(HDC hdc){
// GL context initialization LOG("trying to load wgl extensions...\n");
PIXELFORMATDESCRIPTOR format;
#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.nSize = sizeof(format);
format.nVersion = 1; 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.iPixelType = PFD_TYPE_RGBA;
format.cColorBits = 32; format.cColorBits = 32;
format.cRedBits = 0; format.cAlphaBits = 8;
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.cDepthBits = 24; format.cDepthBits = 24;
format.cStencilBits = 8;
format.cAuxBuffers = 0;
format.iLayerType = PFD_MAIN_PLANE; format.iLayerType = PFD_MAIN_PLANE;
format.bReserved = 0; i32 suggested_format_index = ChoosePixelFormat(hwgldc, &format);
format.dwLayerMask = 0; if (suggested_format_index == 0){
format.dwVisibleMask = 0; win32_output_error_string();
format.dwDamageMask = 0; GLInitFail("ChoosePixelFormat");
}
HDC dc = GetDC(win32vars.window_handle); DescribePixelFormat(hwgldc, suggested_format_index, sizeof(format), &format);
Assert(dc); if (!SetPixelFormat(hwgldc, suggested_format_index, &format)){
int format_id = ChoosePixelFormat(dc, &format); win32_output_error_string();
Assert(format_id != 0); GLInitFail("SetPixelFormat");
BOOL success = SetPixelFormat(dc, format_id, &format); }
Assert(success == TRUE); AllowLocal(success);
HGLRC glcontext = wglCreateContext(dc); HGLRC wglcontext = wglCreateContext(hwgldc);
wglMakeCurrent(dc, glcontext); if (wglcontext == 0){
win32_output_error_string();
GLInitFail("wglCreateContext");
}
HMODULE module = LoadLibraryA("opengl32.dll"); if (!wglMakeCurrent(hwgldc, wglcontext)){
AllowLocal(module); win32_output_error_string();
GLInitFail("wglMakeCurrent");
}
wglCreateContextAttribsARB_Function *wglCreateContextAttribsARB = 0; // Load wgl Extensions
wglCreateContextAttribsARB = (wglCreateContextAttribsARB_Function*) #define LoadWGL(f, s) f = (f##_Function*)wglGetProcAddress(#f); b32 got_##f = GLFuncGood(f); \
win32_load_gl_always("wglCreateContextAttribsARB", module); if (!got_##f) { if (s) { GLInitFail(#f " missing"); } else { f = 0; } }
LoadWGL(wglCreateContextAttribsARB, true);
LoadWGL(wglChoosePixelFormatARB, true);
LoadWGL(wglGetExtensionsStringEXT, true);
wglChoosePixelFormatARB_Function *wglChoosePixelFormatARB = 0; LOG("got wgl functions\n");
wglChoosePixelFormatARB = (wglChoosePixelFormatARB_Function*)
win32_load_gl_always("wglChoosePixelFormatARB", module);
if (wglCreateContextAttribsARB != 0 && wglChoosePixelFormatARB != 0){ char *extensions_c = wglGetExtensionsStringEXT();
const int choosePixel_attribList[] = String extensions = make_string_slowly(extensions_c);
{ if (has_substr(extensions, make_lit_string("WGL_EXT_swap_interval"))){
WGL_DRAW_TO_WINDOW_ARB, TRUE, LoadWGL(wglSwapIntervalEXT, false);
WGL_SUPPORT_OPENGL_ARB, TRUE, if (wglSwapIntervalEXT != 0){
WGL_DOUBLE_BUFFER_ARB, GL_TRUE, LOG("got wglSwapIntervalEXT\n");
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;
}
}
} }
} }
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) u32 ignore = 0;
#if defined(FRED_INTERNAL) if (!wglChoosePixelFormatARB(hdc, pixel_attrib_list, 0, 1, &suggested_format_index, &ignore)){
// NOTE(casey): This slows down GL but puts error messages to GLInitFail("wglChoosePixelFormatARB");
// 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);
} }
#endif
#endif
glEnable(GL_TEXTURE_2D); DescribePixelFormat(hdc, suggested_format_index, sizeof(format), &format);
glEnable(GL_SCISSOR_TEST); if (!SetPixelFormat(hdc, suggested_format_index, &format)){
glEnable(GL_BLEND); GLInitFail("SetPixelFormat");
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); }
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 internal void
@ -1080,10 +1091,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
win32vars.dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); win32vars.dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
GetClientRect(win32vars.window_handle, &window_rect); GetClientRect(win32vars.window_handle, &window_rect);
win32_init_gl(hdc);
ReleaseDC(win32vars.window_handle, hdc); ReleaseDC(win32vars.window_handle, hdc);
} }
Win32InitGL();
Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top);
// //

View File

@ -3,17 +3,19 @@
* *
* 18.07.2017 * 18.07.2017
* *
* Linux fatal error message box. * Windows fatal error message box.
* *
*/ */
// TOP // TOP
internal void internal void
system_error_box(char *msg){ system_error_box(char *msg, b32 shutdown = true){
LOGF("Fatal Error: %s\n", msg); LOGF("error box: %s\n", msg);
MessageBox_utf8(0, (u8*)msg, (u8*)"Error",0); MessageBox_utf8(0, (u8*)msg, (u8*)"Error", 0);
exit(1); if (shutdown){
exit(1);
}
} }
// BOTTOM // BOTTOM

View File

@ -70,26 +70,7 @@
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #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. // 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_SYNCHRONOUS 0x8242
#define GL_DEBUG_OUTPUT 0x92E0 #define GL_DEBUG_OUTPUT 0x92E0