// wglext.cpp // // Copyright (C) 2001, Chris Laurel // // Set up pointers for WGL functions. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. #include //#define WGL_WGLEXT_PROTOTYPES 1 #include "wglext.h" #include #include #include using namespace std; static vector supportedExtensions; extern "C" { PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL; // WGL_ARB_pixel_format functions PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = NULL; PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB = NULL; PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL; // WGL_ARB_pbuffer functions PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB = NULL; PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB = NULL; PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB = NULL; PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB = NULL; PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB = NULL; }; // Select a floating point pixel format int FindFormatFloat(HDC hDC) { int ifmtList[] = { WGL_DRAW_TO_PBUFFER_ARB, TRUE, WGL_SUPPORT_OPENGL_ARB, TRUE, //WGL_DOUBLE_BUFFER_ARB, TRUE, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_FLOAT_ATI, WGL_DEPTH_BITS_ARB, 24, WGL_COLOR_BITS_ARB, 0, WGL_RED_BITS_ARB, 16, WGL_GREEN_BITS_ARB, 16, WGL_BLUE_BITS_ARB, 16, WGL_ALPHA_BITS_ARB, 0, WGL_ACCUM_BITS_ARB, 0, WGL_STENCIL_BITS_ARB, 8, WGL_BIND_TO_TEXTURE_RGB_ARB, TRUE, 0 }; int pixelFormatIndex = -1; int pixFormats[256]; unsigned int numFormats; wglChoosePixelFormatARB(hDC, ifmtList, NULL, 256, pixFormats, &numFormats); if (numFormats != 0) { for (unsigned int i = 0; i < numFormats; i++) { int results[7]; int query[] = { WGL_COLOR_BITS_ARB, WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB, WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB }; wglGetPixelFormatAttribivARB(hDC, pixFormats[i], 0, 7, query, results); // Select an fp16 format. No existing hardware fully supports // fp32 render targets (no alpha blending, etc.), and fp16 is // probably good enough anyway. if (results[0] == 64 && results[3] == 16) return pixFormats[i]; } } return -1; } // Called when dummy window is opened. Its only job is to get hold // of wgl extensions. static void WGLCallback(HWND wnd) { if (wnd == NULL) return; HDC hdc = GetDC(wnd); if (hdc == NULL) return; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 24, // 24-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; unsigned int pixelFormat = ChoosePixelFormat(hdc, &pfd); DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); if (!SetPixelFormat(hdc, pixelFormat, &pfd)) return; HGLRC context = wglCreateContext(hdc); if (context == NULL) return; wglMakeCurrent(hdc, context); wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB"); if (wglGetExtensionsStringARB == NULL) return; const char *ext = wglGetExtensionsStringARB(hdc); char buff[100]; if (ext == NULL) return; while (*ext != '\0') { // TODO: This is prone to buffer overflows if the driver reports a // bad extension string. sscanf(ext, "%s", buff); // Check for required extension and fill in pointers if (strcmp(buff, "WGL_ARB_pixel_format") == 0) { wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribivARB"); wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribfvARB"); wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB"); if (wglChoosePixelFormatARB != NULL && wglGetPixelFormatAttribivARB != NULL && wglGetPixelFormatAttribfvARB != NULL) { supportedExtensions.push_back(buff); } } else if (strcmp(buff, "WGL_ARB_pbuffer") == 0) { wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB"); wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB"); wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB"); wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB"); wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB"); if (wglCreatePbufferARB != NULL && wglGetPbufferDCARB != NULL && wglReleasePbufferDCARB != NULL && wglDestroyPbufferARB != NULL && wglQueryPbufferARB != NULL) { supportedExtensions.push_back(buff); } } else if (strcmp(buff, "WGL_ARB_multisample") == 0) { //wglSampleCoverageARB = (PFNWGLSAMPLECOVERAGEARBPROC) wglGetProcAddres("wglSampleCoverageARB"); supportedExtensions.push_back(buff); } else if (strcmp(buff, "WGL_ATI_pixel_format_float") == 0) { supportedExtensions.push_back(buff); } else if (strcmp(buff, "WGL_ARB_render_texture") == 0) { } ext += strlen(buff) + 1; } // Close down this context wglMakeCurrent(NULL, NULL); wglDeleteContext(context); ReleaseDC(wnd, hdc); } // This window exists only to call WGLCallback when its created static LRESULT CALLBACK WGLWindProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: { CREATESTRUCT *cs = (CREATESTRUCT *) lParam; WGLCallback(hwnd); return -1; } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } // Create a dummy window to initialise WGL extensions. void InitWGLExtensions(HINSTANCE appInstance) { WNDCLASS wglClass = { 0, WGLWindProc, 0, 0, appInstance, NULL, NULL, NULL, NULL, "InitWGL" }; ATOM classId = RegisterClass(&wglClass); HWND hwnd = CreateWindow("InitWGL", "", 0, 0, 0, 0, 0, (HWND) NULL, (HMENU) NULL, appInstance, NULL); } bool WGLExtensionSupported(const string& extName) { for (unsigned int i = 0; i < supportedExtensions.size(); i++) { if (supportedExtensions[i] == extName) return true; } return false; }