diff --git a/Windows/OpenGLBase.cpp b/Windows/OpenGLBase.cpp index 1ea7f835bb..3664e3eb1a 100644 --- a/Windows/OpenGLBase.cpp +++ b/Windows/OpenGLBase.cpp @@ -3,6 +3,9 @@ #include #include "../native/gfx_es2/gl_state.h" #include "../native/gfx/gl_common.h" +#include "GL/gl.h" +#include "GL/glext.h" +#include "GL/wglew.h" #include "OpenGLBase.h" @@ -13,22 +16,19 @@ static HINSTANCE hInstance; // Holds The Instance Of The Application static int xres, yres; -typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int ); -PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0; +// TODO: Make config? +static bool enableGLDebug = false; + + +//typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int ); +//static PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0; void setVSync(int interval=1) { const char *extensions = (const char *)glGetString( GL_EXTENSIONS ); - if( strstr( extensions, "WGL_EXT_swap_control" ) == 0 ) - return; // Error: WGL_EXT_swap_control extension not supported on your computer.\n"); - else - { - wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress( "wglSwapIntervalEXT" ); - - if( wglSwapIntervalEXT ) - wglSwapIntervalEXT(interval); - } + if( wglSwapIntervalEXT ) + wglSwapIntervalEXT(interval); } void GL_Resized() // Resize And Initialize The GL Window @@ -67,6 +67,59 @@ void GL_EndFrame() SwapBuffers(hDC); } +void FormatDebugOutputARB(char outStr[], size_t outStrSize, GLenum source, GLenum type, + GLuint id, GLenum severity, const char *msg) +{ + char sourceStr[32]; + const char *sourceFmt = "UNDEFINED(0x%04X)"; + switch(source) + { + case GL_DEBUG_SOURCE_API_ARB: sourceFmt = "API"; break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: sourceFmt = "WINDOW_SYSTEM"; break; + case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: sourceFmt = "SHADER_COMPILER"; break; + case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: sourceFmt = "THIRD_PARTY"; break; + case GL_DEBUG_SOURCE_APPLICATION_ARB: sourceFmt = "APPLICATION"; break; + case GL_DEBUG_SOURCE_OTHER_ARB: sourceFmt = "OTHER"; break; + } + _snprintf(sourceStr, 32, sourceFmt, source); + + char typeStr[32]; + const char *typeFmt = "UNDEFINED(0x%04X)"; + switch(type) + { + case GL_DEBUG_TYPE_ERROR_ARB: typeFmt = "ERROR"; break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: typeFmt = "DEPRECATED_BEHAVIOR"; break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: typeFmt = "UNDEFINED_BEHAVIOR"; break; + case GL_DEBUG_TYPE_PORTABILITY_ARB: typeFmt = "PORTABILITY"; break; + case GL_DEBUG_TYPE_PERFORMANCE_ARB: typeFmt = "PERFORMANCE"; break; + case GL_DEBUG_TYPE_OTHER_ARB: typeFmt = "OTHER"; break; + } + _snprintf(typeStr, 32, typeFmt, type); + + char severityStr[32]; + const char *severityFmt = "UNDEFINED"; + switch(severity) + { + case GL_DEBUG_SEVERITY_HIGH_ARB: severityFmt = "HIGH"; break; + case GL_DEBUG_SEVERITY_MEDIUM_ARB: severityFmt = "MEDIUM"; break; + case GL_DEBUG_SEVERITY_LOW_ARB: severityFmt = "LOW"; break; + } + + _snprintf(severityStr, 32, severityFmt, severity); + + _snprintf(outStr, outStrSize, "OpenGL: %s [source=%s type=%s severity=%s id=%d]", msg, sourceStr, typeStr, severityStr, id); +} + +void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar *message, GLvoid *userParam) +{ + (void)length; + FILE *outFile = (FILE*)userParam; + char finalMessage[256]; + FormatDebugOutputARB(finalMessage, 256, source, type, id, severity, message); + ERROR_LOG(HLE, "GL: %s", finalMessage); +} + bool GL_Init(HWND window) { hWnd = window; @@ -125,10 +178,49 @@ bool GL_Init(HWND window) MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); return false; } - setVSync(0); - glewInit(); + + // Alright, now for the modernity. + int attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 1, + WGL_CONTEXT_FLAGS_ARB, enableGLDebug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, + 0 + }; + + HGLRC m_hrc; + if(wglewIsSupported("WGL_ARB_create_context") == 1) + { + m_hrc = wglCreateContextAttribsARB(hDC,0, attribs); + wglMakeCurrent(NULL,NULL); + wglDeleteContext(hRC); + wglMakeCurrent(hDC, m_hrc); + } + else + { //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before) + m_hrc = hRC; + } + + //Checking GL version + const char *GLVersionString = (const char *)glGetString(GL_VERSION); + + //Or better yet, use the GL3 way to get the version number + int OpenGLVersion[2]; + glGetIntegerv(GL_MAJOR_VERSION, &OpenGLVersion[0]); + glGetIntegerv(GL_MINOR_VERSION, &OpenGLVersion[1]); + + if (!m_hrc) return false; + + hRC = m_hrc; + glstate.Initialize(); + setVSync(0); + if (enableGLDebug && glewIsSupported("GL_ARB_debug_output")) + { + glDebugMessageCallbackARB((GLDEBUGPROCARB)&DebugCallbackARB, 0); // print debug output to stderr + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + } GL_Resized(); // Set Up Our Perspective GL Screen