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