]> git.saurik.com Git - wxWidgets.git/blob - src/msw/glcanvas.cpp
Refactored wxListBox code so that it correctly implements
[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 PIXELFORMATDESCRIPTOR pfd = {
403 sizeof(PIXELFORMATDESCRIPTOR), /* size */
404 1, /* version */
405 PFD_SUPPORT_OPENGL |
406 PFD_DRAW_TO_WINDOW |
407 PFD_DOUBLEBUFFER, /* support double-buffering */
408 PFD_TYPE_RGBA, /* color type */
409 16, /* prefered color depth */
410 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
411 0, /* no alpha buffer */
412 0, /* alpha bits (ignored) */
413 0, /* no accumulation buffer */
414 0, 0, 0, 0, /* accum bits (ignored) */
415 16, /* depth buffer */
416 0, /* no stencil buffer */
417 0, /* no auxiliary buffers */
418 PFD_MAIN_PLANE, /* main layer */
419 0, /* reserved */
420 0, 0, 0, /* no layer, visible, damage masks */
421 };
422
423 AdjustPFDForAttributes(pfd, attribList);
424
425 int pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd);
426 if (pixelFormat == 0) {
427 wxLogLastError(_T("ChoosePixelFormat"));
428 }
429 else {
430 if ( !::SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) ) {
431 wxLogLastError(_T("SetPixelFormat"));
432 }
433 }
434 }
435
436 void wxGLCanvas::SetupPalette(const wxPalette& palette)
437 {
438 int pixelFormat = GetPixelFormat((HDC) m_hDC);
439 PIXELFORMATDESCRIPTOR pfd;
440
441 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
442
443 if (pfd.dwFlags & PFD_NEED_PALETTE)
444 {
445 }
446 else
447 {
448 return;
449 }
450
451 m_palette = palette;
452
453 if ( !m_palette.Ok() )
454 {
455 m_palette = CreateDefaultPalette();
456 }
457
458 if (m_palette.Ok())
459 {
460 SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE);
461 RealizePalette((HDC) m_hDC);
462 }
463 }
464
465 wxPalette wxGLCanvas::CreateDefaultPalette()
466 {
467 PIXELFORMATDESCRIPTOR pfd;
468 int paletteSize;
469 int pixelFormat = GetPixelFormat((HDC) m_hDC);
470
471 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
472
473 paletteSize = 1 << pfd.cColorBits;
474
475 LOGPALETTE* pPal =
476 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
477 pPal->palVersion = 0x300;
478 pPal->palNumEntries = paletteSize;
479
480 /* build a simple RGB color palette */
481 {
482 int redMask = (1 << pfd.cRedBits) - 1;
483 int greenMask = (1 << pfd.cGreenBits) - 1;
484 int blueMask = (1 << pfd.cBlueBits) - 1;
485 int i;
486
487 for (i=0; i<paletteSize; ++i) {
488 pPal->palPalEntry[i].peRed =
489 (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
490 pPal->palPalEntry[i].peGreen =
491 (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
492 pPal->palPalEntry[i].peBlue =
493 (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
494 pPal->palPalEntry[i].peFlags = 0;
495 }
496 }
497
498 HPALETTE hPalette = CreatePalette(pPal);
499 free(pPal);
500
501 wxPalette palette;
502 palette.SetHPALETTE((WXHPALETTE) hPalette);
503
504 return palette;
505 }
506
507 void wxGLCanvas::SwapBuffers()
508 {
509 if (m_glContext)
510 m_glContext->SwapBuffers();
511 }
512
513 void wxGLCanvas::OnSize(wxSizeEvent& event)
514 {
515 }
516
517 void wxGLCanvas::SetCurrent()
518 {
519 if (m_glContext)
520 {
521 m_glContext->SetCurrent();
522 }
523 }
524
525 void wxGLCanvas::SetColour(const char *colour)
526 {
527 if (m_glContext)
528 m_glContext->SetColour(colour);
529 }
530
531 // TODO: Have to have this called by parent frame (?)
532 // So we need wxFrame to call OnQueryNewPalette for all children...
533 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
534 {
535 /* realize palette if this is the current window */
536 if ( GetPalette()->Ok() ) {
537 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
538 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
539 ::RealizePalette((HDC) GetHDC());
540 Refresh();
541 event.SetPaletteRealized(TRUE);
542 }
543 else
544 event.SetPaletteRealized(FALSE);
545 }
546
547 // I think this doesn't have to be propagated to child windows.
548 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
549 {
550 /* realize palette if this is *not* the current window */
551 if ( GetPalette() &&
552 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
553 {
554 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
555 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
556 ::RealizePalette((HDC) GetHDC());
557 Refresh();
558 }
559 }
560
561 /* Give extensions proper function names. */
562
563 /* EXT_vertex_array */
564 void glArrayElementEXT(GLint i)
565 {
566 }
567
568 void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
569 {
570 }
571
572 void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count)
573 {
574 #ifdef GL_EXT_vertex_array
575 static PFNGLDRAWARRAYSEXTPROC proc = 0;
576
577 if ( !proc )
578 {
579 proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT");
580 }
581
582 if ( proc )
583 (* proc) (mode, first, count);
584 #endif
585 }
586
587 void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer)
588 {
589 }
590
591 void glGetPointervEXT(GLenum pname, GLvoid* *params)
592 {
593 }
594
595 void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
596 {
597 }
598
599 void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
600 {
601 #ifdef GL_EXT_vertex_array
602 static PFNGLNORMALPOINTEREXTPROC proc = 0;
603
604 if ( !proc )
605 {
606 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
607 }
608
609 if ( proc )
610 (* proc) (type, stride, count, pointer);
611 #endif
612 }
613
614 void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
615 {
616 }
617
618 void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
619 {
620 #ifdef GL_EXT_vertex_array
621 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
622
623 if ( !proc )
624 {
625 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
626 }
627 if ( proc )
628 (* proc) (size, type, stride, count, pointer);
629 #endif
630 }
631
632 /* EXT_color_subtable */
633 void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table)
634 {
635 }
636
637 /* EXT_color_table */
638 void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
639 {
640 }
641
642 void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
643 {
644 }
645
646 void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table)
647 {
648 }
649
650 void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params)
651 {
652 }
653
654 void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params)
655 {
656 }
657
658 /* SGI_compiled_vertex_array */
659 void glLockArraysSGI(GLint first, GLsizei count)
660 {
661 }
662
663 void glUnlockArraysSGI()
664 {
665 }
666
667
668 /* SGI_cull_vertex */
669 void glCullParameterdvSGI(GLenum pname, GLdouble* params)
670 {
671 }
672
673 void glCullParameterfvSGI(GLenum pname, GLfloat* params)
674 {
675 }
676
677 /* SGI_index_func */
678 void glIndexFuncSGI(GLenum func, GLclampf ref)
679 {
680 }
681
682 /* SGI_index_material */
683 void glIndexMaterialSGI(GLenum face, GLenum mode)
684 {
685 }
686
687 /* WIN_swap_hint */
688 void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height)
689 {
690 }
691
692
693 //---------------------------------------------------------------------------
694 // wxGLApp
695 //---------------------------------------------------------------------------
696
697 IMPLEMENT_CLASS(wxGLApp, wxApp)
698
699 bool wxGLApp::InitGLVisual(int *attribList)
700 {
701 int pixelFormat;
702 PIXELFORMATDESCRIPTOR pfd = {
703 sizeof(PIXELFORMATDESCRIPTOR), /* size */
704 1, /* version */
705 PFD_SUPPORT_OPENGL |
706 PFD_DRAW_TO_WINDOW |
707 PFD_DOUBLEBUFFER, /* support double-buffering */
708 PFD_TYPE_RGBA, /* color type */
709 16, /* prefered color depth */
710 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
711 0, /* no alpha buffer */
712 0, /* alpha bits (ignored) */
713 0, /* no accumulation buffer */
714 0, 0, 0, 0, /* accum bits (ignored) */
715 16, /* depth buffer */
716 0, /* no stencil buffer */
717 0, /* no auxiliary buffers */
718 PFD_MAIN_PLANE, /* main layer */
719 0, /* reserved */
720 0, 0, 0, /* no layer, visible, damage masks */
721 };
722
723 AdjustPFDForAttributes(pfd, attribList);
724
725 // use DC for whole (root) screen, since no windows have yet been created
726 pixelFormat = ChoosePixelFormat(ScreenHDC(), &pfd);
727
728 if (pixelFormat == 0) {
729 wxLogError(_("Failed to initialize OpenGL"));
730 return FALSE;
731 }
732
733 return TRUE;
734 }
735
736 wxGLApp::~wxGLApp()
737 {
738 }
739
740 #endif
741 // wxUSE_GLCANVAS