1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/glcanvas.cpp
3 // Purpose: wxGLCanvas, for using OpenGL with wxWidgets under MS Windows
4 // Author: Julian Smart
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
21 #if defined(__BORLANDC__)
33 #include "wx/msw/private.h"
35 #include "wx/glcanvas.h"
37 // from src/msw/window.cpp
38 LRESULT WXDLLEXPORT APIENTRY _EXPORT
wxWndProc(HWND hWnd
, UINT message
,
39 WPARAM wParam
, LPARAM lParam
);
41 #ifdef GL_EXT_vertex_array
42 #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) name
44 #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) WXUNUSED(name)
47 // ----------------------------------------------------------------------------
48 // define possibly missing WGL constants
49 // ----------------------------------------------------------------------------
51 #ifndef WGL_ARB_pixel_format
52 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
53 #define WGL_ACCELERATION_ARB 0x2003
54 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
55 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
56 #define WGL_SUPPORT_OPENGL_ARB 0x2010
57 #define WGL_DOUBLE_BUFFER_ARB 0x2011
58 #define WGL_STEREO_ARB 0x2012
59 #define WGL_COLOR_BITS_ARB 0x2014
60 #define WGL_RED_BITS_ARB 0x2015
61 #define WGL_GREEN_BITS_ARB 0x2017
62 #define WGL_BLUE_BITS_ARB 0x2019
63 #define WGL_ALPHA_BITS_ARB 0x201B
64 #define WGL_ACCUM_RED_BITS_ARB 0x201E
65 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
66 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
67 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
68 #define WGL_DEPTH_BITS_ARB 0x2022
69 #define WGL_STENCIL_BITS_ARB 0x2023
70 #define WGL_AUX_BUFFERS_ARB 0x2024
71 #define WGL_FULL_ACCELERATION_ARB 0x2027
74 #ifndef WGL_ARB_multisample
75 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
76 #define WGL_SAMPLES_ARB 0x2042
79 // ----------------------------------------------------------------------------
81 // ----------------------------------------------------------------------------
84 The following two compiler directives are specific to the Microsoft Visual
85 C++ family of compilers
87 Fundementally what they do is instruct the linker to use these two libraries
88 for the resolution of symbols. In essence, this is the equivalent of adding
89 these two libraries to either the Makefile or project file.
91 This is NOT a recommended technique, and certainly is unlikely to be used
92 anywhere else in wxWidgets given it is so specific to not only wxMSW, but
93 also the VC compiler. However, in the case of opengl support, it's an
94 applicable technique as opengl is optional in setup.h This code (wrapped by
95 wxUSE_GLCANVAS), now allows opengl support to be added purely by modifying
96 setup.h rather than by having to modify either the project or DSP fle.
98 See MSDN for further information on the exact usage of these commands.
101 # pragma comment( lib, "opengl32" )
102 # pragma comment( lib, "glu32" )
105 // ----------------------------------------------------------------------------
107 // ----------------------------------------------------------------------------
109 IMPLEMENT_CLASS(wxGLContext
, wxObject
)
111 wxGLContext::wxGLContext(wxGLCanvas
*win
, const wxGLContext
* other
)
113 m_glContext
= wglCreateContext(win
->GetHDC());
114 wxCHECK_RET( m_glContext
, wxT("Couldn't create OpenGL context") );
118 if ( !wglShareLists(other
->m_glContext
, m_glContext
) )
120 wxLogLastError(wxT("wglShareLists"));
125 wxGLContext::~wxGLContext()
127 // note that it's ok to delete the context even if it's the current one
128 wglDeleteContext(m_glContext
);
131 bool wxGLContext::SetCurrent(const wxGLCanvas
& win
) const
133 if ( !wglMakeCurrent(win
.GetHDC(), m_glContext
) )
135 wxLogLastError(wxT("wglMakeCurrent"));
141 // ============================================================================
143 // ============================================================================
145 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
)
147 BEGIN_EVENT_TABLE(wxGLCanvas
, wxWindow
)
149 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged
)
150 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette
)
154 // ----------------------------------------------------------------------------
155 // wxGLCanvas construction
156 // ----------------------------------------------------------------------------
158 static int ChoosePixelFormatARB(HDC hdc
, const int *attribList
);
160 void wxGLCanvas::Init()
162 #if WXWIN_COMPATIBILITY_2_8
168 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
170 const int *attribList
,
174 const wxString
& name
,
175 const wxPalette
& palette
)
179 (void)Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
182 wxGLCanvas::~wxGLCanvas()
184 ::ReleaseDC(GetHwnd(), m_hDC
);
187 // Replaces wxWindow::Create functionality, since we need to use a different
189 bool wxGLCanvas::CreateWindow(wxWindow
*parent
,
194 const wxString
& name
)
196 wxCHECK_MSG( parent
, false, wxT("can't create wxWindow without parent") );
198 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
201 parent
->AddChild(this);
204 A general rule with OpenGL and Win32 is that any window that will have a
205 HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS.
206 You can find references about this within the knowledge base and most OpenGL
207 books that contain the wgl function descriptions.
210 DWORD msflags
= WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
;
211 msflags
|= MSWGetStyle(style
, &exStyle
);
213 if ( !MSWCreate(wxApp::GetRegisteredClassName(wxT("wxGLCanvas"), -1, CS_OWNDC
),
214 NULL
, pos
, size
, msflags
, exStyle
) )
217 m_hDC
= ::GetDC(GetHwnd());
224 bool wxGLCanvas::Create(wxWindow
*parent
,
229 const wxString
& name
,
230 const int *attribList
,
231 const wxPalette
& palette
)
233 // Create the window first: we will either use it as is or use it to query
234 // for multisampling support and recreate it later with another pixel format
235 if ( !CreateWindow(parent
, id
, pos
, size
, style
, name
) )
238 PIXELFORMATDESCRIPTOR pfd
;
239 const int setupVal
= DoSetup(pfd
, attribList
);
240 if ( setupVal
== 0 ) // PixelFormat error
243 if ( setupVal
== -1 ) // FSAA requested
245 // now that we have a valid OpenGL window, query it for FSAA support
248 wxGLContext
ctx(this);
249 ctx
.SetCurrent(*this);
250 pixelFormat
= ::ChoosePixelFormatARB(m_hDC
, attribList
);
253 if ( pixelFormat
> 0 )
255 // from http://msdn.microsoft.com/en-us/library/ms537559(VS.85).aspx:
257 // Setting the pixel format of a window more than once can
258 // lead to significant complications for the Window Manager
259 // and for multithread applications, so it is not allowed. An
260 // application can only set the pixel format of a window one
261 // time. Once a window's pixel format is set, it cannot be
264 // so we need to delete the old window and create the new one
267 ::ReleaseDC(GetHwnd(), m_hDC
);
270 parent
->RemoveChild(this);
271 const HWND hwnd
= GetHwnd();
272 DissociateHandle(); // will do SetHWND(0);
273 ::DestroyWindow(hwnd
);
275 // now recreate with FSAA pixelFormat
276 if ( !CreateWindow(parent
, id
, pos
, size
, style
, name
) )
279 if ( !::SetPixelFormat(m_hDC
, pixelFormat
, &pfd
) )
281 wxLogLastError(wxT("SetPixelFormat"));
288 if ( !SetupPalette(palette
) )
290 #else // !wxUSE_PALETTE
291 wxUnusedVar(palette
);
292 #endif // wxUSE_PALETTE/!wxUSE_PALETTE
297 // ----------------------------------------------------------------------------
299 // ----------------------------------------------------------------------------
301 bool wxGLCanvas::SwapBuffers()
303 if ( !::SwapBuffers(m_hDC
) )
305 wxLogLastError(wxT("SwapBuffers"));
313 // ----------------------------------------------------------------------------
314 // multi sample support
315 // ----------------------------------------------------------------------------
317 // this macro defines a variable of type "name_t" called "name" and initializes
318 // it with the pointer to WGL function "name" (which may be NULL)
319 #define wxDEFINE_WGL_FUNC(name) \
320 name##_t name = (name##_t)wglGetProcAddress(#name)
323 bool wxGLCanvasBase::IsExtensionSupported(const char *extension
)
325 static const char *s_extensionsList
= (char *)wxUIntPtr(-1);
326 if ( s_extensionsList
== (char *)wxUIntPtr(-1) )
328 typedef const char * (WINAPI
*wglGetExtensionsStringARB_t
)(HDC hdc
);
330 wxDEFINE_WGL_FUNC(wglGetExtensionsStringARB
);
331 if ( wglGetExtensionsStringARB
)
333 s_extensionsList
= wglGetExtensionsStringARB(wglGetCurrentDC());
337 typedef const char * (WINAPI
* wglGetExtensionsStringEXT_t
)();
339 wxDEFINE_WGL_FUNC(wglGetExtensionsStringEXT
);
340 if ( wglGetExtensionsStringEXT
)
342 s_extensionsList
= wglGetExtensionsStringEXT();
346 s_extensionsList
= NULL
;
351 return s_extensionsList
&& IsExtensionInList(s_extensionsList
, extension
);
354 // this is a wrapper around wglChoosePixelFormatARB(): returns the pixel format
355 // index matching the given attributes on success or 0 on failure
356 static int ChoosePixelFormatARB(HDC hdc
, const int *attribList
)
358 if ( !wxGLCanvas::IsExtensionSupported("WGL_ARB_multisample") )
361 typedef BOOL (WINAPI
* wglChoosePixelFormatARB_t
)
363 const int *piAttribIList
,
364 const FLOAT
*pfAttribFList
,
370 wxDEFINE_WGL_FUNC(wglChoosePixelFormatARB
);
371 if ( !wglChoosePixelFormatARB
)
372 return 0; // should not occur if extension is supported
374 int iAttributes
[128];
375 int dst
= 0; // index in iAttributes array
377 #define ADD_ATTR(attr, value) \
378 iAttributes[dst++] = attr; iAttributes[dst++] = value
380 ADD_ATTR( WGL_DRAW_TO_WINDOW_ARB
, GL_TRUE
);
381 ADD_ATTR( WGL_SUPPORT_OPENGL_ARB
, GL_TRUE
);
382 ADD_ATTR( WGL_ACCELERATION_ARB
, WGL_FULL_ACCELERATION_ARB
);
386 ADD_ATTR( WGL_COLOR_BITS_ARB
, 24 );
387 ADD_ATTR( WGL_ALPHA_BITS_ARB
, 8 );
388 ADD_ATTR( WGL_DEPTH_BITS_ARB
, 16 );
389 ADD_ATTR( WGL_STENCIL_BITS_ARB
, 0 );
390 ADD_ATTR( WGL_DOUBLE_BUFFER_ARB
, GL_TRUE
);
391 ADD_ATTR( WGL_SAMPLE_BUFFERS_ARB
, GL_TRUE
);
392 ADD_ATTR( WGL_SAMPLES_ARB
, 4 );
394 else // have custom attributes
396 #define ADD_ATTR_VALUE(attr) ADD_ATTR(attr, attribList[src++])
399 while ( attribList
[src
] )
401 switch ( attribList
[src
++] )
404 ADD_ATTR( WGL_COLOR_BITS_ARB
, 24 );
405 ADD_ATTR( WGL_ALPHA_BITS_ARB
, 8 );
408 case WX_GL_BUFFER_SIZE
:
409 ADD_ATTR_VALUE( WGL_COLOR_BITS_ARB
);
413 if ( attribList
[src
] > 0 )
415 ADD_ATTR( WGL_NUMBER_OVERLAYS_ARB
, 1 );
417 else if ( attribList
[src
] <0 )
419 ADD_ATTR( WGL_NUMBER_UNDERLAYS_ARB
, 1 );
423 src
++; // skip the value in any case
426 case WX_GL_DOUBLEBUFFER
:
427 ADD_ATTR( WGL_DOUBLE_BUFFER_ARB
, GL_TRUE
);
431 ADD_ATTR( WGL_STEREO_ARB
, GL_TRUE
);
434 case WX_GL_AUX_BUFFERS
:
435 ADD_ATTR_VALUE( WGL_AUX_BUFFERS_ARB
);
439 ADD_ATTR_VALUE( WGL_RED_BITS_ARB
);
442 case WX_GL_MIN_GREEN
:
443 ADD_ATTR_VALUE( WGL_GREEN_BITS_ARB
);
447 ADD_ATTR_VALUE( WGL_BLUE_BITS_ARB
);
450 case WX_GL_MIN_ALPHA
:
451 ADD_ATTR_VALUE( WGL_ALPHA_BITS_ARB
);
454 case WX_GL_DEPTH_SIZE
:
455 ADD_ATTR_VALUE( WGL_DEPTH_BITS_ARB
);
458 case WX_GL_STENCIL_SIZE
:
459 ADD_ATTR_VALUE( WGL_STENCIL_BITS_ARB
);
462 case WX_GL_MIN_ACCUM_RED
:
463 ADD_ATTR_VALUE( WGL_ACCUM_RED_BITS_ARB
);
466 case WX_GL_MIN_ACCUM_GREEN
:
467 ADD_ATTR_VALUE( WGL_ACCUM_GREEN_BITS_ARB
);
470 case WX_GL_MIN_ACCUM_BLUE
:
471 ADD_ATTR_VALUE( WGL_ACCUM_BLUE_BITS_ARB
);
474 case WX_GL_MIN_ACCUM_ALPHA
:
475 ADD_ATTR_VALUE( WGL_ACCUM_ALPHA_BITS_ARB
);
478 case WX_GL_SAMPLE_BUFFERS
:
479 ADD_ATTR_VALUE( WGL_SAMPLE_BUFFERS_ARB
);
483 ADD_ATTR_VALUE( WGL_SAMPLES_ARB
);
488 #undef ADD_ATTR_VALUE
493 iAttributes
[dst
++] = 0;
498 if ( !wglChoosePixelFormatARB(hdc
, iAttributes
, NULL
, 1, &pf
, &numFormats
) )
500 wxLogLastError(wxT("wglChoosePixelFormatARB"));
504 // Although TRUE is returned if no matching formats are found (see
505 // http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt), pf is
506 // not initialized in this case so we need to check for numFormats being
507 // not 0 explicitly (however this is not an error so don't call
508 // wxLogLastError() here).
515 // ----------------------------------------------------------------------------
516 // pixel format stuff
517 // ----------------------------------------------------------------------------
519 // returns true if pfd was adjusted accordingly to attributes provided, false
520 // if there is an error with attributes or -1 if the attributes indicate
521 // features not supported by ChoosePixelFormat() at all (currently only multi
524 AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR
& pfd
, const int *attribList
)
529 // remove default attributes
530 pfd
.dwFlags
&= ~PFD_DOUBLEBUFFER
;
531 pfd
.iPixelType
= PFD_TYPE_COLORINDEX
;
533 bool requestFSAA
= false;
534 for ( int arg
= 0; attribList
[arg
]; )
536 switch ( attribList
[arg
++] )
539 pfd
.iPixelType
= PFD_TYPE_RGBA
;
542 case WX_GL_BUFFER_SIZE
:
543 pfd
.cColorBits
= attribList
[arg
++];
547 // this member looks like it may be obsolete
548 if ( attribList
[arg
] > 0 )
549 pfd
.iLayerType
= PFD_OVERLAY_PLANE
;
550 else if ( attribList
[arg
] < 0 )
551 pfd
.iLayerType
= (BYTE
)PFD_UNDERLAY_PLANE
;
553 pfd
.iLayerType
= PFD_MAIN_PLANE
;
557 case WX_GL_DOUBLEBUFFER
:
558 pfd
.dwFlags
|= PFD_DOUBLEBUFFER
;
562 pfd
.dwFlags
|= PFD_STEREO
;
565 case WX_GL_AUX_BUFFERS
:
566 pfd
.cAuxBuffers
= attribList
[arg
++];
570 pfd
.cColorBits
+= (pfd
.cRedBits
= attribList
[arg
++]);
573 case WX_GL_MIN_GREEN
:
574 pfd
.cColorBits
+= (pfd
.cGreenBits
= attribList
[arg
++]);
578 pfd
.cColorBits
+= (pfd
.cBlueBits
= attribList
[arg
++]);
581 case WX_GL_MIN_ALPHA
:
582 // doesn't count in cColorBits
583 pfd
.cAlphaBits
= attribList
[arg
++];
586 case WX_GL_DEPTH_SIZE
:
587 pfd
.cDepthBits
= attribList
[arg
++];
590 case WX_GL_STENCIL_SIZE
:
591 pfd
.cStencilBits
= attribList
[arg
++];
594 case WX_GL_MIN_ACCUM_RED
:
595 pfd
.cAccumBits
+= (pfd
.cAccumRedBits
= attribList
[arg
++]);
598 case WX_GL_MIN_ACCUM_GREEN
:
599 pfd
.cAccumBits
+= (pfd
.cAccumGreenBits
= attribList
[arg
++]);
602 case WX_GL_MIN_ACCUM_BLUE
:
603 pfd
.cAccumBits
+= (pfd
.cAccumBlueBits
= attribList
[arg
++]);
606 case WX_GL_MIN_ACCUM_ALPHA
:
607 pfd
.cAccumBits
+= (pfd
.cAccumAlphaBits
= attribList
[arg
++]);
610 case WX_GL_SAMPLE_BUFFERS
:
612 // There is no support for multisample when using PIXELFORMATDESCRIPTOR
613 requestFSAA
= true; // Remember that multi sample is requested.
614 arg
++; // will call ChoosePixelFormatARB() later
619 return requestFSAA
? -1 : 1;
624 wxGLCanvas::ChooseMatchingPixelFormat(HDC hdc
,
625 const int *attribList
,
626 PIXELFORMATDESCRIPTOR
*ppfd
)
628 // default neutral pixel format
629 PIXELFORMATDESCRIPTOR pfd
=
631 sizeof(PIXELFORMATDESCRIPTOR
), // size
635 PFD_DOUBLEBUFFER
, // use double-buffering by default
636 PFD_TYPE_RGBA
, // default pixel type
637 0, // preferred color depth (don't care)
638 0, 0, 0, 0, 0, 0, // color bits and shift bits (ignored)
639 0, 0, // alpha bits and shift (ignored)
640 0, // accumulation total bits
641 0, 0, 0, 0, // accumulator RGBA bits (not used)
643 0, // no stencil buffer
644 0, // no auxiliary buffers
645 PFD_MAIN_PLANE
, // main layer
647 0, 0, 0, // no layer, visible, damage masks
655 // adjust the PFD using the provided attributes and also check if we can
656 // use PIXELFORMATDESCRIPTOR at all: if multisampling is requested, we
657 // can't as it's not supported by ChoosePixelFormat()
658 switch ( AdjustPFDForAttributes(*ppfd
, attribList
) )
661 return ::ChoosePixelFormat(hdc
, ppfd
);
664 wxFAIL_MSG( "unexpected AdjustPFDForAttributes() return value" );
668 // error in attributes
672 // requestFSAA == true, will continue as normal
673 // in order to query later for a FSAA pixelformat
679 bool wxGLCanvasBase::IsDisplaySupported(const int *attribList
)
681 // We need a device context to test the pixel format, so get one
682 // for the root window.
683 return wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList
) > 0;
686 int wxGLCanvas::DoSetup(PIXELFORMATDESCRIPTOR
&pfd
, const int *attribList
)
688 int pixelFormat
= ChooseMatchingPixelFormat(m_hDC
, attribList
, &pfd
);
690 const bool requestFSAA
= pixelFormat
== -1;
692 pixelFormat
= ::ChoosePixelFormat(m_hDC
, &pfd
);
696 wxLogLastError(wxT("ChoosePixelFormat"));
700 if ( !::SetPixelFormat(m_hDC
, pixelFormat
, &pfd
) )
702 wxLogLastError(wxT("SetPixelFormat"));
706 return requestFSAA
? -1 : 1;
709 // ----------------------------------------------------------------------------
711 // ----------------------------------------------------------------------------
715 bool wxGLCanvas::SetupPalette(const wxPalette
& palette
)
717 const int pixelFormat
= ::GetPixelFormat(m_hDC
);
720 wxLogLastError(wxT("GetPixelFormat"));
724 PIXELFORMATDESCRIPTOR pfd
;
725 if ( !::DescribePixelFormat(m_hDC
, pixelFormat
, sizeof(pfd
), &pfd
) )
727 wxLogLastError(wxT("DescribePixelFormat"));
731 if ( !(pfd
.dwFlags
& PFD_NEED_PALETTE
) )
736 if ( !m_palette
.IsOk() )
738 m_palette
= CreateDefaultPalette();
739 if ( !m_palette
.IsOk() )
743 if ( !::SelectPalette(m_hDC
, GetHpaletteOf(m_palette
), FALSE
) )
745 wxLogLastError(wxT("SelectPalette"));
749 if ( ::RealizePalette(m_hDC
) == GDI_ERROR
)
751 wxLogLastError(wxT("RealizePalette"));
758 wxPalette
wxGLCanvas::CreateDefaultPalette()
760 PIXELFORMATDESCRIPTOR pfd
;
762 int pixelFormat
= GetPixelFormat(m_hDC
);
764 DescribePixelFormat(m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
);
766 paletteSize
= 1 << pfd
.cColorBits
;
769 (LOGPALETTE
*) malloc(sizeof(LOGPALETTE
) + paletteSize
* sizeof(PALETTEENTRY
));
770 pPal
->palVersion
= 0x300;
771 pPal
->palNumEntries
= (WORD
)paletteSize
;
773 /* build a simple RGB color palette */
774 int redMask
= (1 << pfd
.cRedBits
) - 1;
775 int greenMask
= (1 << pfd
.cGreenBits
) - 1;
776 int blueMask
= (1 << pfd
.cBlueBits
) - 1;
778 for (int i
=0; i
<paletteSize
; ++i
)
780 pPal
->palPalEntry
[i
].peRed
=
781 (BYTE
)((((i
>> pfd
.cRedShift
) & redMask
) * 255) / redMask
);
782 pPal
->palPalEntry
[i
].peGreen
=
783 (BYTE
)((((i
>> pfd
.cGreenShift
) & greenMask
) * 255) / greenMask
);
784 pPal
->palPalEntry
[i
].peBlue
=
785 (BYTE
)((((i
>> pfd
.cBlueShift
) & blueMask
) * 255) / blueMask
);
786 pPal
->palPalEntry
[i
].peFlags
= 0;
789 HPALETTE hPalette
= CreatePalette(pPal
);
793 palette
.SetHPALETTE((WXHPALETTE
) hPalette
);
798 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent
& event
)
800 /* realize palette if this is the current window */
801 if ( GetPalette()->IsOk() ) {
802 ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE());
803 ::SelectPalette(GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
);
804 ::RealizePalette(GetHDC());
806 event
.SetPaletteRealized(true);
809 event
.SetPaletteRealized(false);
812 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent
& event
)
814 /* realize palette if this is *not* the current window */
816 GetPalette()->IsOk() && (this != event
.GetChangedWindow()) )
818 ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE());
819 ::SelectPalette(GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
);
820 ::RealizePalette(GetHDC());
825 #endif // wxUSE_PALETTE
827 // ----------------------------------------------------------------------------
828 // deprecated wxGLCanvas methods using implicit wxGLContext
829 // ----------------------------------------------------------------------------
831 // deprecated constructors creating an implicit m_glContext
832 #if WXWIN_COMPATIBILITY_2_8
834 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
839 const wxString
& name
,
840 const int *attribList
,
841 const wxPalette
& palette
)
845 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
846 m_glContext
= new wxGLContext(this);
849 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
850 const wxGLContext
*shared
,
855 const wxString
& name
,
856 const int *attribList
,
857 const wxPalette
& palette
)
861 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
862 m_glContext
= new wxGLContext(this, shared
);
865 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
866 const wxGLCanvas
*shared
,
871 const wxString
& name
,
872 const int *attribList
,
873 const wxPalette
& palette
)
877 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
878 m_glContext
= new wxGLContext(this, shared
? shared
->m_glContext
: NULL
);
881 #endif // WXWIN_COMPATIBILITY_2_8
884 // ----------------------------------------------------------------------------
886 // ----------------------------------------------------------------------------
888 bool wxGLApp::InitGLVisual(const int *attribList
)
890 if ( !wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList
) )
892 wxLogError(_("Failed to initialize OpenGL"));
899 #endif // wxUSE_GLCANVAS