Create a fake window to check for GL extensions.

This commit is contained in:
leo 2012-07-11 01:17:40 +00:00
parent 4369308e5a
commit 8cdf9099a2
3 changed files with 105 additions and 13 deletions

View file

@ -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");

View file

@ -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;

View file

@ -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()