1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxGLCanvas, for using OpenGL with wxWindows under MS Windows 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "glcanvas.h" 
  16 #include "wx/wxprec.h" 
  18 #if defined(__BORLANDC__) 
  26 #define wxUSE_GLCANVAS 1 
  33 #include <wx/msw/private.h> 
  34 #include <wx/settings.h> 
  37 #include "myglcanvas.h" 
  39 wxChar wxGLCanvasClassName
[]        = wxT("wxGLCanvasClass"); 
  41 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, 
  42                                    WPARAM wParam
, LPARAM lParam
); 
  45  * GLContext implementation 
  48 wxGLContext::wxGLContext(bool isRGB
, wxGLCanvas 
*win
, const wxPalette
& palette
) 
  52   m_hDC 
= win
->GetHDC(); 
  54   m_glContext 
= wglCreateContext((HDC
) m_hDC
); 
  55   wxCHECK_RET( m_glContext
, wxT("Couldn't create OpenGl context") ); 
  57   wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
  60 wxGLContext::wxGLContext( 
  61                bool isRGB
, wxGLCanvas 
*win
, 
  62                const wxPalette
& palette
, 
  63                const wxGLContext 
*other  
/* for sharing display lists */ 
  68   m_hDC 
= win
->GetHDC(); 
  70   m_glContext 
= wglCreateContext((HDC
) m_hDC
); 
  71   wxCHECK_RET( m_glContext
, wxT("Couldn't create OpenGl context") ); 
  74     wglShareLists( other
->m_glContext
, m_glContext 
); 
  76   wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
  79 wxGLContext::~wxGLContext() 
  83     wglMakeCurrent(NULL
, NULL
); 
  84     wglDeleteContext(m_glContext
); 
  88 void wxGLContext::SwapBuffers() 
  92     wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
  93     ::SwapBuffers((HDC
) m_hDC
);    //blits the backbuffer into DC 
  97 void wxGLContext::SetCurrent() 
 101     wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
 105   setupPixelFormat(hDC); 
 110 void wxGLContext::SetColour(const char *colour
) 
 115   wxColour 
*col 
= wxTheColourDatabase
->FindColour(colour
); 
 118     r 
= (float)(col
->Red()/256.0); 
 119     g 
= (float)(col
->Green()/256.0); 
 120     b 
= (float)(col
->Blue()/256.0); 
 127  * wxGLCanvas implementation 
 130 IMPLEMENT_CLASS(wxGLCanvas
, wxScrolledWindow
) 
 132 BEGIN_EVENT_TABLE(wxGLCanvas
, wxScrolledWindow
) 
 133     EVT_SIZE(wxGLCanvas::OnSize
) 
 134     EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged
) 
 135     EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette
) 
 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() 
 142   m_glContext 
= (wxGLContext
*) NULL
; 
 144   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 148     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
)); 
 149     SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
)); 
 152   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 154   SetupPixelFormat(attribList
); 
 155   SetupPalette(palette
); 
 157   m_glContext 
= new wxGLContext(TRUE
, this, palette
); 
 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 
) 
 166   m_glContext 
= (wxGLContext
*) NULL
; 
 168   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 172     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
)); 
 173     SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
)); 
 176   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 178   SetupPixelFormat(attribList
); 
 179   SetupPalette(palette
); 
 181   m_glContext 
= new wxGLContext(TRUE
, this, palette
, shared 
); 
 184 // Not very useful for wxMSW, but this is to be wxGTK compliant 
 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 
): 
 191   m_glContext 
= (wxGLContext
*) NULL
; 
 193   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 197     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
)); 
 198     SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
)); 
 201   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 203   SetupPixelFormat(attribList
); 
 204   SetupPalette(palette
); 
 206   wxGLContext 
*sharedContext
=0; 
 207   if (shared
) sharedContext
=shared
->GetContext(); 
 208   m_glContext 
= new wxGLContext(TRUE
, this, palette
, sharedContext 
); 
 211 wxGLCanvas::~wxGLCanvas() 
 216   ::ReleaseDC((HWND
) GetHWND(), (HDC
) m_hDC
); 
 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
) 
 224   Suggestion from Kelly Brock <kbrock@8cs.com> (not yet implemented): 
 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: 
 229        wxSize parentSize = GetClientSize(); 
 231   All locations within the function that use 'size' are changed to 
 233   The above corrects the initial display corruption with the GeForce and 
 234   TNT2, not sure about other NVidia cards yet. 
 237   static bool registeredGLCanvasClass 
= FALSE
; 
 239   // We have to register a special window class because we need 
 240   // the CS_OWNDC style for GLCanvas. 
 243   From Angel Popov <jumpo@bitex.com> 
 245   Here are two snips from a dicussion in the OpenGL Gamedev list that explains 
 246   how this problem can be fixed: 
 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." 
 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." 
 259   if (!registeredGLCanvasClass
) 
 263     static const long styleNormal 
= CS_HREDRAW 
| CS_VREDRAW 
| CS_DBLCLKS 
| CS_OWNDC
; 
 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
; 
 274     // Register the GLCanvas class name 
 275     wndclass
.hbrBackground 
= (HBRUSH
)NULL
; 
 276     wndclass
.lpszClassName 
= wxGLCanvasClassName
; 
 277     wndclass
.style         
= styleNormal
; 
 279     if ( !RegisterClass(&wndclass
) ) 
 281       wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)")); 
 285     registeredGLCanvasClass 
= TRUE
; 
 288   wxCHECK_MSG( parent
, FALSE
, wxT("can't create wxWindow without parent") ); 
 290   if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 293   parent
->AddChild(this); 
 296   if ( style 
& wxBORDER 
) 
 297     msflags 
|= WS_BORDER
; 
 298   if ( style 
& wxTHICK_FRAME 
) 
 299     msflags 
|= WS_THICKFRAME
; 
 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. 
 308   msflags 
|= WS_CHILD 
| WS_VISIBLE 
| WS_CLIPSIBLINGS
; 
 309   //  if ( style & wxCLIP_CHILDREN ) 
 310   //    msflags |= WS_CLIPCHILDREN; 
 311   msflags 
|= WS_CLIPCHILDREN
; 
 314   WXDWORD exStyle 
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
); 
 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
)) 
 321     msflags 
|= WS_BORDER
; 
 324   // calculate the value to return from WM_GETDLGCODE handler 
 325   if ( GetWindowStyleFlag() & wxWANTS_CHARS 
) 
 327     // want everything: i.e. all keys and WM_CHAR message 
 328     m_lDlgCode 
= DLGC_WANTARROWS 
| DLGC_WANTCHARS 
| 
 329                  DLGC_WANTTAB 
| DLGC_WANTMESSAGE
; 
 332   MSWCreate(m_windowId
, parent
, wxGLCanvasClassName
, this, NULL
, 
 334             WidthDefault(size
.x
), HeightDefault(size
.y
), 
 335             msflags
, NULL
, exStyle
); 
 340 void wxGLCanvas::SetupPixelFormat(int *attribList
) // (HDC hDC) 
 343   PIXELFORMATDESCRIPTOR pfd 
= { 
 344                 sizeof(PIXELFORMATDESCRIPTOR
),  /* size */ 
 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 */ 
 361                 0, 0, 0,                        /* no layer, visible, damage masks */ 
 365     pfd
.dwFlags 
&= ~PFD_DOUBLEBUFFER
; 
 366     pfd
.iPixelType 
= PFD_TYPE_COLORINDEX
; 
 370     while( (attribList
[arg
]!=0) ) 
 372       switch( attribList
[arg
++] ) 
 375           pfd
.iPixelType 
= PFD_TYPE_RGBA
; 
 377         case WX_GL_BUFFER_SIZE
: 
 378           pfd
.cColorBits 
= attribList
[arg
++]; 
 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
; 
 387             pfd
.iLayerType 
= PFD_MAIN_PLANE
; 
 391         case WX_GL_DOUBLEBUFFER
: 
 392           pfd
.dwFlags 
|= PFD_DOUBLEBUFFER
; 
 395           pfd
.dwFlags 
|= PFD_STEREO
; 
 397         case WX_GL_AUX_BUFFERS
: 
 398           pfd
.cAuxBuffers 
= attribList
[arg
++]; 
 401           pfd
.cColorBits 
+= (pfd
.cRedBits 
= attribList
[arg
++]); 
 403         case WX_GL_MIN_GREEN
: 
 404           pfd
.cColorBits 
+= (pfd
.cGreenBits 
= attribList
[arg
++]); 
 407           pfd
.cColorBits 
+= (pfd
.cBlueBits 
= attribList
[arg
++]); 
 409         case WX_GL_MIN_ALPHA
: 
 410           // doesn't count in cColorBits 
 411           pfd
.cAlphaBits 
= attribList
[arg
++]; 
 413         case WX_GL_DEPTH_SIZE
: 
 414           pfd
.cDepthBits 
= attribList
[arg
++]; 
 416         case WX_GL_STENCIL_SIZE
: 
 417           pfd
.cStencilBits 
= attribList
[arg
++]; 
 419         case WX_GL_MIN_ACCUM_RED
: 
 420           pfd
.cAccumBits 
+= (pfd
.cAccumRedBits 
= attribList
[arg
++]); 
 422         case WX_GL_MIN_ACCUM_GREEN
: 
 423           pfd
.cAccumBits 
+= (pfd
.cAccumGreenBits 
= attribList
[arg
++]); 
 425         case WX_GL_MIN_ACCUM_BLUE
: 
 426           pfd
.cAccumBits 
+= (pfd
.cAccumBlueBits 
= attribList
[arg
++]); 
 428         case WX_GL_MIN_ACCUM_ALPHA
: 
 429           pfd
.cAccumBits 
+= (pfd
.cAccumAlphaBits 
= attribList
[arg
++]); 
 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
); 
 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
); 
 450 void wxGLCanvas::SetupPalette(const wxPalette
& palette
) 
 452     int pixelFormat 
= GetPixelFormat((HDC
) m_hDC
); 
 453     PIXELFORMATDESCRIPTOR pfd
; 
 455     DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
); 
 457     if (pfd
.dwFlags 
& PFD_NEED_PALETTE
) 
 467     if ( !m_palette
.Ok() ) 
 469         m_palette 
= CreateDefaultPalette(); 
 474         SelectPalette((HDC
) m_hDC
, (HPALETTE
) m_palette
.GetHPALETTE(), FALSE
); 
 475         RealizePalette((HDC
) m_hDC
); 
 479 wxPalette 
wxGLCanvas::CreateDefaultPalette() 
 481     PIXELFORMATDESCRIPTOR pfd
; 
 483     int pixelFormat 
= GetPixelFormat((HDC
) m_hDC
); 
 485     DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
); 
 487     paletteSize 
= 1 << pfd
.cColorBits
; 
 490      (LOGPALETTE
*) malloc(sizeof(LOGPALETTE
) + paletteSize 
* sizeof(PALETTEENTRY
)); 
 491     pPal
->palVersion 
= 0x300; 
 492     pPal
->palNumEntries 
= paletteSize
; 
 494     /* build a simple RGB color palette */ 
 496         int redMask 
= (1 << pfd
.cRedBits
) - 1; 
 497         int greenMask 
= (1 << pfd
.cGreenBits
) - 1; 
 498         int blueMask 
= (1 << pfd
.cBlueBits
) - 1; 
 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; 
 512     HPALETTE hPalette 
= CreatePalette(pPal
); 
 516     palette
.SetHPALETTE((WXHPALETTE
) hPalette
); 
 521 void wxGLCanvas::SwapBuffers() 
 524     m_glContext
->SwapBuffers(); 
 527 void wxGLCanvas::OnSize(wxSizeEvent
& event
) 
 530   GetClientSize(& width
, & height
); 
 534     m_glContext
->SetCurrent(); 
 536     glViewport(0, 0, (GLint
)width
, (GLint
)height
); 
 537     glMatrixMode(GL_PROJECTION
); 
 539     glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 ); 
 540     glMatrixMode(GL_MODELVIEW
); 
 544 void wxGLCanvas::SetCurrent() 
 548     m_glContext
->SetCurrent(); 
 552 void wxGLCanvas::SetColour(const char *colour
) 
 555     m_glContext
->SetColour(colour
); 
 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
) 
 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()); 
 568     event
.SetPaletteRealized(TRUE
); 
 571     event
.SetPaletteRealized(FALSE
); 
 574 // I think this doesn't have to be propagated to child windows. 
 575 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent
& event
) 
 577   /* realize palette if this is *not* the current window */ 
 579        GetPalette()->Ok() && (this != event
.GetChangedWindow()) ) 
 581     ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE()); 
 582     ::SelectPalette((HDC
) GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
); 
 583     ::RealizePalette((HDC
) GetHDC()); 
 588 /* Give extensions proper function names. */ 
 590 /* EXT_vertex_array */ 
 591 void glArrayElementEXT(GLint i
) 
 595 void glColorPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 599 void glDrawArraysEXT(GLenum mode
, GLint first
, GLsizei count
) 
 601 #ifdef GL_EXT_vertex_array 
 602     static PFNGLDRAWARRAYSEXTPROC proc 
= 0; 
 606         proc 
= (PFNGLDRAWARRAYSEXTPROC
) wglGetProcAddress("glDrawArraysEXT"); 
 610         (* proc
) (mode
, first
, count
); 
 614 void glEdgeFlagPointerEXT(GLsizei stride
, GLsizei count
, const GLboolean 
*pointer
) 
 618 void glGetPointervEXT(GLenum pname
, GLvoid
* *params
) 
 622 void glIndexPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 626 void glNormalPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 628 #ifdef GL_EXT_vertex_array 
 629   static PFNGLNORMALPOINTEREXTPROC proc 
= 0; 
 633     proc 
= (PFNGLNORMALPOINTEREXTPROC
) wglGetProcAddress("glNormalPointerEXT"); 
 637     (* proc
) (type
, stride
, count
, pointer
); 
 641 void glTexCoordPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 645 void glVertexPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 647 #ifdef GL_EXT_vertex_array 
 648   static PFNGLVERTEXPOINTEREXTPROC proc 
= 0; 
 652     proc 
= (PFNGLVERTEXPOINTEREXTPROC
) wglGetProcAddress("glVertexPointerEXT"); 
 655     (* proc
) (size
, type
, stride
, count
, pointer
); 
 659 /* EXT_color_subtable */ 
 660 void glColorSubtableEXT(GLenum target
, GLsizei start
, GLsizei count
, GLenum format
, GLenum type
, const GLvoid 
*table
) 
 664 /* EXT_color_table */ 
 665 void glColorTableEXT(GLenum target
, GLenum internalformat
, GLsizei width
, GLenum format
, GLenum type
, const GLvoid 
*table
) 
 669 void glCopyColorTableEXT(GLenum target
, GLenum internalformat
, GLint x
, GLint y
, GLsizei width
) 
 673 void glGetColorTableEXT(GLenum target
, GLenum format
, GLenum type
, GLvoid 
*table
) 
 677 void glGetColorTableParamaterfvEXT(GLenum target
, GLenum pname
, GLfloat 
*params
) 
 681 void glGetColorTavleParameterivEXT(GLenum target
, GLenum pname
, GLint 
*params
) 
 685 /* SGI_compiled_vertex_array */ 
 686 void glLockArraysSGI(GLint first
, GLsizei count
) 
 690 void glUnlockArraysSGI() 
 695 /* SGI_cull_vertex */ 
 696 void glCullParameterdvSGI(GLenum pname
, GLdouble
* params
) 
 700 void glCullParameterfvSGI(GLenum pname
, GLfloat
* params
) 
 705 void glIndexFuncSGI(GLenum func
, GLclampf ref
) 
 709 /* SGI_index_material */ 
 710 void glIndexMaterialSGI(GLenum face
, GLenum mode
) 
 715 void glAddSwapHintRectWin(GLint x
, GLint y
, GLsizei width
, GLsizei height
)