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