/* Copyright (c) Nate Robins, 1997. */ /* This program is freely distributable without licensing fees and is provided without guarantee or warrantee expressed or implied. This program is -not- in the public domain. */ #include <stdio.h> #include "glutint.h" #include "win32_glx.h" /* global current HDC */ extern HDC XHDC; GLXContext glXCreateContext(Display * display, XVisualInfo * visinfo, GLXContext share, Bool direct) { /* KLUDGE: GLX really expects a display pointer to be passed in as the first parameter, but Win32 needs an HDC instead, so BE SURE that the global XHDC is set before calling this routine. */ HGLRC context; context = wglCreateContext(XHDC); #if 0 /* XXX GLUT doesn't support it now, so don't worry about display list and texture object sharing. */ if (share) { wglShareLists(share, context); } #endif /* Since direct rendering is implicit, the direct flag is ignored. */ return context; } int glXGetConfig(Display * display, XVisualInfo * visual, int attrib, int *value) { if (!visual) return GLX_BAD_VISUAL; switch (attrib) { case GLX_USE_GL: if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) { /* XXX Brad's Matrix Millenium II has problems creating color index windows in 24-bit mode (lead to GDI crash) and 32-bit mode (lead to black window). The cColorBits filed of the PIXELFORMATDESCRIPTOR returned claims to have 24 and 32 bits respectively of color indices. 2^24 and 2^32 are ridiculously huge writable colormaps. Assume that if we get back a color index PIXELFORMATDESCRIPTOR with 24 or more bits, the PIXELFORMATDESCRIPTOR doesn't really work and skip it. -mjk */ if (visual->iPixelType == PFD_TYPE_COLORINDEX && visual->cColorBits >= 24) { *value = 0; } else { *value = 1; } } else { *value = 0; } break; case GLX_BUFFER_SIZE: /* KLUDGE: if we're RGBA, return the number of bits/pixel, otherwise, return 8 (we guessed at 256 colors in CI mode). */ if (visual->iPixelType == PFD_TYPE_RGBA) *value = visual->cColorBits; else *value = 8; break; case GLX_LEVEL: /* The bReserved flag of the pfd contains the overlay/underlay info. */ *value = visual->bReserved; break; case GLX_RGBA: *value = visual->iPixelType == PFD_TYPE_RGBA; break; case GLX_DOUBLEBUFFER: *value = visual->dwFlags & PFD_DOUBLEBUFFER; break; case GLX_STEREO: *value = visual->dwFlags & PFD_STEREO; break; case GLX_AUX_BUFFERS: *value = visual->cAuxBuffers; break; case GLX_RED_SIZE: *value = visual->cRedBits; break; case GLX_GREEN_SIZE: *value = visual->cGreenBits; break; case GLX_BLUE_SIZE: *value = visual->cBlueBits; break; case GLX_ALPHA_SIZE: *value = visual->cAlphaBits; break; case GLX_DEPTH_SIZE: *value = visual->cDepthBits; break; case GLX_STENCIL_SIZE: *value = visual->cStencilBits; break; case GLX_ACCUM_RED_SIZE: *value = visual->cAccumRedBits; break; case GLX_ACCUM_GREEN_SIZE: *value = visual->cAccumGreenBits; break; case GLX_ACCUM_BLUE_SIZE: *value = visual->cAccumBlueBits; break; case GLX_ACCUM_ALPHA_SIZE: *value = visual->cAccumAlphaBits; break; default: return GLX_BAD_ATTRIB; } return 0; } XVisualInfo * glXChooseVisual(Display * display, int screen, int *attribList) { /* KLUDGE: since we need the HDC, MAKE SURE to set XHDC before calling this routine. */ int *p = attribList; int pf; PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR *match = NULL; int stereo = 0; /* Avoid seg-faults. */ if (!p) return NULL; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = (sizeof(PIXELFORMATDESCRIPTOR)); pfd.nVersion = 1; /* Defaults. */ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; pfd.iPixelType = PFD_TYPE_COLORINDEX; pfd.cColorBits = 32; pfd.cDepthBits = 0; while (*p) { switch (*p) { case GLX_USE_GL: pfd.dwFlags |= PFD_SUPPORT_OPENGL; break; case GLX_BUFFER_SIZE: pfd.cColorBits = *(++p); break; case GLX_LEVEL: /* the bReserved flag of the pfd contains the overlay/underlay info. */ pfd.bReserved = *(++p); break; case GLX_RGBA: pfd.iPixelType = PFD_TYPE_RGBA; break; case GLX_DOUBLEBUFFER: pfd.dwFlags |= PFD_DOUBLEBUFFER; break; case GLX_STEREO: stereo = 1; pfd.dwFlags |= PFD_STEREO; break; case GLX_AUX_BUFFERS: pfd.cAuxBuffers = *(++p); break; case GLX_RED_SIZE: pfd.cRedBits = 8; /* Try to get the maximum. */ ++p; break; case GLX_GREEN_SIZE: pfd.cGreenBits = 8; ++p; break; case GLX_BLUE_SIZE: pfd.cBlueBits = 8; ++p; break; case GLX_ALPHA_SIZE: pfd.cAlphaBits = 8; ++p; break; case GLX_DEPTH_SIZE: pfd.cDepthBits = 32; ++p; break; case GLX_STENCIL_SIZE: pfd.cStencilBits = *(++p); break; case GLX_ACCUM_RED_SIZE: case GLX_ACCUM_GREEN_SIZE: case GLX_ACCUM_BLUE_SIZE: case GLX_ACCUM_ALPHA_SIZE: /* I believe that WGL only used the cAccumRedBits, cAccumBlueBits, cAccumGreenBits, and cAccumAlphaBits fields when returning info about the accumulation buffer precision. Only cAccumBits is used for requesting an accumulation buffer. */ pfd.cAccumBits = 1; ++p; break; } ++p; } /* Let Win32 choose one for us. */ pf = ChoosePixelFormat(XHDC, &pfd); if (pf > 0) { match = (PIXELFORMATDESCRIPTOR *) malloc(sizeof(PIXELFORMATDESCRIPTOR)); DescribePixelFormat(XHDC, pf, sizeof(PIXELFORMATDESCRIPTOR), match); /* ChoosePixelFormat is dumb in that it will return a pixel format that doesn't have stereo even if it was requested so we need to make sure that if stereo was selected, we got it. */ if (stereo) { if (!(match->dwFlags & PFD_STEREO)) { free(match); return NULL; } } /* XXX Brad's Matrix Millenium II has problems creating color index windows in 24-bit mode (lead to GDI crash) and 32-bit mode (lead to black window). The cColorBits filed of the PIXELFORMATDESCRIPTOR returned claims to have 24 and 32 bits respectively of color indices. 2^24 and 2^32 are ridiculously huge writable colormaps. Assume that if we get back a color index PIXELFORMATDESCRIPTOR with 24 or more bits, the PIXELFORMATDESCRIPTOR doesn't really work and skip it. -mjk */ if (match->iPixelType == PFD_TYPE_COLORINDEX && match->cColorBits >= 24) { free(match); return NULL; } } return match; }