1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/glcanvas.cpp
3 // Purpose: wxGLCanvas, for using OpenGL with wxWidgets under MS Windows
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
22 #if defined(__BORLANDC__)
34 #include "wx/msw/private.h"
36 #include "wx/glcanvas.h"
38 // from src/msw/window.cpp
39 LRESULT WXDLLEXPORT APIENTRY _EXPORT
wxWndProc(HWND hWnd
, UINT message
,
40 WPARAM wParam
, LPARAM lParam
);
42 #ifdef GL_EXT_vertex_array
43 #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) name
45 #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) WXUNUSED(name)
48 // ----------------------------------------------------------------------------
49 // define possibly missing WGL constants
50 // ----------------------------------------------------------------------------
52 #ifndef WGL_ARB_pixel_format
53 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
54 #define WGL_ACCELERATION_ARB 0x2003
55 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
56 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
57 #define WGL_SUPPORT_OPENGL_ARB 0x2010
58 #define WGL_DOUBLE_BUFFER_ARB 0x2011
59 #define WGL_STEREO_ARB 0x2012
60 #define WGL_COLOR_BITS_ARB 0x2014
61 #define WGL_RED_BITS_ARB 0x2015
62 #define WGL_GREEN_BITS_ARB 0x2017
63 #define WGL_BLUE_BITS_ARB 0x2019
64 #define WGL_ALPHA_BITS_ARB 0x201B
65 #define WGL_ACCUM_RED_BITS_ARB 0x201E
66 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
67 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
68 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
69 #define WGL_DEPTH_BITS_ARB 0x2022
70 #define WGL_STENCIL_BITS_ARB 0x2023
71 #define WGL_AUX_BUFFERS_ARB 0x2024
72 #define WGL_FULL_ACCELERATION_ARB 0x2027
75 #ifndef WGL_ARB_multisample
76 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
77 #define WGL_SAMPLES_ARB 0x2042
80 // ----------------------------------------------------------------------------
82 // ----------------------------------------------------------------------------
85 The following two compiler directives are specific to the Microsoft Visual
86 C++ family of compilers
88 Fundementally what they do is instruct the linker to use these two libraries
89 for the resolution of symbols. In essence, this is the equivalent of adding
90 these two libraries to either the Makefile or project file.
92 This is NOT a recommended technique, and certainly is unlikely to be used
93 anywhere else in wxWidgets given it is so specific to not only wxMSW, but
94 also the VC compiler. However, in the case of opengl support, it's an
95 applicable technique as opengl is optional in setup.h This code (wrapped by
96 wxUSE_GLCANVAS), now allows opengl support to be added purely by modifying
97 setup.h rather than by having to modify either the project or DSP fle.
99 See MSDN for further information on the exact usage of these commands.
102 # pragma comment( lib, "opengl32" )
103 # pragma comment( lib, "glu32" )
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
110 IMPLEMENT_CLASS(wxGLContext
, wxObject
)
112 wxGLContext::wxGLContext(wxGLCanvas
*win
, const wxGLContext
* other
)
114 m_glContext
= wglCreateContext(win
->GetHDC());
115 wxCHECK_RET( m_glContext
, wxT("Couldn't create OpenGL context") );
119 if ( !wglShareLists(other
->m_glContext
, m_glContext
) )
121 wxLogLastError(wxT("wglShareLists"));
126 wxGLContext::~wxGLContext()
128 // note that it's ok to delete the context even if it's the current one
129 wglDeleteContext(m_glContext
);
132 bool wxGLContext::SetCurrent(const wxGLCanvas
& win
) const
134 if ( !wglMakeCurrent(win
.GetHDC(), m_glContext
) )
136 wxLogLastError(wxT("wglMakeCurrent"));
142 // ============================================================================
144 // ============================================================================
146 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
)
148 BEGIN_EVENT_TABLE(wxGLCanvas
, wxWindow
)
149 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged
)
150 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette
)
153 // ----------------------------------------------------------------------------
154 // wxGLCanvas construction
155 // ----------------------------------------------------------------------------
157 static int ChoosePixelFormatARB(HDC hdc
, const int *attribList
);
159 void wxGLCanvas::Init()
161 #if WXWIN_COMPATIBILITY_2_8
167 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
169 const int *attribList
,
173 const wxString
& name
,
174 const wxPalette
& palette
)
178 (void)Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
181 wxGLCanvas::~wxGLCanvas()
183 ::ReleaseDC(GetHwnd(), m_hDC
);
186 // Replaces wxWindow::Create functionality, since we need to use a different
188 bool wxGLCanvas::CreateWindow(wxWindow
*parent
,
193 const wxString
& name
)
195 wxCHECK_MSG( parent
, false, wxT("can't create wxWindow without parent") );
197 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
200 parent
->AddChild(this);
203 A general rule with OpenGL and Win32 is that any window that will have a
204 HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS.
205 You can find references about this within the knowledge base and most OpenGL
206 books that contain the wgl function descriptions.
209 DWORD msflags
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
;
210 msflags
|= MSWGetStyle(style
, &exStyle
);
212 if ( !MSWCreate(wxApp::GetRegisteredClassName(wxT("wxGLCanvas"), -1, CS_OWNDC
),
213 NULL
, pos
, size
, msflags
, exStyle
) )
216 m_hDC
= ::GetDC(GetHwnd());
223 bool wxGLCanvas::Create(wxWindow
*parent
,
228 const wxString
& name
,
229 const int *attribList
,
230 const wxPalette
& palette
)
232 // Create the window first: we will either use it as is or use it to query
233 // for multisampling support and recreate it later with another pixel format
234 if ( !CreateWindow(parent
, id
, pos
, size
, style
, name
) )
237 PIXELFORMATDESCRIPTOR pfd
;
238 const int setupVal
= DoSetup(pfd
, attribList
);
239 if ( setupVal
== 0 ) // PixelFormat error
242 if ( setupVal
== -1 ) // FSAA requested
244 // now that we have a valid OpenGL window, query it for FSAA support
247 wxGLContext
ctx(this);
248 ctx
.SetCurrent(*this);
249 pixelFormat
= ::ChoosePixelFormatARB(m_hDC
, attribList
);
252 if ( pixelFormat
> 0 )
254 // from http://msdn.microsoft.com/en-us/library/ms537559(VS.85).aspx:
256 // Setting the pixel format of a window more than once can
257 // lead to significant complications for the Window Manager
258 // and for multithread applications, so it is not allowed. An
259 // application can only set the pixel format of a window one
260 // time. Once a window's pixel format is set, it cannot be
263 // so we need to delete the old window and create the new one
266 ::ReleaseDC(GetHwnd(), m_hDC
);
269 parent
->RemoveChild(this);
270 const HWND hwnd
= GetHwnd();
271 DissociateHandle(); // will do SetHWND(0);
272 ::DestroyWindow(hwnd
);
274 // now recreate with FSAA pixelFormat
275 if ( !CreateWindow(parent
, id
, pos
, size
, style
, name
) )
278 if ( !::SetPixelFormat(m_hDC
, pixelFormat
, &pfd
) )
280 wxLogLastError(wxT("SetPixelFormat"));
287 if ( !SetupPalette(palette
) )
289 #else // !wxUSE_PALETTE
290 wxUnusedVar(palette
);
291 #endif // wxUSE_PALETTE/!wxUSE_PALETTE
296 // ----------------------------------------------------------------------------
298 // ----------------------------------------------------------------------------
300 bool wxGLCanvas::SwapBuffers()
302 if ( !::SwapBuffers(m_hDC
) )
304 wxLogLastError(wxT("SwapBuffers"));
312 // ----------------------------------------------------------------------------
313 // multi sample support
314 // ----------------------------------------------------------------------------
316 // this macro defines a variable of type "name_t" called "name" and initializes
317 // it with the pointer to WGL function "name" (which may be NULL)
318 #define wxDEFINE_WGL_FUNC(name) \
319 name##_t name = (name##_t)wglGetProcAddress(#name)
322 bool wxGLCanvasBase::IsExtensionSupported(const char *extension
)
324 static const char *s_extensionsList
= (char *)wxUIntPtr(-1);
325 if ( s_extensionsList
== (char *)wxUIntPtr(-1) )
327 typedef const char * (WINAPI
*wglGetExtensionsStringARB_t
)(HDC hdc
);
329 wxDEFINE_WGL_FUNC(wglGetExtensionsStringARB
);
330 if ( wglGetExtensionsStringARB
)
332 s_extensionsList
= wglGetExtensionsStringARB(wglGetCurrentDC());
336 typedef const char * (WINAPI
* wglGetExtensionsStringEXT_t
)();
338 wxDEFINE_WGL_FUNC(wglGetExtensionsStringEXT
);
339 if ( wglGetExtensionsStringEXT
)
341 s_extensionsList
= wglGetExtensionsStringEXT();
345 s_extensionsList
= NULL
;
350 return s_extensionsList
&& IsExtensionInList(s_extensionsList
, extension
);
353 // this is a wrapper around wglChoosePixelFormatARB(): returns the pixel format
354 // index matching the given attributes on success or 0 on failure
355 static int ChoosePixelFormatARB(HDC hdc
, const int *attribList
)
357 if ( !wxGLCanvas::IsExtensionSupported("WGL_ARB_multisample") )
360 typedef BOOL (WINAPI
* wglChoosePixelFormatARB_t
)
362 const int *piAttribIList
,
363 const FLOAT
*pfAttribFList
,
369 wxDEFINE_WGL_FUNC(wglChoosePixelFormatARB
);
370 if ( !wglChoosePixelFormatARB
)
371 return 0; // should not occur if extension is supported
373 int iAttributes
[128];
374 int dst
= 0; // index in iAttributes array
376 #define ADD_ATTR(attr, value) \
377 iAttributes[dst++] = attr; iAttributes[dst++] = value
379 ADD_ATTR( WGL_DRAW_TO_WINDOW_ARB
, GL_TRUE
);
380 ADD_ATTR( WGL_SUPPORT_OPENGL_ARB
, GL_TRUE
);
381 ADD_ATTR( WGL_ACCELERATION_ARB
, WGL_FULL_ACCELERATION_ARB
);
385 ADD_ATTR( WGL_COLOR_BITS_ARB
, 24 );
386 ADD_ATTR( WGL_ALPHA_BITS_ARB
, 8 );
387 ADD_ATTR( WGL_DEPTH_BITS_ARB
, 16 );
388 ADD_ATTR( WGL_STENCIL_BITS_ARB
, 0 );
389 ADD_ATTR( WGL_DOUBLE_BUFFER_ARB
, GL_TRUE
);
390 ADD_ATTR( WGL_SAMPLE_BUFFERS_ARB
, GL_TRUE
);
391 ADD_ATTR( WGL_SAMPLES_ARB
, 4 );
393 else // have custom attributes
395 #define ADD_ATTR_VALUE(attr) ADD_ATTR(attr, attribList[src++])
398 while ( attribList
[src
] )
400 switch ( attribList
[src
++] )
403 ADD_ATTR( WGL_COLOR_BITS_ARB
, 24 );
404 ADD_ATTR( WGL_ALPHA_BITS_ARB
, 8 );
407 case WX_GL_BUFFER_SIZE
:
408 ADD_ATTR_VALUE( WGL_COLOR_BITS_ARB
);
412 if ( attribList
[src
] > 0 )
414 ADD_ATTR( WGL_NUMBER_OVERLAYS_ARB
, 1 );
416 else if ( attribList
[src
] <0 )
418 ADD_ATTR( WGL_NUMBER_UNDERLAYS_ARB
, 1 );
422 src
++; // skip the value in any case
425 case WX_GL_DOUBLEBUFFER
:
426 ADD_ATTR( WGL_DOUBLE_BUFFER_ARB
, GL_TRUE
);
430 ADD_ATTR( WGL_STEREO_ARB
, GL_TRUE
);
433 case WX_GL_AUX_BUFFERS
:
434 ADD_ATTR_VALUE( WGL_AUX_BUFFERS_ARB
);
438 ADD_ATTR_VALUE( WGL_RED_BITS_ARB
);
441 case WX_GL_MIN_GREEN
:
442 ADD_ATTR_VALUE( WGL_GREEN_BITS_ARB
);
446 ADD_ATTR_VALUE( WGL_BLUE_BITS_ARB
);
449 case WX_GL_MIN_ALPHA
:
450 ADD_ATTR_VALUE( WGL_ALPHA_BITS_ARB
);
453 case WX_GL_DEPTH_SIZE
:
454 ADD_ATTR_VALUE( WGL_DEPTH_BITS_ARB
);
457 case WX_GL_STENCIL_SIZE
:
458 ADD_ATTR_VALUE( WGL_STENCIL_BITS_ARB
);
461 case WX_GL_MIN_ACCUM_RED
:
462 ADD_ATTR_VALUE( WGL_ACCUM_RED_BITS_ARB
);
465 case WX_GL_MIN_ACCUM_GREEN
:
466 ADD_ATTR_VALUE( WGL_ACCUM_GREEN_BITS_ARB
);
469 case WX_GL_MIN_ACCUM_BLUE
:
470 ADD_ATTR_VALUE( WGL_ACCUM_BLUE_BITS_ARB
);
473 case WX_GL_MIN_ACCUM_ALPHA
:
474 ADD_ATTR_VALUE( WGL_ACCUM_ALPHA_BITS_ARB
);
477 case WX_GL_SAMPLE_BUFFERS
:
478 ADD_ATTR_VALUE( WGL_SAMPLE_BUFFERS_ARB
);
482 ADD_ATTR_VALUE( WGL_SAMPLES_ARB
);
487 #undef ADD_ATTR_VALUE
492 iAttributes
[dst
++] = 0;
496 if ( !wglChoosePixelFormatARB(hdc
, iAttributes
, NULL
, 1, &pf
, &numFormats
) )
498 wxLogLastError(wxT("wglChoosePixelFormatARB"));
505 // ----------------------------------------------------------------------------
506 // pixel format stuff
507 // ----------------------------------------------------------------------------
509 // returns true if pfd was adjusted accordingly to attributes provided, false
510 // if there is an error with attributes or -1 if the attributes indicate
511 // features not supported by ChoosePixelFormat() at all (currently only multi
514 AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR
& pfd
, const int *attribList
)
519 // remove default attributes
520 pfd
.dwFlags
&= ~PFD_DOUBLEBUFFER
;
521 pfd
.iPixelType
= PFD_TYPE_COLORINDEX
;
523 bool requestFSAA
= false;
524 for ( int arg
= 0; attribList
[arg
]; )
526 switch ( attribList
[arg
++] )
529 pfd
.iPixelType
= PFD_TYPE_RGBA
;
532 case WX_GL_BUFFER_SIZE
:
533 pfd
.cColorBits
= attribList
[arg
++];
537 // this member looks like it may be obsolete
538 if ( attribList
[arg
] > 0 )
539 pfd
.iLayerType
= PFD_OVERLAY_PLANE
;
540 else if ( attribList
[arg
] < 0 )
541 pfd
.iLayerType
= (BYTE
)PFD_UNDERLAY_PLANE
;
543 pfd
.iLayerType
= PFD_MAIN_PLANE
;
547 case WX_GL_DOUBLEBUFFER
:
548 pfd
.dwFlags
|= PFD_DOUBLEBUFFER
;
552 pfd
.dwFlags
|= PFD_STEREO
;
555 case WX_GL_AUX_BUFFERS
:
556 pfd
.cAuxBuffers
= attribList
[arg
++];
560 pfd
.cColorBits
+= (pfd
.cRedBits
= attribList
[arg
++]);
563 case WX_GL_MIN_GREEN
:
564 pfd
.cColorBits
+= (pfd
.cGreenBits
= attribList
[arg
++]);
568 pfd
.cColorBits
+= (pfd
.cBlueBits
= attribList
[arg
++]);
571 case WX_GL_MIN_ALPHA
:
572 // doesn't count in cColorBits
573 pfd
.cAlphaBits
= attribList
[arg
++];
576 case WX_GL_DEPTH_SIZE
:
577 pfd
.cDepthBits
= attribList
[arg
++];
580 case WX_GL_STENCIL_SIZE
:
581 pfd
.cStencilBits
= attribList
[arg
++];
584 case WX_GL_MIN_ACCUM_RED
:
585 pfd
.cAccumBits
+= (pfd
.cAccumRedBits
= attribList
[arg
++]);
588 case WX_GL_MIN_ACCUM_GREEN
:
589 pfd
.cAccumBits
+= (pfd
.cAccumGreenBits
= attribList
[arg
++]);
592 case WX_GL_MIN_ACCUM_BLUE
:
593 pfd
.cAccumBits
+= (pfd
.cAccumBlueBits
= attribList
[arg
++]);
596 case WX_GL_MIN_ACCUM_ALPHA
:
597 pfd
.cAccumBits
+= (pfd
.cAccumAlphaBits
= attribList
[arg
++]);
600 case WX_GL_SAMPLE_BUFFERS
:
602 // There is no support for multisample when using PIXELFORMATDESCRIPTOR
603 requestFSAA
= true; // Remember that multi sample is requested.
604 arg
++; // will call ChoosePixelFormatARB() later
609 return requestFSAA
? -1 : 1;
614 wxGLCanvas::ChooseMatchingPixelFormat(HDC hdc
,
615 const int *attribList
,
616 PIXELFORMATDESCRIPTOR
*ppfd
)
618 // default neutral pixel format
619 PIXELFORMATDESCRIPTOR pfd
=
621 sizeof(PIXELFORMATDESCRIPTOR
), // size
625 PFD_DOUBLEBUFFER
, // use double-buffering by default
626 PFD_TYPE_RGBA
, // default pixel type
627 0, // preferred color depth (don't care)
628 0, 0, 0, 0, 0, 0, // color bits and shift bits (ignored)
629 0, 0, // alpha bits and shift (ignored)
630 0, // accumulation total bits
631 0, 0, 0, 0, // accumulator RGBA bits (not used)
633 0, // no stencil buffer
634 0, // no auxiliary buffers
635 PFD_MAIN_PLANE
, // main layer
637 0, 0, 0, // no layer, visible, damage masks
645 // adjust the PFD using the provided attributes and also check if we can
646 // use PIXELFORMATDESCRIPTOR at all: if multisampling is requested, we
647 // can't as it's not supported by ChoosePixelFormat()
648 switch ( AdjustPFDForAttributes(*ppfd
, attribList
) )
651 return ::ChoosePixelFormat(hdc
, ppfd
);
654 wxFAIL_MSG( "unexpected AdjustPFDForAttributes() return value" );
658 // error in attributes
662 // requestFSAA == true, will continue as normal
663 // in order to query later for a FSAA pixelformat
669 bool wxGLCanvasBase::IsDisplaySupported(const int *attribList
)
671 // We need a device context to test the pixel format, so get one
672 // for the root window.
673 return wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList
) > 0;
676 int wxGLCanvas::DoSetup(PIXELFORMATDESCRIPTOR
&pfd
, const int *attribList
)
678 int pixelFormat
= ChooseMatchingPixelFormat(m_hDC
, attribList
, &pfd
);
680 const bool requestFSAA
= pixelFormat
== -1;
682 pixelFormat
= ::ChoosePixelFormat(m_hDC
, &pfd
);
686 wxLogLastError(wxT("ChoosePixelFormat"));
690 if ( !::SetPixelFormat(m_hDC
, pixelFormat
, &pfd
) )
692 wxLogLastError(wxT("SetPixelFormat"));
696 return requestFSAA
? -1 : 1;
699 // ----------------------------------------------------------------------------
701 // ----------------------------------------------------------------------------
705 bool wxGLCanvas::SetupPalette(const wxPalette
& palette
)
707 const int pixelFormat
= ::GetPixelFormat(m_hDC
);
710 wxLogLastError(wxT("GetPixelFormat"));
714 PIXELFORMATDESCRIPTOR pfd
;
715 if ( !::DescribePixelFormat(m_hDC
, pixelFormat
, sizeof(pfd
), &pfd
) )
717 wxLogLastError(wxT("DescribePixelFormat"));
721 if ( !(pfd
.dwFlags
& PFD_NEED_PALETTE
) )
726 if ( !m_palette
.Ok() )
728 m_palette
= CreateDefaultPalette();
729 if ( !m_palette
.Ok() )
733 if ( !::SelectPalette(m_hDC
, GetHpaletteOf(m_palette
), FALSE
) )
735 wxLogLastError(wxT("SelectPalette"));
739 if ( ::RealizePalette(m_hDC
) == GDI_ERROR
)
741 wxLogLastError(wxT("RealizePalette"));
748 wxPalette
wxGLCanvas::CreateDefaultPalette()
750 PIXELFORMATDESCRIPTOR pfd
;
752 int pixelFormat
= GetPixelFormat(m_hDC
);
754 DescribePixelFormat(m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
);
756 paletteSize
= 1 << pfd
.cColorBits
;
759 (LOGPALETTE
*) malloc(sizeof(LOGPALETTE
) + paletteSize
* sizeof(PALETTEENTRY
));
760 pPal
->palVersion
= 0x300;
761 pPal
->palNumEntries
= (WORD
)paletteSize
;
763 /* build a simple RGB color palette */
764 int redMask
= (1 << pfd
.cRedBits
) - 1;
765 int greenMask
= (1 << pfd
.cGreenBits
) - 1;
766 int blueMask
= (1 << pfd
.cBlueBits
) - 1;
768 for (int i
=0; i
<paletteSize
; ++i
)
770 pPal
->palPalEntry
[i
].peRed
=
771 (BYTE
)((((i
>> pfd
.cRedShift
) & redMask
) * 255) / redMask
);
772 pPal
->palPalEntry
[i
].peGreen
=
773 (BYTE
)((((i
>> pfd
.cGreenShift
) & greenMask
) * 255) / greenMask
);
774 pPal
->palPalEntry
[i
].peBlue
=
775 (BYTE
)((((i
>> pfd
.cBlueShift
) & blueMask
) * 255) / blueMask
);
776 pPal
->palPalEntry
[i
].peFlags
= 0;
779 HPALETTE hPalette
= CreatePalette(pPal
);
783 palette
.SetHPALETTE((WXHPALETTE
) hPalette
);
788 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent
& event
)
790 /* realize palette if this is the current window */
791 if ( GetPalette()->Ok() ) {
792 ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE());
793 ::SelectPalette(GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
);
794 ::RealizePalette(GetHDC());
796 event
.SetPaletteRealized(true);
799 event
.SetPaletteRealized(false);
802 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent
& event
)
804 /* realize palette if this is *not* the current window */
806 GetPalette()->Ok() && (this != event
.GetChangedWindow()) )
808 ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE());
809 ::SelectPalette(GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
);
810 ::RealizePalette(GetHDC());
815 #endif // wxUSE_PALETTE
817 // ----------------------------------------------------------------------------
818 // deprecated wxGLCanvas methods using implicit wxGLContext
819 // ----------------------------------------------------------------------------
821 // deprecated constructors creating an implicit m_glContext
822 #if WXWIN_COMPATIBILITY_2_8
824 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
829 const wxString
& name
,
830 const int *attribList
,
831 const wxPalette
& palette
)
835 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
836 m_glContext
= new wxGLContext(this);
839 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
840 const wxGLContext
*shared
,
845 const wxString
& name
,
846 const int *attribList
,
847 const wxPalette
& palette
)
851 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
852 m_glContext
= new wxGLContext(this, shared
);
855 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
856 const wxGLCanvas
*shared
,
861 const wxString
& name
,
862 const int *attribList
,
863 const wxPalette
& palette
)
867 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
868 m_glContext
= new wxGLContext(this, shared
? shared
->m_glContext
: NULL
);
871 #endif // WXWIN_COMPATIBILITY_2_8
874 // ----------------------------------------------------------------------------
876 // ----------------------------------------------------------------------------
878 bool wxGLApp::InitGLVisual(const int *attribList
)
880 if ( !wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList
) )
882 wxLogError(_("Failed to initialize OpenGL"));
889 #endif // wxUSE_GLCANVAS