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