]> git.saurik.com Git - wxWidgets.git/blob - src/msw/glcanvas.cpp
1.
[wxWidgets.git] / src / msw / glcanvas.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/glcanvas.cpp
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
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 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
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 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
172 }
173
174 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
175
176 SetupPixelFormat(attribList);
177 SetupPalette(palette);
178
179 m_glContext = new wxGLContext(TRUE, this, palette);
180 }
181
182 wxGLCanvas::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 )
186 : wxWindow()
187 {
188 m_glContext = (wxGLContext*) NULL;
189
190 bool ret = Create(parent, id, pos, size, style, name);
191
192 if ( ret )
193 {
194 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
195 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
196 }
197
198 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
199
200 SetupPixelFormat(attribList);
201 SetupPalette(palette);
202
203 m_glContext = new wxGLContext(TRUE, this, palette, shared );
204 }
205
206 // Not very useful for wxMSW, but this is to be wxGTK compliant
207
208 wxGLCanvas::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 ):
211 wxWindow()
212 {
213 m_glContext = (wxGLContext*) NULL;
214
215 bool ret = Create(parent, id, pos, size, style, name);
216
217 if ( ret )
218 {
219 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
220 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
221 }
222
223 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
224
225 SetupPixelFormat(attribList);
226 SetupPalette(palette);
227
228 wxGLContext *sharedContext=0;
229 if (shared) sharedContext=shared->GetContext();
230 m_glContext = new wxGLContext(TRUE, this, palette, sharedContext );
231 }
232
233 wxGLCanvas::~wxGLCanvas()
234 {
235 if (m_glContext)
236 delete m_glContext;
237
238 ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC);
239 }
240
241 // Replaces wxWindow::Create functionality, since we need to use a different
242 // window class
243 bool wxGLCanvas::Create(wxWindow *parent,
244 wxWindowID id,
245 const wxPoint& pos,
246 const wxSize& size,
247 long style,
248 const wxString& name)
249 {
250 static bool s_registeredGLCanvasClass = FALSE;
251
252 // We have to register a special window class because we need
253 // the CS_OWNDC style for GLCanvas.
254
255 /*
256 From Angel Popov <jumpo@bitex.com>
257
258 Here are two snips from a dicussion in the OpenGL Gamedev list that explains
259 how this problem can be fixed:
260
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."
265
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 */
271
272 if (!s_registeredGLCanvasClass)
273 {
274 WNDCLASS wndclass;
275
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;
284
285 // Register the GLCanvas class name
286 wndclass.hbrBackground = (HBRUSH)NULL;
287 wndclass.lpszClassName = wxGLCanvasClassName;
288 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
289
290 if ( !::RegisterClass(&wndclass) )
291 {
292 wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
293 return FALSE;
294 }
295
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
305 ::UnregisterClass(wxGLCanvasClassName, wxhInstance);
306
307 return FALSE;
308 }
309
310 s_registeredGLCanvasClass = TRUE;
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;
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 */
328
329 WXDWORD exStyle = 0;
330 msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
331 msflags |= MSWGetStyle(style, & exStyle) ;
332
333 return MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle);
334 }
335
336 static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList)
337 {
338 if (attribList) {
339 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
340 pfd.iPixelType = PFD_TYPE_COLORINDEX;
341 pfd.cColorBits = 0;
342 int arg=0;
343
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) {
357 pfd.iLayerType = (BYTE)PFD_OVERLAY_PLANE;
358 } else if (attribList[arg] < 0) {
359 pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE;
360 } else {
361 pfd.iLayerType = (BYTE)PFD_MAIN_PLANE;
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;
387 case WX_GL_DEPTH_SIZE:
388 pfd.cDepthBits = attribList[arg++];
389 break;
390 case WX_GL_STENCIL_SIZE:
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 }
408 }
409 }
410 }
411
412 void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC)
413 {
414 PIXELFORMATDESCRIPTOR pfd = {
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 };
434
435 AdjustPFDForAttributes(pfd, attribList);
436
437 int pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd);
438 if (pixelFormat == 0) {
439 wxLogLastError(_T("ChoosePixelFormat"));
440 }
441 else {
442 if ( !::SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) ) {
443 wxLogLastError(_T("SetPixelFormat"));
444 }
445 }
446 }
447
448 void 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 {
460 return;
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
477 wxPalette 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
485 paletteSize = 1 << pfd.cColorBits;
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 {
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 }
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
519 void wxGLCanvas::SwapBuffers()
520 {
521 if (m_glContext)
522 m_glContext->SwapBuffers();
523 }
524
525 void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
526 {
527 }
528
529 void wxGLCanvas::SetCurrent()
530 {
531 if (m_glContext)
532 {
533 m_glContext->SetCurrent();
534 }
535 }
536
537 void wxGLCanvas::SetColour(const wxChar *colour)
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...
545 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
546 {
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);
557 }
558
559 // I think this doesn't have to be propagated to child windows.
560 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
561 {
562 /* realize palette if this is *not* the current window */
563 if ( GetPalette() &&
564 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
565 {
566 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
567 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
568 ::RealizePalette((HDC) GetHDC());
569 Refresh();
570 }
571 }
572
573 /* Give extensions proper function names. */
574
575 /* EXT_vertex_array */
576 void glArrayElementEXT(GLint WXUNUSED(i))
577 {
578 }
579
580 void glColorPointerEXT(GLint WXUNUSED(size), GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer))
581 {
582 }
583
584 void 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
599 void glEdgeFlagPointerEXT(GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLboolean *WXUNUSED(pointer))
600 {
601 }
602
603 void glGetPointervEXT(GLenum WXUNUSED(pname), GLvoid* *WXUNUSED(params))
604 {
605 }
606
607 void glIndexPointerEXT(GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer))
608 {
609 }
610
611 void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
612 {
613 #ifdef GL_EXT_vertex_array
614 static PFNGLNORMALPOINTEREXTPROC proc = 0;
615
616 if ( !proc )
617 {
618 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
619 }
620
621 if ( proc )
622 (* proc) (type, stride, count, pointer);
623 #endif
624 }
625
626 void glTexCoordPointerEXT(GLint WXUNUSED(size), GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer))
627 {
628 }
629
630 void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
631 {
632 #ifdef GL_EXT_vertex_array
633 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
634
635 if ( !proc )
636 {
637 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
638 }
639 if ( proc )
640 (* proc) (size, type, stride, count, pointer);
641 #endif
642 }
643
644 /* EXT_color_subtable */
645 void glColorSubtableEXT(GLenum WXUNUSED(target), GLsizei WXUNUSED(start), GLsizei WXUNUSED(count), GLenum WXUNUSED(format), GLenum WXUNUSED(type), const GLvoid *WXUNUSED(table))
646 {
647 }
648
649 /* EXT_color_table */
650 void glColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(internalformat), GLsizei WXUNUSED(width), GLenum WXUNUSED(format), GLenum WXUNUSED(type), const GLvoid *WXUNUSED(table))
651 {
652 }
653
654 void glCopyColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(internalformat), GLint WXUNUSED(x), GLint WXUNUSED(y), GLsizei WXUNUSED(width))
655 {
656 }
657
658 void glGetColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(format), GLenum WXUNUSED(type), GLvoid *WXUNUSED(table))
659 {
660 }
661
662 void glGetColorTableParamaterfvEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(pname), GLfloat *WXUNUSED(params))
663 {
664 }
665
666 void glGetColorTavleParameterivEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(pname), GLint *WXUNUSED(params))
667 {
668 }
669
670 /* SGI_compiled_vertex_array */
671 void glLockArraysSGI(GLint WXUNUSED(first), GLsizei WXUNUSED(count))
672 {
673 }
674
675 void glUnlockArraysSGI()
676 {
677 }
678
679
680 /* SGI_cull_vertex */
681 void glCullParameterdvSGI(GLenum WXUNUSED(pname), GLdouble* WXUNUSED(params))
682 {
683 }
684
685 void glCullParameterfvSGI(GLenum WXUNUSED(pname), GLfloat* WXUNUSED(params))
686 {
687 }
688
689 /* SGI_index_func */
690 void glIndexFuncSGI(GLenum WXUNUSED(func), GLclampf WXUNUSED(ref))
691 {
692 }
693
694 /* SGI_index_material */
695 void glIndexMaterialSGI(GLenum WXUNUSED(face), GLenum WXUNUSED(mode))
696 {
697 }
698
699 /* WIN_swap_hint */
700 void glAddSwapHintRectWin(GLint WXUNUSED(x), GLint WXUNUSED(y), GLsizei WXUNUSED(width), GLsizei WXUNUSED(height))
701 {
702 }
703
704
705 //---------------------------------------------------------------------------
706 // wxGLApp
707 //---------------------------------------------------------------------------
708
709 IMPLEMENT_CLASS(wxGLApp, wxApp)
710
711 bool wxGLApp::InitGLVisual(int *attribList)
712 {
713 int pixelFormat;
714 PIXELFORMATDESCRIPTOR pfd = {
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 };
734
735 AdjustPFDForAttributes(pfd, attribList);
736
737 // use DC for whole (root) screen, since no windows have yet been created
738 pixelFormat = ChoosePixelFormat(ScreenHDC(), &pfd);
739
740 if (pixelFormat == 0) {
741 wxLogError(_("Failed to initialize OpenGL"));
742 return FALSE;
743 }
744
745 return TRUE;
746 }
747
748 wxGLApp::~wxGLApp()
749 {
750 }
751
752 #endif
753 // wxUSE_GLCANVAS