]> git.saurik.com Git - wxWidgets.git/blame - src/msw/glcanvas.cpp
preliminary EXTENDED_RTTI
[wxWidgets.git] / src / msw / glcanvas.cpp
CommitLineData
8b089c5e 1/////////////////////////////////////////////////////////////////////////////
2b8646e0 2// Name: src/msw/glcanvas.cpp
8b089c5e
JS
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
2b8646e0 9// Licence: wxWindows licence
8b089c5e
JS
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
8b089c5e
JS
22#if wxUSE_GLCANVAS
23
24#ifndef WX_PRECOMP
af0b1533
VZ
25 #include "wx/frame.h"
26 #include "wx/settings.h"
27 #include "wx/intl.h"
28 #include "wx/log.h"
8b089c5e
JS
29#endif
30
af0b1533 31#include "wx/msw/private.h"
8b089c5e 32
af0b1533 33#include "wx/glcanvas.h"
8b089c5e 34
0e82bd96
VZ
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
b225f659
VZ
57static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass");
58static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR");
8b089c5e
JS
59
60LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
61 WPARAM wParam, LPARAM lParam);
62
63/*
64 * GLContext implementation
65 */
66
67wxGLContext::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);
f6bcfd97 74 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
8b089c5e
JS
75
76 wglMakeCurrent((HDC) m_hDC, m_glContext);
77}
78
79wxGLContext::wxGLContext(
80 bool isRGB, wxGLCanvas *win,
81 const wxPalette& palette,
f48d169c
UN
82 const wxGLContext *other /* for sharing display lists */
83 )
8b089c5e 84{
f48d169c 85 m_window = win;
8b089c5e 86
f48d169c 87 m_hDC = win->GetHDC();
8b089c5e 88
f48d169c
UN
89 m_glContext = wglCreateContext((HDC) m_hDC);
90 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
8b089c5e 91
f48d169c
UN
92 if( other != 0 )
93 wglShareLists( other->m_glContext, m_glContext );
8b089c5e 94
f48d169c 95 wglMakeCurrent((HDC) m_hDC, m_glContext);
8b089c5e
JS
96}
97
98wxGLContext::~wxGLContext()
99{
100 if (m_glContext)
101 {
102 wglMakeCurrent(NULL, NULL);
f48d169c 103 wglDeleteContext(m_glContext);
8b089c5e
JS
104 }
105}
106
107void 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
116void wxGLContext::SetCurrent()
117{
118 if (m_glContext)
119 {
120 wglMakeCurrent((HDC) m_hDC, m_glContext);
121 }
122
f48d169c
UN
123 /*
124 setupPixelFormat(hDC);
125 setupPalette(hDC);
126 */
8b089c5e
JS
127}
128
2b5f62a0 129void wxGLContext::SetColour(const wxChar *colour)
8b089c5e
JS
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
4660d7e5 149IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
8b089c5e 150
4660d7e5 151BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
8b089c5e
JS
152 EVT_SIZE(wxGLCanvas::OnSize)
153 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged)
154 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette)
155END_EVENT_TABLE()
156
157wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
158 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
4660d7e5 159 int *attribList, const wxPalette& palette) : wxWindow()
8b089c5e 160{
f48d169c 161 m_glContext = (wxGLContext*) NULL;
8b089c5e 162
f48d169c 163 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 164
f48d169c
UN
165 if ( ret )
166 {
a756f210
VS
167 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
168 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 169 }
8b089c5e 170
f48d169c 171 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 172
f48d169c
UN
173 SetupPixelFormat(attribList);
174 SetupPalette(palette);
8b089c5e 175
f48d169c 176 m_glContext = new wxGLContext(TRUE, this, palette);
8b089c5e
JS
177}
178
179wxGLCanvas::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 )
4660d7e5 183 : wxWindow()
8b089c5e 184{
f48d169c 185 m_glContext = (wxGLContext*) NULL;
8b089c5e 186
f48d169c 187 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 188
f48d169c
UN
189 if ( ret )
190 {
a756f210
VS
191 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
192 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 193 }
8b089c5e 194
f48d169c 195 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 196
f48d169c
UN
197 SetupPixelFormat(attribList);
198 SetupPalette(palette);
8b089c5e 199
f48d169c 200 m_glContext = new wxGLContext(TRUE, this, palette, shared );
8b089c5e
JS
201}
202
f6bcfd97 203// Not very useful for wxMSW, but this is to be wxGTK compliant
8b089c5e
JS
204
205wxGLCanvas::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 ):
4660d7e5 208 wxWindow()
8b089c5e 209{
f48d169c 210 m_glContext = (wxGLContext*) NULL;
8b089c5e 211
f48d169c 212 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 213
f48d169c
UN
214 if ( ret )
215 {
a756f210
VS
216 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
217 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 218 }
8b089c5e 219
f48d169c 220 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 221
f48d169c
UN
222 SetupPixelFormat(attribList);
223 SetupPalette(palette);
8b089c5e 224
f48d169c
UN
225 wxGLContext *sharedContext=0;
226 if (shared) sharedContext=shared->GetContext();
227 m_glContext = new wxGLContext(TRUE, this, palette, sharedContext );
8b089c5e
JS
228}
229
230wxGLCanvas::~wxGLCanvas()
231{
232 if (m_glContext)
233 delete m_glContext;
234
235 ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC);
236}
237
b225f659
VZ
238// Replaces wxWindow::Create functionality, since we need to use a different
239// window class
240bool wxGLCanvas::Create(wxWindow *parent,
241 wxWindowID id,
242 const wxPoint& pos,
243 const wxSize& size,
244 long style,
245 const wxString& name)
8b089c5e 246{
b225f659 247 static bool s_registeredGLCanvasClass = FALSE;
8b089c5e 248
f48d169c
UN
249 // We have to register a special window class because we need
250 // the CS_OWNDC style for GLCanvas.
8b089c5e 251
f48d169c
UN
252 /*
253 From Angel Popov <jumpo@bitex.com>
8b089c5e 254
f48d169c
UN
255 Here are two snips from a dicussion in the OpenGL Gamedev list that explains
256 how this problem can be fixed:
8b089c5e 257
f48d169c
UN
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."
8b089c5e 262
f48d169c
UN
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 */
8b089c5e 268
b225f659 269 if (!s_registeredGLCanvasClass)
f48d169c
UN
270 {
271 WNDCLASS wndclass;
8b089c5e 272
f48d169c
UN
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;
8b089c5e 281
f48d169c
UN
282 // Register the GLCanvas class name
283 wndclass.hbrBackground = (HBRUSH)NULL;
284 wndclass.lpszClassName = wxGLCanvasClassName;
b225f659 285 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
8b089c5e 286
b225f659 287 if ( !::RegisterClass(&wndclass) )
8b089c5e 288 {
f48d169c
UN
289 wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
290 return FALSE;
8b089c5e
JS
291 }
292
b225f659
VZ
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
a8d20c57 302 ::UnregisterClass(wxGLCanvasClassName, wxhInstance);
b225f659
VZ
303
304 return FALSE;
305 }
306
307 s_registeredGLCanvasClass = TRUE;
f48d169c
UN
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;
f48d169c
UN
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 */
8b089c5e 325
fe3d9123 326 WXDWORD exStyle = 0;
b225f659 327 msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
fe3d9123 328 msflags |= MSWGetStyle(style, & exStyle) ;
f48d169c 329
b225f659 330 return MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle);
8b089c5e
JS
331}
332
a3081354 333static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList)
8b089c5e 334{
f48d169c
UN
335 if (attribList) {
336 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
337 pfd.iPixelType = PFD_TYPE_COLORINDEX;
338 pfd.cColorBits = 0;
339 int arg=0;
b225f659 340
f48d169c
UN
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) {
d728116a 354 pfd.iLayerType = (BYTE)PFD_OVERLAY_PLANE;
f48d169c 355 } else if (attribList[arg] < 0) {
d728116a 356 pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE;
f48d169c 357 } else {
d728116a 358 pfd.iLayerType = (BYTE)PFD_MAIN_PLANE;
f48d169c
UN
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;
b225f659 384 case WX_GL_DEPTH_SIZE:
f48d169c
UN
385 pfd.cDepthBits = attribList[arg++];
386 break;
b225f659 387 case WX_GL_STENCIL_SIZE:
f48d169c
UN
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 }
8b089c5e 405 }
f48d169c 406 }
a3081354
VZ
407}
408
409void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC)
410{
a3081354 411 PIXELFORMATDESCRIPTOR pfd = {
b225f659
VZ
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 };
a3081354
VZ
431
432 AdjustPFDForAttributes(pfd, attribList);
433
72adfc4b 434 int pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd);
f48d169c 435 if (pixelFormat == 0) {
72adfc4b 436 wxLogLastError(_T("ChoosePixelFormat"));
f48d169c 437 }
a3081354 438 else {
72adfc4b
VZ
439 if ( !::SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) ) {
440 wxLogLastError(_T("SetPixelFormat"));
a3081354 441 }
f48d169c 442 }
8b089c5e
JS
443}
444
445void 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 {
b225f659 457 return;
8b089c5e
JS
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
474wxPalette 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
f48d169c 482 paletteSize = 1 << pfd.cColorBits;
8b089c5e
JS
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 {
b225f659
VZ
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 }
8b089c5e
JS
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
516void wxGLCanvas::SwapBuffers()
517{
518 if (m_glContext)
519 m_glContext->SwapBuffers();
520}
521
522void wxGLCanvas::OnSize(wxSizeEvent& event)
523{
8b089c5e
JS
524}
525
526void wxGLCanvas::SetCurrent()
527{
528 if (m_glContext)
529 {
530 m_glContext->SetCurrent();
531 }
532}
533
2b5f62a0 534void wxGLCanvas::SetColour(const wxChar *colour)
8b089c5e
JS
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...
542void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
543{
f48d169c
UN
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);
8b089c5e
JS
554}
555
556// I think this doesn't have to be propagated to child windows.
557void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
558{
f48d169c
UN
559 /* realize palette if this is *not* the current window */
560 if ( GetPalette() &&
8b089c5e 561 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
f48d169c
UN
562 {
563 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
564 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
565 ::RealizePalette((HDC) GetHDC());
566 Refresh();
567 }
8b089c5e
JS
568}
569
570/* Give extensions proper function names. */
571
572/* EXT_vertex_array */
573void glArrayElementEXT(GLint i)
574{
575}
576
577void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
578{
579}
580
581void 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
596void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer)
597{
598}
599
600void glGetPointervEXT(GLenum pname, GLvoid* *params)
601{
602}
603
604void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
605{
606}
607
608void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
609{
610#ifdef GL_EXT_vertex_array
f48d169c 611 static PFNGLNORMALPOINTEREXTPROC proc = 0;
8b089c5e 612
f48d169c
UN
613 if ( !proc )
614 {
615 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
616 }
8b089c5e 617
f48d169c
UN
618 if ( proc )
619 (* proc) (type, stride, count, pointer);
8b089c5e
JS
620#endif
621}
622
623void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
624{
625}
626
627void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
628{
629#ifdef GL_EXT_vertex_array
f48d169c 630 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
8b089c5e 631
f48d169c
UN
632 if ( !proc )
633 {
634 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
635 }
636 if ( proc )
637 (* proc) (size, type, stride, count, pointer);
8b089c5e
JS
638#endif
639}
640
641/* EXT_color_subtable */
642void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table)
643{
644}
645
646/* EXT_color_table */
647void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
648{
649}
650
651void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
652{
653}
654
655void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table)
656{
657}
658
659void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params)
660{
661}
662
663void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params)
664{
665}
666
667/* SGI_compiled_vertex_array */
668void glLockArraysSGI(GLint first, GLsizei count)
669{
670}
671
672void glUnlockArraysSGI()
673{
674}
675
676
677/* SGI_cull_vertex */
678void glCullParameterdvSGI(GLenum pname, GLdouble* params)
679{
680}
681
682void glCullParameterfvSGI(GLenum pname, GLfloat* params)
683{
684}
685
686/* SGI_index_func */
687void glIndexFuncSGI(GLenum func, GLclampf ref)
688{
689}
690
691/* SGI_index_material */
692void glIndexMaterialSGI(GLenum face, GLenum mode)
693{
694}
695
696/* WIN_swap_hint */
697void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height)
698{
699}
700
a3081354
VZ
701
702//---------------------------------------------------------------------------
703// wxGLApp
704//---------------------------------------------------------------------------
705
706IMPLEMENT_CLASS(wxGLApp, wxApp)
707
708bool wxGLApp::InitGLVisual(int *attribList)
709{
710 int pixelFormat;
711 PIXELFORMATDESCRIPTOR pfd = {
b225f659
VZ
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 };
a3081354
VZ
731
732 AdjustPFDForAttributes(pfd, attribList);
733
734 // use DC for whole (root) screen, since no windows have yet been created
2b8646e0 735 pixelFormat = ChoosePixelFormat(ScreenHDC(), &pfd);
a3081354
VZ
736
737 if (pixelFormat == 0) {
738 wxLogError(_("Failed to initialize OpenGL"));
739 return FALSE;
740 }
741
742 return TRUE;
743}
744
745wxGLApp::~wxGLApp()
746{
747}
748
8b089c5e
JS
749#endif
750 // wxUSE_GLCANVAS