From 8cdf9099a2912ec41d88d2af5d3a1358ca0cc879 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 11 Jul 2012 01:17:40 +0000 Subject: [PATCH] Create a fake window to check for GL extensions. --- common/opengl.cpp | 25 ++++++------- common/opengl.h | 2 ++ win/glwindow.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 13 deletions(-) diff --git a/common/opengl.cpp b/common/opengl.cpp index fbae6484..4cb84fde 100755 --- a/common/opengl.cpp +++ b/common/opengl.cpp @@ -1075,6 +1075,8 @@ bool GL_Initialize(const char* LibraryName) pfnglPopName = (PFNGLPOPNAME)Sys_GLGetProc("glPopName"); #endif // LC_OPENGL_DYNAMIC + GL_InitializeExtensions(); + return true; } @@ -1084,31 +1086,28 @@ bool GL_Initialize(const char* LibraryName) bool GL_SupportsVertexBufferObject = false; bool GL_UseVertexBufferObject = false; -static bool GL_ExtensionSupported(const char* extension) +bool GL_ExtensionSupported(const GLubyte* Extensions, const char* Name) { - const GLubyte *extensions = NULL; const GLubyte *start; GLubyte *where, *terminator; // Extension names should not have spaces. - where = (GLubyte*) strchr(extension, ' '); - if (where || *extension == '\0') + where = (GLubyte*)strchr(Name, ' '); + if (where || *Name == '\0') return false; - extensions = glGetString(GL_EXTENSIONS); - - if (!extensions) + if (!Extensions) return false; // It takes a bit of care to be fool-proof about parsing the // OpenGL extensions string. Don't be fooled by sub-strings, etc. - for (start = extensions; ;) + for (start = Extensions; ;) { - where = (GLubyte*)strstr((const char*)start, extension); + where = (GLubyte*)strstr((const char*)start, Name); if (!where) break; - terminator = where + strlen(extension); + terminator = where + strlen(Name); if (where == start || *(where - 1) == ' ') if (*terminator == ' ' || *terminator == '\0') return true; @@ -1120,9 +1119,11 @@ static bool GL_ExtensionSupported(const char* extension) } // Extensions can only be initialized if there's a current OpenGL context. -void GL_InitializeExtensions() +void GL_InitializeSharedExtensions() { - if (GL_ExtensionSupported("GL_ARB_vertex_buffer_object")) + const GLubyte* Extensions = glGetString(GL_EXTENSIONS); + + if (GL_ExtensionSupported(Extensions, "GL_ARB_vertex_buffer_object")) { glBindBufferARB = (GLBINDBUFFERARBPROC)Sys_GLGetExtension("glBindBufferARB"); glDeleteBuffersARB = (GLDELETEBUFFERSARBPROC)Sys_GLGetExtension("glDeleteBuffersARB"); diff --git a/common/opengl.h b/common/opengl.h index 94049134..de76e987 100755 --- a/common/opengl.h +++ b/common/opengl.h @@ -20,6 +20,8 @@ bool GL_Initialize(const char* libname); void GL_Shutdown(); void GL_InitializeExtensions(); +void GL_InitializeSharedExtensions(); +bool GL_ExtensionSupported(const GLubyte* Extensions, const char* Name); extern bool GL_SupportsVertexBufferObject; extern bool GL_UseVertexBufferObject; diff --git a/win/glwindow.cpp b/win/glwindow.cpp index 66f53ffa..acfbab8c 100644 --- a/win/glwindow.cpp +++ b/win/glwindow.cpp @@ -4,6 +4,16 @@ #include "tools.h" #include "resource.h" +typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues); + +PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL; +PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL; +PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB = NULL; +PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = NULL; + struct GLWindowPrivate { HGLRC m_hrc; @@ -144,6 +154,86 @@ LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam return DefWindowProc(hwnd, uMsg, wParam, lParam); } +static LRESULT CALLBACK TempWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg != WM_CREATE) + return DefWindowProc(hWnd, uMsg, wParam, lParam); + + HDC hDC = GetDC(hWnd); + + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cDepthBits = 24; + pfd.iLayerType = PFD_MAIN_PLANE; + + int PixelFormat = ChoosePixelFormat(hDC, &pfd); + if (PixelFormat == 0) + return 0; + + if (!SetPixelFormat(hDC, PixelFormat, &pfd)) + return 0; + + HGLRC hGLRC = wglCreateContext(hDC); + wglMakeCurrent(hDC, hGLRC); + + const GLubyte* Extensions; + + wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + + if (wglGetExtensionsStringARB) + Extensions = (GLubyte*)wglGetExtensionsStringARB(wglGetCurrentDC()); + else + Extensions = glGetString(GL_EXTENSIONS); + + GL_InitializeSharedExtensions(); + + if (GL_ExtensionSupported(Extensions, "WGL_ARB_pixel_format")) + { + wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribfvARB"); + wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB"); + } + + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hGLRC); + + ReleaseDC(hWnd, hDC); + + return 0; +} + +void GL_InitializeExtensions() +{ + HINSTANCE hInstance; + WNDCLASS wc; + + hInstance = GetModuleHandle(NULL); + + wc.style = CS_OWNDC; + wc.lpfnWndProc = TempWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = "LeoCADGLTempWindow"; + + RegisterClass(&wc); + + HWND hWnd = CreateWindow(wc.lpszClassName, "LeoCAD Temp Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); + + if (hWnd) + DestroyWindow(hWnd); +} + // ============================================================================ // GLWindow class @@ -296,7 +386,6 @@ void GLWindow::DestroyContext() void GLWindow::OnInitialUpdate() { MakeCurrent(); - GL_InitializeExtensions(); } bool GLWindow::MakeCurrent()