]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/glx11.cpp
   1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/univ/glx11.cpp 
   3 // Purpose:     code common to all X11-based wxGLCanvas implementations 
   4 // Author:      Vadim Zeitlin 
   7 // Copyright:   (c) 2007 Vadim Zeitlin <vadim@wxwindows.org> 
   8 // Licence:     wxWindows licence 
   9 /////////////////////////////////////////////////////////////////////////////// 
  11 // ============================================================================ 
  13 // ============================================================================ 
  15 // ---------------------------------------------------------------------------- 
  17 // ---------------------------------------------------------------------------- 
  19 // for compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  28 #include "wx/glcanvas.h" 
  30 // ============================================================================ 
  31 // wxGLContext implementation 
  32 // ============================================================================ 
  34 IMPLEMENT_CLASS(wxGLContext
, wxObject
) 
  36 wxGLContext::wxGLContext(wxGLCanvas 
*gc
, const wxGLContext 
*other
) 
  38     if ( wxGLCanvas::GetGLXVersion() >= 13 ) 
  40         GLXFBConfig 
*fbc 
= gc
->GetGLXFBConfig(); 
  41         wxCHECK_RET( fbc
, _T("invalid GLXFBConfig for OpenGL") ); 
  43         m_glContext 
= glXCreateNewContext( wxGetX11Display(), fbc
[0], GLX_RGBA_TYPE
, 
  44                                            other 
? other
->m_glContext 
: None
, 
  49         XVisualInfo 
*vi 
= gc
->GetXVisualInfo(); 
  50         wxCHECK_RET( vi
, _T("invalid visual for OpenGL") ); 
  52         m_glContext 
= glXCreateContext( wxGetX11Display(), vi
, 
  53                                         other 
? other
->m_glContext 
: None
, 
  57     wxASSERT_MSG( m_glContext
, _T("Couldn't create OpenGL context") ); 
  60 wxGLContext::~wxGLContext() 
  65     if ( m_glContext 
== glXGetCurrentContext() ) 
  66         MakeCurrent(None
, NULL
); 
  68     glXDestroyContext( wxGetX11Display(), m_glContext 
); 
  71 bool wxGLContext::SetCurrent(const wxGLCanvas
& win
) const 
  76     const Window xid 
= win
.GetXWindow(); 
  77     wxCHECK2_MSG( xid
, return false, _T("window must be shown") ); 
  79     return MakeCurrent(xid
, m_glContext
); 
  82 // wrapper around glXMakeContextCurrent/glXMakeCurrent depending on GLX 
  85 bool wxGLContext::MakeCurrent(GLXDrawable drawable
, GLXContext context
) 
  87     if (wxGLCanvas::GetGLXVersion() >= 13) 
  88         return glXMakeContextCurrent( wxGetX11Display(), drawable
, drawable
, context
); 
  89     else // GLX <= 1.2 doesn't have glXMakeContextCurrent() 
  90         return glXMakeCurrent( wxGetX11Display(), drawable
, context
); 
  93 // ============================================================================ 
  94 // wxGLCanvasX11 implementation 
  95 // ============================================================================ 
  97 // ---------------------------------------------------------------------------- 
  98 // initialization methods and dtor 
  99 // ---------------------------------------------------------------------------- 
 101 wxGLCanvasX11::wxGLCanvasX11() 
 107 bool wxGLCanvasX11::InitVisual(const int *attribList
) 
 109     return InitXVisualInfo(attribList
, &m_fbc
, &m_vi
); 
 112 wxGLCanvasX11::~wxGLCanvasX11() 
 114     if ( m_fbc 
&& m_fbc 
!= ms_glFBCInfo 
) 
 117     if ( m_vi 
&& m_vi 
!= ms_glVisualInfo 
) 
 121 // ---------------------------------------------------------------------------- 
 122 // working with GL attributes 
 123 // ---------------------------------------------------------------------------- 
 126 bool wxGLCanvasBase::IsExtensionSupported(const char *extension
) 
 128     Display 
* const dpy 
= wxGetX11Display(); 
 130     return IsExtensionInList(glXQueryExtensionsString(dpy
, DefaultScreen(dpy
)), 
 136 bool wxGLCanvasX11::IsGLXMultiSampleAvailable() 
 138     static int s_isMultiSampleAvailable 
= -1; 
 139     if ( s_isMultiSampleAvailable 
== -1 ) 
 140         s_isMultiSampleAvailable 
= IsExtensionSupported("GLX_ARB_multisample"); 
 142     return s_isMultiSampleAvailable 
!= 0; 
 146 wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs
, int *glattrs
, size_t n
) 
 148     wxCHECK_MSG( n 
>= 16, false, _T("GL attributes buffer too small") ); 
 151        Different versions of GLX API use rather different attributes lists, see 
 154         - <= 1.2: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseVisual.xml 
 155         - >= 1.3: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml 
 157        Notice in particular that 
 158         - GLX_RGBA is boolean attribute in the old version of the API but a 
 159           value of GLX_RENDER_TYPE in the new one 
 160         - Boolean attributes such as GLX_DOUBLEBUFFER don't take values in the 
 161           old version but must be followed by True or False in the new one. 
 168         // use double-buffered true colour by default 
 169         glattrs
[i
++] = GLX_DOUBLEBUFFER
; 
 171         if ( GetGLXVersion() < 13 ) 
 173             // default settings if attriblist = 0 
 174             glattrs
[i
++] = GLX_RGBA
; 
 175             glattrs
[i
++] = GLX_DEPTH_SIZE
;   glattrs
[i
++] = 1; 
 176             glattrs
[i
++] = GLX_RED_SIZE
;     glattrs
[i
++] = 1; 
 177             glattrs
[i
++] = GLX_GREEN_SIZE
;   glattrs
[i
++] = 1; 
 178             glattrs
[i
++] = GLX_BLUE_SIZE
;    glattrs
[i
++] = 1; 
 179             glattrs
[i
++] = GLX_ALPHA_SIZE
;   glattrs
[i
++] = 0; 
 181         else // recent GLX can choose the defaults on its own just fine 
 183             // we just need to have a value after GLX_DOUBLEBUFFER 
 189         wxASSERT_MSG( i 
< n
, _T("GL attributes buffer too small") ); 
 191     else // have non-default attributes 
 194         for ( int arg 
= 0; wxattrs
[arg
] != 0; ) 
 196             // check if we have any space left, knowing that we may insert 2 
 197             // more elements during this loop iteration and we always need to 
 198             // terminate the list with None (hence -3) 
 202             // indicates whether we have a boolean attribute 
 203             bool isBoolAttr 
= false; 
 205             switch ( wxattrs
[arg
++] ) 
 207                 case WX_GL_BUFFER_SIZE
: 
 208                     glattrs
[p
++] = GLX_BUFFER_SIZE
; 
 212                     glattrs
[p
++] = GLX_LEVEL
; 
 216                     if ( GetGLXVersion() >= 13 ) 
 218                         // this is the default GLX_RENDER_TYPE anyhow 
 222                     glattrs
[p
++] = GLX_RGBA
; 
 226                 case WX_GL_DOUBLEBUFFER
: 
 227                     glattrs
[p
++] = GLX_DOUBLEBUFFER
; 
 232                     glattrs
[p
++] = GLX_STEREO
; 
 236                 case WX_GL_AUX_BUFFERS
: 
 237                     glattrs
[p
++] = GLX_AUX_BUFFERS
; 
 241                     glattrs
[p
++] = GLX_RED_SIZE
; 
 244                 case WX_GL_MIN_GREEN
: 
 245                     glattrs
[p
++] = GLX_GREEN_SIZE
; 
 249                     glattrs
[p
++] = GLX_BLUE_SIZE
; 
 252                 case WX_GL_MIN_ALPHA
: 
 253                     glattrs
[p
++] = GLX_ALPHA_SIZE
; 
 256                 case WX_GL_DEPTH_SIZE
: 
 257                     glattrs
[p
++] = GLX_DEPTH_SIZE
; 
 260                 case WX_GL_STENCIL_SIZE
: 
 261                     glattrs
[p
++] = GLX_STENCIL_SIZE
; 
 264                 case WX_GL_MIN_ACCUM_RED
: 
 265                     glattrs
[p
++] = GLX_ACCUM_RED_SIZE
; 
 268                 case WX_GL_MIN_ACCUM_GREEN
: 
 269                     glattrs
[p
++] = GLX_ACCUM_GREEN_SIZE
; 
 272                 case WX_GL_MIN_ACCUM_BLUE
: 
 273                     glattrs
[p
++] = GLX_ACCUM_BLUE_SIZE
; 
 276                 case WX_GL_MIN_ACCUM_ALPHA
: 
 277                     glattrs
[p
++] = GLX_ACCUM_ALPHA_SIZE
; 
 280                 case WX_GL_SAMPLE_BUFFERS
: 
 281                     if ( !IsGLXMultiSampleAvailable() ) 
 283                         // if it was specified just to disable it, no problem 
 284                         if ( !wxattrs
[arg
++] ) 
 287                         // otherwise indicate that it's not supported 
 291                     glattrs
[p
++] = GLX_SAMPLE_BUFFERS_ARB
; 
 295                     if ( !IsGLXMultiSampleAvailable() ) 
 297                         if ( !wxattrs
[arg
++] ) 
 303                     glattrs
[p
++] = GLX_SAMPLES_ARB
; 
 307                     wxLogDebug(_T("Unsupported OpenGL attribute %d"), 
 314                 // as explained above, for pre 1.3 API the attribute just needs 
 315                 // to be present so we only add its value when using the new API 
 316                 if ( GetGLXVersion() >= 13 ) 
 319             else // attribute with real (non-boolean) value 
 321                 // copy attribute value as is 
 322                 glattrs
[p
++] = wxattrs
[arg
++]; 
 334 wxGLCanvasX11::InitXVisualInfo(const int *attribList
, 
 336                                XVisualInfo 
**pXVisual
) 
 339     if ( !ConvertWXAttrsToGL(attribList
, data
, WXSIZEOF(data
)) ) 
 342     Display 
* const dpy 
= wxGetX11Display(); 
 344     if ( GetGLXVersion() >= 13 ) 
 347         *pFBC 
= glXChooseFBConfig(dpy
, DefaultScreen(dpy
), data
, &returned
); 
 351             *pXVisual 
= glXGetVisualFromFBConfig(wxGetX11Display(), **pFBC
); 
 362         *pXVisual 
= glXChooseVisual(dpy
, DefaultScreen(dpy
), data
); 
 365     return *pXVisual 
!= NULL
; 
 370 wxGLCanvasBase::IsDisplaySupported(const int *attribList
) 
 372     GLXFBConfig 
*fbc 
= NULL
; 
 373     XVisualInfo 
*vi 
= NULL
; 
 376         isSupported 
= wxGLCanvasX11::InitXVisualInfo(attribList
, &fbc
, &vi
); 
 386 // ---------------------------------------------------------------------------- 
 387 // default visual management 
 388 // ---------------------------------------------------------------------------- 
 390 XVisualInfo 
*wxGLCanvasX11::ms_glVisualInfo 
= NULL
; 
 391 GLXFBConfig 
*wxGLCanvasX11::ms_glFBCInfo 
= NULL
; 
 394 bool wxGLCanvasX11::InitDefaultVisualInfo(const int *attribList
) 
 396     FreeDefaultVisualInfo(); 
 398     return InitXVisualInfo(attribList
, &ms_glFBCInfo
, &ms_glVisualInfo
); 
 402 void wxGLCanvasX11::FreeDefaultVisualInfo() 
 410     if ( ms_glVisualInfo 
) 
 412         XFree(ms_glVisualInfo
); 
 413         ms_glVisualInfo 
= NULL
; 
 417 // ---------------------------------------------------------------------------- 
 419 // ---------------------------------------------------------------------------- 
 422 int wxGLCanvasX11::GetGLXVersion() 
 424     static int s_glxVersion 
= 0; 
 425     if ( s_glxVersion 
== 0 ) 
 427         // check the GLX version 
 428         int glxMajorVer
, glxMinorVer
; 
 429         bool ok 
= glXQueryVersion(wxGetX11Display(), &glxMajorVer
, &glxMinorVer
); 
 430         wxASSERT_MSG( ok
, _T("GLX version not found") ); 
 432             s_glxVersion 
= 10; // 1.0 by default 
 434             s_glxVersion 
= glxMajorVer
*10 + glxMinorVer
; 
 440 bool wxGLCanvasX11::SwapBuffers() 
 442     const Window xid 
= GetXWindow(); 
 443     wxCHECK2_MSG( xid
, return false, _T("window must be shown") ); 
 445     glXSwapBuffers(wxGetX11Display(), xid
); 
 449 bool wxGLCanvasX11::IsShownOnScreen() const 
 451     return GetXWindow() && wxGLCanvasBase::IsShownOnScreen(); 
 454 #endif // wxUSE_GLCANVAS