]> git.saurik.com Git - wxWidgets.git/blame - src/msw/glcanvas.cpp
Better fix
[wxWidgets.git] / src / msw / glcanvas.cpp
CommitLineData
8b089c5e 1/////////////////////////////////////////////////////////////////////////////
2b8646e0 2// Name: src/msw/glcanvas.cpp
77ffb593 3// Purpose: wxGLCanvas, for using OpenGL with wxWidgets under MS Windows
8b089c5e
JS
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
8b089c5e
JS
10/////////////////////////////////////////////////////////////////////////////
11
dc3065a5
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
8b089c5e
JS
20#include "wx/wxprec.h"
21
22#if defined(__BORLANDC__)
02761f6c 23 #pragma hdrstop
8b089c5e
JS
24#endif
25
8b089c5e
JS
26#if wxUSE_GLCANVAS
27
28#ifndef WX_PRECOMP
af0b1533
VZ
29 #include "wx/intl.h"
30 #include "wx/log.h"
234d8e90 31 #include "wx/app.h"
02761f6c 32 #include "wx/module.h"
8b089c5e
JS
33#endif
34
af0b1533 35#include "wx/msw/private.h"
8b089c5e 36
af0b1533 37#include "wx/glcanvas.h"
8b089c5e 38
dc3065a5
VZ
39// from src/msw/window.cpp
40LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
41 WPARAM wParam, LPARAM lParam);
42
43#ifdef GL_EXT_vertex_array
b8ee9a86
WS
44 #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) name
45#else
46 #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) WXUNUSED(name)
47#endif
48
dc3065a5
VZ
49// ----------------------------------------------------------------------------
50// libraries
51// ----------------------------------------------------------------------------
52
0e82bd96
VZ
53/*
54 The following two compiler directives are specific to the Microsoft Visual
55 C++ family of compilers
56
57 Fundementally what they do is instruct the linker to use these two libraries
58 for the resolution of symbols. In essence, this is the equivalent of adding
59 these two libraries to either the Makefile or project file.
60
61 This is NOT a recommended technique, and certainly is unlikely to be used
77ffb593 62 anywhere else in wxWidgets given it is so specific to not only wxMSW, but
0e82bd96
VZ
63 also the VC compiler. However, in the case of opengl support, it's an
64 applicable technique as opengl is optional in setup.h This code (wrapped by
65 wxUSE_GLCANVAS), now allows opengl support to be added purely by modifying
66 setup.h rather than by having to modify either the project or DSP fle.
67
68 See MSDN for further information on the exact usage of these commands.
69*/
70#ifdef _MSC_VER
71# pragma comment( lib, "opengl32" )
72# pragma comment( lib, "glu32" )
73#endif
74
dc3065a5
VZ
75// ----------------------------------------------------------------------------
76// constants
77// ----------------------------------------------------------------------------
34fdf762 78
b225f659
VZ
79static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass");
80static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR");
8b089c5e 81
dc3065a5
VZ
82// ============================================================================
83// implementation
84// ============================================================================
8b089c5e 85
53fcd32e
VZ
86// ----------------------------------------------------------------------------
87// wxGLModule is responsible for unregistering wxGLCanvasClass Windows class
88// ----------------------------------------------------------------------------
89
90class wxGLModule : public wxModule
91{
92public:
93 bool OnInit() { return true; }
94 void OnExit() { UnregisterClasses(); }
95
96 // register the GL classes if not done yet, return true if ok, false if
97 // registration failed
98 static bool RegisterClasses();
99
100 // unregister the classes, done automatically on program termination
101 static void UnregisterClasses();
102
103private:
104 // wxGLCanvas is only used from the main thread so this is MT-ok
105 static bool ms_registeredGLClasses;
106
107 DECLARE_DYNAMIC_CLASS(wxGLModule)
108};
109
110IMPLEMENT_DYNAMIC_CLASS(wxGLModule, wxModule)
111
112bool wxGLModule::ms_registeredGLClasses = false;
113
114/* static */
115bool wxGLModule::RegisterClasses()
116{
dc3065a5 117 if ( ms_registeredGLClasses )
53fcd32e
VZ
118 return true;
119
120 // We have to register a special window class because we need the CS_OWNDC
dc3065a5
VZ
121 // style for GLCanvas: some OpenGL drivers are buggy and don't work with
122 // windows without this style
53fcd32e
VZ
123 WNDCLASS wndclass;
124
125 // the fields which are common to all classes
126 wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
127 wndclass.cbClsExtra = 0;
128 wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for?
129 wndclass.hInstance = wxhInstance;
130 wndclass.hIcon = (HICON) NULL;
131 wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
132 wndclass.lpszMenuName = NULL;
133
134 // Register the GLCanvas class name
135 wndclass.hbrBackground = (HBRUSH)NULL;
136 wndclass.lpszClassName = wxGLCanvasClassName;
137 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
138
139 if ( !::RegisterClass(&wndclass) )
140 {
141 wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
142 return false;
143 }
144
145 // Register the GLCanvas class name for windows which don't do full repaint
146 // on resize
147 wndclass.lpszClassName = wxGLCanvasClassNameNoRedraw;
148 wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
149
150 if ( !::RegisterClass(&wndclass) )
151 {
152 wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)"));
153
154 ::UnregisterClass(wxGLCanvasClassName, wxhInstance);
155
156 return false;
157 }
158
159 ms_registeredGLClasses = true;
160
161 return true;
162}
163
164/* static */
165void wxGLModule::UnregisterClasses()
166{
167 // we need to unregister the classes in case we're in a DLL which is
168 // unloaded and then loaded again because if we don't, the registration is
169 // going to fail in wxGLCanvas::Create() the next time we're loaded
170 if ( ms_registeredGLClasses )
171 {
172 ::UnregisterClass(wxGLCanvasClassName, wxhInstance);
173 ::UnregisterClass(wxGLCanvasClassNameNoRedraw, wxhInstance);
174
175 ms_registeredGLClasses = false;
176 }
177}
178
dc3065a5
VZ
179// ----------------------------------------------------------------------------
180// wxGLContext
181// ----------------------------------------------------------------------------
8b089c5e 182
b7ea712c 183IMPLEMENT_CLASS(wxGLContext, wxObject)
8b089c5e 184
dc3065a5 185wxGLContext::wxGLContext(wxGLCanvas *win, const wxGLContext* other)
8b089c5e 186{
dc3065a5
VZ
187 m_glContext = wglCreateContext(win->GetHDC());
188 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGL context") );
8b089c5e 189
dc3065a5
VZ
190 if ( other )
191 {
192 if ( !wglShareLists(other->m_glContext, m_glContext) )
193 wxLogLastError(_T("wglShareLists"));
194 }
8b089c5e
JS
195}
196
197wxGLContext::~wxGLContext()
198{
dc3065a5 199 // note that it's ok to delete the context even if it's the current one
f48d169c 200 wglDeleteContext(m_glContext);
8b089c5e
JS
201}
202
5ec69e96 203bool wxGLContext::SetCurrent(const wxGLCanvas& win) const
8b089c5e 204{
dc3065a5
VZ
205 if ( !wglMakeCurrent(win.GetHDC(), m_glContext) )
206 {
207 wxLogLastError(_T("wglMakeCurrent"));
5ec69e96 208 return false;
dc3065a5 209 }
5ec69e96 210 return true;
8b089c5e
JS
211}
212
dc3065a5
VZ
213// ============================================================================
214// wxGLCanvas
215// ============================================================================
8b089c5e 216
4660d7e5 217IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
8b089c5e 218
4660d7e5 219BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
8b089c5e
JS
220 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged)
221 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette)
222END_EVENT_TABLE()
223
dc3065a5
VZ
224// ----------------------------------------------------------------------------
225// wxGLCanvas construction
226// ----------------------------------------------------------------------------
8b089c5e 227
dc3065a5 228void wxGLCanvas::Init()
8b089c5e 229{
dc3065a5
VZ
230#if WXWIN_COMPATIBILITY_2_8
231 m_glContext = NULL;
232#endif
233 m_hDC = NULL;
8b089c5e
JS
234}
235
dc3065a5
VZ
236wxGLCanvas::wxGLCanvas(wxWindow *parent,
237 wxWindowID id,
238 const int *attribList,
239 const wxPoint& pos,
240 const wxSize& size,
241 long style,
242 const wxString& name,
243 const wxPalette& palette)
8b089c5e 244{
dc3065a5 245 Init();
8b089c5e 246
dc3065a5 247 (void)Create(parent, id, pos, size, style, name, attribList, palette);
8b089c5e
JS
248}
249
250wxGLCanvas::~wxGLCanvas()
251{
dc3065a5
VZ
252#if WXWIN_COMPATIBILITY_2_8
253 delete m_glContext;
254#endif
8b089c5e 255
dc3065a5 256 ::ReleaseDC(GetHwnd(), m_hDC);
8b089c5e
JS
257}
258
b225f659
VZ
259// Replaces wxWindow::Create functionality, since we need to use a different
260// window class
261bool wxGLCanvas::Create(wxWindow *parent,
262 wxWindowID id,
263 const wxPoint& pos,
264 const wxSize& size,
265 long style,
dc3065a5
VZ
266 const wxString& name,
267 const int *attribList,
268 const wxPalette& palette)
8b089c5e 269{
53fcd32e 270 wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") );
8b089c5e 271
53fcd32e 272 if ( !wxGLModule::RegisterClasses() )
b225f659 273 {
53fcd32e 274 wxLogError(_("Failed to register OpenGL window class."));
b225f659 275
213ceb3f 276 return false;
b225f659
VZ
277 }
278
53fcd32e
VZ
279 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
280 return false;
f48d169c 281
53fcd32e 282 parent->AddChild(this);
f48d169c 283
53fcd32e
VZ
284 /*
285 A general rule with OpenGL and Win32 is that any window that will have a
286 HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS.
287 You can find references about this within the knowledge base and most OpenGL
288 books that contain the wgl function descriptions.
289 */
53fcd32e 290 WXDWORD exStyle = 0;
dc3065a5
VZ
291 DWORD msflags = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
292 msflags |= MSWGetStyle(style, &exStyle);
293
294 if ( !MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle) )
295 return false;
f48d169c 296
dc3065a5
VZ
297 m_hDC = ::GetDC(GetHwnd());
298 if ( !m_hDC )
299 return false;
300
301 if ( !DoSetup(attribList) )
302 return false;
303
304#if wxUSE_PALETTE
305 if ( !SetupPalette(palette) )
306 return false;
307#else // !wxUSE_PALETTE
308 wxUnusedVar(palette);
309#endif // wxUSE_PALETTE/!wxUSE_PALETTE
310
311 return true;
312}
313
314// ----------------------------------------------------------------------------
315// operations
316// ----------------------------------------------------------------------------
317
5ec69e96 318bool wxGLCanvas::SwapBuffers()
dc3065a5
VZ
319{
320 if ( !::SwapBuffers(m_hDC) )
5ec69e96
VZ
321 {
322 return false;
dc3065a5 323 wxLogLastError(_T("SwapBuffers"));
5ec69e96
VZ
324 }
325 return true;
8b089c5e
JS
326}
327
dc3065a5
VZ
328// ----------------------------------------------------------------------------
329// pixel format stuff
330// ----------------------------------------------------------------------------
331
332static void
333AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, const int *attribList)
8b089c5e 334{
dc3065a5
VZ
335 if ( !attribList )
336 return;
337
f48d169c
UN
338 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
339 pfd.iPixelType = PFD_TYPE_COLORINDEX;
340 pfd.cColorBits = 0;
341 int arg=0;
b225f659 342
dc3065a5 343 while ( attribList[arg] )
f48d169c 344 {
dc3065a5
VZ
345 switch ( attribList[arg++] )
346 {
347 case WX_GL_RGBA:
348 pfd.iPixelType = PFD_TYPE_RGBA;
349 break;
350 case WX_GL_BUFFER_SIZE:
351 pfd.cColorBits = attribList[arg++];
352 break;
353 case WX_GL_LEVEL:
354 // this member looks like it may be obsolete
355 if ( attribList[arg] > 0 )
356 pfd.iLayerType = PFD_OVERLAY_PLANE;
357 else if ( attribList[arg] < 0 )
358 pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE;
359 else
360 pfd.iLayerType = PFD_MAIN_PLANE;
361 arg++;
362 break;
363 case WX_GL_DOUBLEBUFFER:
364 pfd.dwFlags |= PFD_DOUBLEBUFFER;
365 break;
366 case WX_GL_STEREO:
367 pfd.dwFlags |= PFD_STEREO;
368 break;
369 case WX_GL_AUX_BUFFERS:
370 pfd.cAuxBuffers = attribList[arg++];
371 break;
372 case WX_GL_MIN_RED:
373 pfd.cColorBits = (pfd.cColorBits +
374 (pfd.cRedBits = attribList[arg++]));
375 break;
376 case WX_GL_MIN_GREEN:
377 pfd.cColorBits = (pfd.cColorBits +
378 (pfd.cGreenBits = attribList[arg++]));
379 break;
380 case WX_GL_MIN_BLUE:
381 pfd.cColorBits = (pfd.cColorBits +
382 (pfd.cBlueBits = attribList[arg++]));
383 break;
384 case WX_GL_MIN_ALPHA:
385 // doesn't count in cColorBits
386 pfd.cAlphaBits = attribList[arg++];
387 break;
388 case WX_GL_DEPTH_SIZE:
389 pfd.cDepthBits = attribList[arg++];
390 break;
391 case WX_GL_STENCIL_SIZE:
392 pfd.cStencilBits = attribList[arg++];
393 break;
394 case WX_GL_MIN_ACCUM_RED:
395 pfd.cAccumBits = (pfd.cAccumBits +
396 (pfd.cAccumRedBits = attribList[arg++]));
397 break;
398 case WX_GL_MIN_ACCUM_GREEN:
399 pfd.cAccumBits = (pfd.cAccumBits +
400 (pfd.cAccumGreenBits = attribList[arg++]));
401 break;
402 case WX_GL_MIN_ACCUM_BLUE:
403 pfd.cAccumBits = (pfd.cAccumBits +
404 (pfd.cAccumBlueBits = attribList[arg++]));
405 break;
406 case WX_GL_MIN_ACCUM_ALPHA:
407 pfd.cAccumBits = (pfd.cAccumBits +
408 (pfd.cAccumAlphaBits = attribList[arg++]));
409 break;
410 }
8b089c5e 411 }
a3081354
VZ
412}
413
dc3065a5
VZ
414/* static */
415int
416wxGLCanvas::ChooseMatchingPixelFormat(HDC hdc,
417 const int *attribList,
418 PIXELFORMATDESCRIPTOR *ppfd)
a3081354 419{
dc3065a5
VZ
420 // default neutral pixel format
421 PIXELFORMATDESCRIPTOR pfd =
422 {
423 sizeof(PIXELFORMATDESCRIPTOR), // size
424 1, // version
b225f659
VZ
425 PFD_SUPPORT_OPENGL |
426 PFD_DRAW_TO_WINDOW |
dc3065a5
VZ
427 PFD_DOUBLEBUFFER, // support double-buffering
428 PFD_TYPE_RGBA, // color type
429 16, // preferred color depth
430 0, 0, 0, 0, 0, 0, // color bits (ignored)
431 0, // no alpha buffer
432 0, // alpha bits (ignored)
433 0, // no accumulation buffer
434 0, 0, 0, 0, // accumulator bits (ignored)
435 16, // depth buffer
436 0, // no stencil buffer
437 0, // no auxiliary buffers
438 PFD_MAIN_PLANE, // main layer
439 0, // reserved
440 0, 0, 0, // no layer, visible, damage masks
b225f659 441 };
a3081354 442
dc3065a5
VZ
443 if ( !ppfd )
444 ppfd = &pfd;
445 else
446 *ppfd = pfd;
a3081354 447
dc3065a5
VZ
448 AdjustPFDForAttributes(*ppfd, attribList);
449
450 return ::ChoosePixelFormat(hdc, ppfd);
8b089c5e
JS
451}
452
3f20f7d8
VZ
453/* static */
454bool wxGLCanvasBase::IsDisplaySupported(const int *attribList)
455{
456 // We need a device context to test the pixel format, so get one
457 // for the root window.
458 return wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList) > 0;
459}
460
dc3065a5 461bool wxGLCanvas::DoSetup(const int *attribList)
8b089c5e 462{
8b089c5e 463 PIXELFORMATDESCRIPTOR pfd;
dc3065a5
VZ
464 const int pixelFormat = ChooseMatchingPixelFormat(m_hDC, attribList, &pfd);
465 if ( !pixelFormat )
466 {
467 wxLogLastError(_T("ChoosePixelFormat"));
468 return false;
469 }
470
471 if ( !::SetPixelFormat(m_hDC, pixelFormat, &pfd) )
472 {
473 wxLogLastError(_T("SetPixelFormat"));
474 return false;
475 }
476
477 return true;
478}
479
480// ----------------------------------------------------------------------------
481// palette stuff
482// ----------------------------------------------------------------------------
8b089c5e 483
dc3065a5 484#if wxUSE_PALETTE
8b089c5e 485
dc3065a5
VZ
486bool wxGLCanvas::SetupPalette(const wxPalette& palette)
487{
488 const int pixelFormat = ::GetPixelFormat(m_hDC);
489 if ( !pixelFormat )
8b089c5e 490 {
dc3065a5
VZ
491 wxLogLastError(_T("GetPixelFormat"));
492 return false;
8b089c5e 493 }
dc3065a5
VZ
494
495 PIXELFORMATDESCRIPTOR pfd;
496 if ( !::DescribePixelFormat(m_hDC, pixelFormat, sizeof(pfd), &pfd) )
8b089c5e 497 {
dc3065a5
VZ
498 wxLogLastError(_T("DescribePixelFormat"));
499 return false;
8b089c5e
JS
500 }
501
dc3065a5
VZ
502 if ( !(pfd.dwFlags & PFD_NEED_PALETTE) )
503 return true;
504
8b089c5e
JS
505 m_palette = palette;
506
507 if ( !m_palette.Ok() )
508 {
509 m_palette = CreateDefaultPalette();
dc3065a5
VZ
510 if ( !m_palette.Ok() )
511 return false;
512 }
513
514 if ( !::SelectPalette(m_hDC, GetHpaletteOf(m_palette), FALSE) )
515 {
516 wxLogLastError(_T("SelectPalette"));
517 return false;
8b089c5e
JS
518 }
519
dc3065a5 520 if ( ::RealizePalette(m_hDC) == GDI_ERROR )
8b089c5e 521 {
dc3065a5
VZ
522 wxLogLastError(_T("RealizePalette"));
523 return false;
8b089c5e 524 }
dc3065a5
VZ
525
526 return true;
8b089c5e
JS
527}
528
529wxPalette wxGLCanvas::CreateDefaultPalette()
530{
531 PIXELFORMATDESCRIPTOR pfd;
532 int paletteSize;
dc3065a5 533 int pixelFormat = GetPixelFormat(m_hDC);
8b089c5e 534
dc3065a5 535 DescribePixelFormat(m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
8b089c5e 536
f48d169c 537 paletteSize = 1 << pfd.cColorBits;
8b089c5e
JS
538
539 LOGPALETTE* pPal =
540 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
541 pPal->palVersion = 0x300;
b8ee9a86 542 pPal->palNumEntries = (WORD)paletteSize;
8b089c5e
JS
543
544 /* build a simple RGB color palette */
545 {
b225f659
VZ
546 int redMask = (1 << pfd.cRedBits) - 1;
547 int greenMask = (1 << pfd.cGreenBits) - 1;
548 int blueMask = (1 << pfd.cBlueBits) - 1;
549 int i;
550
551 for (i=0; i<paletteSize; ++i) {
552 pPal->palPalEntry[i].peRed =
b8ee9a86 553 (BYTE)((((i >> pfd.cRedShift) & redMask) * 255) / redMask);
b225f659 554 pPal->palPalEntry[i].peGreen =
b8ee9a86 555 (BYTE)((((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask);
b225f659 556 pPal->palPalEntry[i].peBlue =
b8ee9a86 557 (BYTE)((((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask);
b225f659
VZ
558 pPal->palPalEntry[i].peFlags = 0;
559 }
8b089c5e
JS
560 }
561
562 HPALETTE hPalette = CreatePalette(pPal);
563 free(pPal);
564
565 wxPalette palette;
566 palette.SetHPALETTE((WXHPALETTE) hPalette);
567
568 return palette;
569}
570
8b089c5e
JS
571void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
572{
f48d169c
UN
573 /* realize palette if this is the current window */
574 if ( GetPalette()->Ok() ) {
575 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
dc3065a5
VZ
576 ::SelectPalette(GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
577 ::RealizePalette(GetHDC());
f48d169c 578 Refresh();
213ceb3f 579 event.SetPaletteRealized(true);
f48d169c
UN
580 }
581 else
213ceb3f 582 event.SetPaletteRealized(false);
8b089c5e
JS
583}
584
8b089c5e
JS
585void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
586{
f48d169c
UN
587 /* realize palette if this is *not* the current window */
588 if ( GetPalette() &&
8b089c5e 589 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
f48d169c
UN
590 {
591 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
dc3065a5
VZ
592 ::SelectPalette(GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
593 ::RealizePalette(GetHDC());
f48d169c
UN
594 Refresh();
595 }
8b089c5e
JS
596}
597
dc3065a5 598#endif // wxUSE_PALETTE
a3081354 599
dc3065a5
VZ
600// ----------------------------------------------------------------------------
601// deprecated wxGLCanvas methods using implicit wxGLContext
602// ----------------------------------------------------------------------------
a3081354 603
dc3065a5
VZ
604// deprecated constructors creating an implicit m_glContext
605#if WXWIN_COMPATIBILITY_2_8
606
607wxGLCanvas::wxGLCanvas(wxWindow *parent,
608 wxWindowID id,
609 const wxPoint& pos,
610 const wxSize& size,
611 long style,
612 const wxString& name,
613 const int *attribList,
614 const wxPalette& palette)
a3081354 615{
dc3065a5 616 Init();
a3081354 617
dc3065a5
VZ
618 if ( Create(parent, id, pos, size, style, name, attribList, palette) )
619 m_glContext = new wxGLContext(this);
620}
a3081354 621
dc3065a5
VZ
622wxGLCanvas::wxGLCanvas(wxWindow *parent,
623 const wxGLContext *shared,
624 wxWindowID id,
625 const wxPoint& pos,
626 const wxSize& size,
627 long style,
628 const wxString& name,
629 const int *attribList,
630 const wxPalette& palette)
631{
632 Init();
a3081354 633
dc3065a5
VZ
634 if ( Create(parent, id, pos, size, style, name, attribList, palette) )
635 m_glContext = new wxGLContext(this, shared);
636}
637
638wxGLCanvas::wxGLCanvas(wxWindow *parent,
639 const wxGLCanvas *shared,
640 wxWindowID id,
641 const wxPoint& pos,
642 const wxSize& size,
643 long style,
644 const wxString& name,
645 const int *attribList,
646 const wxPalette& palette)
647{
648 Init();
a3081354 649
dc3065a5
VZ
650 if ( Create(parent, id, pos, size, style, name, attribList, palette) )
651 m_glContext = new wxGLContext(this, shared ? shared->m_glContext : NULL);
a3081354
VZ
652}
653
dc3065a5
VZ
654#endif // WXWIN_COMPATIBILITY_2_8
655
656
657// ----------------------------------------------------------------------------
658// wxGLApp
659// ----------------------------------------------------------------------------
660
661bool wxGLApp::InitGLVisual(const int *attribList)
a3081354 662{
dc3065a5
VZ
663 if ( !wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList) )
664 {
665 wxLogError(_("Failed to initialize OpenGL"));
666 return false;
667 }
668
669 return true;
a3081354
VZ
670}
671
dc3065a5 672#endif // wxUSE_GLCANVAS