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