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;
497 if ( !wglChoosePixelFormatARB(hdc
, iAttributes
, NULL
, 1, &pf
, &numFormats
) )
499 wxLogLastError(wxT("wglChoosePixelFormatARB"));
503 // Although TRUE is returned if no matching formats are found (see
504 // http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt), pf is
505 // not initialized in this case so we need to check for numFormats being
506 // not 0 explicitly (however this is not an error so don't call
507 // wxLogLastError() here).
514 // ----------------------------------------------------------------------------
515 // pixel format stuff
516 // ----------------------------------------------------------------------------
518 // returns true if pfd was adjusted accordingly to attributes provided, false
519 // if there is an error with attributes or -1 if the attributes indicate
520 // features not supported by ChoosePixelFormat() at all (currently only multi
523 AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR
& pfd
, const int *attribList
)
528 // remove default attributes
529 pfd
.dwFlags
&= ~PFD_DOUBLEBUFFER
;
530 pfd
.iPixelType
= PFD_TYPE_COLORINDEX
;
532 bool requestFSAA
= false;
533 for ( int arg
= 0; attribList
[arg
]; )
535 switch ( attribList
[arg
++] )
538 pfd
.iPixelType
= PFD_TYPE_RGBA
;
541 case WX_GL_BUFFER_SIZE
:
542 pfd
.cColorBits
= attribList
[arg
++];
546 // this member looks like it may be obsolete
547 if ( attribList
[arg
] > 0 )
548 pfd
.iLayerType
= PFD_OVERLAY_PLANE
;
549 else if ( attribList
[arg
] < 0 )
550 pfd
.iLayerType
= (BYTE
)PFD_UNDERLAY_PLANE
;
552 pfd
.iLayerType
= PFD_MAIN_PLANE
;
556 case WX_GL_DOUBLEBUFFER
:
557 pfd
.dwFlags
|= PFD_DOUBLEBUFFER
;
561 pfd
.dwFlags
|= PFD_STEREO
;
564 case WX_GL_AUX_BUFFERS
:
565 pfd
.cAuxBuffers
= attribList
[arg
++];
569 pfd
.cColorBits
+= (pfd
.cRedBits
= attribList
[arg
++]);
572 case WX_GL_MIN_GREEN
:
573 pfd
.cColorBits
+= (pfd
.cGreenBits
= attribList
[arg
++]);
577 pfd
.cColorBits
+= (pfd
.cBlueBits
= attribList
[arg
++]);
580 case WX_GL_MIN_ALPHA
:
581 // doesn't count in cColorBits
582 pfd
.cAlphaBits
= attribList
[arg
++];
585 case WX_GL_DEPTH_SIZE
:
586 pfd
.cDepthBits
= attribList
[arg
++];
589 case WX_GL_STENCIL_SIZE
:
590 pfd
.cStencilBits
= attribList
[arg
++];
593 case WX_GL_MIN_ACCUM_RED
:
594 pfd
.cAccumBits
+= (pfd
.cAccumRedBits
= attribList
[arg
++]);
597 case WX_GL_MIN_ACCUM_GREEN
:
598 pfd
.cAccumBits
+= (pfd
.cAccumGreenBits
= attribList
[arg
++]);
601 case WX_GL_MIN_ACCUM_BLUE
:
602 pfd
.cAccumBits
+= (pfd
.cAccumBlueBits
= attribList
[arg
++]);
605 case WX_GL_MIN_ACCUM_ALPHA
:
606 pfd
.cAccumBits
+= (pfd
.cAccumAlphaBits
= attribList
[arg
++]);
609 case WX_GL_SAMPLE_BUFFERS
:
611 // There is no support for multisample when using PIXELFORMATDESCRIPTOR
612 requestFSAA
= true; // Remember that multi sample is requested.
613 arg
++; // will call ChoosePixelFormatARB() later
618 return requestFSAA
? -1 : 1;
623 wxGLCanvas::ChooseMatchingPixelFormat(HDC hdc
,
624 const int *attribList
,
625 PIXELFORMATDESCRIPTOR
*ppfd
)
627 // default neutral pixel format
628 PIXELFORMATDESCRIPTOR pfd
=
630 sizeof(PIXELFORMATDESCRIPTOR
), // size
634 PFD_DOUBLEBUFFER
, // use double-buffering by default
635 PFD_TYPE_RGBA
, // default pixel type
636 0, // preferred color depth (don't care)
637 0, 0, 0, 0, 0, 0, // color bits and shift bits (ignored)
638 0, 0, // alpha bits and shift (ignored)
639 0, // accumulation total bits
640 0, 0, 0, 0, // accumulator RGBA bits (not used)
642 0, // no stencil buffer
643 0, // no auxiliary buffers
644 PFD_MAIN_PLANE
, // main layer
646 0, 0, 0, // no layer, visible, damage masks
654 // adjust the PFD using the provided attributes and also check if we can
655 // use PIXELFORMATDESCRIPTOR at all: if multisampling is requested, we
656 // can't as it's not supported by ChoosePixelFormat()
657 switch ( AdjustPFDForAttributes(*ppfd
, attribList
) )
660 return ::ChoosePixelFormat(hdc
, ppfd
);
663 wxFAIL_MSG( "unexpected AdjustPFDForAttributes() return value" );
667 // error in attributes
671 // requestFSAA == true, will continue as normal
672 // in order to query later for a FSAA pixelformat
678 bool wxGLCanvasBase::IsDisplaySupported(const int *attribList
)
680 // We need a device context to test the pixel format, so get one
681 // for the root window.
682 return wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList
) > 0;
685 int wxGLCanvas::DoSetup(PIXELFORMATDESCRIPTOR
&pfd
, const int *attribList
)
687 int pixelFormat
= ChooseMatchingPixelFormat(m_hDC
, attribList
, &pfd
);
689 const bool requestFSAA
= pixelFormat
== -1;
691 pixelFormat
= ::ChoosePixelFormat(m_hDC
, &pfd
);
695 wxLogLastError(wxT("ChoosePixelFormat"));
699 if ( !::SetPixelFormat(m_hDC
, pixelFormat
, &pfd
) )
701 wxLogLastError(wxT("SetPixelFormat"));
705 return requestFSAA
? -1 : 1;
708 // ----------------------------------------------------------------------------
710 // ----------------------------------------------------------------------------
714 bool wxGLCanvas::SetupPalette(const wxPalette
& palette
)
716 const int pixelFormat
= ::GetPixelFormat(m_hDC
);
719 wxLogLastError(wxT("GetPixelFormat"));
723 PIXELFORMATDESCRIPTOR pfd
;
724 if ( !::DescribePixelFormat(m_hDC
, pixelFormat
, sizeof(pfd
), &pfd
) )
726 wxLogLastError(wxT("DescribePixelFormat"));
730 if ( !(pfd
.dwFlags
& PFD_NEED_PALETTE
) )
735 if ( !m_palette
.Ok() )
737 m_palette
= CreateDefaultPalette();
738 if ( !m_palette
.Ok() )
742 if ( !::SelectPalette(m_hDC
, GetHpaletteOf(m_palette
), FALSE
) )
744 wxLogLastError(wxT("SelectPalette"));
748 if ( ::RealizePalette(m_hDC
) == GDI_ERROR
)
750 wxLogLastError(wxT("RealizePalette"));
757 wxPalette
wxGLCanvas::CreateDefaultPalette()
759 PIXELFORMATDESCRIPTOR pfd
;
761 int pixelFormat
= GetPixelFormat(m_hDC
);
763 DescribePixelFormat(m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
);
765 paletteSize
= 1 << pfd
.cColorBits
;
768 (LOGPALETTE
*) malloc(sizeof(LOGPALETTE
) + paletteSize
* sizeof(PALETTEENTRY
));
769 pPal
->palVersion
= 0x300;
770 pPal
->palNumEntries
= (WORD
)paletteSize
;
772 /* build a simple RGB color palette */
773 int redMask
= (1 << pfd
.cRedBits
) - 1;
774 int greenMask
= (1 << pfd
.cGreenBits
) - 1;
775 int blueMask
= (1 << pfd
.cBlueBits
) - 1;
777 for (int i
=0; i
<paletteSize
; ++i
)
779 pPal
->palPalEntry
[i
].peRed
=
780 (BYTE
)((((i
>> pfd
.cRedShift
) & redMask
) * 255) / redMask
);
781 pPal
->palPalEntry
[i
].peGreen
=
782 (BYTE
)((((i
>> pfd
.cGreenShift
) & greenMask
) * 255) / greenMask
);
783 pPal
->palPalEntry
[i
].peBlue
=
784 (BYTE
)((((i
>> pfd
.cBlueShift
) & blueMask
) * 255) / blueMask
);
785 pPal
->palPalEntry
[i
].peFlags
= 0;
788 HPALETTE hPalette
= CreatePalette(pPal
);
792 palette
.SetHPALETTE((WXHPALETTE
) hPalette
);
797 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent
& event
)
799 /* realize palette if this is the current window */
800 if ( GetPalette()->Ok() ) {
801 ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE());
802 ::SelectPalette(GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
);
803 ::RealizePalette(GetHDC());
805 event
.SetPaletteRealized(true);
808 event
.SetPaletteRealized(false);
811 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent
& event
)
813 /* realize palette if this is *not* the current window */
815 GetPalette()->Ok() && (this != event
.GetChangedWindow()) )
817 ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE());
818 ::SelectPalette(GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
);
819 ::RealizePalette(GetHDC());
824 #endif // wxUSE_PALETTE
826 // ----------------------------------------------------------------------------
827 // deprecated wxGLCanvas methods using implicit wxGLContext
828 // ----------------------------------------------------------------------------
830 // deprecated constructors creating an implicit m_glContext
831 #if WXWIN_COMPATIBILITY_2_8
833 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
838 const wxString
& name
,
839 const int *attribList
,
840 const wxPalette
& palette
)
844 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
845 m_glContext
= new wxGLContext(this);
848 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
849 const wxGLContext
*shared
,
854 const wxString
& name
,
855 const int *attribList
,
856 const wxPalette
& palette
)
860 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
861 m_glContext
= new wxGLContext(this, shared
);
864 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
865 const wxGLCanvas
*shared
,
870 const wxString
& name
,
871 const int *attribList
,
872 const wxPalette
& palette
)
876 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
877 m_glContext
= new wxGLContext(this, shared
? shared
->m_glContext
: NULL
);
880 #endif // WXWIN_COMPATIBILITY_2_8
883 // ----------------------------------------------------------------------------
885 // ----------------------------------------------------------------------------
887 bool wxGLApp::InitGLVisual(const int *attribList
)
889 if ( !wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList
) )
891 wxLogError(_("Failed to initialize OpenGL"));
898 #endif // wxUSE_GLCANVAS