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