]> git.saurik.com Git - wxWidgets.git/blame - src/msw/glcanvas.cpp
Fix memory leak by letting the base class version handle the
[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
77ffb593 9// Licence: wxWidgets licence
8b089c5e
JS
10/////////////////////////////////////////////////////////////////////////////
11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
8b089c5e
JS
13#pragma implementation "glcanvas.h"
14#endif
15
16#include "wx/wxprec.h"
17
18#if defined(__BORLANDC__)
19#pragma hdrstop
20#endif
21
8b089c5e
JS
22#if wxUSE_GLCANVAS
23
24#ifndef WX_PRECOMP
af0b1533
VZ
25 #include "wx/frame.h"
26 #include "wx/settings.h"
27 #include "wx/intl.h"
28 #include "wx/log.h"
234d8e90 29 #include "wx/app.h"
8b089c5e
JS
30#endif
31
af0b1533 32#include "wx/msw/private.h"
8b089c5e 33
34fdf762
VS
34// DLL options compatibility check:
35#include "wx/build.h"
36WX_CHECK_BUILD_OPTIONS("wxGL")
37
af0b1533 38#include "wx/glcanvas.h"
8b089c5e 39
0e82bd96
VZ
40/*
41 The following two compiler directives are specific to the Microsoft Visual
42 C++ family of compilers
43
44 Fundementally what they do is instruct the linker to use these two libraries
45 for the resolution of symbols. In essence, this is the equivalent of adding
46 these two libraries to either the Makefile or project file.
47
48 This is NOT a recommended technique, and certainly is unlikely to be used
77ffb593 49 anywhere else in wxWidgets given it is so specific to not only wxMSW, but
0e82bd96
VZ
50 also the VC compiler. However, in the case of opengl support, it's an
51 applicable technique as opengl is optional in setup.h This code (wrapped by
52 wxUSE_GLCANVAS), now allows opengl support to be added purely by modifying
53 setup.h rather than by having to modify either the project or DSP fle.
54
55 See MSDN for further information on the exact usage of these commands.
56*/
57#ifdef _MSC_VER
58# pragma comment( lib, "opengl32" )
59# pragma comment( lib, "glu32" )
60#endif
61
34fdf762 62
b225f659
VZ
63static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass");
64static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR");
8b089c5e
JS
65
66LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
67 WPARAM wParam, LPARAM lParam);
68
69/*
70 * GLContext implementation
71 */
72
2341cf5f 73wxGLContext::wxGLContext(bool WXUNUSED(isRGB), wxGLCanvas *win, const wxPalette& WXUNUSED(palette))
8b089c5e
JS
74{
75 m_window = win;
76
77 m_hDC = win->GetHDC();
78
79 m_glContext = wglCreateContext((HDC) m_hDC);
f6bcfd97 80 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
8b089c5e
JS
81
82 wglMakeCurrent((HDC) m_hDC, m_glContext);
83}
84
85wxGLContext::wxGLContext(
2341cf5f
MB
86 bool WXUNUSED(isRGB), wxGLCanvas *win,
87 const wxPalette& WXUNUSED(palette),
f48d169c
UN
88 const wxGLContext *other /* for sharing display lists */
89 )
8b089c5e 90{
f48d169c 91 m_window = win;
8b089c5e 92
f48d169c 93 m_hDC = win->GetHDC();
8b089c5e 94
f48d169c
UN
95 m_glContext = wglCreateContext((HDC) m_hDC);
96 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
8b089c5e 97
f48d169c
UN
98 if( other != 0 )
99 wglShareLists( other->m_glContext, m_glContext );
8b089c5e 100
f48d169c 101 wglMakeCurrent((HDC) m_hDC, m_glContext);
8b089c5e
JS
102}
103
104wxGLContext::~wxGLContext()
105{
106 if (m_glContext)
107 {
108 wglMakeCurrent(NULL, NULL);
f48d169c 109 wglDeleteContext(m_glContext);
8b089c5e
JS
110 }
111}
112
113void wxGLContext::SwapBuffers()
114{
115 if (m_glContext)
116 {
117 wglMakeCurrent((HDC) m_hDC, m_glContext);
118 ::SwapBuffers((HDC) m_hDC); //blits the backbuffer into DC
119 }
120}
121
122void wxGLContext::SetCurrent()
123{
124 if (m_glContext)
125 {
126 wglMakeCurrent((HDC) m_hDC, m_glContext);
127 }
128
f48d169c
UN
129 /*
130 setupPixelFormat(hDC);
131 setupPalette(hDC);
132 */
8b089c5e
JS
133}
134
2b5f62a0 135void wxGLContext::SetColour(const wxChar *colour)
8b089c5e 136{
564a150b
VZ
137 wxColour col = wxTheColourDatabase->Find(colour);
138 if (col.Ok())
139 {
140 float r = (float)(col.Red()/256.0);
141 float g = (float)(col.Green()/256.0);
142 float b = (float)(col.Blue()/256.0);
143 glColor3f( r, g, b);
144 }
8b089c5e
JS
145}
146
147
148/*
149 * wxGLCanvas implementation
150 */
151
4660d7e5 152IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
8b089c5e 153
4660d7e5 154BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
8b089c5e
JS
155 EVT_SIZE(wxGLCanvas::OnSize)
156 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged)
157 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette)
158END_EVENT_TABLE()
159
160wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
161 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
4660d7e5 162 int *attribList, const wxPalette& palette) : wxWindow()
8b089c5e 163{
f48d169c 164 m_glContext = (wxGLContext*) NULL;
8b089c5e 165
f48d169c 166 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 167
f48d169c
UN
168 if ( ret )
169 {
a756f210
VS
170 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
171 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 172 }
8b089c5e 173
f48d169c 174 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 175
f48d169c
UN
176 SetupPixelFormat(attribList);
177 SetupPalette(palette);
8b089c5e 178
f48d169c 179 m_glContext = new wxGLContext(TRUE, this, palette);
8b089c5e
JS
180}
181
182wxGLCanvas::wxGLCanvas( wxWindow *parent,
183 const wxGLContext *shared, wxWindowID id,
184 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
185 int *attribList, const wxPalette& palette )
4660d7e5 186 : wxWindow()
8b089c5e 187{
f48d169c 188 m_glContext = (wxGLContext*) NULL;
8b089c5e 189
f48d169c 190 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 191
f48d169c
UN
192 if ( ret )
193 {
a756f210
VS
194 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
195 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 196 }
8b089c5e 197
f48d169c 198 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 199
f48d169c
UN
200 SetupPixelFormat(attribList);
201 SetupPalette(palette);
8b089c5e 202
f48d169c 203 m_glContext = new wxGLContext(TRUE, this, palette, shared );
8b089c5e
JS
204}
205
f6bcfd97 206// Not very useful for wxMSW, but this is to be wxGTK compliant
8b089c5e
JS
207
208wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID id,
209 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
210 int *attribList, const wxPalette& palette ):
4660d7e5 211 wxWindow()
8b089c5e 212{
f48d169c 213 m_glContext = (wxGLContext*) NULL;
8b089c5e 214
f48d169c 215 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 216
f48d169c
UN
217 if ( ret )
218 {
a756f210
VS
219 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
220 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 221 }
8b089c5e 222
f48d169c 223 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 224
f48d169c
UN
225 SetupPixelFormat(attribList);
226 SetupPalette(palette);
8b089c5e 227
f48d169c
UN
228 wxGLContext *sharedContext=0;
229 if (shared) sharedContext=shared->GetContext();
230 m_glContext = new wxGLContext(TRUE, this, palette, sharedContext );
8b089c5e
JS
231}
232
233wxGLCanvas::~wxGLCanvas()
234{
235 if (m_glContext)
236 delete m_glContext;
237
238 ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC);
239}
240
b225f659
VZ
241// Replaces wxWindow::Create functionality, since we need to use a different
242// window class
243bool wxGLCanvas::Create(wxWindow *parent,
244 wxWindowID id,
245 const wxPoint& pos,
246 const wxSize& size,
247 long style,
248 const wxString& name)
8b089c5e 249{
b225f659 250 static bool s_registeredGLCanvasClass = FALSE;
8b089c5e 251
f48d169c
UN
252 // We have to register a special window class because we need
253 // the CS_OWNDC style for GLCanvas.
8b089c5e 254
f48d169c
UN
255 /*
256 From Angel Popov <jumpo@bitex.com>
8b089c5e 257
f48d169c
UN
258 Here are two snips from a dicussion in the OpenGL Gamedev list that explains
259 how this problem can be fixed:
8b089c5e 260
f48d169c
UN
261 "There are 5 common DCs available in Win95. These are aquired when you call
262 GetDC or GetDCEx from a window that does _not_ have the OWNDC flag.
263 OWNDC flagged windows do not get their DC from the common DC pool, the issue
264 is they require 800 bytes each from the limited 64Kb local heap for GDI."
8b089c5e 265
f48d169c
UN
266 "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps
267 do), Win95 will actually "steal" it from you. MakeCurrent fails,
268 apparently, because Windows re-assigns the HDC to a different window. The
269 only way to prevent this, the only reliable means, is to set CS_OWNDC."
270 */
8b089c5e 271
b225f659 272 if (!s_registeredGLCanvasClass)
f48d169c
UN
273 {
274 WNDCLASS wndclass;
8b089c5e 275
f48d169c
UN
276 // the fields which are common to all classes
277 wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
278 wndclass.cbClsExtra = 0;
279 wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for?
280 wndclass.hInstance = wxhInstance;
281 wndclass.hIcon = (HICON) NULL;
282 wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
283 wndclass.lpszMenuName = NULL;
8b089c5e 284
f48d169c
UN
285 // Register the GLCanvas class name
286 wndclass.hbrBackground = (HBRUSH)NULL;
287 wndclass.lpszClassName = wxGLCanvasClassName;
b225f659 288 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
8b089c5e 289
b225f659 290 if ( !::RegisterClass(&wndclass) )
8b089c5e 291 {
f48d169c
UN
292 wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
293 return FALSE;
8b089c5e
JS
294 }
295
b225f659
VZ
296 // Register the GLCanvas class name for windows which don't do full repaint
297 // on resize
298 wndclass.lpszClassName = wxGLCanvasClassNameNoRedraw;
299 wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
300
301 if ( !::RegisterClass(&wndclass) )
302 {
303 wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)"));
304
a8d20c57 305 ::UnregisterClass(wxGLCanvasClassName, wxhInstance);
b225f659
VZ
306
307 return FALSE;
308 }
309
310 s_registeredGLCanvasClass = TRUE;
f48d169c
UN
311 }
312
313 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
314
315 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
316 return FALSE;
317
318 parent->AddChild(this);
319
320 DWORD msflags = 0;
f48d169c
UN
321
322 /*
323 A general rule with OpenGL and Win32 is that any window that will have a
324 HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS.
325 You can find references about this within the knowledge base and most OpenGL
326 books that contain the wgl function descriptions.
327 */
8b089c5e 328
fe3d9123 329 WXDWORD exStyle = 0;
b225f659 330 msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
fe3d9123 331 msflags |= MSWGetStyle(style, & exStyle) ;
f48d169c 332
b225f659 333 return MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle);
8b089c5e
JS
334}
335
a3081354 336static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList)
8b089c5e 337{
f48d169c
UN
338 if (attribList) {
339 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
340 pfd.iPixelType = PFD_TYPE_COLORINDEX;
341 pfd.cColorBits = 0;
342 int arg=0;
b225f659 343
f48d169c
UN
344 while( (attribList[arg]!=0) )
345 {
346 switch( attribList[arg++] )
347 {
348 case WX_GL_RGBA:
349 pfd.iPixelType = PFD_TYPE_RGBA;
350 break;
351 case WX_GL_BUFFER_SIZE:
352 pfd.cColorBits = attribList[arg++];
353 break;
354 case WX_GL_LEVEL:
355 // this member looks like it may be obsolete
356 if (attribList[arg] > 0) {
d728116a 357 pfd.iLayerType = (BYTE)PFD_OVERLAY_PLANE;
f48d169c 358 } else if (attribList[arg] < 0) {
d728116a 359 pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE;
f48d169c 360 } else {
d728116a 361 pfd.iLayerType = (BYTE)PFD_MAIN_PLANE;
f48d169c
UN
362 }
363 arg++;
364 break;
365 case WX_GL_DOUBLEBUFFER:
366 pfd.dwFlags |= PFD_DOUBLEBUFFER;
367 break;
368 case WX_GL_STEREO:
369 pfd.dwFlags |= PFD_STEREO;
370 break;
371 case WX_GL_AUX_BUFFERS:
372 pfd.cAuxBuffers = attribList[arg++];
373 break;
374 case WX_GL_MIN_RED:
375 pfd.cColorBits += (pfd.cRedBits = attribList[arg++]);
376 break;
377 case WX_GL_MIN_GREEN:
378 pfd.cColorBits += (pfd.cGreenBits = attribList[arg++]);
379 break;
380 case WX_GL_MIN_BLUE:
381 pfd.cColorBits += (pfd.cBlueBits = attribList[arg++]);
382 break;
383 case WX_GL_MIN_ALPHA:
384 // doesn't count in cColorBits
385 pfd.cAlphaBits = attribList[arg++];
386 break;
b225f659 387 case WX_GL_DEPTH_SIZE:
f48d169c
UN
388 pfd.cDepthBits = attribList[arg++];
389 break;
b225f659 390 case WX_GL_STENCIL_SIZE:
f48d169c
UN
391 pfd.cStencilBits = attribList[arg++];
392 break;
393 case WX_GL_MIN_ACCUM_RED:
394 pfd.cAccumBits += (pfd.cAccumRedBits = attribList[arg++]);
395 break;
396 case WX_GL_MIN_ACCUM_GREEN:
397 pfd.cAccumBits += (pfd.cAccumGreenBits = attribList[arg++]);
398 break;
399 case WX_GL_MIN_ACCUM_BLUE:
400 pfd.cAccumBits += (pfd.cAccumBlueBits = attribList[arg++]);
401 break;
402 case WX_GL_MIN_ACCUM_ALPHA:
403 pfd.cAccumBits += (pfd.cAccumAlphaBits = attribList[arg++]);
404 break;
405 default:
406 break;
407 }
8b089c5e 408 }
f48d169c 409 }
a3081354
VZ
410}
411
412void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC)
413{
a3081354 414 PIXELFORMATDESCRIPTOR pfd = {
b225f659
VZ
415 sizeof(PIXELFORMATDESCRIPTOR), /* size */
416 1, /* version */
417 PFD_SUPPORT_OPENGL |
418 PFD_DRAW_TO_WINDOW |
419 PFD_DOUBLEBUFFER, /* support double-buffering */
420 PFD_TYPE_RGBA, /* color type */
421 16, /* prefered color depth */
422 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
423 0, /* no alpha buffer */
424 0, /* alpha bits (ignored) */
425 0, /* no accumulation buffer */
426 0, 0, 0, 0, /* accum bits (ignored) */
427 16, /* depth buffer */
428 0, /* no stencil buffer */
429 0, /* no auxiliary buffers */
430 PFD_MAIN_PLANE, /* main layer */
431 0, /* reserved */
432 0, 0, 0, /* no layer, visible, damage masks */
433 };
a3081354
VZ
434
435 AdjustPFDForAttributes(pfd, attribList);
436
72adfc4b 437 int pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd);
f48d169c 438 if (pixelFormat == 0) {
72adfc4b 439 wxLogLastError(_T("ChoosePixelFormat"));
f48d169c 440 }
a3081354 441 else {
72adfc4b
VZ
442 if ( !::SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) ) {
443 wxLogLastError(_T("SetPixelFormat"));
a3081354 444 }
f48d169c 445 }
8b089c5e
JS
446}
447
448void wxGLCanvas::SetupPalette(const wxPalette& palette)
449{
450 int pixelFormat = GetPixelFormat((HDC) m_hDC);
451 PIXELFORMATDESCRIPTOR pfd;
452
453 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
454
455 if (pfd.dwFlags & PFD_NEED_PALETTE)
456 {
457 }
458 else
459 {
b225f659 460 return;
8b089c5e
JS
461 }
462
463 m_palette = palette;
464
465 if ( !m_palette.Ok() )
466 {
467 m_palette = CreateDefaultPalette();
468 }
469
470 if (m_palette.Ok())
471 {
472 SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE);
473 RealizePalette((HDC) m_hDC);
474 }
475}
476
477wxPalette wxGLCanvas::CreateDefaultPalette()
478{
479 PIXELFORMATDESCRIPTOR pfd;
480 int paletteSize;
481 int pixelFormat = GetPixelFormat((HDC) m_hDC);
482
483 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
484
f48d169c 485 paletteSize = 1 << pfd.cColorBits;
8b089c5e
JS
486
487 LOGPALETTE* pPal =
488 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
489 pPal->palVersion = 0x300;
490 pPal->palNumEntries = paletteSize;
491
492 /* build a simple RGB color palette */
493 {
b225f659
VZ
494 int redMask = (1 << pfd.cRedBits) - 1;
495 int greenMask = (1 << pfd.cGreenBits) - 1;
496 int blueMask = (1 << pfd.cBlueBits) - 1;
497 int i;
498
499 for (i=0; i<paletteSize; ++i) {
500 pPal->palPalEntry[i].peRed =
501 (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
502 pPal->palPalEntry[i].peGreen =
503 (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
504 pPal->palPalEntry[i].peBlue =
505 (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
506 pPal->palPalEntry[i].peFlags = 0;
507 }
8b089c5e
JS
508 }
509
510 HPALETTE hPalette = CreatePalette(pPal);
511 free(pPal);
512
513 wxPalette palette;
514 palette.SetHPALETTE((WXHPALETTE) hPalette);
515
516 return palette;
517}
518
519void wxGLCanvas::SwapBuffers()
520{
521 if (m_glContext)
522 m_glContext->SwapBuffers();
523}
524
2341cf5f 525void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
8b089c5e 526{
8b089c5e
JS
527}
528
529void wxGLCanvas::SetCurrent()
530{
531 if (m_glContext)
532 {
533 m_glContext->SetCurrent();
534 }
535}
536
2b5f62a0 537void wxGLCanvas::SetColour(const wxChar *colour)
8b089c5e
JS
538{
539 if (m_glContext)
540 m_glContext->SetColour(colour);
541}
542
543// TODO: Have to have this called by parent frame (?)
544// So we need wxFrame to call OnQueryNewPalette for all children...
545void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
546{
f48d169c
UN
547 /* realize palette if this is the current window */
548 if ( GetPalette()->Ok() ) {
549 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
550 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
551 ::RealizePalette((HDC) GetHDC());
552 Refresh();
553 event.SetPaletteRealized(TRUE);
554 }
555 else
556 event.SetPaletteRealized(FALSE);
8b089c5e
JS
557}
558
559// I think this doesn't have to be propagated to child windows.
560void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
561{
f48d169c
UN
562 /* realize palette if this is *not* the current window */
563 if ( GetPalette() &&
8b089c5e 564 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
f48d169c
UN
565 {
566 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
567 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
568 ::RealizePalette((HDC) GetHDC());
569 Refresh();
570 }
8b089c5e
JS
571}
572
573/* Give extensions proper function names. */
574
575/* EXT_vertex_array */
2341cf5f 576void glArrayElementEXT(GLint WXUNUSED(i))
8b089c5e
JS
577{
578}
579
2341cf5f 580void glColorPointerEXT(GLint WXUNUSED(size), GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer))
8b089c5e
JS
581{
582}
583
584void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count)
585{
586#ifdef GL_EXT_vertex_array
587 static PFNGLDRAWARRAYSEXTPROC proc = 0;
588
589 if ( !proc )
590 {
591 proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT");
592 }
593
594 if ( proc )
595 (* proc) (mode, first, count);
596#endif
597}
598
2341cf5f 599void glEdgeFlagPointerEXT(GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLboolean *WXUNUSED(pointer))
8b089c5e
JS
600{
601}
602
2341cf5f 603void glGetPointervEXT(GLenum WXUNUSED(pname), GLvoid* *WXUNUSED(params))
8b089c5e
JS
604{
605}
606
2341cf5f 607void glIndexPointerEXT(GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer))
8b089c5e
JS
608{
609}
610
611void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
612{
613#ifdef GL_EXT_vertex_array
f48d169c 614 static PFNGLNORMALPOINTEREXTPROC proc = 0;
8b089c5e 615
f48d169c
UN
616 if ( !proc )
617 {
618 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
619 }
8b089c5e 620
f48d169c
UN
621 if ( proc )
622 (* proc) (type, stride, count, pointer);
8b089c5e
JS
623#endif
624}
625
2341cf5f 626void glTexCoordPointerEXT(GLint WXUNUSED(size), GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer))
8b089c5e
JS
627{
628}
629
630void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
631{
632#ifdef GL_EXT_vertex_array
f48d169c 633 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
8b089c5e 634
f48d169c
UN
635 if ( !proc )
636 {
637 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
638 }
639 if ( proc )
640 (* proc) (size, type, stride, count, pointer);
8b089c5e
JS
641#endif
642}
643
644/* EXT_color_subtable */
2341cf5f 645void glColorSubtableEXT(GLenum WXUNUSED(target), GLsizei WXUNUSED(start), GLsizei WXUNUSED(count), GLenum WXUNUSED(format), GLenum WXUNUSED(type), const GLvoid *WXUNUSED(table))
8b089c5e
JS
646{
647}
648
649/* EXT_color_table */
2341cf5f 650void glColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(internalformat), GLsizei WXUNUSED(width), GLenum WXUNUSED(format), GLenum WXUNUSED(type), const GLvoid *WXUNUSED(table))
8b089c5e
JS
651{
652}
653
2341cf5f 654void glCopyColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(internalformat), GLint WXUNUSED(x), GLint WXUNUSED(y), GLsizei WXUNUSED(width))
8b089c5e
JS
655{
656}
657
2341cf5f 658void glGetColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(format), GLenum WXUNUSED(type), GLvoid *WXUNUSED(table))
8b089c5e
JS
659{
660}
661
2341cf5f 662void glGetColorTableParamaterfvEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(pname), GLfloat *WXUNUSED(params))
8b089c5e
JS
663{
664}
665
2341cf5f 666void glGetColorTavleParameterivEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(pname), GLint *WXUNUSED(params))
8b089c5e
JS
667{
668}
669
670/* SGI_compiled_vertex_array */
2341cf5f 671void glLockArraysSGI(GLint WXUNUSED(first), GLsizei WXUNUSED(count))
8b089c5e
JS
672{
673}
674
675void glUnlockArraysSGI()
676{
677}
678
679
680/* SGI_cull_vertex */
2341cf5f 681void glCullParameterdvSGI(GLenum WXUNUSED(pname), GLdouble* WXUNUSED(params))
8b089c5e
JS
682{
683}
684
2341cf5f 685void glCullParameterfvSGI(GLenum WXUNUSED(pname), GLfloat* WXUNUSED(params))
8b089c5e
JS
686{
687}
688
689/* SGI_index_func */
2341cf5f 690void glIndexFuncSGI(GLenum WXUNUSED(func), GLclampf WXUNUSED(ref))
8b089c5e
JS
691{
692}
693
694/* SGI_index_material */
2341cf5f 695void glIndexMaterialSGI(GLenum WXUNUSED(face), GLenum WXUNUSED(mode))
8b089c5e
JS
696{
697}
698
699/* WIN_swap_hint */
2341cf5f 700void glAddSwapHintRectWin(GLint WXUNUSED(x), GLint WXUNUSED(y), GLsizei WXUNUSED(width), GLsizei WXUNUSED(height))
8b089c5e
JS
701{
702}
703
a3081354
VZ
704
705//---------------------------------------------------------------------------
706// wxGLApp
707//---------------------------------------------------------------------------
708
709IMPLEMENT_CLASS(wxGLApp, wxApp)
710
711bool wxGLApp::InitGLVisual(int *attribList)
712{
713 int pixelFormat;
714 PIXELFORMATDESCRIPTOR pfd = {
b225f659
VZ
715 sizeof(PIXELFORMATDESCRIPTOR), /* size */
716 1, /* version */
717 PFD_SUPPORT_OPENGL |
718 PFD_DRAW_TO_WINDOW |
719 PFD_DOUBLEBUFFER, /* support double-buffering */
720 PFD_TYPE_RGBA, /* color type */
721 16, /* prefered color depth */
722 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
723 0, /* no alpha buffer */
724 0, /* alpha bits (ignored) */
725 0, /* no accumulation buffer */
726 0, 0, 0, 0, /* accum bits (ignored) */
727 16, /* depth buffer */
728 0, /* no stencil buffer */
729 0, /* no auxiliary buffers */
730 PFD_MAIN_PLANE, /* main layer */
731 0, /* reserved */
732 0, 0, 0, /* no layer, visible, damage masks */
733 };
a3081354
VZ
734
735 AdjustPFDForAttributes(pfd, attribList);
736
737 // use DC for whole (root) screen, since no windows have yet been created
2b8646e0 738 pixelFormat = ChoosePixelFormat(ScreenHDC(), &pfd);
a3081354
VZ
739
740 if (pixelFormat == 0) {
741 wxLogError(_("Failed to initialize OpenGL"));
742 return FALSE;
743 }
744
745 return TRUE;
746}
747
748wxGLApp::~wxGLApp()
749{
750}
751
8b089c5e
JS
752#endif
753 // wxUSE_GLCANVAS