wglext.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:9k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // wglext.cpp
  2. //
  3. // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
  4. //
  5. // Set up pointers for WGL functions.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. #include "celengine/gl.h"
  12. //#define WGL_WGLEXT_PROTOTYPES 1
  13. #include "wglext.h"
  14. #include <windows.h>
  15. #include <cstdio>
  16. #include <vector>
  17. using namespace std;
  18. static vector<string> supportedExtensions;
  19. extern "C"
  20. {
  21. PFNWGLGETEXTENSIONSSTRINGARBPROC    wglGetExtensionsStringARB    = NULL;
  22. // WGL_ARB_pixel_format functions
  23. PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = NULL;
  24. PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB = NULL;
  25. PFNWGLCHOOSEPIXELFORMATARBPROC      wglChoosePixelFormatARB      = NULL;
  26. // WGL_ARB_pbuffer functions
  27. PFNWGLCREATEPBUFFERARBPROC          wglCreatePbufferARB          = NULL;
  28. PFNWGLGETPBUFFERDCARBPROC           wglGetPbufferDCARB           = NULL;
  29. PFNWGLRELEASEPBUFFERDCARBPROC       wglReleasePbufferDCARB       = NULL;
  30. PFNWGLDESTROYPBUFFERARBPROC         wglDestroyPbufferARB         = NULL;
  31. PFNWGLQUERYPBUFFERARBPROC           wglQueryPbufferARB           = NULL;
  32. };
  33. // Select a floating point pixel format
  34. int FindFormatFloat(HDC hDC)
  35. {
  36.     int ifmtList[] = {
  37.         WGL_DRAW_TO_PBUFFER_ARB,       TRUE,
  38.         WGL_SUPPORT_OPENGL_ARB,        TRUE,
  39.         //WGL_DOUBLE_BUFFER_ARB,         TRUE,
  40.         WGL_PIXEL_TYPE_ARB,            WGL_TYPE_RGBA_FLOAT_ATI,
  41.         WGL_DEPTH_BITS_ARB,            24,
  42.         WGL_COLOR_BITS_ARB,             0,
  43.         WGL_RED_BITS_ARB,               16,
  44.         WGL_GREEN_BITS_ARB,             16,
  45.         WGL_BLUE_BITS_ARB,              16,
  46.         WGL_ALPHA_BITS_ARB,             0,
  47.         WGL_ACCUM_BITS_ARB,             0,
  48.         WGL_STENCIL_BITS_ARB,           8,
  49.         WGL_BIND_TO_TEXTURE_RGB_ARB,    TRUE,
  50.         0
  51.     };
  52.     int             pixelFormatIndex = -1;
  53.     int             pixFormats[256];
  54.     unsigned int    numFormats;
  55.     wglChoosePixelFormatARB(hDC, ifmtList, NULL, 256, pixFormats, &numFormats);
  56.     if (numFormats != 0)
  57.     {
  58.         for (unsigned int i = 0; i < numFormats; i++)
  59.         {
  60.             int results[7];
  61.             int query[] = { WGL_COLOR_BITS_ARB,
  62.                             WGL_DEPTH_BITS_ARB,
  63.                             WGL_STENCIL_BITS_ARB,
  64.                             WGL_RED_BITS_ARB,
  65.                             WGL_GREEN_BITS_ARB,
  66.                             WGL_BLUE_BITS_ARB,
  67.                             WGL_ALPHA_BITS_ARB };
  68.             wglGetPixelFormatAttribivARB(hDC, pixFormats[i], 0,
  69.                                          7, query, results);
  70.             // Select an fp16 format.  No existing hardware fully supports
  71.             // fp32 render targets (no alpha blending, etc.), and fp16 is
  72.             // probably good enough anyway.
  73.             if (results[0] == 64 && results[3] == 16)
  74.                 return pixFormats[i];
  75.         }
  76.     }
  77.     return -1;
  78. }
  79. // Called when dummy window is opened. Its only job is to get hold
  80. // of wgl extensions.
  81. static void WGLCallback(HWND wnd)
  82. {
  83.     if (wnd == NULL)
  84.         return;
  85.     
  86.     HDC hdc = GetDC(wnd);
  87.     if (hdc == NULL)
  88.         return;
  89.     PIXELFORMATDESCRIPTOR pfd = { 
  90.         sizeof(PIXELFORMATDESCRIPTOR),  //  size of this pfd 
  91.         1,                              // version number 
  92.         PFD_DRAW_TO_WINDOW |            // support window 
  93.         PFD_SUPPORT_OPENGL |            // support OpenGL 
  94.         PFD_DOUBLEBUFFER, // double buffered 
  95.         PFD_TYPE_RGBA,                  // RGBA type 
  96.         24,                             // 24-bit color depth 
  97.         0, 0, 0, 0, 0, 0, // color bits ignored 
  98.         0,                              // no alpha buffer 
  99.         0,                              // shift bit ignored 
  100.         0,                              // no accumulation buffer 
  101.         0, 0, 0, 0,                     // accum bits ignored 
  102.         24,                             // 24-bit z-buffer     
  103.         0,                              // no stencil buffer 
  104.         0,                              // no auxiliary buffer 
  105.         PFD_MAIN_PLANE,                 // main layer 
  106.         0,                              // reserved 
  107.         0, 0, 0                         // layer masks ignored 
  108.     }; 
  109.     unsigned int pixelFormat = ChoosePixelFormat(hdc, &pfd);
  110.     DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  111.     if (!SetPixelFormat(hdc, pixelFormat, &pfd))
  112.         return;
  113.     HGLRC context = wglCreateContext(hdc);
  114.     if (context == NULL)
  115.         return;
  116.     wglMakeCurrent(hdc, context);
  117.     wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
  118.     if (wglGetExtensionsStringARB == NULL)
  119.         return;
  120.     const char *ext = wglGetExtensionsStringARB(hdc);
  121.     char        buff[100];
  122.     if (ext == NULL)
  123.         return;
  124.     while (*ext != '')
  125.     {
  126.         // TODO: This is prone to buffer overflows if the driver reports a
  127.         // bad extension string.
  128.         sscanf(ext, "%s", buff);
  129.         // Check for required extension and fill in pointers
  130.         if (strcmp(buff, "WGL_ARB_pixel_format") == 0)
  131.         {
  132.             wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribivARB");
  133.             wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribfvARB");
  134.             wglChoosePixelFormatARB      = (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
  135.             
  136.             if (wglChoosePixelFormatARB      != NULL &&
  137.                 wglGetPixelFormatAttribivARB != NULL &&
  138.                 wglGetPixelFormatAttribfvARB != NULL)
  139.             {
  140.                 supportedExtensions.push_back(buff);
  141.             }
  142.         }
  143.         else if (strcmp(buff, "WGL_ARB_pbuffer") == 0)
  144.         {
  145.             wglCreatePbufferARB    = (PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
  146.             wglGetPbufferDCARB     = (PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
  147.             wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB");
  148.             wglDestroyPbufferARB   = (PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB");
  149.             wglQueryPbufferARB     = (PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
  150.             if (wglCreatePbufferARB         != NULL &&
  151.                 wglGetPbufferDCARB          != NULL &&
  152.                 wglReleasePbufferDCARB      != NULL &&
  153.                 wglDestroyPbufferARB        != NULL &&
  154.                 wglQueryPbufferARB          != NULL)
  155.             {
  156.                 supportedExtensions.push_back(buff);
  157.             }
  158.         }
  159.         else if (strcmp(buff, "WGL_ARB_multisample") == 0)
  160.         {
  161.             //wglSampleCoverageARB = (PFNWGLSAMPLECOVERAGEARBPROC) wglGetProcAddres("wglSampleCoverageARB");
  162.             supportedExtensions.push_back(buff);
  163.         }
  164.         else if (strcmp(buff, "WGL_ATI_pixel_format_float") == 0)
  165.         {
  166.             supportedExtensions.push_back(buff);
  167.         }
  168.         else if (strcmp(buff, "WGL_ARB_render_texture") == 0)
  169.         {
  170.         }
  171.         ext += strlen(buff) + 1;
  172.     }
  173.     
  174.     // Close down this context
  175.     wglMakeCurrent(NULL, NULL);
  176.     wglDeleteContext(context);
  177.     ReleaseDC(wnd, hdc);
  178. }
  179. // This window exists only to call WGLCallback when its created
  180. static LRESULT CALLBACK WGLWindProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  181. {
  182.     switch (uMsg) 
  183.     { 
  184.     case WM_CREATE:
  185.         {
  186.             CREATESTRUCT *cs = (CREATESTRUCT *) lParam;
  187.             WGLCallback(hwnd);
  188.             return -1; 
  189. }
  190.  
  191.     default: 
  192.         return DefWindowProc(hwnd, uMsg, wParam, lParam); 
  193.     } 
  194.     return 0; 
  195. }
  196. // Create a dummy window to initialise WGL extensions.
  197. void InitWGLExtensions(HINSTANCE appInstance)
  198. {
  199.     WNDCLASS wglClass = {
  200.         0, WGLWindProc, 0, 0, appInstance, NULL, NULL, NULL, NULL, "InitWGL"
  201.     };
  202.     ATOM classId  = RegisterClass(&wglClass);
  203.     HWND hwnd = CreateWindow("InitWGL", "",
  204.                              0, 0, 0, 0, 0,
  205.                              (HWND) NULL,
  206.                              (HMENU) NULL,
  207.                              appInstance,
  208.                              NULL);
  209. }
  210. bool WGLExtensionSupported(const string& extName)
  211. {
  212.     for (unsigned int i = 0; i < supportedExtensions.size(); i++)
  213.     {
  214.         if (supportedExtensions[i] == extName)
  215.             return true;
  216.     }
  217.     return false;
  218. }