1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/glcanvas.cpp 
   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 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "glcanvas.h" 
  16 #include "wx/wxprec.h" 
  18 #if defined(__BORLANDC__) 
  26     #include "wx/settings.h" 
  32 #include "wx/msw/private.h" 
  34 // DLL options compatibility check: 
  36 WX_CHECK_BUILD_OPTIONS("wxGL") 
  38 #include "wx/glcanvas.h" 
  41   The following two compiler directives are specific to the Microsoft Visual 
  42   C++ family of compilers 
  44   Fundementally what they do is instruct the linker to use these two libraries 
  45   for the resolution of symbols. In essence, this is the equivalent of adding 
  46   these two libraries to either the Makefile or project file. 
  48   This is NOT a recommended technique, and certainly is unlikely to be used 
  49   anywhere else in wxWindows given it is so specific to not only wxMSW, but 
  50   also the VC compiler. However, in the case of opengl support, it's an 
  51   applicable technique as opengl is optional in setup.h This code (wrapped by 
  52   wxUSE_GLCANVAS), now allows opengl support to be added purely by modifying 
  53   setup.h rather than by having to modify either the project or DSP fle. 
  55   See MSDN for further information on the exact usage of these commands. 
  58 #  pragma comment( lib, "opengl32" ) 
  59 #  pragma comment( lib, "glu32" ) 
  63 static const wxChar 
*wxGLCanvasClassName 
= wxT("wxGLCanvasClass"); 
  64 static const wxChar 
*wxGLCanvasClassNameNoRedraw 
= wxT("wxGLCanvasClassNR"); 
  66 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, 
  67                                    WPARAM wParam
, LPARAM lParam
); 
  70  * GLContext implementation 
  73 wxGLContext::wxGLContext(bool WXUNUSED(isRGB
), wxGLCanvas 
*win
, const wxPalette
& WXUNUSED(palette
)) 
  77   m_hDC 
= win
->GetHDC(); 
  79   m_glContext 
= wglCreateContext((HDC
) m_hDC
); 
  80   wxCHECK_RET( m_glContext
, wxT("Couldn't create OpenGl context") ); 
  82   wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
  85 wxGLContext::wxGLContext( 
  86                bool WXUNUSED(isRGB
), wxGLCanvas 
*win
, 
  87                const wxPalette
& WXUNUSED(palette
), 
  88                const wxGLContext 
*other  
/* for sharing display lists */ 
  93   m_hDC 
= win
->GetHDC(); 
  95   m_glContext 
= wglCreateContext((HDC
) m_hDC
); 
  96   wxCHECK_RET( m_glContext
, wxT("Couldn't create OpenGl context") ); 
  99     wglShareLists( other
->m_glContext
, m_glContext 
); 
 101   wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
 104 wxGLContext::~wxGLContext() 
 108     wglMakeCurrent(NULL
, NULL
); 
 109     wglDeleteContext(m_glContext
); 
 113 void wxGLContext::SwapBuffers() 
 117     wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
 118     ::SwapBuffers((HDC
) m_hDC
);    //blits the backbuffer into DC 
 122 void wxGLContext::SetCurrent() 
 126     wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
 130   setupPixelFormat(hDC); 
 135 void wxGLContext::SetColour(const wxChar 
*colour
) 
 137     wxColour col 
= wxTheColourDatabase
->Find(colour
); 
 140         float r 
= (float)(col
.Red()/256.0); 
 141         float g 
= (float)(col
.Green()/256.0); 
 142         float b 
= (float)(col
.Blue()/256.0); 
 149  * wxGLCanvas implementation 
 152 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
) 
 154 BEGIN_EVENT_TABLE(wxGLCanvas
, wxWindow
) 
 155     EVT_SIZE(wxGLCanvas::OnSize
) 
 156     EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged
) 
 157     EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette
) 
 160 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, wxWindowID id
, 
 161     const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
, 
 162     int *attribList
, const wxPalette
& palette
) : wxWindow() 
 164   m_glContext 
= (wxGLContext
*) NULL
; 
 166   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 170     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
 171     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 174   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 176   SetupPixelFormat(attribList
); 
 177   SetupPalette(palette
); 
 179   m_glContext 
= new wxGLContext(TRUE
, this, palette
); 
 182 wxGLCanvas::wxGLCanvas( wxWindow 
*parent
, 
 183               const wxGLContext 
*shared
, wxWindowID id
, 
 184               const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
, 
 185               int *attribList
, const wxPalette
& palette 
) 
 188   m_glContext 
= (wxGLContext
*) NULL
; 
 190   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 194     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
 195     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 198   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 200   SetupPixelFormat(attribList
); 
 201   SetupPalette(palette
); 
 203   m_glContext 
= new wxGLContext(TRUE
, this, palette
, shared 
); 
 206 // Not very useful for wxMSW, but this is to be wxGTK compliant 
 208 wxGLCanvas::wxGLCanvas( wxWindow 
*parent
, const wxGLCanvas 
*shared
, wxWindowID id
, 
 209                         const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
, 
 210                         int *attribList
, const wxPalette
& palette 
): 
 213   m_glContext 
= (wxGLContext
*) NULL
; 
 215   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 219     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
 220     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 223   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 225   SetupPixelFormat(attribList
); 
 226   SetupPalette(palette
); 
 228   wxGLContext 
*sharedContext
=0; 
 229   if (shared
) sharedContext
=shared
->GetContext(); 
 230   m_glContext 
= new wxGLContext(TRUE
, this, palette
, sharedContext 
); 
 233 wxGLCanvas::~wxGLCanvas() 
 238   ::ReleaseDC((HWND
) GetHWND(), (HDC
) m_hDC
); 
 241 // Replaces wxWindow::Create functionality, since we need to use a different 
 243 bool wxGLCanvas::Create(wxWindow 
*parent
, 
 248                         const wxString
& name
) 
 250   static bool s_registeredGLCanvasClass 
= FALSE
; 
 252   // We have to register a special window class because we need 
 253   // the CS_OWNDC style for GLCanvas. 
 256   From Angel Popov <jumpo@bitex.com> 
 258   Here are two snips from a dicussion in the OpenGL Gamedev list that explains 
 259   how this problem can be fixed: 
 261   "There are 5 common DCs available in Win95. These are aquired when you call 
 262   GetDC or GetDCEx from a window that does _not_ have the OWNDC flag. 
 263   OWNDC flagged windows do not get their DC from the common DC pool, the issue 
 264   is they require 800 bytes each from the limited 64Kb local heap for GDI." 
 266   "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps 
 267   do), Win95 will actually "steal" it from you.  MakeCurrent fails, 
 268   apparently, because Windows re-assigns the HDC to a different window.  The 
 269   only way to prevent this, the only reliable means, is to set CS_OWNDC." 
 272   if (!s_registeredGLCanvasClass
) 
 276     // the fields which are common to all classes 
 277     wndclass
.lpfnWndProc   
= (WNDPROC
)wxWndProc
; 
 278     wndclass
.cbClsExtra    
= 0; 
 279     wndclass
.cbWndExtra    
= sizeof( DWORD 
); // VZ: what is this DWORD used for? 
 280     wndclass
.hInstance     
= wxhInstance
; 
 281     wndclass
.hIcon         
= (HICON
) NULL
; 
 282     wndclass
.hCursor       
= ::LoadCursor((HINSTANCE
)NULL
, IDC_ARROW
); 
 283     wndclass
.lpszMenuName  
= NULL
; 
 285     // Register the GLCanvas class name 
 286     wndclass
.hbrBackground 
= (HBRUSH
)NULL
; 
 287     wndclass
.lpszClassName 
= wxGLCanvasClassName
; 
 288     wndclass
.style         
= CS_HREDRAW 
| CS_VREDRAW 
| CS_DBLCLKS 
| CS_OWNDC
; 
 290     if ( !::RegisterClass(&wndclass
) ) 
 292       wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)")); 
 296     // Register the GLCanvas class name for windows which don't do full repaint 
 298     wndclass
.lpszClassName 
= wxGLCanvasClassNameNoRedraw
; 
 299     wndclass
.style        
&= ~(CS_HREDRAW 
| CS_VREDRAW
); 
 301     if ( !::RegisterClass(&wndclass
) ) 
 303         wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)")); 
 305         ::UnregisterClass(wxGLCanvasClassName
, wxhInstance
); 
 310     s_registeredGLCanvasClass 
= TRUE
; 
 313   wxCHECK_MSG( parent
, FALSE
, wxT("can't create wxWindow without parent") ); 
 315   if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 318   parent
->AddChild(this); 
 323   A general rule with OpenGL and Win32 is that any window that will have a 
 324   HGLRC built for it must have two flags:  WS_CLIPCHILDREN & WS_CLIPSIBLINGS. 
 325   You can find references about this within the knowledge base and most OpenGL 
 326   books that contain the wgl function descriptions. 
 330   msflags 
|= WS_CHILD 
| WS_VISIBLE 
| WS_CLIPSIBLINGS 
| WS_CLIPCHILDREN
; 
 331   msflags 
|= MSWGetStyle(style
, & exStyle
) ; 
 333   return MSWCreate(wxGLCanvasClassName
, NULL
, pos
, size
, msflags
, exStyle
); 
 336 static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR
& pfd
, int *attribList
) 
 339     pfd
.dwFlags 
&= ~PFD_DOUBLEBUFFER
; 
 340     pfd
.iPixelType 
= PFD_TYPE_COLORINDEX
; 
 344     while( (attribList
[arg
]!=0) ) 
 346       switch( attribList
[arg
++] ) 
 349           pfd
.iPixelType 
= PFD_TYPE_RGBA
; 
 351         case WX_GL_BUFFER_SIZE
: 
 352           pfd
.cColorBits 
= attribList
[arg
++]; 
 355           // this member looks like it may be obsolete 
 356           if (attribList
[arg
] > 0) { 
 357             pfd
.iLayerType 
= (BYTE
)PFD_OVERLAY_PLANE
; 
 358           } else if (attribList
[arg
] < 0) { 
 359             pfd
.iLayerType 
= (BYTE
)PFD_UNDERLAY_PLANE
; 
 361             pfd
.iLayerType 
= (BYTE
)PFD_MAIN_PLANE
; 
 365         case WX_GL_DOUBLEBUFFER
: 
 366           pfd
.dwFlags 
|= PFD_DOUBLEBUFFER
; 
 369           pfd
.dwFlags 
|= PFD_STEREO
; 
 371         case WX_GL_AUX_BUFFERS
: 
 372           pfd
.cAuxBuffers 
= attribList
[arg
++]; 
 375           pfd
.cColorBits 
+= (pfd
.cRedBits 
= attribList
[arg
++]); 
 377         case WX_GL_MIN_GREEN
: 
 378           pfd
.cColorBits 
+= (pfd
.cGreenBits 
= attribList
[arg
++]); 
 381           pfd
.cColorBits 
+= (pfd
.cBlueBits 
= attribList
[arg
++]); 
 383         case WX_GL_MIN_ALPHA
: 
 384           // doesn't count in cColorBits 
 385           pfd
.cAlphaBits 
= attribList
[arg
++]; 
 387         case WX_GL_DEPTH_SIZE
: 
 388           pfd
.cDepthBits 
= attribList
[arg
++]; 
 390         case WX_GL_STENCIL_SIZE
: 
 391           pfd
.cStencilBits 
= attribList
[arg
++]; 
 393         case WX_GL_MIN_ACCUM_RED
: 
 394           pfd
.cAccumBits 
+= (pfd
.cAccumRedBits 
= attribList
[arg
++]); 
 396         case WX_GL_MIN_ACCUM_GREEN
: 
 397           pfd
.cAccumBits 
+= (pfd
.cAccumGreenBits 
= attribList
[arg
++]); 
 399         case WX_GL_MIN_ACCUM_BLUE
: 
 400           pfd
.cAccumBits 
+= (pfd
.cAccumBlueBits 
= attribList
[arg
++]); 
 402         case WX_GL_MIN_ACCUM_ALPHA
: 
 403           pfd
.cAccumBits 
+= (pfd
.cAccumAlphaBits 
= attribList
[arg
++]); 
 412 void wxGLCanvas::SetupPixelFormat(int *attribList
) // (HDC hDC) 
 414   PIXELFORMATDESCRIPTOR pfd 
= { 
 415         sizeof(PIXELFORMATDESCRIPTOR
),    /* size */ 
 419         PFD_DOUBLEBUFFER
,        /* support double-buffering */ 
 420         PFD_TYPE_RGBA
,            /* color type */ 
 421         16,                /* prefered color depth */ 
 422         0, 0, 0, 0, 0, 0,        /* color bits (ignored) */ 
 423         0,                /* no alpha buffer */ 
 424         0,                /* alpha bits (ignored) */ 
 425         0,                /* no accumulation buffer */ 
 426         0, 0, 0, 0,            /* accum bits (ignored) */ 
 427         16,                /* depth buffer */ 
 428         0,                /* no stencil buffer */ 
 429         0,                /* no auxiliary buffers */ 
 430         PFD_MAIN_PLANE
,            /* main layer */ 
 432         0, 0, 0,            /* no layer, visible, damage masks */ 
 435   AdjustPFDForAttributes(pfd
, attribList
); 
 437   int pixelFormat 
= ChoosePixelFormat((HDC
) m_hDC
, &pfd
); 
 438   if (pixelFormat 
== 0) { 
 439     wxLogLastError(_T("ChoosePixelFormat")); 
 442     if ( !::SetPixelFormat((HDC
) m_hDC
, pixelFormat
, &pfd
) ) { 
 443       wxLogLastError(_T("SetPixelFormat")); 
 448 void wxGLCanvas::SetupPalette(const wxPalette
& palette
) 
 450     int pixelFormat 
= GetPixelFormat((HDC
) m_hDC
); 
 451     PIXELFORMATDESCRIPTOR pfd
; 
 453     DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
); 
 455     if (pfd
.dwFlags 
& PFD_NEED_PALETTE
) 
 465     if ( !m_palette
.Ok() ) 
 467         m_palette 
= CreateDefaultPalette(); 
 472         SelectPalette((HDC
) m_hDC
, (HPALETTE
) m_palette
.GetHPALETTE(), FALSE
); 
 473         RealizePalette((HDC
) m_hDC
); 
 477 wxPalette 
wxGLCanvas::CreateDefaultPalette() 
 479     PIXELFORMATDESCRIPTOR pfd
; 
 481     int pixelFormat 
= GetPixelFormat((HDC
) m_hDC
); 
 483     DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
); 
 485     paletteSize 
= 1 << pfd
.cColorBits
; 
 488      (LOGPALETTE
*) malloc(sizeof(LOGPALETTE
) + paletteSize 
* sizeof(PALETTEENTRY
)); 
 489     pPal
->palVersion 
= 0x300; 
 490     pPal
->palNumEntries 
= paletteSize
; 
 492     /* build a simple RGB color palette */ 
 494     int redMask 
= (1 << pfd
.cRedBits
) - 1; 
 495     int greenMask 
= (1 << pfd
.cGreenBits
) - 1; 
 496     int blueMask 
= (1 << pfd
.cBlueBits
) - 1; 
 499     for (i
=0; i
<paletteSize
; ++i
) { 
 500         pPal
->palPalEntry
[i
].peRed 
= 
 501             (((i 
>> pfd
.cRedShift
) & redMask
) * 255) / redMask
; 
 502         pPal
->palPalEntry
[i
].peGreen 
= 
 503             (((i 
>> pfd
.cGreenShift
) & greenMask
) * 255) / greenMask
; 
 504         pPal
->palPalEntry
[i
].peBlue 
= 
 505             (((i 
>> pfd
.cBlueShift
) & blueMask
) * 255) / blueMask
; 
 506         pPal
->palPalEntry
[i
].peFlags 
= 0; 
 510     HPALETTE hPalette 
= CreatePalette(pPal
); 
 514     palette
.SetHPALETTE((WXHPALETTE
) hPalette
); 
 519 void wxGLCanvas::SwapBuffers() 
 522     m_glContext
->SwapBuffers(); 
 525 void wxGLCanvas::OnSize(wxSizeEvent
& WXUNUSED(event
)) 
 529 void wxGLCanvas::SetCurrent() 
 533     m_glContext
->SetCurrent(); 
 537 void wxGLCanvas::SetColour(const wxChar 
*colour
) 
 540     m_glContext
->SetColour(colour
); 
 543 // TODO: Have to have this called by parent frame (?) 
 544 // So we need wxFrame to call OnQueryNewPalette for all children... 
 545 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent
& event
) 
 547   /* realize palette if this is the current window */ 
 548   if ( GetPalette()->Ok() ) { 
 549     ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE()); 
 550     ::SelectPalette((HDC
) GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
); 
 551     ::RealizePalette((HDC
) GetHDC()); 
 553     event
.SetPaletteRealized(TRUE
); 
 556     event
.SetPaletteRealized(FALSE
); 
 559 // I think this doesn't have to be propagated to child windows. 
 560 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent
& event
) 
 562   /* realize palette if this is *not* the current window */ 
 564        GetPalette()->Ok() && (this != event
.GetChangedWindow()) ) 
 566     ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE()); 
 567     ::SelectPalette((HDC
) GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
); 
 568     ::RealizePalette((HDC
) GetHDC()); 
 573 /* Give extensions proper function names. */ 
 575 /* EXT_vertex_array */ 
 576 void glArrayElementEXT(GLint 
WXUNUSED(i
)) 
 580 void glColorPointerEXT(GLint 
WXUNUSED(size
), GLenum 
WXUNUSED(type
), GLsizei 
WXUNUSED(stride
), GLsizei 
WXUNUSED(count
), const GLvoid 
*WXUNUSED(pointer
)) 
 584 void glDrawArraysEXT(GLenum mode
, GLint first
, GLsizei count
) 
 586 #ifdef GL_EXT_vertex_array 
 587     static PFNGLDRAWARRAYSEXTPROC proc 
= 0; 
 591         proc 
= (PFNGLDRAWARRAYSEXTPROC
) wglGetProcAddress("glDrawArraysEXT"); 
 595         (* proc
) (mode
, first
, count
); 
 599 void glEdgeFlagPointerEXT(GLsizei 
WXUNUSED(stride
), GLsizei 
WXUNUSED(count
), const GLboolean 
*WXUNUSED(pointer
)) 
 603 void glGetPointervEXT(GLenum 
WXUNUSED(pname
), GLvoid
* *WXUNUSED(params
)) 
 607 void glIndexPointerEXT(GLenum 
WXUNUSED(type
), GLsizei 
WXUNUSED(stride
), GLsizei 
WXUNUSED(count
), const GLvoid 
*WXUNUSED(pointer
)) 
 611 void glNormalPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 613 #ifdef GL_EXT_vertex_array 
 614   static PFNGLNORMALPOINTEREXTPROC proc 
= 0; 
 618     proc 
= (PFNGLNORMALPOINTEREXTPROC
) wglGetProcAddress("glNormalPointerEXT"); 
 622     (* proc
) (type
, stride
, count
, pointer
); 
 626 void glTexCoordPointerEXT(GLint 
WXUNUSED(size
), GLenum 
WXUNUSED(type
), GLsizei 
WXUNUSED(stride
), GLsizei 
WXUNUSED(count
), const GLvoid 
*WXUNUSED(pointer
)) 
 630 void glVertexPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 632 #ifdef GL_EXT_vertex_array 
 633   static PFNGLVERTEXPOINTEREXTPROC proc 
= 0; 
 637     proc 
= (PFNGLVERTEXPOINTEREXTPROC
) wglGetProcAddress("glVertexPointerEXT"); 
 640     (* proc
) (size
, type
, stride
, count
, pointer
); 
 644 /* EXT_color_subtable */ 
 645 void glColorSubtableEXT(GLenum 
WXUNUSED(target
), GLsizei 
WXUNUSED(start
), GLsizei 
WXUNUSED(count
), GLenum 
WXUNUSED(format
), GLenum 
WXUNUSED(type
), const GLvoid 
*WXUNUSED(table
)) 
 649 /* EXT_color_table */ 
 650 void glColorTableEXT(GLenum 
WXUNUSED(target
), GLenum 
WXUNUSED(internalformat
), GLsizei 
WXUNUSED(width
), GLenum 
WXUNUSED(format
), GLenum 
WXUNUSED(type
), const GLvoid 
*WXUNUSED(table
)) 
 654 void glCopyColorTableEXT(GLenum 
WXUNUSED(target
), GLenum 
WXUNUSED(internalformat
), GLint 
WXUNUSED(x
), GLint 
WXUNUSED(y
), GLsizei 
WXUNUSED(width
)) 
 658 void glGetColorTableEXT(GLenum 
WXUNUSED(target
), GLenum 
WXUNUSED(format
), GLenum 
WXUNUSED(type
), GLvoid 
*WXUNUSED(table
)) 
 662 void glGetColorTableParamaterfvEXT(GLenum 
WXUNUSED(target
), GLenum 
WXUNUSED(pname
), GLfloat 
*WXUNUSED(params
)) 
 666 void glGetColorTavleParameterivEXT(GLenum 
WXUNUSED(target
), GLenum 
WXUNUSED(pname
), GLint 
*WXUNUSED(params
)) 
 670 /* SGI_compiled_vertex_array */ 
 671 void glLockArraysSGI(GLint 
WXUNUSED(first
), GLsizei 
WXUNUSED(count
)) 
 675 void glUnlockArraysSGI() 
 680 /* SGI_cull_vertex */ 
 681 void glCullParameterdvSGI(GLenum 
WXUNUSED(pname
), GLdouble
* WXUNUSED(params
)) 
 685 void glCullParameterfvSGI(GLenum 
WXUNUSED(pname
), GLfloat
* WXUNUSED(params
)) 
 690 void glIndexFuncSGI(GLenum 
WXUNUSED(func
), GLclampf 
WXUNUSED(ref
)) 
 694 /* SGI_index_material */ 
 695 void glIndexMaterialSGI(GLenum 
WXUNUSED(face
), GLenum 
WXUNUSED(mode
)) 
 700 void glAddSwapHintRectWin(GLint 
WXUNUSED(x
), GLint 
WXUNUSED(y
), GLsizei 
WXUNUSED(width
), GLsizei 
WXUNUSED(height
)) 
 705 //--------------------------------------------------------------------------- 
 707 //--------------------------------------------------------------------------- 
 709 IMPLEMENT_CLASS(wxGLApp
, wxApp
) 
 711 bool wxGLApp::InitGLVisual(int *attribList
) 
 714   PIXELFORMATDESCRIPTOR pfd 
= { 
 715         sizeof(PIXELFORMATDESCRIPTOR
),    /* size */ 
 719         PFD_DOUBLEBUFFER
,        /* support double-buffering */ 
 720         PFD_TYPE_RGBA
,            /* color type */ 
 721         16,                /* prefered color depth */ 
 722         0, 0, 0, 0, 0, 0,        /* color bits (ignored) */ 
 723         0,                /* no alpha buffer */ 
 724         0,                /* alpha bits (ignored) */ 
 725         0,                /* no accumulation buffer */ 
 726         0, 0, 0, 0,            /* accum bits (ignored) */ 
 727         16,                /* depth buffer */ 
 728         0,                /* no stencil buffer */ 
 729         0,                /* no auxiliary buffers */ 
 730         PFD_MAIN_PLANE
,            /* main layer */ 
 732         0, 0, 0,            /* no layer, visible, damage masks */ 
 735   AdjustPFDForAttributes(pfd
, attribList
); 
 737   // use DC for whole (root) screen, since no windows have yet been created 
 738   pixelFormat 
= ChoosePixelFormat(ScreenHDC(), &pfd
); 
 740   if (pixelFormat 
== 0) { 
 741     wxLogError(_("Failed to initialize OpenGL"));