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 
  31     #include "wx/settings.h" 
  36 #include "wx/msw/private.h" 
  38 #include "myglcanvas.h" 
  40 const wxChar
* wxGLCanvasName 
= wxT("GLcanvas"); 
  41 static const wxChar 
*wxGLCanvasClassName 
= wxT("wxGLCanvasClass"); 
  42 static const wxChar 
*wxGLCanvasClassNameNoRedraw 
= wxT("wxGLCanvasClassNR"); 
  44 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, 
  45                                    WPARAM wParam
, LPARAM lParam
); 
  48  * GLContext implementation 
  51 wxGLContext::wxGLContext(bool isRGB
, wxGLCanvas 
*win
, const wxPalette
& palette
) 
  55   m_hDC 
= win
->GetHDC(); 
  57   m_glContext 
= wglCreateContext((HDC
) m_hDC
); 
  58   wxCHECK_RET( m_glContext
, wxT("Couldn't create OpenGl context") ); 
  60   wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
  63 wxGLContext::wxGLContext( 
  64                bool isRGB
, wxGLCanvas 
*win
, 
  65                const wxPalette
& palette
, 
  66                const wxGLContext 
*other  
/* for sharing display lists */ 
  71   m_hDC 
= win
->GetHDC(); 
  73   m_glContext 
= wglCreateContext((HDC
) m_hDC
); 
  74   wxCHECK_RET( m_glContext
, wxT("Couldn't create OpenGl context") ); 
  77     wglShareLists( other
->m_glContext
, m_glContext 
); 
  79   wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
  82 wxGLContext::~wxGLContext() 
  86     wglMakeCurrent(NULL
, NULL
); 
  87     wglDeleteContext(m_glContext
); 
  91 void wxGLContext::SwapBuffers() 
  95     wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
  96     ::SwapBuffers((HDC
) m_hDC
);    //blits the backbuffer into DC 
 100 void wxGLContext::SetCurrent() 
 104     wglMakeCurrent((HDC
) m_hDC
, m_glContext
); 
 108   setupPixelFormat(hDC); 
 113 void wxGLContext::SetColour(const wxChar 
*colour
) 
 118   wxColour 
*col 
= wxTheColourDatabase
->FindColour(colour
); 
 121     r 
= (float)(col
->Red()/256.0); 
 122     g 
= (float)(col
->Green()/256.0); 
 123     b 
= (float)(col
->Blue()/256.0); 
 130  * wxGLCanvas implementation 
 133 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
) 
 135 BEGIN_EVENT_TABLE(wxGLCanvas
, wxWindow
) 
 136     EVT_SIZE(wxGLCanvas::OnSize
) 
 137     EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged
) 
 138     EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette
) 
 141 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, wxWindowID id
, 
 142     const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
, 
 143     int *attribList
, const wxPalette
& palette
) : wxWindow() 
 145   m_glContext 
= (wxGLContext
*) NULL
; 
 147   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 151     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
 152     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 155   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 157   SetupPixelFormat(attribList
); 
 158   SetupPalette(palette
); 
 160   m_glContext 
= new wxGLContext(TRUE
, this, palette
); 
 163 wxGLCanvas::wxGLCanvas( wxWindow 
*parent
, 
 164               const wxGLContext 
*shared
, wxWindowID id
, 
 165               const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
, 
 166               int *attribList
, const wxPalette
& palette 
) 
 169   m_glContext 
= (wxGLContext
*) NULL
; 
 171   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 175     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
 176     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 179   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 181   SetupPixelFormat(attribList
); 
 182   SetupPalette(palette
); 
 184   m_glContext 
= new wxGLContext(TRUE
, this, palette
, shared 
); 
 187 // Not very useful for wxMSW, but this is to be wxGTK compliant 
 189 wxGLCanvas::wxGLCanvas( wxWindow 
*parent
, const wxGLCanvas 
*shared
, wxWindowID id
, 
 190                         const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
, 
 191                         int *attribList
, const wxPalette
& palette 
): 
 194   m_glContext 
= (wxGLContext
*) NULL
; 
 196   bool ret 
= Create(parent
, id
, pos
, size
, style
, name
); 
 200     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)); 
 201     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 204   m_hDC 
= (WXHDC
) ::GetDC((HWND
) GetHWND()); 
 206   SetupPixelFormat(attribList
); 
 207   SetupPalette(palette
); 
 209   wxGLContext 
*sharedContext
=0; 
 210   if (shared
) sharedContext
=shared
->GetContext(); 
 211   m_glContext 
= new wxGLContext(TRUE
, this, palette
, sharedContext 
); 
 214 wxGLCanvas::~wxGLCanvas() 
 219   ::ReleaseDC((HWND
) GetHWND(), (HDC
) m_hDC
); 
 222 // Replaces wxWindow::Create functionality, since we need to use a different 
 224 bool wxGLCanvas::Create(wxWindow 
*parent
, 
 229                         const wxString
& name
) 
 231   static bool s_registeredGLCanvasClass 
= FALSE
; 
 233   // We have to register a special window class because we need 
 234   // the CS_OWNDC style for GLCanvas. 
 237   From Angel Popov <jumpo@bitex.com> 
 239   Here are two snips from a dicussion in the OpenGL Gamedev list that explains 
 240   how this problem can be fixed: 
 242   "There are 5 common DCs available in Win95. These are aquired when you call 
 243   GetDC or GetDCEx from a window that does _not_ have the OWNDC flag. 
 244   OWNDC flagged windows do not get their DC from the common DC pool, the issue 
 245   is they require 800 bytes each from the limited 64Kb local heap for GDI." 
 247   "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps 
 248   do), Win95 will actually "steal" it from you.  MakeCurrent fails, 
 249   apparently, because Windows re-assigns the HDC to a different window.  The 
 250   only way to prevent this, the only reliable means, is to set CS_OWNDC." 
 253   if (!s_registeredGLCanvasClass
) 
 257     // the fields which are common to all classes 
 258     wndclass
.lpfnWndProc   
= (WNDPROC
)wxWndProc
; 
 259     wndclass
.cbClsExtra    
= 0; 
 260     wndclass
.cbWndExtra    
= sizeof( DWORD 
); // VZ: what is this DWORD used for? 
 261     wndclass
.hInstance     
= wxhInstance
; 
 262     wndclass
.hIcon         
= (HICON
) NULL
; 
 263     wndclass
.hCursor       
= ::LoadCursor((HINSTANCE
)NULL
, IDC_ARROW
); 
 264     wndclass
.lpszMenuName  
= NULL
; 
 266     // Register the GLCanvas class name 
 267     wndclass
.hbrBackground 
= (HBRUSH
)NULL
; 
 268     wndclass
.lpszClassName 
= wxGLCanvasClassName
; 
 269     wndclass
.style         
= CS_HREDRAW 
| CS_VREDRAW 
| CS_DBLCLKS 
| CS_OWNDC
; 
 271     if ( !::RegisterClass(&wndclass
) ) 
 273       wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)")); 
 277     // Register the GLCanvas class name for windows which don't do full repaint 
 279     wndclass
.lpszClassName 
= wxGLCanvasClassNameNoRedraw
; 
 280     wndclass
.style        
&= ~(CS_HREDRAW 
| CS_VREDRAW
); 
 282     if ( !::RegisterClass(&wndclass
) ) 
 284         wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)")); 
 286         ::UnregisterClass(wxGLCanvasClassName
, wxhInstance
); 
 291     s_registeredGLCanvasClass 
= TRUE
; 
 294   wxCHECK_MSG( parent
, FALSE
, wxT("can't create wxWindow without parent") ); 
 296   if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 299   parent
->AddChild(this); 
 302   if ( style 
& wxBORDER 
) 
 303     msflags 
|= WS_BORDER
; 
 304   if ( style 
& wxTHICK_FRAME 
) 
 305     msflags 
|= WS_THICKFRAME
; 
 308   A general rule with OpenGL and Win32 is that any window that will have a 
 309   HGLRC built for it must have two flags:  WS_CLIPCHILDREN & WS_CLIPSIBLINGS. 
 310   You can find references about this within the knowledge base and most OpenGL 
 311   books that contain the wgl function descriptions. 
 314   msflags 
|= WS_CHILD 
| WS_VISIBLE 
| WS_CLIPSIBLINGS 
| WS_CLIPCHILDREN
; 
 317   WXDWORD exStyle 
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
); 
 319   // Even with extended styles, need to combine with WS_BORDER 
 320   // for them to look right. 
 321   if ( want3D 
|| (m_windowStyle 
& wxSIMPLE_BORDER
) || (m_windowStyle 
& wxRAISED_BORDER 
) || 
 322        (m_windowStyle 
& wxSUNKEN_BORDER
) || (m_windowStyle 
& wxDOUBLE_BORDER
)) 
 324     msflags 
|= WS_BORDER
; 
 327   return MSWCreate(wxGLCanvasClassName
, NULL
, pos
, size
, msflags
, exStyle
); 
 330 static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR
& pfd
, int *attribList
) 
 333     pfd
.dwFlags 
&= ~PFD_DOUBLEBUFFER
; 
 334     pfd
.iPixelType 
= PFD_TYPE_COLORINDEX
; 
 338     while( (attribList
[arg
]!=0) ) 
 340       switch( attribList
[arg
++] ) 
 343           pfd
.iPixelType 
= PFD_TYPE_RGBA
; 
 345         case WX_GL_BUFFER_SIZE
: 
 346           pfd
.cColorBits 
= attribList
[arg
++]; 
 349           // this member looks like it may be obsolete 
 350           if (attribList
[arg
] > 0) { 
 351             pfd
.iLayerType 
= (BYTE
)PFD_OVERLAY_PLANE
; 
 352           } else if (attribList
[arg
] < 0) { 
 353             pfd
.iLayerType 
= (BYTE
)PFD_UNDERLAY_PLANE
; 
 355             pfd
.iLayerType 
= (BYTE
)PFD_MAIN_PLANE
; 
 359         case WX_GL_DOUBLEBUFFER
: 
 360           pfd
.dwFlags 
|= PFD_DOUBLEBUFFER
; 
 363           pfd
.dwFlags 
|= PFD_STEREO
; 
 365         case WX_GL_AUX_BUFFERS
: 
 366           pfd
.cAuxBuffers 
= attribList
[arg
++]; 
 369           pfd
.cColorBits 
+= (pfd
.cRedBits 
= attribList
[arg
++]); 
 371         case WX_GL_MIN_GREEN
: 
 372           pfd
.cColorBits 
+= (pfd
.cGreenBits 
= attribList
[arg
++]); 
 375           pfd
.cColorBits 
+= (pfd
.cBlueBits 
= attribList
[arg
++]); 
 377         case WX_GL_MIN_ALPHA
: 
 378           // doesn't count in cColorBits 
 379           pfd
.cAlphaBits 
= attribList
[arg
++]; 
 381         case WX_GL_DEPTH_SIZE
: 
 382           pfd
.cDepthBits 
= attribList
[arg
++]; 
 384         case WX_GL_STENCIL_SIZE
: 
 385           pfd
.cStencilBits 
= attribList
[arg
++]; 
 387         case WX_GL_MIN_ACCUM_RED
: 
 388           pfd
.cAccumBits 
+= (pfd
.cAccumRedBits 
= attribList
[arg
++]); 
 390         case WX_GL_MIN_ACCUM_GREEN
: 
 391           pfd
.cAccumBits 
+= (pfd
.cAccumGreenBits 
= attribList
[arg
++]); 
 393         case WX_GL_MIN_ACCUM_BLUE
: 
 394           pfd
.cAccumBits 
+= (pfd
.cAccumBlueBits 
= attribList
[arg
++]); 
 396         case WX_GL_MIN_ACCUM_ALPHA
: 
 397           pfd
.cAccumBits 
+= (pfd
.cAccumAlphaBits 
= attribList
[arg
++]); 
 406 void wxGLCanvas::SetupPixelFormat(int *attribList
) // (HDC hDC) 
 408   PIXELFORMATDESCRIPTOR pfd 
= { 
 409         sizeof(PIXELFORMATDESCRIPTOR
),    /* size */ 
 413         PFD_DOUBLEBUFFER
,        /* support double-buffering */ 
 414         PFD_TYPE_RGBA
,            /* color type */ 
 415         16,                /* prefered color depth */ 
 416         0, 0, 0, 0, 0, 0,        /* color bits (ignored) */ 
 417         0,                /* no alpha buffer */ 
 418         0,                /* alpha bits (ignored) */ 
 419         0,                /* no accumulation buffer */ 
 420         0, 0, 0, 0,            /* accum bits (ignored) */ 
 421         16,                /* depth buffer */ 
 422         0,                /* no stencil buffer */ 
 423         0,                /* no auxiliary buffers */ 
 424         PFD_MAIN_PLANE
,            /* main layer */ 
 426         0, 0, 0,            /* no layer, visible, damage masks */ 
 429   AdjustPFDForAttributes(pfd
, attribList
); 
 431   int pixelFormat 
= ChoosePixelFormat((HDC
) m_hDC
, &pfd
); 
 432   if (pixelFormat 
== 0) { 
 433     wxLogLastError(_T("ChoosePixelFormat")); 
 436     if ( !::SetPixelFormat((HDC
) m_hDC
, pixelFormat
, &pfd
) ) { 
 437       wxLogLastError(_T("SetPixelFormat")); 
 442 void wxGLCanvas::SetupPalette(const wxPalette
& palette
) 
 444     int pixelFormat 
= GetPixelFormat((HDC
) m_hDC
); 
 445     PIXELFORMATDESCRIPTOR pfd
; 
 447     DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
); 
 449     if (pfd
.dwFlags 
& PFD_NEED_PALETTE
) 
 459     if ( !m_palette
.Ok() ) 
 461         m_palette 
= CreateDefaultPalette(); 
 466         SelectPalette((HDC
) m_hDC
, (HPALETTE
) m_palette
.GetHPALETTE(), FALSE
); 
 467         RealizePalette((HDC
) m_hDC
); 
 471 wxPalette 
wxGLCanvas::CreateDefaultPalette() 
 473     PIXELFORMATDESCRIPTOR pfd
; 
 475     int pixelFormat 
= GetPixelFormat((HDC
) m_hDC
); 
 477     DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
); 
 479     paletteSize 
= 1 << pfd
.cColorBits
; 
 482      (LOGPALETTE
*) malloc(sizeof(LOGPALETTE
) + paletteSize 
* sizeof(PALETTEENTRY
)); 
 483     pPal
->palVersion 
= 0x300; 
 484     pPal
->palNumEntries 
= paletteSize
; 
 486     /* build a simple RGB color palette */ 
 488     int redMask 
= (1 << pfd
.cRedBits
) - 1; 
 489     int greenMask 
= (1 << pfd
.cGreenBits
) - 1; 
 490     int blueMask 
= (1 << pfd
.cBlueBits
) - 1; 
 493     for (i
=0; i
<paletteSize
; ++i
) { 
 494         pPal
->palPalEntry
[i
].peRed 
= 
 495             (((i 
>> pfd
.cRedShift
) & redMask
) * 255) / redMask
; 
 496         pPal
->palPalEntry
[i
].peGreen 
= 
 497             (((i 
>> pfd
.cGreenShift
) & greenMask
) * 255) / greenMask
; 
 498         pPal
->palPalEntry
[i
].peBlue 
= 
 499             (((i 
>> pfd
.cBlueShift
) & blueMask
) * 255) / blueMask
; 
 500         pPal
->palPalEntry
[i
].peFlags 
= 0; 
 504     HPALETTE hPalette 
= CreatePalette(pPal
); 
 508     palette
.SetHPALETTE((WXHPALETTE
) hPalette
); 
 513 void wxGLCanvas::SwapBuffers() 
 516     m_glContext
->SwapBuffers(); 
 519 void wxGLCanvas::OnSize(wxSizeEvent
& event
) 
 523 void wxGLCanvas::SetCurrent() 
 527     m_glContext
->SetCurrent(); 
 531 void wxGLCanvas::SetColour(const wxChar 
*colour
) 
 534     m_glContext
->SetColour(colour
); 
 537 // TODO: Have to have this called by parent frame (?) 
 538 // So we need wxFrame to call OnQueryNewPalette for all children... 
 539 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent
& event
) 
 541   /* realize palette if this is the current window */ 
 542   if ( GetPalette()->Ok() ) { 
 543     ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE()); 
 544     ::SelectPalette((HDC
) GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
); 
 545     ::RealizePalette((HDC
) GetHDC()); 
 547     event
.SetPaletteRealized(TRUE
); 
 550     event
.SetPaletteRealized(FALSE
); 
 553 // I think this doesn't have to be propagated to child windows. 
 554 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent
& event
) 
 556   /* realize palette if this is *not* the current window */ 
 558        GetPalette()->Ok() && (this != event
.GetChangedWindow()) ) 
 560     ::UnrealizeObject((HPALETTE
) GetPalette()->GetHPALETTE()); 
 561     ::SelectPalette((HDC
) GetHDC(), (HPALETTE
) GetPalette()->GetHPALETTE(), FALSE
); 
 562     ::RealizePalette((HDC
) GetHDC()); 
 567 /* Give extensions proper function names. */ 
 569 /* EXT_vertex_array */ 
 570 void glArrayElementEXT(GLint i
) 
 574 void glColorPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 578 void glDrawArraysEXT(GLenum mode
, GLint first
, GLsizei count
) 
 580 #ifdef GL_EXT_vertex_array 
 581     static PFNGLDRAWARRAYSEXTPROC proc 
= 0; 
 585         proc 
= (PFNGLDRAWARRAYSEXTPROC
) wglGetProcAddress("glDrawArraysEXT"); 
 589         (* proc
) (mode
, first
, count
); 
 593 void glEdgeFlagPointerEXT(GLsizei stride
, GLsizei count
, const GLboolean 
*pointer
) 
 597 void glGetPointervEXT(GLenum pname
, GLvoid
* *params
) 
 601 void glIndexPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 605 void glNormalPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 607 #ifdef GL_EXT_vertex_array 
 608   static PFNGLNORMALPOINTEREXTPROC proc 
= 0; 
 612     proc 
= (PFNGLNORMALPOINTEREXTPROC
) wglGetProcAddress("glNormalPointerEXT"); 
 616     (* proc
) (type
, stride
, count
, pointer
); 
 620 void glTexCoordPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 624 void glVertexPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid 
*pointer
) 
 626 #ifdef GL_EXT_vertex_array 
 627   static PFNGLVERTEXPOINTEREXTPROC proc 
= 0; 
 631     proc 
= (PFNGLVERTEXPOINTEREXTPROC
) wglGetProcAddress("glVertexPointerEXT"); 
 634     (* proc
) (size
, type
, stride
, count
, pointer
); 
 638 /* EXT_color_subtable */ 
 639 void glColorSubtableEXT(GLenum target
, GLsizei start
, GLsizei count
, GLenum format
, GLenum type
, const GLvoid 
*table
) 
 643 /* EXT_color_table */ 
 644 void glColorTableEXT(GLenum target
, GLenum internalformat
, GLsizei width
, GLenum format
, GLenum type
, const GLvoid 
*table
) 
 648 void glCopyColorTableEXT(GLenum target
, GLenum internalformat
, GLint x
, GLint y
, GLsizei width
) 
 652 void glGetColorTableEXT(GLenum target
, GLenum format
, GLenum type
, GLvoid 
*table
) 
 656 void glGetColorTableParamaterfvEXT(GLenum target
, GLenum pname
, GLfloat 
*params
) 
 660 void glGetColorTavleParameterivEXT(GLenum target
, GLenum pname
, GLint 
*params
) 
 664 /* SGI_compiled_vertex_array */ 
 665 void glLockArraysSGI(GLint first
, GLsizei count
) 
 669 void glUnlockArraysSGI() 
 674 /* SGI_cull_vertex */ 
 675 void glCullParameterdvSGI(GLenum pname
, GLdouble
* params
) 
 679 void glCullParameterfvSGI(GLenum pname
, GLfloat
* params
) 
 684 void glIndexFuncSGI(GLenum func
, GLclampf ref
) 
 688 /* SGI_index_material */ 
 689 void glIndexMaterialSGI(GLenum face
, GLenum mode
) 
 694 void glAddSwapHintRectWin(GLint x
, GLint y
, GLsizei width
, GLsizei height
) 
 699 //--------------------------------------------------------------------------- 
 701 //--------------------------------------------------------------------------- 
 703 IMPLEMENT_CLASS(wxGLApp
, wxApp
) 
 705 bool wxGLApp::InitGLVisual(int *attribList
) 
 708   PIXELFORMATDESCRIPTOR pfd 
= { 
 709         sizeof(PIXELFORMATDESCRIPTOR
),    /* size */ 
 713         PFD_DOUBLEBUFFER
,        /* support double-buffering */ 
 714         PFD_TYPE_RGBA
,            /* color type */ 
 715         16,                /* prefered color depth */ 
 716         0, 0, 0, 0, 0, 0,        /* color bits (ignored) */ 
 717         0,                /* no alpha buffer */ 
 718         0,                /* alpha bits (ignored) */ 
 719         0,                /* no accumulation buffer */ 
 720         0, 0, 0, 0,            /* accum bits (ignored) */ 
 721         16,                /* depth buffer */ 
 722         0,                /* no stencil buffer */ 
 723         0,                /* no auxiliary buffers */ 
 724         PFD_MAIN_PLANE
,            /* main layer */ 
 726         0, 0, 0,            /* no layer, visible, damage masks */ 
 729   AdjustPFDForAttributes(pfd
, attribList
); 
 731   // use DC for whole (root) screen, since no windows have yet been created 
 732   pixelFormat 
= ChoosePixelFormat(ScreenHDC(), &pfd
); 
 734   if (pixelFormat 
== 0) { 
 735     wxLogError(_("Failed to initialize OpenGL"));