/* ** visualinfo.c ** ** Copyright (C) Nate Robins, 1997 ** Michael Wimmer, 1999 ** Milan Ikits, 2002-2008 ** Nigel Stewart, 2008-2013 ** ** visualinfo is a small utility that displays all available visuals, ** aka. pixelformats, in an OpenGL system along with renderer version ** information. It shows a table of all the visuals that support OpenGL ** along with their capabilities. The format of the table is similar to ** that of glxinfo on Unix systems: ** ** visual ~= pixel format descriptor ** id = visual id (integer from 1 - max visuals) ** tp = type (wn: window, pb: pbuffer, wp: window & pbuffer, bm: bitmap) ** ac = acceleration (ge: generic, fu: full, no: none) ** fm = format (i: integer, f: float, c: color index) ** db = double buffer (y = yes) ** sw = swap method (x: exchange, c: copy, u: undefined) ** st = stereo (y = yes) ** sz = total # bits ** r = # bits of red ** g = # bits of green ** b = # bits of blue ** a = # bits of alpha ** axbf = # aux buffers ** dpth = # bits of depth ** stcl = # bits of stencil */ #include #include #include #include #if defined(_WIN32) #include #elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) #include #elif !defined(__HAIKU__) #include #endif #ifdef GLEW_MX GLEWContext _glewctx; # define glewGetContext() (&_glewctx) # ifdef _WIN32 WGLEWContext _wglewctx; # define wglewGetContext() (&_wglewctx) # elif !defined(__APPLE__) && !defined(__HAIKU__) || defined(GLEW_APPLE_GLX) GLXEWContext _glxewctx; # define glxewGetContext() (&_glxewctx) # endif #endif /* GLEW_MX */ typedef struct GLContextStruct { #ifdef _WIN32 HWND wnd; HDC dc; HGLRC rc; #elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) AGLContext ctx, octx; #elif !defined(__HAIKU__) Display* dpy; XVisualInfo* vi; GLXContext ctx; Window wnd; Colormap cmap; #endif } GLContext; void InitContext (GLContext* ctx); GLboolean CreateContext (GLContext* ctx); void DestroyContext (GLContext* ctx); void VisualInfo (GLContext* ctx); void PrintExtensions (const char* s); GLboolean ParseArgs (int argc, char** argv); int showall = 0; int displaystdout = 0; int verbose = 0; int drawableonly = 0; char* display = NULL; int visual = -1; FILE* file = 0; int main (int argc, char** argv) { GLenum err; GLContext ctx; /* ---------------------------------------------------------------------- */ /* parse arguments */ if (GL_TRUE == ParseArgs(argc-1, argv+1)) { #if defined(_WIN32) fprintf(stderr, "Usage: visualinfo [-a] [-s] [-h] [-pf ]\n"); fprintf(stderr, " -a: show all visuals\n"); fprintf(stderr, " -s: display to stdout instead of visualinfo.txt\n"); fprintf(stderr, " -pf : use given pixelformat\n"); fprintf(stderr, " -h: this screen\n"); #else fprintf(stderr, "Usage: visualinfo [-h] [-display ] [-visual ]\n"); fprintf(stderr, " -h: this screen\n"); fprintf(stderr, " -display : use given display\n"); fprintf(stderr, " -visual : use given visual\n"); #endif return 1; } /* ---------------------------------------------------------------------- */ /* create OpenGL rendering context */ InitContext(&ctx); if (GL_TRUE == CreateContext(&ctx)) { fprintf(stderr, "Error: CreateContext failed\n"); DestroyContext(&ctx); return 1; } /* ---------------------------------------------------------------------- */ /* initialize GLEW */ glewExperimental = GL_TRUE; #ifdef GLEW_MX err = glewContextInit(glewGetContext()); # ifdef _WIN32 err = err || wglewContextInit(wglewGetContext()); # elif !defined(__APPLE__) && !defined(__HAIKU__) || defined(GLEW_APPLE_GLX) err = err || glxewContextInit(glxewGetContext()); # endif #else err = glewInit(); #endif if (GLEW_OK != err) { fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); DestroyContext(&ctx); return 1; } /* ---------------------------------------------------------------------- */ /* open file */ #if defined(_WIN32) if (!displaystdout) { #if defined(_MSC_VER) && (_MSC_VER >= 1400) if (fopen_s(&file, "visualinfo.txt", "w") != 0) file = stdout; #else file = fopen("visualinfo.txt", "w"); #endif } if (file == NULL) file = stdout; #else file = stdout; #endif /* ---------------------------------------------------------------------- */ /* output header information */ /* OpenGL extensions */ fprintf(file, "OpenGL vendor string: %s\n", glGetString(GL_VENDOR)); fprintf(file, "OpenGL renderer string: %s\n", glGetString(GL_RENDERER)); fprintf(file, "OpenGL version string: %s\n", glGetString(GL_VERSION)); fprintf(file, "OpenGL extensions (GL_): \n"); PrintExtensions((char*)glGetString(GL_EXTENSIONS)); #ifndef GLEW_NO_GLU /* GLU extensions */ fprintf(file, "GLU version string: %s\n", gluGetString(GLU_VERSION)); fprintf(file, "GLU extensions (GLU_): \n"); PrintExtensions((char*)gluGetString(GLU_EXTENSIONS)); #endif /* ---------------------------------------------------------------------- */ /* extensions string */ #if defined(_WIN32) /* WGL extensions */ if (WGLEW_ARB_extensions_string || WGLEW_EXT_extensions_string) { fprintf(file, "WGL extensions (WGL_): \n"); PrintExtensions(wglGetExtensionsStringARB ? (char*)wglGetExtensionsStringARB(ctx.dc) : (char*)wglGetExtensionsStringEXT()); } #elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) #elif defined(__HAIKU__) /* TODO */ #else /* GLX extensions */ fprintf(file, "GLX extensions (GLX_): \n"); PrintExtensions(glXQueryExtensionsString(glXGetCurrentDisplay(), DefaultScreen(glXGetCurrentDisplay()))); #endif /* ---------------------------------------------------------------------- */ /* enumerate all the formats */ VisualInfo(&ctx); /* ---------------------------------------------------------------------- */ /* release resources */ DestroyContext(&ctx); if (file != stdout) fclose(file); return 0; } /* do the magic to separate all extensions with comma's, except for the last one that _may_ terminate in a space. */ void PrintExtensions (const char* s) { char t[80]; int i=0; char* p=0; t[79] = '\0'; while (*s) { t[i++] = *s; if(*s == ' ') { if (*(s+1) != '\0') { t[i-1] = ','; t[i] = ' '; p = &t[i++]; } else /* zoinks! last one terminated in a space! */ { t[i-1] = '\0'; } } if(i > 80 - 5) { *p = t[i] = '\0'; fprintf(file, " %s\n", t); p++; i = (int)strlen(p); #if defined(_MSC_VER) && (_MSC_VER >= 1400) strcpy_s(t, sizeof(t), p); #else strcpy(t, p); #endif } s++; } t[i] = '\0'; fprintf(file, " %s.\n", t); } /* ---------------------------------------------------------------------- */ #if defined(_WIN32) void VisualInfoARB (GLContext* ctx) { int attrib[32], value[32], n_attrib, n_pbuffer=0, n_float=0; int i, pf, maxpf; unsigned int c; /* to get pbuffer capable pixel formats */ attrib[0] = WGL_DRAW_TO_PBUFFER_ARB; attrib[1] = GL_TRUE; attrib[2] = 0; wglChoosePixelFormatARB(ctx->dc, attrib, 0, 1, &pf, &c); /* query number of pixel formats */ attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB; wglGetPixelFormatAttribivARB(ctx->dc, 0, 0, 1, attrib, value); maxpf = value[0]; for (i=0; i<32; i++) value[i] = 0; attrib[0] = WGL_SUPPORT_OPENGL_ARB; attrib[1] = WGL_DRAW_TO_WINDOW_ARB; attrib[2] = WGL_DRAW_TO_BITMAP_ARB; attrib[3] = WGL_ACCELERATION_ARB; /* WGL_NO_ACCELERATION_ARB, WGL_GENERIC_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB */ attrib[4] = WGL_SWAP_METHOD_ARB; /* WGL_SWAP_EXCHANGE_ARB, WGL_SWAP_COPY_ARB, WGL_SWAP_UNDEFINED_ARB */ attrib[5] = WGL_DOUBLE_BUFFER_ARB; attrib[6] = WGL_STEREO_ARB; attrib[7] = WGL_PIXEL_TYPE_ARB; /* WGL_TYPE_RGBA_ARB, WGL_TYPE_COLORINDEX_ARB, WGL_TYPE_RGBA_FLOAT_ATI (WGL_ATI_pixel_format_float) */ /* Color buffer information */ attrib[8] = WGL_COLOR_BITS_ARB; attrib[9] = WGL_RED_BITS_ARB; attrib[10] = WGL_GREEN_BITS_ARB; attrib[11] = WGL_BLUE_BITS_ARB; attrib[12] = WGL_ALPHA_BITS_ARB; /* Accumulation buffer information */ attrib[13] = WGL_ACCUM_BITS_ARB; attrib[14] = WGL_ACCUM_RED_BITS_ARB; attrib[15] = WGL_ACCUM_GREEN_BITS_ARB; attrib[16] = WGL_ACCUM_BLUE_BITS_ARB; attrib[17] = WGL_ACCUM_ALPHA_BITS_ARB; /* Depth, stencil, and aux buffer information */ attrib[18] = WGL_DEPTH_BITS_ARB; attrib[19] = WGL_STENCIL_BITS_ARB; attrib[20] = WGL_AUX_BUFFERS_ARB; /* Layer information */ attrib[21] = WGL_NUMBER_OVERLAYS_ARB; attrib[22] = WGL_NUMBER_UNDERLAYS_ARB; attrib[23] = WGL_SWAP_LAYER_BUFFERS_ARB; attrib[24] = WGL_SAMPLES_ARB; attrib[25] = WGL_SUPPORT_GDI_ARB; n_attrib = 26; if (WGLEW_ARB_pbuffer) { attrib[n_attrib] = WGL_DRAW_TO_PBUFFER_ARB; n_pbuffer = n_attrib; n_attrib++; } if (WGLEW_NV_float_buffer) { attrib[n_attrib] = WGL_FLOAT_COMPONENTS_NV; n_float = n_attrib; n_attrib++; } if (!verbose) { /* print table header */ fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { wglGetPixelFormatAttribivARB(ctx->dc, i, 0, n_attrib, attrib, value); /* only describe this format if it supports OpenGL */ if (!value[0]) continue; /* by default show only fully accelerated window or pbuffer capable visuals */ if (!showall && ((value[2] && !value[1]) || (!WGLEW_ARB_pbuffer || !value[n_pbuffer]) || (value[3] != WGL_FULL_ACCELERATION_ARB))) continue; /* print out the information for this visual */ /* visual id */ fprintf(file, " |% 4d | ", i); /* visual type */ if (value[1]) { if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "wp "); else fprintf(file, "wn "); } else { if (value[2]) fprintf(file, "bm "); else if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "pb "); } /* acceleration */ fprintf(file, "%s ", value[3] == WGL_FULL_ACCELERATION_ARB ? "fu" : value[3] == WGL_GENERIC_ACCELERATION_ARB ? "ge" : value[3] == WGL_NO_ACCELERATION_ARB ? "no" : ". "); /* gdi support */ fprintf(file, " %c ", value[25] ? 'y' : '.'); /* format */ if (WGLEW_NV_float_buffer && value[n_float]) fprintf(file, " f "); else if (WGLEW_ATI_pixel_format_float && value[7] == WGL_TYPE_RGBA_FLOAT_ATI) fprintf(file, " f "); else if (value[7] == WGL_TYPE_RGBA_ARB) fprintf(file, " i "); else if (value[7] == WGL_TYPE_COLORINDEX_ARB) fprintf(file, " c "); else if (value[7] == WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT) fprintf(file," p "); else fprintf(file," ? "); /* double buffer */ fprintf(file, " %c ", value[5] ? 'y' : '.'); /* swap method */ if (value[4] == WGL_SWAP_EXCHANGE_ARB) fprintf(file, " x "); else if (value[4] == WGL_SWAP_COPY_ARB) fprintf(file, " c "); else if (value[4] == WGL_SWAP_UNDEFINED_ARB) fprintf(file, " . "); else fprintf(file, " . "); /* stereo */ fprintf(file, " %c ", value[6] ? 'y' : '.'); /* multisample */ if (value[24] > 0) fprintf(file, "%2d | ", value[24]); else fprintf(file, " . | "); /* color size */ if (value[8]) fprintf(file, "%3d ", value[8]); else fprintf(file, " . "); /* red */ if (value[9]) fprintf(file, "%2d ", value[9]); else fprintf(file, " . "); /* green */ if (value[10]) fprintf(file, "%2d ", value[10]); else fprintf(file, " . "); /* blue */ if (value[11]) fprintf(file, "%2d ", value[11]); else fprintf(file, " . "); /* alpha */ if (value[12]) fprintf(file, "%2d | ", value[12]); else fprintf(file, " . | "); /* aux buffers */ if (value[20]) fprintf(file, "%2d ", value[20]); else fprintf(file, " . "); /* depth */ if (value[18]) fprintf(file, "%2d ", value[18]); else fprintf(file, " . "); /* stencil */ if (value[19]) fprintf(file, "%2d | ", value[19]); else fprintf(file, " . | "); /* accum size */ if (value[13]) fprintf(file, "%3d ", value[13]); else fprintf(file, " . "); /* accum red */ if (value[14]) fprintf(file, "%2d ", value[14]); else fprintf(file, " . "); /* accum green */ if (value[15]) fprintf(file, "%2d ", value[15]); else fprintf(file, " . "); /* accum blue */ if (value[16]) fprintf(file, "%2d ", value[16]); else fprintf(file, " . "); /* accum alpha */ if (value[17]) fprintf(file, "%2d | ", value[17]); else fprintf(file, " . | "); /* overlay */ if (value[21]) fprintf(file, "%2d ", value[21]); else fprintf(file, " . "); /* underlay */ if (value[22]) fprintf(file, "%2d ", value[22]); else fprintf(file, " . "); /* layer swap */ if (value[23]) fprintf(file, "y "); else fprintf(file, " . "); fprintf(file, "|\n"); } /* print table footer */ fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); } else /* verbose */ { #if 0 fprintf(file, "\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); 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); fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); fprintf(file, " Opaque.\n"); } #endif } } void VisualInfoGDI (GLContext* ctx) { int i, maxpf; PIXELFORMATDESCRIPTOR pfd; /* calling DescribePixelFormat() with NULL pfd (!!!) return maximum number of pixel formats */ maxpf = DescribePixelFormat(ctx->dc, 1, 0, NULL); if (!verbose) { fprintf(file, "-----------------------------------------------------------------------------\n"); fprintf(file, " visual x bf lv rg d st ge ge r g b a ax dp st accum buffs ms \n"); 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"); fprintf(file, "-----------------------------------------------------------------------------\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || (drawableonly && (pfd.dwFlags & PFD_DRAW_TO_BITMAP))) continue; /* other criteria could be tested here for actual pixel format choosing in an application: for (...each pixel format...) { if (pfd.dwFlags & PFD_SUPPORT_OPENGL && pfd.dwFlags & PFD_DOUBLEBUFFER && pfd.cDepthBits >= 24 && pfd.cColorBits >= 24) { goto found; } } ... not found so exit ... found: ... found so use it ... */ /* print out the information for this pixel format */ fprintf(file, "0x%02x ", i); fprintf(file, "%3d ", pfd.cColorBits); if(pfd.dwFlags & PFD_DRAW_TO_WINDOW) fprintf(file, "wn "); else if(pfd.dwFlags & PFD_DRAW_TO_BITMAP) fprintf(file, "bm "); else fprintf(file, "pb "); /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ fprintf(file, " . "); fprintf(file, "%3d ", pfd.cColorBits); /* bReserved field indicates number of over/underlays */ if(pfd.bReserved) fprintf(file, " %d ", pfd.bReserved); else fprintf(file, " . "); fprintf(file, " %c ", pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); fprintf(file, "%c ", pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); fprintf(file, " %c ", pfd.dwFlags & PFD_STEREO ? 'y' : '.'); /* added: */ fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_FORMAT ? 'y' : '.'); fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_ACCELERATED ? 'y' : '.'); if(pfd.cRedBits && pfd.iPixelType == PFD_TYPE_RGBA) fprintf(file, "%2d ", pfd.cRedBits); else fprintf(file, " . "); if(pfd.cGreenBits && pfd.iPixelType == PFD_TYPE_RGBA) fprintf(file, "%2d ", pfd.cGreenBits); else fprintf(file, " . "); if(pfd.cBlueBits && pfd.iPixelType == PFD_TYPE_RGBA) fprintf(file, "%2d ", pfd.cBlueBits); else fprintf(file, " . "); if(pfd.cAlphaBits && pfd.iPixelType == PFD_TYPE_RGBA) fprintf(file, "%2d ", pfd.cAlphaBits); else fprintf(file, " . "); if(pfd.cAuxBuffers) fprintf(file, "%2d ", pfd.cAuxBuffers); else fprintf(file, " . "); if(pfd.cDepthBits) fprintf(file, "%2d ", pfd.cDepthBits); else fprintf(file, " . "); if(pfd.cStencilBits) fprintf(file, "%2d ", pfd.cStencilBits); else fprintf(file, " . "); if(pfd.cAccumBits) fprintf(file, "%3d ", pfd.cAccumBits); else fprintf(file, " . "); if(pfd.cAccumRedBits) fprintf(file, "%2d ", pfd.cAccumRedBits); else fprintf(file, " . "); if(pfd.cAccumGreenBits) fprintf(file, "%2d ", pfd.cAccumGreenBits); else fprintf(file, " . "); if(pfd.cAccumBlueBits) fprintf(file, "%2d ", pfd.cAccumBlueBits); else fprintf(file, " . "); if(pfd.cAccumAlphaBits) fprintf(file, "%2d ", pfd.cAccumAlphaBits); else fprintf(file, " . "); /* no multisample in win32 */ fprintf(file, " . .\n"); } /* print table footer */ fprintf(file, "-----------------------------------------------------------------------------\n"); fprintf(file, " visual x bf lv rg d st ge ge r g b a ax dp st accum buffs ms \n"); 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"); fprintf(file, "-----------------------------------------------------------------------------\n"); } else /* verbose */ { fprintf(file, "\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); fprintf(file, " bufferSize=%d level=%d renderType=%s doubleBuffer=%ld stereo=%ld\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); fprintf(file, " Opaque.\n"); } } } void VisualInfo (GLContext* ctx) { if (WGLEW_ARB_pixel_format) VisualInfoARB(ctx); else VisualInfoGDI(ctx); } /* ---------------------------------------------------------------------- */ #elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) void VisualInfo (GLContext* __attribute__((__unused__)) ctx) { /* int attrib[] = { AGL_RGBA, AGL_NONE }; AGLPixelFormat pf; GLint value; pf = aglChoosePixelFormat(NULL, 0, attrib); while (pf != NULL) { aglDescribePixelFormat(pf, GL_RGBA, &value); fprintf(stderr, "%d\n", value); pf = aglNextPixelFormat(pf); } */ } /* ---------------------------------------------------------------------- */ #elif defined(__HAIKU__) void VisualInfo (GLContext* ctx) { /* TODO */ } #else /* GLX */ void VisualInfo (GLContext* ctx) { int n_fbc; GLXFBConfig* fbc; int value, ret, i; fbc = glXGetFBConfigs(ctx->dpy, DefaultScreen(ctx->dpy), &n_fbc); if (fbc) { if (!verbose) { /* print table header */ fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); fprintf(file, " | | visual | color | ax dp st | accum | ms | cav |\n"); fprintf(file, " | id | tp xr cl fm db st lv xp | sz r g b a | bf th cl | r g b a | ns b | eat |\n"); fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); /* loop through all the fbcs */ for (i=0; idpy, fbc[i], GLX_FBCONFIG_ID, &value); if (ret != Success) { fprintf(file, "| ? |"); } else { fprintf(file, " |% 4d | ", value); } /* visual type */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DRAWABLE_TYPE, &value); if (ret != Success) { fprintf(file, " ? "); } else { if (value & GLX_WINDOW_BIT) { if (value & GLX_PBUFFER_BIT) { fprintf(file, "wp "); } else { fprintf(file, "wn "); } } else { if (value & GLX_PBUFFER_BIT) { fprintf(file, "pb "); } else if (value & GLX_PIXMAP_BIT) { fprintf(file, "pm "); } else { fprintf(file, " ? "); } } } /* x renderable */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_X_RENDERABLE, &value); if (ret != Success) { fprintf(file, " ? "); } else { fprintf(file, value ? " y " : " n "); } /* class */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_X_VISUAL_TYPE, &value); if (ret != Success) { fprintf(file, " ? "); } else { if (GLX_TRUE_COLOR == value) fprintf(file, "tc "); else if (GLX_DIRECT_COLOR == value) fprintf(file, "dc "); else if (GLX_PSEUDO_COLOR == value) fprintf(file, "pc "); else if (GLX_STATIC_COLOR == value) fprintf(file, "sc "); else if (GLX_GRAY_SCALE == value) fprintf(file, "gs "); else if (GLX_STATIC_GRAY == value) fprintf(file, "sg "); else if (GLX_X_VISUAL_TYPE == value) fprintf(file, " . "); else fprintf(file, " ? "); } /* format */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_RENDER_TYPE, &value); if (ret != Success) { fprintf(file, " ? "); } else { if (GLXEW_NV_float_buffer) { int ret2, value2; ret2 = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_FLOAT_COMPONENTS_NV, &value2); if (Success == ret2 && GL_TRUE == value2) { fprintf(file, " f "); } else if (value & GLX_RGBA_BIT) fprintf(file, " i "); else if (value & GLX_COLOR_INDEX_BIT) fprintf(file, " c "); else fprintf(file, " ? "); } else { if (value & GLX_RGBA_FLOAT_ATI_BIT) fprintf(file, " f "); else if (value & GLX_RGBA_BIT) fprintf(file, " i "); else if (value & GLX_COLOR_INDEX_BIT) fprintf(file, " c "); else fprintf(file, " ? "); } } /* double buffer */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DOUBLEBUFFER, &value); fprintf(file, " %c ", Success != ret ? '?' : (value ? 'y' : '.')); /* stereo */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_STEREO, &value); fprintf(file, " %c ", Success != ret ? '?' : (value ? 'y' : '.')); /* level */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_LEVEL, &value); if (Success != ret) { fprintf(file, " ? "); } else { fprintf(file, "%2d ", value); } /* transparency */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_TRANSPARENT_TYPE, &value); if (Success != ret) { fprintf(file, " ? | "); } else { if (GLX_TRANSPARENT_RGB == value) fprintf(file, " r | "); else if (GLX_TRANSPARENT_INDEX == value) fprintf(file, " i | "); else if (GLX_NONE == value) fprintf(file, " . | "); else fprintf(file, " ? | "); } /* color size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_BUFFER_SIZE, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%3d ", value); else fprintf(file, " . "); } /* red size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_RED_SIZE, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%2d ", value); else fprintf(file, " . "); } /* green size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_GREEN_SIZE, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%2d ", value); else fprintf(file, " . "); } /* blue size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_BLUE_SIZE, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%2d ", value); else fprintf(file, " . "); } /* alpha size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ALPHA_SIZE, &value); if (Success != ret) { fprintf(file, " ? | "); } else { if (value) fprintf(file, "%2d | ", value); else fprintf(file, " . | "); } /* aux buffers */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_AUX_BUFFERS, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%2d ", value); else fprintf(file, " . "); } /* depth size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_DEPTH_SIZE, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%2d ", value); else fprintf(file, " . "); } /* stencil size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_STENCIL_SIZE, &value); if (Success != ret) { fprintf(file, " ? | "); } else { if (value) fprintf(file, "%2d | ", value); else fprintf(file, " . | "); } /* accum red size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_RED_SIZE, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%2d ", value); else fprintf(file, " . "); } /* accum green size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_GREEN_SIZE, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%2d ", value); else fprintf(file, " . "); } /* accum blue size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_BLUE_SIZE, &value); if (Success != ret) { fprintf(file, " ? "); } else { if (value) fprintf(file, "%2d ", value); else fprintf(file, " . "); } /* accum alpha size */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_ACCUM_ALPHA_SIZE, &value); if (Success != ret) { fprintf(file, " ? | "); } else { if (value) fprintf(file, "%2d | ", value); else fprintf(file, " . | "); } /* multisample */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_SAMPLES, &value); if (Success != ret) { fprintf(file, " ? "); } else { fprintf(file, "%2d ", value); } ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_SAMPLE_BUFFERS, &value); if (Success != ret) { fprintf(file, " ? | "); } else { fprintf(file, "%2d | ", value); } /* caveat */ ret = glXGetFBConfigAttrib(ctx->dpy, fbc[i], GLX_CONFIG_CAVEAT, &value); if (Success != ret) { fprintf(file, "???? |"); } else { if (GLX_NONE == value) fprintf(file, "none |\n"); else if (GLX_SLOW_CONFIG == value) fprintf(file, "slow |\n"); else if (GLX_NON_CONFORMANT_CONFIG == value) fprintf(file, "ncft |\n"); else fprintf(file, "???? |\n"); } } /* print table footer */ fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); fprintf(file, " | id | tp xr cl fm db st lv xp | sz r g b a | bf th cl | r g b a | ns b | eat |\n"); fprintf(file, " | | visual | color | ax dp st | accum | ms | cav |\n"); fprintf(file, " +-----+-------------------------+-----------------+----------+-------------+-------+------+\n"); } } } #endif /* ------------------------------------------------------------------------ */ #if defined(_WIN32) void InitContext (GLContext* ctx) { ctx->wnd = NULL; ctx->dc = NULL; ctx->rc = NULL; } GLboolean CreateContext (GLContext* ctx) { WNDCLASS wc; PIXELFORMATDESCRIPTOR pfd; /* check for input */ if (NULL == ctx) return GL_TRUE; /* register window class */ ZeroMemory(&wc, sizeof(WNDCLASS)); wc.hInstance = GetModuleHandle(NULL); wc.lpfnWndProc = DefWindowProc; wc.lpszClassName = "GLEW"; if (0 == RegisterClass(&wc)) return GL_TRUE; /* create window */ ctx->wnd = CreateWindow("GLEW", "GLEW", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, GetModuleHandle(NULL), NULL); if (NULL == ctx->wnd) return GL_TRUE; /* get the device context */ ctx->dc = GetDC(ctx->wnd); if (NULL == ctx->dc) return GL_TRUE; /* find pixel format */ ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); if (visual == -1) /* find default */ { pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; visual = ChoosePixelFormat(ctx->dc, &pfd); if (0 == visual) return GL_TRUE; } /* set the pixel format for the dc */ if (FALSE == SetPixelFormat(ctx->dc, visual, &pfd)) return GL_TRUE; /* create rendering context */ ctx->rc = wglCreateContext(ctx->dc); if (NULL == ctx->rc) return GL_TRUE; if (FALSE == wglMakeCurrent(ctx->dc, ctx->rc)) return GL_TRUE; return GL_FALSE; } void DestroyContext (GLContext* ctx) { if (NULL == ctx) return; if (NULL != ctx->rc) wglMakeCurrent(NULL, NULL); if (NULL != ctx->rc) wglDeleteContext(wglGetCurrentContext()); if (NULL != ctx->wnd && NULL != ctx->dc) ReleaseDC(ctx->wnd, ctx->dc); if (NULL != ctx->wnd) DestroyWindow(ctx->wnd); UnregisterClass("GLEW", GetModuleHandle(NULL)); } /* ------------------------------------------------------------------------ */ #elif defined(__APPLE__) && !defined(GLEW_APPLE_GLX) void InitContext (GLContext* ctx) { ctx->ctx = NULL; ctx->octx = NULL; } GLboolean CreateContext (GLContext* ctx) { int attrib[] = { AGL_RGBA, AGL_NONE }; AGLPixelFormat pf; /* check input */ if (NULL == ctx) return GL_TRUE; /*int major, minor; SetPortWindowPort(wnd); aglGetVersion(&major, &minor); fprintf(stderr, "GL %d.%d\n", major, minor);*/ pf = aglChoosePixelFormat(NULL, 0, attrib); if (NULL == pf) return GL_TRUE; ctx->ctx = aglCreateContext(pf, NULL); if (NULL == ctx->ctx || AGL_NO_ERROR != aglGetError()) return GL_TRUE; aglDestroyPixelFormat(pf); /*aglSetDrawable(ctx, GetWindowPort(wnd));*/ ctx->octx = aglGetCurrentContext(); if (GL_FALSE == aglSetCurrentContext(ctx->ctx)) return GL_TRUE; return GL_FALSE; } void DestroyContext (GLContext* ctx) { if (NULL == ctx) return; aglSetCurrentContext(ctx->octx); if (NULL != ctx->ctx) aglDestroyContext(ctx->ctx); } /* ------------------------------------------------------------------------ */ #elif defined(__HAIKU__) void InitContext (GLContext* ctx) { /* TODO */ } GLboolean CreateContext (GLContext* ctx) { /* TODO */ return GL_FALSE; } void DestroyContext (GLContext* ctx) { /* TODO */ } /* ------------------------------------------------------------------------ */ #else /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ void InitContext (GLContext* ctx) { ctx->dpy = NULL; ctx->vi = NULL; ctx->ctx = NULL; ctx->wnd = 0; ctx->cmap = 0; } GLboolean CreateContext (GLContext* ctx) { int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; int erb, evb; XSetWindowAttributes swa; /* check input */ if (NULL == ctx) return GL_TRUE; /* open display */ ctx->dpy = XOpenDisplay(display); if (NULL == ctx->dpy) return GL_TRUE; /* query for glx */ if (!glXQueryExtension(ctx->dpy, &erb, &evb)) return GL_TRUE; /* choose visual */ ctx->vi = glXChooseVisual(ctx->dpy, DefaultScreen(ctx->dpy), attrib); if (NULL == ctx->vi) return GL_TRUE; /* create context */ ctx->ctx = glXCreateContext(ctx->dpy, ctx->vi, None, True); if (NULL == ctx->ctx) return GL_TRUE; /* create window */ /*wnd = XCreateSimpleWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, 1, 1, 1, 0, 0);*/ ctx->cmap = XCreateColormap(ctx->dpy, RootWindow(ctx->dpy, ctx->vi->screen), ctx->vi->visual, AllocNone); swa.border_pixel = 0; swa.colormap = ctx->cmap; ctx->wnd = XCreateWindow(ctx->dpy, RootWindow(ctx->dpy, ctx->vi->screen), 0, 0, 1, 1, 0, ctx->vi->depth, InputOutput, ctx->vi->visual, CWBorderPixel | CWColormap, &swa); /* make context current */ if (!glXMakeCurrent(ctx->dpy, ctx->wnd, ctx->ctx)) return GL_TRUE; return GL_FALSE; } void DestroyContext (GLContext* ctx) { if (NULL != ctx->dpy && NULL != ctx->ctx) glXDestroyContext(ctx->dpy, ctx->ctx); if (NULL != ctx->dpy && 0 != ctx->wnd) XDestroyWindow(ctx->dpy, ctx->wnd); if (NULL != ctx->dpy && 0 != ctx->cmap) XFreeColormap(ctx->dpy, ctx->cmap); if (NULL != ctx->vi) XFree(ctx->vi); if (NULL != ctx->dpy) XCloseDisplay(ctx->dpy); } #endif /* __UNIX || (__APPLE__ && GLEW_APPLE_GLX) */ GLboolean ParseArgs (int argc, char** argv) { int p = 0; while (p < argc) { #if defined(_WIN32) if (!strcmp(argv[p], "-pf") || !strcmp(argv[p], "-pixelformat")) { if (++p >= argc) return GL_TRUE; display = NULL; visual = strtol(argv[p], NULL, 0); } else if (!strcmp(argv[p], "-a")) { showall = 1; } else if (!strcmp(argv[p], "-s")) { displaystdout = 1; } else if (!strcmp(argv[p], "-h")) { return GL_TRUE; } else return GL_TRUE; #else if (!strcmp(argv[p], "-display")) { if (++p >= argc) return GL_TRUE; display = argv[p]; } else if (!strcmp(argv[p], "-visual")) { if (++p >= argc) return GL_TRUE; visual = (int)strtol(argv[p], NULL, 0); } else if (!strcmp(argv[p], "-h")) { return GL_TRUE; } else return GL_TRUE; #endif p++; } return GL_FALSE; }