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