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