mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-26 22:00:33 +05:00
596 lines
20 KiB
C
596 lines
20 KiB
C
|
/* $Id: toglWGL.c,v 1.8 2009/12/23 21:50:49 gregcouch Exp $ */
|
||
|
|
||
|
/* vi:set sw=4 expandtab: */
|
||
|
|
||
|
/*
|
||
|
* Togl - a Tk OpenGL widget
|
||
|
*
|
||
|
* Copyright (C) 1996-2002 Brian Paul and Ben Bederson
|
||
|
* Copyright (C) 2005-2009 Greg Couch
|
||
|
* See the LICENSE file for copyright details.
|
||
|
*/
|
||
|
|
||
|
/* TODO: fullscreen support */
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <GL/gl.h>
|
||
|
#include <wingdi.h>
|
||
|
#include <tk.h>
|
||
|
#include <tkPlatDecls.h>
|
||
|
#include <GL/wglext.h>
|
||
|
|
||
|
#ifndef PFD_SUPPORT_COMPOSITION
|
||
|
/* for Vista -- not needed because we don't use PFD_SUPPORT_GDI/BITMAP */
|
||
|
# define PFD_SUPPORT_COMPOSITION 0x00008000
|
||
|
#endif
|
||
|
|
||
|
/* TODO: move these statics into global structure */
|
||
|
static PFNWGLGETEXTENSIONSSTRINGARBPROC getExtensionsString = NULL;
|
||
|
static PFNWGLCHOOSEPIXELFORMATARBPROC choosePixelFormat;
|
||
|
static PFNWGLGETPIXELFORMATATTRIBIVARBPROC getPixelFormatAttribiv;
|
||
|
static PFNWGLCREATEPBUFFERARBPROC createPbuffer = NULL;
|
||
|
static PFNWGLDESTROYPBUFFERARBPROC destroyPbuffer = NULL;
|
||
|
static PFNWGLGETPBUFFERDCARBPROC getPbufferDC = NULL;
|
||
|
static PFNWGLRELEASEPBUFFERDCARBPROC releasePbufferDC = NULL;
|
||
|
static PFNWGLQUERYPBUFFERARBPROC queryPbuffer = NULL;
|
||
|
static int hasMultisampling = FALSE;
|
||
|
static int hasPbuffer = FALSE;
|
||
|
static int hasARBPbuffer = FALSE;
|
||
|
|
||
|
static HWND
|
||
|
toglCreateTestWindow(HWND parent)
|
||
|
{
|
||
|
static char ClassName[] = "ToglTestWindow";
|
||
|
WNDCLASS wc;
|
||
|
HINSTANCE instance = GetModuleHandle(NULL);
|
||
|
HWND wnd;
|
||
|
HDC dc;
|
||
|
PIXELFORMATDESCRIPTOR pfd;
|
||
|
int pixelFormat;
|
||
|
|
||
|
wc.style = CS_OWNDC;
|
||
|
wc.lpfnWndProc = DefWindowProc;
|
||
|
wc.cbClsExtra = 0;
|
||
|
wc.cbWndExtra = 0;
|
||
|
wc.hInstance = instance;
|
||
|
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
|
wc.hbrBackground = NULL;
|
||
|
wc.lpszMenuName = NULL;
|
||
|
wc.lpszClassName = ClassName;
|
||
|
if (!RegisterClass(&wc)) {
|
||
|
DWORD err = GetLastError();
|
||
|
|
||
|
if (err != ERROR_CLASS_ALREADY_EXISTS) {
|
||
|
fprintf(stderr, "Unable to register Togl Test Window class\n");
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
wnd = CreateWindow(ClassName, "test OpenGL capabilities",
|
||
|
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||
|
0, 0, 1, 1, parent, NULL, instance, NULL);
|
||
|
if (wnd == NULL) {
|
||
|
fprintf(stderr, "Unable to create temporary OpenGL window\n");
|
||
|
return NULL;
|
||
|
}
|
||
|
dc = GetDC(wnd);
|
||
|
|
||
|
memset(&pfd, 0, sizeof pfd);
|
||
|
pfd.nSize = sizeof pfd;
|
||
|
pfd.nVersion = 1;
|
||
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
||
|
pfd.cColorBits = 3;
|
||
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
||
|
pixelFormat = ChoosePixelFormat(dc, &pfd);
|
||
|
if (pixelFormat == 0) {
|
||
|
fprintf(stderr, "Unable to choose simple pixel format\n");
|
||
|
ReleaseDC(wnd, dc);
|
||
|
return NULL;
|
||
|
}
|
||
|
if (!SetPixelFormat(dc, pixelFormat, &pfd)) {
|
||
|
fprintf(stderr, "Unable to set simple pixel format\n");
|
||
|
ReleaseDC(wnd, dc);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
ShowWindow(wnd, SW_HIDE); // make sure it's hidden
|
||
|
ReleaseDC(wnd, dc);
|
||
|
return wnd;
|
||
|
}
|
||
|
|
||
|
struct FBInfo
|
||
|
{
|
||
|
int stereo;
|
||
|
int acceleration;
|
||
|
int colors;
|
||
|
int depth;
|
||
|
int samples;
|
||
|
int pixelFormat;
|
||
|
};
|
||
|
typedef struct FBInfo FBInfo;
|
||
|
static int FBAttribs[] = {
|
||
|
/* must match order in FBInfo structure */
|
||
|
WGL_STEREO_ARB,
|
||
|
WGL_ACCELERATION_ARB,
|
||
|
WGL_COLOR_BITS_ARB,
|
||
|
WGL_DEPTH_BITS_ARB,
|
||
|
WGL_SAMPLES_ARB,
|
||
|
};
|
||
|
|
||
|
#define NUM_FBAttribs (sizeof FBAttribs / sizeof FBAttribs[0])
|
||
|
|
||
|
static int
|
||
|
FBInfoCmp(const void *a, const void *b)
|
||
|
{
|
||
|
/*
|
||
|
* 1. stereo is better
|
||
|
* 2. full acceleration is better
|
||
|
* 3. greater color bits is better
|
||
|
* 4. greater depth bits is better
|
||
|
* 5. more multisampling is better
|
||
|
*/
|
||
|
const FBInfo *x = (const FBInfo *) a;
|
||
|
const FBInfo *y = (const FBInfo *) b;
|
||
|
|
||
|
if (x->stereo != y->stereo)
|
||
|
return y->stereo - x->stereo;
|
||
|
if (x->acceleration != y->acceleration)
|
||
|
return y->acceleration - x->acceleration;
|
||
|
if (x->colors != y->colors)
|
||
|
return y->colors - x->colors;
|
||
|
if (x->depth != y->depth)
|
||
|
return y->depth - x->depth;
|
||
|
if (x->samples != y->samples)
|
||
|
return y->samples - x->samples;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
togl_pixelFormat(Togl *togl, HWND hwnd)
|
||
|
{
|
||
|
/* return 0 when pixel format is unavailable. */
|
||
|
int pixelformat = 0;
|
||
|
static int loadedOpenGL = FALSE;
|
||
|
int formats[256];
|
||
|
UINT numFormats;
|
||
|
FBInfo *info;
|
||
|
UINT i;
|
||
|
int attribs[128];
|
||
|
int na = 0;
|
||
|
|
||
|
if (!loadedOpenGL) {
|
||
|
HWND test = NULL;
|
||
|
HDC dc;
|
||
|
HGLRC rc;
|
||
|
|
||
|
if (wglGetCurrentContext() != NULL) {
|
||
|
dc = wglGetCurrentDC();
|
||
|
} else {
|
||
|
/* HWND hwnd = Tk_GetHWND(Tk_WindowId(togl->TkWin)); */
|
||
|
|
||
|
test = toglCreateTestWindow(hwnd);
|
||
|
if (test == NULL) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "can't create dummy OpenGL window",
|
||
|
TCL_STATIC);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
dc = GetDC(test);
|
||
|
rc = wglCreateContext(dc);
|
||
|
wglMakeCurrent(dc, rc);
|
||
|
}
|
||
|
loadedOpenGL = TRUE;
|
||
|
|
||
|
/*
|
||
|
* Now that we have an OpenGL window, we can initialize all
|
||
|
* OpenGL information and figure out if multisampling is supported.
|
||
|
*/
|
||
|
getExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
||
|
wglGetProcAddress("wglGetExtensionsStringARB");
|
||
|
if (getExtensionsString == NULL)
|
||
|
getExtensionsString = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
||
|
wglGetProcAddress("wglGetExtensionsStringEXT");
|
||
|
if (getExtensionsString) {
|
||
|
const char *extensions = getExtensionsString(dc);
|
||
|
|
||
|
if (strstr(extensions, "WGL_ARB_multisample") != NULL
|
||
|
|| strstr(extensions, "WGL_EXT_multisample") != NULL)
|
||
|
hasMultisampling = TRUE;
|
||
|
|
||
|
if (strstr(extensions, "WGL_ARB_pixel_format") != NULL) {
|
||
|
choosePixelFormat = (PFNWGLCHOOSEPIXELFORMATARBPROC)
|
||
|
wglGetProcAddress("wglChoosePixelFormatARB");
|
||
|
getPixelFormatAttribiv = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
||
|
wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||
|
if (choosePixelFormat == NULL || getPixelFormatAttribiv == NULL) {
|
||
|
choosePixelFormat = NULL;
|
||
|
getPixelFormatAttribiv = NULL;
|
||
|
}
|
||
|
}
|
||
|
if (choosePixelFormat == NULL
|
||
|
&& strstr(extensions, "WGL_EXT_pixel_format") != NULL) {
|
||
|
choosePixelFormat = (PFNWGLCHOOSEPIXELFORMATARBPROC)
|
||
|
wglGetProcAddress("wglChoosePixelFormatEXT");
|
||
|
getPixelFormatAttribiv = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
||
|
wglGetProcAddress("wglGetPixelFormatAttribivEXT");
|
||
|
if (choosePixelFormat == NULL || getPixelFormatAttribiv == NULL) {
|
||
|
choosePixelFormat = NULL;
|
||
|
getPixelFormatAttribiv = NULL;
|
||
|
}
|
||
|
}
|
||
|
if (createPbuffer == NULL
|
||
|
&& strstr(extensions, "WGL_ARB_pbuffer") != NULL) {
|
||
|
createPbuffer = (PFNWGLCREATEPBUFFERARBPROC)
|
||
|
wglGetProcAddress("wglCreatePbufferARB");
|
||
|
destroyPbuffer = (PFNWGLDESTROYPBUFFERARBPROC)
|
||
|
wglGetProcAddress("wglDestroyPbufferARB");
|
||
|
getPbufferDC = (PFNWGLGETPBUFFERDCARBPROC)
|
||
|
wglGetProcAddress("wglGetPbufferDCARB");
|
||
|
releasePbufferDC = (PFNWGLRELEASEPBUFFERDCARBPROC)
|
||
|
wglGetProcAddress("wglReleasePbufferDCARB");
|
||
|
queryPbuffer = (PFNWGLQUERYPBUFFERARBPROC)
|
||
|
wglGetProcAddress("wglQueryPbufferARB");
|
||
|
if (createPbuffer == NULL || destroyPbuffer == NULL
|
||
|
|| getPbufferDC == NULL || releasePbufferDC == NULL
|
||
|
|| queryPbuffer == NULL) {
|
||
|
createPbuffer = NULL;
|
||
|
destroyPbuffer = NULL;
|
||
|
getPbufferDC = NULL;
|
||
|
releasePbufferDC = NULL;
|
||
|
queryPbuffer = NULL;
|
||
|
} else {
|
||
|
hasPbuffer = TRUE;
|
||
|
hasARBPbuffer = TRUE;
|
||
|
}
|
||
|
}
|
||
|
if (createPbuffer == NULL
|
||
|
&& strstr(extensions, "WGL_EXT_pbuffer") != NULL) {
|
||
|
createPbuffer = (PFNWGLCREATEPBUFFERARBPROC)
|
||
|
wglGetProcAddress("wglCreatePbufferEXT");
|
||
|
destroyPbuffer = (PFNWGLDESTROYPBUFFERARBPROC)
|
||
|
wglGetProcAddress("wglDestroyPbufferEXT");
|
||
|
getPbufferDC = (PFNWGLGETPBUFFERDCARBPROC)
|
||
|
wglGetProcAddress("wglGetPbufferDCEXT");
|
||
|
releasePbufferDC = (PFNWGLRELEASEPBUFFERDCARBPROC)
|
||
|
wglGetProcAddress("wglReleasePbufferDCEXT");
|
||
|
queryPbuffer = (PFNWGLQUERYPBUFFERARBPROC)
|
||
|
wglGetProcAddress("wglQueryPbufferEXT");
|
||
|
if (createPbuffer == NULL || destroyPbuffer == NULL
|
||
|
|| getPbufferDC == NULL || releasePbufferDC == NULL
|
||
|
|| queryPbuffer == NULL) {
|
||
|
createPbuffer = NULL;
|
||
|
destroyPbuffer = NULL;
|
||
|
getPbufferDC = NULL;
|
||
|
releasePbufferDC = NULL;
|
||
|
queryPbuffer = NULL;
|
||
|
} else {
|
||
|
hasPbuffer = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* No need to confirm multisampling is in glGetString(GL_EXTENSIONS)
|
||
|
* because OpenGL driver is local */
|
||
|
|
||
|
if (test != NULL) {
|
||
|
/* cleanup by removing temporary OpenGL window */
|
||
|
wglMakeCurrent(NULL, NULL);
|
||
|
wglDeleteContext(rc);
|
||
|
ReleaseDC(test, dc);
|
||
|
DestroyWindow(test);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (togl->MultisampleFlag && !hasMultisampling) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "multisampling not supported", TCL_STATIC);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (togl->PbufferFlag && !hasPbuffer) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "pbuffers are not supported", TCL_STATIC);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (choosePixelFormat == NULL) {
|
||
|
PIXELFORMATDESCRIPTOR pfd;
|
||
|
|
||
|
/* Don't have the great wglChoosePixelFormatARB() function, so do it
|
||
|
* the old way. */
|
||
|
if (togl->MultisampleFlag) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "multisampling not supported", TCL_STATIC);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
memset(&pfd, 0, sizeof pfd);
|
||
|
pfd.nSize = sizeof pfd;
|
||
|
pfd.nVersion = 1;
|
||
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
|
||
|
| PFD_SUPPORT_COMPOSITION;
|
||
|
if (togl->DoubleFlag) {
|
||
|
pfd.dwFlags |= PFD_DOUBLEBUFFER;
|
||
|
}
|
||
|
if (togl->Stereo == TOGL_STEREO_NATIVE) {
|
||
|
pfd.dwFlags |= PFD_STEREO;
|
||
|
}
|
||
|
pfd.iPixelType = togl->RgbaFlag ? PFD_TYPE_RGBA : PFD_TYPE_COLORINDEX;
|
||
|
pfd.cColorBits = togl->RgbaRed + togl->RgbaGreen + togl->RgbaBlue;
|
||
|
/* Alpha bitplanes are not supported in the current generic OpenGL
|
||
|
* implementation, but may be supported by specific hardware devices. */
|
||
|
pfd.cAlphaBits = togl->AlphaFlag ? togl->AlphaSize : 0;
|
||
|
pfd.cAccumBits = togl->AccumFlag ? (togl->AccumRed + togl->AccumGreen +
|
||
|
togl->AccumBlue + togl->AccumAlpha) : 0;
|
||
|
pfd.cDepthBits = togl->DepthFlag ? togl->DepthSize : 0;
|
||
|
pfd.cStencilBits = togl->StencilFlag ? togl->StencilSize : 0;
|
||
|
/* Auxiliary buffers are not supported in the current generic OpenGL
|
||
|
* implementation, but may be supported by specific hardware devices. */
|
||
|
pfd.cAuxBuffers = togl->AuxNumber;
|
||
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
||
|
|
||
|
if ((pixelformat = ChoosePixelFormat(togl->tglGLHdc, &pfd)) == 0) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "couldn't choose pixel format", TCL_STATIC);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* double check that we got the stereo format we requested */
|
||
|
if (togl->Stereo == TOGL_STEREO_NATIVE) {
|
||
|
DescribePixelFormat(togl->tglGLHdc, pixelformat, sizeof (pfd),
|
||
|
&pfd);
|
||
|
if ((pfd.dwFlags & PFD_STEREO) == 0) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "couldn't choose stereo pixel format",
|
||
|
TCL_STATIC);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
return pixelformat;
|
||
|
}
|
||
|
// We have the new wglChoosePixelFormat!!
|
||
|
if (togl->MultisampleFlag && !hasMultisampling) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "multisampling not supported", TCL_STATIC);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (togl->PbufferFlag)
|
||
|
attribs[na++] = WGL_DRAW_TO_PBUFFER_ARB;
|
||
|
else
|
||
|
attribs[na++] = WGL_DRAW_TO_WINDOW_ARB;
|
||
|
attribs[na++] = GL_TRUE;
|
||
|
attribs[na++] = WGL_SUPPORT_OPENGL_ARB;
|
||
|
attribs[na++] = GL_TRUE;
|
||
|
attribs[na++] = WGL_PIXEL_TYPE_ARB;
|
||
|
if (!togl->RgbaFlag) {
|
||
|
attribs[na++] = WGL_TYPE_COLORINDEX_ARB;
|
||
|
} else {
|
||
|
attribs[na++] = WGL_TYPE_RGBA_ARB;
|
||
|
attribs[na++] = WGL_RED_BITS_ARB;
|
||
|
attribs[na++] = togl->RgbaRed;
|
||
|
attribs[na++] = WGL_GREEN_BITS_ARB;
|
||
|
attribs[na++] = togl->RgbaGreen;
|
||
|
attribs[na++] = WGL_BLUE_BITS_ARB;
|
||
|
attribs[na++] = togl->RgbaBlue;
|
||
|
if (togl->AlphaFlag) {
|
||
|
attribs[na++] = WGL_ALPHA_BITS_ARB;
|
||
|
attribs[na++] = togl->AlphaSize;
|
||
|
}
|
||
|
}
|
||
|
if (togl->DepthFlag) {
|
||
|
attribs[na++] = WGL_DEPTH_BITS_ARB;
|
||
|
attribs[na++] = togl->DepthSize;
|
||
|
}
|
||
|
if (togl->DoubleFlag) {
|
||
|
attribs[na++] = WGL_DOUBLE_BUFFER_ARB;
|
||
|
attribs[na++] = GL_TRUE;
|
||
|
}
|
||
|
if (togl->StencilFlag) {
|
||
|
attribs[na++] = WGL_STENCIL_BITS_ARB;
|
||
|
attribs[na++] = togl->StencilSize;
|
||
|
}
|
||
|
if (togl->AccumFlag) {
|
||
|
attribs[na++] = WGL_ACCUM_RED_BITS_ARB;
|
||
|
attribs[na++] = togl->AccumRed;
|
||
|
attribs[na++] = WGL_ACCUM_GREEN_BITS_ARB;
|
||
|
attribs[na++] = togl->AccumGreen;
|
||
|
attribs[na++] = WGL_ACCUM_BLUE_BITS_ARB;
|
||
|
attribs[na++] = togl->AccumBlue;
|
||
|
if (togl->AlphaFlag) {
|
||
|
attribs[na++] = WGL_ACCUM_ALPHA_BITS_ARB;
|
||
|
attribs[na++] = togl->AccumAlpha;
|
||
|
}
|
||
|
}
|
||
|
if (togl->Stereo == TOGL_STEREO_NATIVE) {
|
||
|
attribs[na++] = WGL_STEREO_ARB;
|
||
|
attribs[na++] = GL_TRUE;
|
||
|
}
|
||
|
if (togl->MultisampleFlag) {
|
||
|
attribs[na++] = WGL_SAMPLE_BUFFERS_ARB;
|
||
|
attribs[na++] = 1;
|
||
|
attribs[na++] = WGL_SAMPLES_ARB;
|
||
|
attribs[na++] = 2;
|
||
|
}
|
||
|
if (togl->AuxNumber) {
|
||
|
attribs[na++] = WGL_AUX_BUFFERS_ARB;
|
||
|
attribs[na++] = togl->AuxNumber;
|
||
|
}
|
||
|
attribs[na++] = 0; // must be last
|
||
|
|
||
|
if (!choosePixelFormat(togl->tglGLHdc, &attribs[0], NULL, 256, formats,
|
||
|
&numFormats) || numFormats == 0) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "couldn't choose pixel format", TCL_STATIC);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Pick best format
|
||
|
*/
|
||
|
info = (FBInfo *) malloc(numFormats * sizeof (FBInfo));
|
||
|
for (i = 0; i != numFormats; ++i) {
|
||
|
info[i].pixelFormat = formats[i];
|
||
|
getPixelFormatAttribiv(togl->tglGLHdc, formats[i], 0,
|
||
|
NUM_FBAttribs, FBAttribs, &info[i].stereo);
|
||
|
/* revise attributes so larger is better */
|
||
|
if (!togl->DepthFlag)
|
||
|
info[i].depth = -info[i].depth;
|
||
|
if (!togl->MultisampleFlag)
|
||
|
info[i].samples = -info[i].samples;
|
||
|
if (togl->Stereo != TOGL_STEREO_NATIVE)
|
||
|
info[i].stereo = -info[i].stereo;
|
||
|
}
|
||
|
qsort(info, numFormats, sizeof info[0], FBInfoCmp);
|
||
|
pixelformat = info[0].pixelFormat;
|
||
|
/* double check that we got the stereo format we requested */
|
||
|
if (togl->Stereo == TOGL_STEREO_NATIVE && !info[0].stereo) {
|
||
|
Tcl_SetResult(togl->Interp,
|
||
|
TCL_STUPID "couldn't choose stereo pixel format", TCL_STATIC);
|
||
|
free(info);
|
||
|
return 0;
|
||
|
}
|
||
|
free(info);
|
||
|
return pixelformat;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
togl_describePixelFormat(Togl *togl)
|
||
|
{
|
||
|
if (getPixelFormatAttribiv == NULL) {
|
||
|
PIXELFORMATDESCRIPTOR pfd;
|
||
|
|
||
|
DescribePixelFormat(togl->tglGLHdc, (int) togl->PixelFormat,
|
||
|
sizeof (pfd), &pfd);
|
||
|
/* fill in flags normally passed in that affect behavior */
|
||
|
togl->RgbaFlag = pfd.iPixelType == PFD_TYPE_RGBA;
|
||
|
togl->DoubleFlag = (pfd.dwFlags & PFD_DOUBLEBUFFER) != 0;
|
||
|
togl->DepthFlag = (pfd.cDepthBits != 0);
|
||
|
togl->AccumFlag = (pfd.cAccumBits != 0);
|
||
|
togl->AlphaFlag = (pfd.cAlphaBits != 0);
|
||
|
togl->StencilFlag = (pfd.cStencilBits != 0);
|
||
|
if ((pfd.dwFlags & PFD_STEREO) != 0)
|
||
|
togl->Stereo = TOGL_STEREO_NATIVE;
|
||
|
else
|
||
|
togl->Stereo = TOGL_STEREO_NONE;
|
||
|
} else {
|
||
|
static int attribs[] = {
|
||
|
WGL_PIXEL_TYPE_ARB,
|
||
|
WGL_DOUBLE_BUFFER_ARB,
|
||
|
WGL_DEPTH_BITS_ARB,
|
||
|
WGL_ACCUM_RED_BITS_ARB,
|
||
|
WGL_ALPHA_BITS_ARB,
|
||
|
WGL_STENCIL_BITS_ARB,
|
||
|
WGL_STEREO_ARB,
|
||
|
WGL_SAMPLES_ARB
|
||
|
};
|
||
|
#define NUM_ATTRIBS (sizeof attribs / sizeof attribs[0])
|
||
|
int info[NUM_ATTRIBS];
|
||
|
|
||
|
getPixelFormatAttribiv(togl->tglGLHdc, (int) togl->PixelFormat, 0,
|
||
|
NUM_ATTRIBS, attribs, info);
|
||
|
#undef NUM_ATTRIBS
|
||
|
togl->RgbaFlag = info[0];
|
||
|
togl->DoubleFlag = info[1];
|
||
|
togl->DepthFlag = (info[2] != 0);
|
||
|
togl->AccumFlag = (info[3] != 0);
|
||
|
togl->AlphaFlag = (info[4] != 0);
|
||
|
togl->StencilFlag = (info[5] != 0);
|
||
|
togl->Stereo = info[6] ? TOGL_STEREO_NATIVE : TOGL_STEREO_NONE;
|
||
|
togl->MultisampleFlag = (info[7] != 0);
|
||
|
}
|
||
|
return True;
|
||
|
}
|
||
|
|
||
|
static HPBUFFERARB
|
||
|
togl_createPbuffer(Togl *togl)
|
||
|
{
|
||
|
int attribs[32];
|
||
|
int na = 0;
|
||
|
HPBUFFERARB pbuf;
|
||
|
|
||
|
if (togl->LargestPbufferFlag) {
|
||
|
attribs[na++] = WGL_PBUFFER_LARGEST_ARB;
|
||
|
attribs[na++] = 1;
|
||
|
}
|
||
|
attribs[na] = 0;
|
||
|
pbuf = createPbuffer(togl->tglGLHdc, (int) togl->PixelFormat, togl->Width,
|
||
|
togl->Height, attribs);
|
||
|
if (pbuf && togl->LargestPbufferFlag) {
|
||
|
queryPbuffer(pbuf, WGL_PBUFFER_WIDTH_ARB, &togl->Width);
|
||
|
queryPbuffer(pbuf, WGL_PBUFFER_HEIGHT_ARB, &togl->Height);
|
||
|
}
|
||
|
return pbuf;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
togl_destroyPbuffer(Togl *togl)
|
||
|
{
|
||
|
destroyPbuffer(togl->pbuf);
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
// From nvidia.com
|
||
|
|
||
|
Multisampling requires WGL_ARB_extension_string and WGL_ARB_pixel_format
|
||
|
wglGetProcAddress("wglGetExtensionsStringARB")
|
||
|
// From msdn.microsoft.com, various ways to enumerate PixelFormats
|
||
|
void CPixForm::OnClickedLastPfd()
|
||
|
{
|
||
|
COpenGL gl;
|
||
|
PIXELFORMATDESCRIPTOR pfd;
|
||
|
|
||
|
//
|
||
|
// Get the hwnd of the view window.
|
||
|
//
|
||
|
HWND hwndview = GetViewHwnd();
|
||
|
|
||
|
//
|
||
|
// Get a DC associated with the view window.
|
||
|
//
|
||
|
HDC dc =::GetDC(hwndview);
|
||
|
int nID = (m_nNextID > 1) ? m_nNextID-- : 1;
|
||
|
|
||
|
//
|
||
|
// Get a description of the pixel format. If it is valid, then go and
|
||
|
// update the controls in the dialog box, otherwise do nothing.
|
||
|
//
|
||
|
if (gl.DescribePixelFormat(dc, nID, sizeof (PIXELFORMATDESCRIPTOR), &pfd))
|
||
|
UpdateDlg(&pfd);
|
||
|
//
|
||
|
// Release the DC.
|
||
|
//
|
||
|
::ReleaseDC(hwndview, dc);
|
||
|
}
|
||
|
|
||
|
----------------------
|
||
|
// local variables
|
||
|
int iMax;
|
||
|
PIXELFORMATDESCRIPTOR pfd;
|
||
|
int iPixelFormat;
|
||
|
|
||
|
// initialize a pixel format index variable
|
||
|
iPixelFormat = 1;
|
||
|
|
||
|
// keep obtaining and examining pixel format data...
|
||
|
do {
|
||
|
// try to obtain some pixel format data
|
||
|
iMax = DescribePixelFormat(dc, iPixelFormat, sizeof (pfd), &pfd);
|
||
|
|
||
|
// if there was some problem with that...
|
||
|
if (iMax == 0)
|
||
|
// return indicating failure
|
||
|
return (FALSE);
|
||
|
|
||
|
// we have successfully obtained pixel format data
|
||
|
|
||
|
// let's examine the pixel format data...
|
||
|
myPixelFormatExaminer(&pfd);
|
||
|
}
|
||
|
// ...until we've looked at all the device context's pixel formats
|
||
|
while (++iPixelFormat <= iMax);
|
||
|
#endif
|