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