#define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) WXUNUSED(name)
#endif
+// ----------------------------------------------------------------------------
+// define possibly missing WGL constants
+// ----------------------------------------------------------------------------
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
// ----------------------------------------------------------------------------
// libraries
// ----------------------------------------------------------------------------
return true;
}
+
+// ----------------------------------------------------------------------------
+// multi sample support
+// ----------------------------------------------------------------------------
+
+// this macro defines a variable of type "name_t" called "name" and initializes
+// it with the pointer to WGL function "name" (which may be NULL)
+#define wxDEFINE_WGL_FUNC(name) \
+ name##_t name = (name##_t)wglGetProcAddress(#name)
+
+/* static */
+bool wxGLCanvasBase::IsExtensionSupported(const char *extension)
+{
+ static const char *s_extensionsList = (char *)wxUIntPtr(-1);
+ if ( s_extensionsList == (char *)wxUIntPtr(-1) )
+ {
+ typedef const char * (WINAPI *wglGetExtensionsStringARB_t)(HDC hdc);
+
+ wxDEFINE_WGL_FUNC(wglGetExtensionsStringARB);
+ if ( wglGetExtensionsStringARB )
+ {
+ s_extensionsList = wglGetExtensionsStringARB(wglGetCurrentDC());
+ }
+ else
+ {
+ typedef const char * (WINAPI * wglGetExtensionsStringEXT_t)();
+
+ wxDEFINE_WGL_FUNC(wglGetExtensionsStringEXT);
+ if ( wglGetExtensionsStringEXT )
+ {
+ s_extensionsList = wglGetExtensionsStringEXT();
+ }
+ else
+ {
+ s_extensionsList = NULL;
+ }
+ }
+ }
+
+ return s_extensionsList && IsExtensionInList(s_extensionsList, extension);
+}
+
+// this is a wrapper around wglChoosePixelFormatARB(): returns the pixel format
+// index matching the given attributes on success or 0 on failure
+static int ChoosePixelFormatARB(HDC hdc, const int *attribList)
+{
+ if ( !wxGLCanvas::IsExtensionSupported("WGL_ARB_multisample") )
+ return 0;
+
+ typedef BOOL (WINAPI * wglChoosePixelFormatARB_t)
+ (HDC hdc,
+ const int *piAttribIList,
+ const FLOAT *pfAttribFList,
+ UINT nMaxFormats,
+ int *piFormats,
+ UINT *nNumFormats
+ );
+
+ wxDEFINE_WGL_FUNC(wglChoosePixelFormatARB);
+ if ( !wglChoosePixelFormatARB )
+ return 0; // should not occur if extension is supported
+
+ int iAttributes[128];
+ int dst = 0; // index in iAttributes array
+
+ #define ADD_ATTR(attr, value) \
+ iAttributes[dst++] = attr; iAttributes[dst++] = value
+
+ ADD_ATTR( WGL_DRAW_TO_WINDOW_ARB, GL_TRUE );
+ ADD_ATTR( WGL_SUPPORT_OPENGL_ARB, GL_TRUE );
+ ADD_ATTR( WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB );
+
+ if ( !attribList )
+ {
+ ADD_ATTR( WGL_COLOR_BITS_ARB, 24 );
+ ADD_ATTR( WGL_ALPHA_BITS_ARB, 8 );
+ ADD_ATTR( WGL_DEPTH_BITS_ARB, 16 );
+ ADD_ATTR( WGL_STENCIL_BITS_ARB, 0 );
+ ADD_ATTR( WGL_DOUBLE_BUFFER_ARB, GL_TRUE );
+ ADD_ATTR( WGL_SAMPLE_BUFFERS_ARB, GL_TRUE );
+ ADD_ATTR( WGL_SAMPLES_ARB, 4 );
+ }
+ else // have custom attributes
+ {
+ #define ADD_ATTR_VALUE(attr) ADD_ATTR(attr, attribList[src++])
+
+ int src = 0;
+ while ( attribList[src] )
+ {
+ switch ( attribList[src++] )
+ {
+ case WX_GL_RGBA:
+ ADD_ATTR( WGL_COLOR_BITS_ARB, 24 );
+ ADD_ATTR( WGL_ALPHA_BITS_ARB, 8 );
+ break;
+
+ case WX_GL_BUFFER_SIZE:
+ ADD_ATTR_VALUE( WGL_COLOR_BITS_ARB);
+ break;
+
+ case WX_GL_LEVEL:
+ if ( attribList[src] > 0 )
+ {
+ ADD_ATTR( WGL_NUMBER_OVERLAYS_ARB, 1 );
+ }
+ else if ( attribList[src] <0 )
+ {
+ ADD_ATTR( WGL_NUMBER_UNDERLAYS_ARB, 1 );
+ }
+ //else: ignore it
+
+ src++; // skip the value in any case
+ break;
+
+ case WX_GL_DOUBLEBUFFER:
+ ADD_ATTR( WGL_DOUBLE_BUFFER_ARB, GL_TRUE );
+ break;
+
+ case WX_GL_STEREO:
+ ADD_ATTR( WGL_STEREO_ARB, GL_TRUE );
+ break;
+
+ case WX_GL_AUX_BUFFERS:
+ ADD_ATTR_VALUE( WGL_AUX_BUFFERS_ARB );
+ break;
+
+ case WX_GL_MIN_RED:
+ ADD_ATTR_VALUE( WGL_RED_BITS_ARB );
+ break;
+
+ case WX_GL_MIN_GREEN:
+ ADD_ATTR_VALUE( WGL_GREEN_BITS_ARB );
+ break;
+
+ case WX_GL_MIN_BLUE:
+ ADD_ATTR_VALUE( WGL_BLUE_BITS_ARB );
+ break;
+
+ case WX_GL_MIN_ALPHA:
+ ADD_ATTR_VALUE( WGL_ALPHA_BITS_ARB );
+ break;
+
+ case WX_GL_DEPTH_SIZE:
+ ADD_ATTR_VALUE( WGL_DEPTH_BITS_ARB );
+ break;
+
+ case WX_GL_STENCIL_SIZE:
+ ADD_ATTR_VALUE( WGL_STENCIL_BITS_ARB );
+ break;
+
+ case WX_GL_MIN_ACCUM_RED:
+ ADD_ATTR_VALUE( WGL_ACCUM_RED_BITS_ARB );
+ break;
+
+ case WX_GL_MIN_ACCUM_GREEN:
+ ADD_ATTR_VALUE( WGL_ACCUM_GREEN_BITS_ARB );
+ break;
+
+ case WX_GL_MIN_ACCUM_BLUE:
+ ADD_ATTR_VALUE( WGL_ACCUM_BLUE_BITS_ARB );
+ break;
+
+ case WX_GL_MIN_ACCUM_ALPHA:
+ ADD_ATTR_VALUE( WGL_ACCUM_ALPHA_BITS_ARB );
+ break;
+
+ case WX_GL_SAMPLE_BUFFERS:
+ ADD_ATTR_VALUE( WGL_SAMPLE_BUFFERS_ARB );
+ break;
+
+ case WX_GL_SAMPLES:
+ ADD_ATTR_VALUE( WGL_SAMPLES_ARB );
+ break;
+ }
+ }
+
+ #undef ADD_ATTR_VALUE
+ }
+
+ #undef ADD_ATTR
+
+ iAttributes[dst++] = 0;
+
+ int pf;
+ UINT numFormats = 0;
+ if ( !wglChoosePixelFormatARB(hdc, iAttributes, NULL, 1, &pf, &numFormats) )
+ {
+ wxLogLastError(_T("wglChoosePixelFormatARB"));
+ return 0;
+ }
+
+ return pf;
+}
+
// ----------------------------------------------------------------------------
// pixel format stuff
// ----------------------------------------------------------------------------
-static void
+// returns true if pfd was adjusted accordingly to attributes provided, false
+// if there is an error with attributes or -1 if the attributes indicate
+// features not supported by ChoosePixelFormat() at all (currently only multi
+// sampling)
+static int
AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, const int *attribList)
{
if ( !attribList )
- return;
+ return 1;
// remove default attributes
pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
case WX_GL_MIN_ACCUM_ALPHA:
pfd.cAccumBits += (pfd.cAccumAlphaBits = attribList[arg++]);
break;
+
+ case WX_GL_SAMPLE_BUFFERS:
+ case WX_GL_SAMPLES:
+ return -1;
}
}
+
+ return 1;
}
/* static */
else
*ppfd = pfd;
- AdjustPFDForAttributes(*ppfd, attribList);
+ // adjust the PFD using the provided attributes and also check if we can
+ // use PIXELFORMATDESCRIPTOR at all: if multisampling is requested, we
+ // can't as it's not supported by ChoosePixelFormat()
+ switch ( AdjustPFDForAttributes(*ppfd, attribList) )
+ {
+ case 1:
+ return ::ChoosePixelFormat(hdc, ppfd);
+
+ default:
+ wxFAIL_MSG( "unexpected AdjustPFDForAttributes() return value" );
+ // fall through
- return ::ChoosePixelFormat(hdc, ppfd);
+ case 0:
+ // error in attributes
+ return 0;
+
+ case -1:
+ return ::ChoosePixelFormatARB(hdc, attribList);
+ }
}
/* static */
pPal->palNumEntries = (WORD)paletteSize;
/* build a simple RGB color palette */
- {
int redMask = (1 << pfd.cRedBits) - 1;
int greenMask = (1 << pfd.cGreenBits) - 1;
int blueMask = (1 << pfd.cBlueBits) - 1;
- int i;
- for (i=0; i<paletteSize; ++i) {
+ for (int i=0; i<paletteSize; ++i)
+ {
pPal->palPalEntry[i].peRed =
(BYTE)((((i >> pfd.cRedShift) & redMask) * 255) / redMask);
pPal->palPalEntry[i].peGreen =
(BYTE)((((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask);
pPal->palPalEntry[i].peFlags = 0;
}
- }
HPALETTE hPalette = CreatePalette(pPal);
free(pPal);