]> git.saurik.com Git - wxWidgets.git/blame - src/msw/glcanvas.cpp
always pass WM_DESTROY to DefWindowProc() - this fixes memory/resource leak for wxListBox
[wxWidgets.git] / src / msw / glcanvas.cpp
CommitLineData
8b089c5e
JS
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>
7e42f2f8
UN
31#include <wx/settings.h>
32#include <wx/log.h>
8b089c5e
JS
33
34#include <wx/glcanvas.h>
35
36wxChar wxGLCanvasClassName[] = wxT("wxGLCanvasClass");
37
38LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
39 WPARAM wParam, LPARAM lParam);
40
41/*
42 * GLContext implementation
43 */
44
45wxGLContext::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);
f6bcfd97 52 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
8b089c5e
JS
53
54 wglMakeCurrent((HDC) m_hDC, m_glContext);
55}
56
57wxGLContext::wxGLContext(
58 bool isRGB, wxGLCanvas *win,
59 const wxPalette& palette,
f48d169c
UN
60 const wxGLContext *other /* for sharing display lists */
61 )
8b089c5e 62{
f48d169c 63 m_window = win;
8b089c5e 64
f48d169c 65 m_hDC = win->GetHDC();
8b089c5e 66
f48d169c
UN
67 m_glContext = wglCreateContext((HDC) m_hDC);
68 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
8b089c5e 69
f48d169c
UN
70 if( other != 0 )
71 wglShareLists( other->m_glContext, m_glContext );
8b089c5e 72
f48d169c 73 wglMakeCurrent((HDC) m_hDC, m_glContext);
8b089c5e
JS
74}
75
76wxGLContext::~wxGLContext()
77{
78 if (m_glContext)
79 {
80 wglMakeCurrent(NULL, NULL);
f48d169c 81 wglDeleteContext(m_glContext);
8b089c5e
JS
82 }
83}
84
85void 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
94void wxGLContext::SetCurrent()
95{
96 if (m_glContext)
97 {
98 wglMakeCurrent((HDC) m_hDC, m_glContext);
99 }
100
f48d169c
UN
101 /*
102 setupPixelFormat(hDC);
103 setupPalette(hDC);
104 */
8b089c5e
JS
105}
106
107void 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
127IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow)
128
129BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow)
130 EVT_SIZE(wxGLCanvas::OnSize)
131 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged)
132 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette)
133END_EVENT_TABLE()
134
135wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
136 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
f48d169c 137 int *attribList, const wxPalette& palette) : wxScrolledWindow()
8b089c5e 138{
f48d169c 139 m_glContext = (wxGLContext*) NULL;
8b089c5e 140
f48d169c 141 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 142
f48d169c
UN
143 if ( ret )
144 {
145 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
146 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
147 }
8b089c5e 148
f48d169c 149 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 150
f48d169c
UN
151 SetupPixelFormat(attribList);
152 SetupPalette(palette);
8b089c5e 153
f48d169c 154 m_glContext = new wxGLContext(TRUE, this, palette);
8b089c5e
JS
155}
156
157wxGLCanvas::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 : wxScrolledWindow()
162{
f48d169c 163 m_glContext = (wxGLContext*) NULL;
8b089c5e 164
f48d169c 165 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 166
f48d169c
UN
167 if ( ret )
168 {
169 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
170 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
171 }
8b089c5e 172
f48d169c 173 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 174
f48d169c
UN
175 SetupPixelFormat(attribList);
176 SetupPalette(palette);
8b089c5e 177
f48d169c 178 m_glContext = new wxGLContext(TRUE, this, palette, shared );
8b089c5e
JS
179}
180
f6bcfd97 181// Not very useful for wxMSW, but this is to be wxGTK compliant
8b089c5e
JS
182
183wxGLCanvas::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 wxScrolledWindow()
187{
f48d169c 188 m_glContext = (wxGLContext*) NULL;
8b089c5e 189
f48d169c 190 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 191
f48d169c
UN
192 if ( ret )
193 {
194 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
195 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
196 }
8b089c5e 197
f48d169c 198 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 199
f48d169c
UN
200 SetupPixelFormat(attribList);
201 SetupPalette(palette);
8b089c5e 202
f48d169c
UN
203 wxGLContext *sharedContext=0;
204 if (shared) sharedContext=shared->GetContext();
205 m_glContext = new wxGLContext(TRUE, this, palette, sharedContext );
8b089c5e
JS
206}
207
208wxGLCanvas::~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 window class
217bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id,
218 const wxPoint& pos, const wxSize& size, long style, const wxString& name)
219{
f48d169c
UN
220 /*
221 Suggestion from Kelly Brock <kbrock@8cs.com> (not yet implemented):
f6bcfd97 222
f48d169c
UN
223 OpenGL corruption fix is simple assuming it doesn't screw anything else
224 up. Add the following line to the top of the create function:
225
226 wxSize parentSize = GetClientSize();
f6bcfd97 227
f48d169c
UN
228 All locations within the function that use 'size' are changed to
229 'parentSize'.
230 The above corrects the initial display corruption with the GeForce and
231 TNT2, not sure about other NVidia cards yet.
232 */
8b089c5e 233
f48d169c 234 static bool registeredGLCanvasClass = FALSE;
8b089c5e 235
f48d169c
UN
236 // We have to register a special window class because we need
237 // the CS_OWNDC style for GLCanvas.
8b089c5e 238
f48d169c
UN
239 /*
240 From Angel Popov <jumpo@bitex.com>
8b089c5e 241
f48d169c
UN
242 Here are two snips from a dicussion in the OpenGL Gamedev list that explains
243 how this problem can be fixed:
8b089c5e 244
f48d169c
UN
245 "There are 5 common DCs available in Win95. These are aquired when you call
246 GetDC or GetDCEx from a window that does _not_ have the OWNDC flag.
247 OWNDC flagged windows do not get their DC from the common DC pool, the issue
248 is they require 800 bytes each from the limited 64Kb local heap for GDI."
8b089c5e 249
f48d169c
UN
250 "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps
251 do), Win95 will actually "steal" it from you. MakeCurrent fails,
252 apparently, because Windows re-assigns the HDC to a different window. The
253 only way to prevent this, the only reliable means, is to set CS_OWNDC."
254 */
8b089c5e 255
f48d169c
UN
256 if (!registeredGLCanvasClass)
257 {
258 WNDCLASS wndclass;
8b089c5e 259
f48d169c 260 static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
8b089c5e 261
f48d169c
UN
262 // the fields which are common to all classes
263 wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
264 wndclass.cbClsExtra = 0;
265 wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for?
266 wndclass.hInstance = wxhInstance;
267 wndclass.hIcon = (HICON) NULL;
268 wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
269 wndclass.lpszMenuName = NULL;
8b089c5e 270
f48d169c
UN
271 // Register the GLCanvas class name
272 wndclass.hbrBackground = (HBRUSH)NULL;
273 wndclass.lpszClassName = wxGLCanvasClassName;
274 wndclass.style = styleNormal;
8b089c5e 275
f48d169c 276 if ( !RegisterClass(&wndclass) )
8b089c5e 277 {
f48d169c
UN
278 wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
279 return FALSE;
8b089c5e
JS
280 }
281
f48d169c
UN
282 registeredGLCanvasClass = TRUE;
283 }
284
285 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
286
287 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
288 return FALSE;
289
290 parent->AddChild(this);
291
292 DWORD msflags = 0;
293 if ( style & wxBORDER )
294 msflags |= WS_BORDER;
295 if ( style & wxTHICK_FRAME )
296 msflags |= WS_THICKFRAME;
297
298 /*
299 A general rule with OpenGL and Win32 is that any window that will have a
300 HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS.
301 You can find references about this within the knowledge base and most OpenGL
302 books that contain the wgl function descriptions.
303 */
8b089c5e 304
f48d169c
UN
305 msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
306 // if ( style & wxCLIP_CHILDREN )
307 // msflags |= WS_CLIPCHILDREN;
308 msflags |= WS_CLIPCHILDREN;
8b089c5e 309
f48d169c
UN
310 bool want3D;
311 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
8b089c5e 312
f48d169c
UN
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 // calculate the value to return from WM_GETDLGCODE handler
322 if ( GetWindowStyleFlag() & wxWANTS_CHARS )
323 {
324 // want everything: i.e. all keys and WM_CHAR message
325 m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS |
326 DLGC_WANTTAB | DLGC_WANTMESSAGE;
327 }
328
329 MSWCreate(m_windowId, parent, wxGLCanvasClassName, this, NULL,
330 pos.x, pos.y,
331 WidthDefault(size.x), HeightDefault(size.y),
332 msflags, NULL, exStyle);
333
334 return TRUE;
8b089c5e
JS
335}
336
f48d169c 337void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC)
8b089c5e 338{
f48d169c
UN
339 int pixelFormat;
340 PIXELFORMATDESCRIPTOR pfd = {
341 sizeof(PIXELFORMATDESCRIPTOR), /* size */
342 1, /* version */
343 PFD_SUPPORT_OPENGL |
344 PFD_DRAW_TO_WINDOW |
345 PFD_DOUBLEBUFFER, /* support double-buffering */
346 PFD_TYPE_RGBA, /* color type */
347 16, /* prefered color depth */
348 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
349 0, /* no alpha buffer */
350 0, /* alpha bits (ignored) */
351 0, /* no accumulation buffer */
352 0, 0, 0, 0, /* accum bits (ignored) */
353 16, /* depth buffer */
354 0, /* no stencil buffer */
355 0, /* no auxiliary buffers */
356 PFD_MAIN_PLANE, /* main layer */
357 0, /* reserved */
358 0, 0, 0, /* no layer, visible, damage masks */
359 };
360
361 if (attribList) {
362 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
363 pfd.iPixelType = PFD_TYPE_COLORINDEX;
364 pfd.cColorBits = 0;
365 int arg=0;
366
367 while( (attribList[arg]!=0) )
368 {
369 switch( attribList[arg++] )
370 {
371 case WX_GL_RGBA:
372 pfd.iPixelType = PFD_TYPE_RGBA;
373 break;
374 case WX_GL_BUFFER_SIZE:
375 pfd.cColorBits = attribList[arg++];
376 break;
377 case WX_GL_LEVEL:
378 // this member looks like it may be obsolete
379 if (attribList[arg] > 0) {
380 pfd.iLayerType = PFD_OVERLAY_PLANE;
381 } else if (attribList[arg] < 0) {
382 pfd.iLayerType = PFD_UNDERLAY_PLANE;
383 } else {
384 pfd.iLayerType = PFD_MAIN_PLANE;
385 }
386 arg++;
387 break;
388 case WX_GL_DOUBLEBUFFER:
389 pfd.dwFlags |= PFD_DOUBLEBUFFER;
390 break;
391 case WX_GL_STEREO:
392 pfd.dwFlags |= PFD_STEREO;
393 break;
394 case WX_GL_AUX_BUFFERS:
395 pfd.cAuxBuffers = attribList[arg++];
396 break;
397 case WX_GL_MIN_RED:
398 pfd.cColorBits += (pfd.cRedBits = attribList[arg++]);
399 break;
400 case WX_GL_MIN_GREEN:
401 pfd.cColorBits += (pfd.cGreenBits = attribList[arg++]);
402 break;
403 case WX_GL_MIN_BLUE:
404 pfd.cColorBits += (pfd.cBlueBits = attribList[arg++]);
405 break;
406 case WX_GL_MIN_ALPHA:
407 // doesn't count in cColorBits
408 pfd.cAlphaBits = attribList[arg++];
409 break;
410 case WX_GL_DEPTH_SIZE:
411 pfd.cDepthBits = attribList[arg++];
412 break;
413 case WX_GL_STENCIL_SIZE:
414 pfd.cStencilBits = attribList[arg++];
415 break;
416 case WX_GL_MIN_ACCUM_RED:
417 pfd.cAccumBits += (pfd.cAccumRedBits = attribList[arg++]);
418 break;
419 case WX_GL_MIN_ACCUM_GREEN:
420 pfd.cAccumBits += (pfd.cAccumGreenBits = attribList[arg++]);
421 break;
422 case WX_GL_MIN_ACCUM_BLUE:
423 pfd.cAccumBits += (pfd.cAccumBlueBits = attribList[arg++]);
424 break;
425 case WX_GL_MIN_ACCUM_ALPHA:
426 pfd.cAccumBits += (pfd.cAccumAlphaBits = attribList[arg++]);
427 break;
428 default:
429 break;
430 }
8b089c5e 431 }
f48d169c
UN
432 }
433 pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd);
434 if (pixelFormat == 0) {
435 MessageBox(WindowFromDC((HDC) m_hDC), wxT("ChoosePixelFormat failed."), wxT("Error"),
436 MB_ICONERROR | MB_OK);
437 exit(1);
438 }
8b089c5e 439
f48d169c
UN
440 if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) {
441 MessageBox(WindowFromDC((HDC) m_hDC), wxT("SetPixelFormat failed."), wxT("Error"),
442 MB_ICONERROR | MB_OK);
443 exit(1);
444 }
8b089c5e
JS
445}
446
447void wxGLCanvas::SetupPalette(const wxPalette& palette)
448{
449 int pixelFormat = GetPixelFormat((HDC) m_hDC);
450 PIXELFORMATDESCRIPTOR pfd;
451
452 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
453
454 if (pfd.dwFlags & PFD_NEED_PALETTE)
455 {
456 }
457 else
458 {
459 return;
460 }
461
462 m_palette = palette;
463
464 if ( !m_palette.Ok() )
465 {
466 m_palette = CreateDefaultPalette();
467 }
468
469 if (m_palette.Ok())
470 {
471 SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE);
472 RealizePalette((HDC) m_hDC);
473 }
474}
475
476wxPalette wxGLCanvas::CreateDefaultPalette()
477{
478 PIXELFORMATDESCRIPTOR pfd;
479 int paletteSize;
480 int pixelFormat = GetPixelFormat((HDC) m_hDC);
481
482 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
483
f48d169c 484 paletteSize = 1 << pfd.cColorBits;
8b089c5e
JS
485
486 LOGPALETTE* pPal =
487 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
488 pPal->palVersion = 0x300;
489 pPal->palNumEntries = paletteSize;
490
491 /* build a simple RGB color palette */
492 {
493 int redMask = (1 << pfd.cRedBits) - 1;
494 int greenMask = (1 << pfd.cGreenBits) - 1;
495 int blueMask = (1 << pfd.cBlueBits) - 1;
496 int i;
497
498 for (i=0; i<paletteSize; ++i) {
499 pPal->palPalEntry[i].peRed =
500 (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
501 pPal->palPalEntry[i].peGreen =
502 (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
503 pPal->palPalEntry[i].peBlue =
504 (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
505 pPal->palPalEntry[i].peFlags = 0;
506 }
507 }
508
509 HPALETTE hPalette = CreatePalette(pPal);
510 free(pPal);
511
512 wxPalette palette;
513 palette.SetHPALETTE((WXHPALETTE) hPalette);
514
515 return palette;
516}
517
518void wxGLCanvas::SwapBuffers()
519{
520 if (m_glContext)
521 m_glContext->SwapBuffers();
522}
523
524void wxGLCanvas::OnSize(wxSizeEvent& event)
525{
526 int width, height;
527 GetClientSize(& width, & height);
528
529 if (m_glContext)
530 {
531 m_glContext->SetCurrent();
532
533 glViewport(0, 0, (GLint)width, (GLint)height);
534 glMatrixMode(GL_PROJECTION);
535 glLoadIdentity();
536 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
537 glMatrixMode(GL_MODELVIEW);
538 }
539}
540
541void wxGLCanvas::SetCurrent()
542{
543 if (m_glContext)
544 {
545 m_glContext->SetCurrent();
546 }
547}
548
549void wxGLCanvas::SetColour(const char *colour)
550{
551 if (m_glContext)
552 m_glContext->SetColour(colour);
553}
554
555// TODO: Have to have this called by parent frame (?)
556// So we need wxFrame to call OnQueryNewPalette for all children...
557void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
558{
f48d169c
UN
559 /* realize palette if this is the current window */
560 if ( GetPalette()->Ok() ) {
561 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
562 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
563 ::RealizePalette((HDC) GetHDC());
564 Refresh();
565 event.SetPaletteRealized(TRUE);
566 }
567 else
568 event.SetPaletteRealized(FALSE);
8b089c5e
JS
569}
570
571// I think this doesn't have to be propagated to child windows.
572void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
573{
f48d169c
UN
574 /* realize palette if this is *not* the current window */
575 if ( GetPalette() &&
8b089c5e 576 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
f48d169c
UN
577 {
578 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
579 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
580 ::RealizePalette((HDC) GetHDC());
581 Refresh();
582 }
8b089c5e
JS
583}
584
585/* Give extensions proper function names. */
586
587/* EXT_vertex_array */
588void glArrayElementEXT(GLint i)
589{
590}
591
592void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
593{
594}
595
596void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count)
597{
598#ifdef GL_EXT_vertex_array
599 static PFNGLDRAWARRAYSEXTPROC proc = 0;
600
601 if ( !proc )
602 {
603 proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT");
604 }
605
606 if ( proc )
607 (* proc) (mode, first, count);
608#endif
609}
610
611void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer)
612{
613}
614
615void glGetPointervEXT(GLenum pname, GLvoid* *params)
616{
617}
618
619void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
620{
621}
622
623void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
624{
625#ifdef GL_EXT_vertex_array
f48d169c 626 static PFNGLNORMALPOINTEREXTPROC proc = 0;
8b089c5e 627
f48d169c
UN
628 if ( !proc )
629 {
630 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
631 }
8b089c5e 632
f48d169c
UN
633 if ( proc )
634 (* proc) (type, stride, count, pointer);
8b089c5e
JS
635#endif
636}
637
638void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
639{
640}
641
642void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
643{
644#ifdef GL_EXT_vertex_array
f48d169c 645 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
8b089c5e 646
f48d169c
UN
647 if ( !proc )
648 {
649 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
650 }
651 if ( proc )
652 (* proc) (size, type, stride, count, pointer);
8b089c5e
JS
653#endif
654}
655
656/* EXT_color_subtable */
657void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table)
658{
659}
660
661/* EXT_color_table */
662void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
663{
664}
665
666void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
667{
668}
669
670void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table)
671{
672}
673
674void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params)
675{
676}
677
678void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params)
679{
680}
681
682/* SGI_compiled_vertex_array */
683void glLockArraysSGI(GLint first, GLsizei count)
684{
685}
686
687void glUnlockArraysSGI()
688{
689}
690
691
692/* SGI_cull_vertex */
693void glCullParameterdvSGI(GLenum pname, GLdouble* params)
694{
695}
696
697void glCullParameterfvSGI(GLenum pname, GLfloat* params)
698{
699}
700
701/* SGI_index_func */
702void glIndexFuncSGI(GLenum func, GLclampf ref)
703{
704}
705
706/* SGI_index_material */
707void glIndexMaterialSGI(GLenum face, GLenum mode)
708{
709}
710
711/* WIN_swap_hint */
712void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height)
713{
714}
715
716#endif
717 // wxUSE_GLCANVAS