arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

wglinfo.c

Go to the documentation of this file.
00001 /*
00002 ** wglinfo.c
00003 **
00004 ** Copyright (C) Nate Robins, 1997
00005 **               Michael Wimmer, 1999
00006 **               Milan Ikits, 2003
00007 **
00008 ** wglinfo is a small utility that displays all available visuals,
00009 ** aka. pixelformats, in an OpenGL system along with renderer version
00010 ** information. It shows a table of all the visuals that support OpenGL
00011 ** and their capabilities. The format of the table is similar to glxinfo
00012 ** on Unix systems:
00013 **
00014 ** visual  ~= pixel format descriptor
00015 ** id       = visual id (integer from 1 - max visuals)
00016 ** dep      = cColorBits - color depth
00017 ** tp       = dwFlags - visual type (wn: window, pb: pbuffer, bm: bitmap)
00018 ** xsp      = no analog - transparent pixel (currently always ".")
00019 ** bfsz     = cColorBits - framebuffer size
00020 ** lvl      = bReserved - overlay (>0), underlay (<0), main plane (0)
00021 ** rgci     = iPixelType - rb = rgba mode, ci = color index mode
00022 ** db       = dwFlags & PFD_DOUBLEBUFFER - double buffer flag (y = yes)
00023 ** stro     = dwFlags & PFD_STEREO - stereo flag (y = yes)
00024 ** gene     = dwFlags & PFD_GENERIC - software generic (y = yes) or ICD
00025 ** geac     = dwFlags & PFD_GENERIC_ACCELERATED - generic with hardware (MCD)
00026 ** rsz      = cRedBits - # bits of red
00027 ** gsz      = cGreenBits - # bits of green
00028 ** bsz      = cBlueBits - # bits of blue
00029 ** asz      = cAlphaBits - # bits of alpha
00030 ** axbf     = cAuxBuffers - # of aux buffers
00031 ** dpth     = cDepthBits - # bits of depth
00032 ** stcl     = cStencilBits - # bits of stencil
00033 ** accum sz = cAccumBits - total # of bits in accumulation buffer
00034 ** accum r  = cAccumRedBits - # bits of red in accumulation buffer
00035 ** accum g  = cAccumGreenBits - # bits of green in accumulation buffer
00036 ** accum b  = cAccumBlueBits  - # bits of blue in accumulation buffer
00037 ** accum a  = cAccumAlphaBits - # bits of alpha in accumulation buffer
00038 ** ms ns/b  = no analog  - multisample buffers (currently always ".")
00039 */
00040 
00041 #include <stdio.h>
00042 #include <windows.h> /* must include */
00043 #include <GL/gl.h>   /* OpenGL header */
00044 #include <GL/glu.h>  /* GLU header */
00045 
00046 int drawableonly = 0;
00047 int pixelformatok = 0;
00048 int dontcreatecontext = 0;
00049 int displaystdout = 0;
00050 int verbose = 0;
00051 FILE* file = stdout;
00052 
00053 #define WGL_DRAW_TO_PBUFFER_ARB                                 0x202D
00054 #define WGL_NUMBER_PIXEL_FORMATS_ARB                            0x2000
00055 
00056 typedef const char* (APIENTRY * wglGetExtensionsStringARBPROC) (HDC hdc);
00057 typedef const char* (APIENTRY * wglGetExtensionsStringEXTPROC) ();
00058 typedef BOOL (APIENTRY * wglGetPixelFormatAttribivARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
00059 typedef BOOL (APIENTRY * wglChoosePixelFormatARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
00060 
00061 wglGetExtensionsStringARBPROC wglGetExtensionsStringARB = NULL;
00062 wglGetExtensionsStringEXTPROC wglGetExtensionsStringEXT = NULL;
00063 wglGetPixelFormatAttribivARBPROC wglGetPixelFormatAttribivARB = NULL;
00064 wglChoosePixelFormatARBPROC wglChoosePixelFormatARB = NULL;
00065 
00066 void
00067 VisualInfo (HDC hDC, int verbose)
00068 {
00069   int i, maxpf;
00070   PIXELFORMATDESCRIPTOR pfd;
00071 
00072   /* calling DescribePixelFormat() with NULL pfd (!!!) return maximum
00073      number of pixel formats */
00074   maxpf = DescribePixelFormat(hDC, 1, 0, NULL);
00075 
00076   if (!verbose)
00077   {
00078     fprintf(file, "-----------------------------------------------------------------------------\n");
00079     fprintf(file, "   visual   x  bf  lv rg d st ge ge  r  g  b a  ax dp st   accum buffs    ms \n");
00080     fprintf(file, " id  dep tp sp sz  l  ci b ro ne ac sz sz sz sz bf th cl  sz  r  g  b  a ns b\n");
00081     fprintf(file, "-----------------------------------------------------------------------------\n");
00082 
00083     /* loop through all the pixel formats */
00084     for(i = 1; i <= maxpf; i++)
00085     {
00086       DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00087       /* only describe this format if it supports OpenGL */
00088       if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL)
00089          || (drawableonly && (pfd.dwFlags & PFD_DRAW_TO_BITMAP))) continue;
00090       /* other criteria could be tested here for actual pixel format
00091          choosing in an application:
00092            
00093          for (...each pixel format...) {
00094          if (pfd.dwFlags & PFD_SUPPORT_OPENGL &&
00095          pfd.dwFlags & PFD_DOUBLEBUFFER &&
00096          pfd.cDepthBits >= 24 &&
00097          pfd.cColorBits >= 24)
00098          {
00099          goto found;
00100          }
00101          }
00102          ... not found so exit ...
00103          found:
00104          ... found so use it ...
00105       */
00106       /* print out the information for this pixel format */
00107       fprintf(file, "0x%02x ", i);
00108       fprintf(file, "%3d ", pfd.cColorBits);
00109       if(pfd.dwFlags & PFD_DRAW_TO_WINDOW) fprintf(file, "wn ");
00110       else if(pfd.dwFlags & PFD_DRAW_TO_BITMAP) fprintf(file, "bm ");
00111       else fprintf(file, "pb ");
00112       /* should find transparent pixel from LAYERPLANEDESCRIPTOR */
00113       fprintf(file, " . "); 
00114       fprintf(file, "%3d ", pfd.cColorBits);
00115       /* bReserved field indicates number of over/underlays */
00116       if(pfd.bReserved) fprintf(file, " %d ", pfd.bReserved);
00117       else fprintf(file, " . "); 
00118       fprintf(file, " %c ", pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c');
00119       fprintf(file, "%c ", pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.');
00120       fprintf(file, " %c ", pfd.dwFlags & PFD_STEREO ? 'y' : '.');
00121       /* added: */
00122       fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_FORMAT ? 'y' : '.');
00123       fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_ACCELERATED ? 'y' : '.');
00124       if(pfd.cRedBits && pfd.iPixelType == PFD_TYPE_RGBA) 
00125         fprintf(file, "%2d ", pfd.cRedBits);
00126       else fprintf(file, " . ");
00127       if(pfd.cGreenBits && pfd.iPixelType == PFD_TYPE_RGBA) 
00128         fprintf(file, "%2d ", pfd.cGreenBits);
00129       else fprintf(file, " . ");
00130       if(pfd.cBlueBits && pfd.iPixelType == PFD_TYPE_RGBA) 
00131         fprintf(file, "%2d ", pfd.cBlueBits);
00132       else fprintf(file, " . ");
00133       if(pfd.cAlphaBits && pfd.iPixelType == PFD_TYPE_RGBA) 
00134         fprintf(file, "%2d ", pfd.cAlphaBits);
00135       else fprintf(file, " . ");
00136       if(pfd.cAuxBuffers)     fprintf(file, "%2d ", pfd.cAuxBuffers);
00137       else fprintf(file, " . ");
00138       if(pfd.cDepthBits)      fprintf(file, "%2d ", pfd.cDepthBits);
00139       else fprintf(file, " . ");
00140       if(pfd.cStencilBits)    fprintf(file, "%2d ", pfd.cStencilBits);
00141       else fprintf(file, " . ");
00142       if(pfd.cAccumBits)   fprintf(file, "%3d ", pfd.cAccumBits);
00143       else fprintf(file, "  . ");
00144       if(pfd.cAccumRedBits)   fprintf(file, "%2d ", pfd.cAccumRedBits);
00145       else fprintf(file, " . ");
00146       if(pfd.cAccumGreenBits) fprintf(file, "%2d ", pfd.cAccumGreenBits);
00147       else fprintf(file, " . ");
00148       if(pfd.cAccumBlueBits)  fprintf(file, "%2d ", pfd.cAccumBlueBits);
00149       else fprintf(file, " . ");
00150       if(pfd.cAccumAlphaBits) fprintf(file, "%2d ", pfd.cAccumAlphaBits);
00151       else fprintf(file, " . ");
00152       /* no multisample in win32 */
00153       fprintf(file, " . .\n");
00154     }
00155     /* print table footer */
00156     fprintf(file, "-----------------------------------------------------------------------------\n");
00157     fprintf(file, "   visual   x  bf  lv rg d st ge ge  r  g  b a  ax dp st   accum buffs    ms \n");
00158     fprintf(file, " id  dep tp sp sz  l  ci b ro ne ac sz sz sz sz bf th cl  sz  r  g  b  a ns b\n");
00159     fprintf(file, "-----------------------------------------------------------------------------\n");
00160   }
00161   else /* verbose */
00162   {
00163     fprintf(file, "\n");
00164     /* loop through all the pixel formats */
00165     for(i = 1; i <= maxpf; i++)
00166     {       
00167       DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00168       /* only describe this format if it supports OpenGL */
00169       if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL)
00170          || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue;
00171       fprintf(file, "Visual ID: %2d  depth=%d  class=%s\n", i, pfd.cDepthBits, 
00172              pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor");
00173       fprintf(file, "    bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO);
00174       fprintf(file, "    generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED);
00175       fprintf(file, "    rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits);
00176       fprintf(file, "    auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits);
00177       fprintf(file, "    accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits);
00178       fprintf(file, "    multiSample=%d multisampleBuffers=%d\n", 0, 0);
00179       fprintf(file, "    Opaque.\n");
00180     }
00181   }
00182 }
00183 
00184 LONG WINAPI
00185 WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00186 { 
00187   static PAINTSTRUCT ps;
00188 
00189   switch(uMsg)
00190   {
00191     case WM_PAINT:
00192     BeginPaint(hWnd, &ps);
00193     EndPaint(hWnd, &ps);
00194     return 0;
00195 
00196     case WM_SIZE:
00197     //glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
00198     PostMessage(hWnd, WM_PAINT, 0, 0);
00199     return 0;
00200 
00201     case WM_CHAR:
00202     switch (wParam)
00203     {
00204       case 27:
00205       PostQuitMessage(0);
00206       break;
00207     }
00208     return 0;
00209 
00210     case WM_CLOSE:
00211     PostQuitMessage(0);
00212     return 0;
00213   }
00214 
00215   return DefWindowProc(hWnd, uMsg, wParam, lParam); 
00216 } 
00217 
00218 HWND
00219 CreateGLWindow (char* title, int x, int y, int width, int height, 
00220                 BYTE type, DWORD flags)
00221 {
00222   int pf;
00223   HDC hDC;
00224   HWND hWnd;
00225   WNDCLASS wc;
00226   PIXELFORMATDESCRIPTOR pfd;
00227   static HINSTANCE hInstance = 0;
00228 
00229   /* only register the window class once - use hInstance as a flag. */
00230   if (!hInstance)
00231   {
00232     hInstance = GetModuleHandle(NULL);
00233     wc.style = CS_OWNDC;
00234     wc.lpfnWndProc = (WNDPROC)WindowProc;
00235     wc.cbClsExtra = 0;
00236     wc.cbWndExtra = 0;
00237     wc.hInstance = hInstance;
00238     wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
00239     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
00240     wc.hbrBackground = NULL;
00241     wc.lpszMenuName  = NULL;
00242     wc.lpszClassName = "OpenGL";
00243 
00244     if (!RegisterClass(&wc))
00245     {
00246       MessageBox(NULL, "RegisterClass() failed:  "
00247                  "Cannot register window class.", "Error", MB_OK);
00248       return NULL;
00249     }
00250   }
00251   hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
00252                       WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
00253                       x, y, width, height, NULL, NULL, hInstance, NULL);
00254 
00255   if (hWnd == NULL)
00256   {
00257     MessageBox(NULL, "CreateWindow() failed:  Cannot create a window.",
00258                "Error", MB_OK);
00259     return NULL;
00260   }
00261   hDC = GetDC(hWnd);
00262   /* there is no guarantee that the contents of the stack that become
00263      the pfd are zeroed, therefore _make sure_ to clear these bits. */
00264   memset(&pfd, 0, sizeof(pfd));
00265   pfd.nSize = sizeof(pfd);
00266   pfd.nVersion = 1;
00267   pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
00268   //pfd.iPixelType = type;
00269   //pfd.cColorBits = 32;
00270   pf = ChoosePixelFormat(hDC, &pfd);
00271   if (pf == 0)
00272   {
00273     fprintf(stderr, "ChoosePixelFormat() failed - trying with Pixelformat 1!\n");
00274     pf = 1;
00275   } 
00276   if (SetPixelFormat(hDC, pf, &pfd) == FALSE)
00277   {
00278     fprintf(stderr, "SetPixelFormat(%d) failed! No Renderer data will be available!\n", pf);
00279   } 
00280   else
00281   {
00282     DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00283     if (pfd.cColorBits == 0)
00284       fprintf(stderr, "SetPixelFormat(%d) returned pfd with 0 colorbits - assuming invalid!\n", pf);
00285     else
00286       pixelformatok = 1;
00287   }
00288   // no effect (because of CS_OWNDC)
00289   ReleaseDC(hWnd, hDC);
00290 
00291   return hWnd;
00292 }    
00293 
00294 /* do the magic to separate all extensions with comma's, except
00295    for the last one that _may_ terminate in a space. */
00296 void PrintExtensions (char* s)
00297 {
00298   char t[80];
00299   int i=0;
00300   char* p;
00301 
00302   t[79] = '\0';
00303   while (*s)
00304   {
00305     t[i++] = *s;
00306     if(*s == ' ')
00307     {
00308       if (*(s+1) != '\0') {
00309         t[i-1] = ',';
00310         t[i] = ' ';
00311         p = &t[i++];
00312       }
00313       else /* zoinks! last one terminated in a space! */
00314       {
00315         t[i-1] = '\0';
00316       }
00317     }
00318     if(i > 80 - 5)
00319     {
00320       *p = t[i] = '\0';
00321       fprintf(file, "    %s\n", t);
00322       p++;
00323       i = strlen(p);
00324       strcpy(t, p);
00325     }
00326     s++;
00327   }
00328   t[i] = '\0';
00329   fprintf(file, "    %s.\n", t);
00330 }
00331 
00332 int 
00333 main (int argc, char** argv)
00334 {
00335   HDC hDC;
00336   HGLRC hRC;
00337   HWND hWnd;
00338   MSG msg;
00339 
00340   while (--argc)
00341   {
00342     if (strcmp("-h", argv[argc]) == 0) {
00343       //printf("Usage: wglinfo [-v] [-t] [-m] [-h] [-dispay <dname>] [-nfbc] [-fpcinfo]\n");
00344       fprintf(stderr, "Usage: wglinfo [-d] [-v] [-w] [-s] [-h]\n");
00345       fprintf(stderr, "        -d: no context (pixelformat enumeration, but no render string)\n");
00346       fprintf(stderr, "        -v: print visuals info in verbose form\n");
00347       /*
00348         printf("        -t: Print verbose table (not implemented on Win32)\n");
00349         printf("        -m: Don't print mid table headers (in long tables). (not on Win32)\n");
00350         printf("        -display <dname>: Print GLX visuals on specified server. (not on Win32)\n");
00351         printf("        -nfbc: Don't use fbconfig extension (not available on Win32)\n");
00352         printf("        -fbcinfo: print out additional fbconfig information (not on Win32)\n");
00353       */
00354       fprintf(stderr, "        -w: show only visuals that can draw to the screen\n");
00355       fprintf(stderr, "        -s: display to stdout instead of wglinfo.txt\n");      
00356       fprintf(stderr, "        -h: this screen\n");
00357       return 1;
00358     }
00359     else if (strcmp("-v", argv[argc]) == 0)
00360     {
00361       verbose = 1;
00362     }
00363     else if (strcmp("-w", argv[argc]) == 0)
00364     {
00365       drawableonly = 1;
00366     }
00367     else if (strcmp("-d", argv[argc]) == 0)
00368     {
00369       dontcreatecontext = 1;
00370     }   
00371     else if (strcmp("-s", argv[argc]) == 0)
00372     {
00373       displaystdout = 1;
00374     }
00375   }
00376 
00377   if (!displaystdout) file = fopen("wglinfo.txt", "w");
00378   if (file == NULL) file = stdout;
00379 
00380   hWnd = CreateGLWindow("wglinfo", 0, 0, 100, 100, PFD_TYPE_RGBA, PFD_DOUBLEBUFFER);
00381   if (hWnd == NULL) return 1;
00382   hDC = GetDC(hWnd);
00383   pixelformatok = pixelformatok && !dontcreatecontext;
00384   if (pixelformatok)
00385   {
00386     hRC = wglCreateContext(hDC);
00387     wglMakeCurrent(hDC, hRC);
00388   }
00389   ShowWindow(hWnd, SW_HIDE);
00390 
00391   if (pixelformatok)
00392   {
00393     /* output header information */
00394     /* OpenGL extensions */
00395     /*
00396       printf("display: N/A\n");
00397       printf("server wgl vendor string: N/A\n");
00398       printf("server wgl version string: N/A\n");
00399       printf("server wgl extensions (WGL_): N/A\n");
00400       printf("client wgl version: N/A\n");
00401       printf("client wgl extensions (WGL_): none\n");
00402     */
00403     fprintf(file, "OpenGL vendor string: %s\n", glGetString(GL_VENDOR));
00404     fprintf(file, "OpenGL renderer string: %s\n", glGetString(GL_RENDERER));
00405     fprintf(file, "OpenGL version string: %s\n", glGetString(GL_VERSION));
00406     fprintf(file, "OpenGL extensions (GL_): \n");
00407     PrintExtensions((char*)glGetString(GL_EXTENSIONS));
00408 
00409     /* GLU extensions */
00410     fprintf(file, "GLU version string: %s\n", gluGetString(GLU_VERSION));
00411     fprintf(file, "GLU extensions (GLU_): \n");
00412     PrintExtensions((char*)gluGetString(GLU_EXTENSIONS));
00413 
00414     /* WGL extensions */
00415     wglGetExtensionsStringARB = (wglGetExtensionsStringARBPROC)
00416       wglGetProcAddress("wglGetExtensionsStringARB");
00417     if (!wglGetExtensionsStringARB)
00418     {
00419       wglGetExtensionsStringEXT = (wglGetExtensionsStringEXTPROC)
00420         wglGetProcAddress("wglGetExtensionsStringEXT");
00421     }
00422     if (wglGetExtensionsStringARB || wglGetExtensionsStringEXT)
00423     {
00424       //fprintf(file, "WGL vendor string: %s\n", );
00425       //fprintf(file, "WGL version string: %s\n", );
00426       fprintf(file, "WGL extensions (WGL_): \n");
00427       if (wglGetExtensionsStringARB)
00428         PrintExtensions(wglGetExtensionsStringARB ? (char*)wglGetExtensionsStringARB(hDC):
00429                         (char*)wglGetExtensionsStringARB(hDC));
00430     }
00431   }
00432 
00433   /* enumerate all the formats */
00434   wglChoosePixelFormatARB = 
00435     (wglChoosePixelFormatARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
00436   wglGetPixelFormatAttribivARB =
00437     (wglGetPixelFormatAttribivARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
00438   if (wglChoosePixelFormatARB != NULL && wglGetPixelFormatAttribivARB != NULL)
00439   {
00440     int attrib[16], value[16], pf;
00441     unsigned int c;
00442     attrib[0] = WGL_DRAW_TO_PBUFFER_ARB;
00443     attrib[1] = GL_TRUE;
00444     attrib[2] = 0;
00445     wglChoosePixelFormatARB(hDC, attrib, 0, 1, &pf, &c);
00446     attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB;
00447     wglGetPixelFormatAttribivARB(hDC, 0, 0, 1, attrib, value);
00448   }
00449   VisualInfo(hDC, verbose);
00450 
00451   PostQuitMessage(0);
00452   while (GetMessage(&msg, hWnd, 0, 0))
00453   {
00454     TranslateMessage(&msg);
00455     DispatchMessage(&msg);
00456   }
00457 
00458   if (pixelformatok) wglMakeCurrent(NULL, NULL);
00459   ReleaseDC(hWnd, hDC);
00460   if (pixelformatok) wglDeleteContext(hRC);
00461   DestroyWindow(hWnd);
00462 
00463   if (file != stdout) fclose(file);
00464 
00465   return msg.wParam;
00466 }

Send questions, comments, and bug reports to:
jmk