]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/glx11.cpp
   1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/unix/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 // IRIX headers call this differently 
  32     #ifndef GLX_SAMPLE_BUFFERS_ARB 
  33         #define GLX_SAMPLE_BUFFERS_ARB GLX_SAMPLE_BUFFERS_SGIS 
  35     #ifndef GLX_SAMPLES_ARB 
  36         #define GLX_SAMPLES_ARB GLX_SAMPLES_SGIS 
  40 // ============================================================================ 
  41 // wxGLContext implementation 
  42 // ============================================================================ 
  44 IMPLEMENT_CLASS(wxGLContext
, wxObject
) 
  46 wxGLContext::wxGLContext(wxGLCanvas 
*gc
, const wxGLContext 
*other
) 
  48     if ( wxGLCanvas::GetGLXVersion() >= 13 ) 
  50         GLXFBConfig 
*fbc 
= gc
->GetGLXFBConfig(); 
  51         wxCHECK_RET( fbc
, wxT("invalid GLXFBConfig for OpenGL") ); 
  53         m_glContext 
= glXCreateNewContext( wxGetX11Display(), fbc
[0], GLX_RGBA_TYPE
, 
  54                                            other 
? other
->m_glContext 
: None
, 
  59         XVisualInfo 
*vi 
= gc
->GetXVisualInfo(); 
  60         wxCHECK_RET( vi
, wxT("invalid visual for OpenGL") ); 
  62         m_glContext 
= glXCreateContext( wxGetX11Display(), vi
, 
  63                                         other 
? other
->m_glContext 
: None
, 
  67     wxASSERT_MSG( m_glContext
, wxT("Couldn't create OpenGL context") ); 
  70 wxGLContext::~wxGLContext() 
  75     if ( m_glContext 
== glXGetCurrentContext() ) 
  76         MakeCurrent(None
, NULL
); 
  78     glXDestroyContext( wxGetX11Display(), m_glContext 
); 
  81 bool wxGLContext::SetCurrent(const wxGLCanvas
& win
) const 
  86     const Window xid 
= win
.GetXWindow(); 
  87     wxCHECK2_MSG( xid
, return false, wxT("window must be shown") ); 
  89     return MakeCurrent(xid
, m_glContext
); 
  92 // wrapper around glXMakeContextCurrent/glXMakeCurrent depending on GLX 
  95 bool wxGLContext::MakeCurrent(GLXDrawable drawable
, GLXContext context
) 
  97     if (wxGLCanvas::GetGLXVersion() >= 13) 
  98         return glXMakeContextCurrent( wxGetX11Display(), drawable
, drawable
, context
); 
  99     else // GLX <= 1.2 doesn't have glXMakeContextCurrent() 
 100         return glXMakeCurrent( wxGetX11Display(), drawable
, context
); 
 103 // ============================================================================ 
 104 // wxGLCanvasX11 implementation 
 105 // ============================================================================ 
 107 // ---------------------------------------------------------------------------- 
 108 // initialization methods and dtor 
 109 // ---------------------------------------------------------------------------- 
 111 wxGLCanvasX11::wxGLCanvasX11() 
 117 bool wxGLCanvasX11::InitVisual(const int *attribList
) 
 119     return InitXVisualInfo(attribList
, &m_fbc
, &m_vi
); 
 122 wxGLCanvasX11::~wxGLCanvasX11() 
 124     if ( m_fbc 
&& m_fbc 
!= ms_glFBCInfo 
) 
 127     if ( m_vi 
&& m_vi 
!= ms_glVisualInfo 
) 
 131 // ---------------------------------------------------------------------------- 
 132 // working with GL attributes 
 133 // ---------------------------------------------------------------------------- 
 136 bool wxGLCanvasBase::IsExtensionSupported(const char *extension
) 
 138     Display 
* const dpy 
= wxGetX11Display(); 
 140     return IsExtensionInList(glXQueryExtensionsString(dpy
, DefaultScreen(dpy
)), 
 146 bool wxGLCanvasX11::IsGLXMultiSampleAvailable() 
 148     static int s_isMultiSampleAvailable 
= -1; 
 149     if ( s_isMultiSampleAvailable 
== -1 ) 
 150         s_isMultiSampleAvailable 
= IsExtensionSupported("GLX_ARB_multisample"); 
 152     return s_isMultiSampleAvailable 
!= 0; 
 156 wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs
, int *glattrs
, size_t n
) 
 158     wxCHECK_MSG( n 
>= 16, false, wxT("GL attributes buffer too small") ); 
 161        Different versions of GLX API use rather different attributes lists, see 
 164         - <= 1.2: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseVisual.xml 
 165         - >= 1.3: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml 
 167        Notice in particular that 
 168         - GLX_RGBA is boolean attribute in the old version of the API but a 
 169           value of GLX_RENDER_TYPE in the new one 
 170         - Boolean attributes such as GLX_DOUBLEBUFFER don't take values in the 
 171           old version but must be followed by True or False in the new one. 
 178         // use double-buffered true colour by default 
 179         glattrs
[i
++] = GLX_DOUBLEBUFFER
; 
 181         if ( GetGLXVersion() < 13 ) 
 183             // default settings if attriblist = 0 
 184             glattrs
[i
++] = GLX_RGBA
; 
 185             glattrs
[i
++] = GLX_DEPTH_SIZE
;   glattrs
[i
++] = 1; 
 186             glattrs
[i
++] = GLX_RED_SIZE
;     glattrs
[i
++] = 1; 
 187             glattrs
[i
++] = GLX_GREEN_SIZE
;   glattrs
[i
++] = 1; 
 188             glattrs
[i
++] = GLX_BLUE_SIZE
;    glattrs
[i
++] = 1; 
 189             glattrs
[i
++] = GLX_ALPHA_SIZE
;   glattrs
[i
++] = 0; 
 191         else // recent GLX can choose the defaults on its own just fine 
 193             // we just need to have a value after GLX_DOUBLEBUFFER 
 199         wxASSERT_MSG( i 
< n
, wxT("GL attributes buffer too small") ); 
 201     else // have non-default attributes 
 204         for ( int arg 
= 0; wxattrs
[arg
] != 0; ) 
 206             // check if we have any space left, knowing that we may insert 2 
 207             // more elements during this loop iteration and we always need to 
 208             // terminate the list with None (hence -3) 
 212             // indicates whether we have a boolean attribute 
 213             bool isBoolAttr 
= false; 
 215             switch ( wxattrs
[arg
++] ) 
 217                 case WX_GL_BUFFER_SIZE
: 
 218                     glattrs
[p
++] = GLX_BUFFER_SIZE
; 
 222                     glattrs
[p
++] = GLX_LEVEL
; 
 226                     if ( GetGLXVersion() >= 13 ) 
 228                         // this is the default GLX_RENDER_TYPE anyhow 
 232                     glattrs
[p
++] = GLX_RGBA
; 
 236                 case WX_GL_DOUBLEBUFFER
: 
 237                     glattrs
[p
++] = GLX_DOUBLEBUFFER
; 
 242                     glattrs
[p
++] = GLX_STEREO
; 
 246                 case WX_GL_AUX_BUFFERS
: 
 247                     glattrs
[p
++] = GLX_AUX_BUFFERS
; 
 251                     glattrs
[p
++] = GLX_RED_SIZE
; 
 254                 case WX_GL_MIN_GREEN
: 
 255                     glattrs
[p
++] = GLX_GREEN_SIZE
; 
 259                     glattrs
[p
++] = GLX_BLUE_SIZE
; 
 262                 case WX_GL_MIN_ALPHA
: 
 263                     glattrs
[p
++] = GLX_ALPHA_SIZE
; 
 266                 case WX_GL_DEPTH_SIZE
: 
 267                     glattrs
[p
++] = GLX_DEPTH_SIZE
; 
 270                 case WX_GL_STENCIL_SIZE
: 
 271                     glattrs
[p
++] = GLX_STENCIL_SIZE
; 
 274                 case WX_GL_MIN_ACCUM_RED
: 
 275                     glattrs
[p
++] = GLX_ACCUM_RED_SIZE
; 
 278                 case WX_GL_MIN_ACCUM_GREEN
: 
 279                     glattrs
[p
++] = GLX_ACCUM_GREEN_SIZE
; 
 282                 case WX_GL_MIN_ACCUM_BLUE
: 
 283                     glattrs
[p
++] = GLX_ACCUM_BLUE_SIZE
; 
 286                 case WX_GL_MIN_ACCUM_ALPHA
: 
 287                     glattrs
[p
++] = GLX_ACCUM_ALPHA_SIZE
; 
 290                 case WX_GL_SAMPLE_BUFFERS
: 
 291 #ifdef GLX_SAMPLE_BUFFERS_ARB 
 292                     if ( IsGLXMultiSampleAvailable() ) 
 294                         glattrs
[p
++] = GLX_SAMPLE_BUFFERS_ARB
; 
 297 #endif // GLX_SAMPLE_BUFFERS_ARB 
 298                     // if it was specified just to disable it, no problem 
 299                     if ( !wxattrs
[arg
++] ) 
 302                     // otherwise indicate that it's not supported 
 306 #ifdef GLX_SAMPLES_ARB 
 307                     if ( IsGLXMultiSampleAvailable() ) 
 309                         glattrs
[p
++] = GLX_SAMPLES_ARB
; 
 312 #endif // GLX_SAMPLES_ARB 
 314                     if ( !wxattrs
[arg
++] ) 
 320                     wxLogDebug(wxT("Unsupported OpenGL attribute %d"), 
 327                 // as explained above, for pre 1.3 API the attribute just needs 
 328                 // to be present so we only add its value when using the new API 
 329                 if ( GetGLXVersion() >= 13 ) 
 332             else // attribute with real (non-boolean) value 
 334                 // copy attribute value as is 
 335                 glattrs
[p
++] = wxattrs
[arg
++]; 
 347 wxGLCanvasX11::InitXVisualInfo(const int *attribList
, 
 349                                XVisualInfo 
**pXVisual
) 
 352     if ( !ConvertWXAttrsToGL(attribList
, data
, WXSIZEOF(data
)) ) 
 355     Display 
* const dpy 
= wxGetX11Display(); 
 357     if ( GetGLXVersion() >= 13 ) 
 360         *pFBC 
= glXChooseFBConfig(dpy
, DefaultScreen(dpy
), data
, &returned
); 
 364             *pXVisual 
= glXGetVisualFromFBConfig(wxGetX11Display(), **pFBC
); 
 375         *pXVisual 
= glXChooseVisual(dpy
, DefaultScreen(dpy
), data
); 
 378     return *pXVisual 
!= NULL
; 
 383 wxGLCanvasBase::IsDisplaySupported(const int *attribList
) 
 385     GLXFBConfig 
*fbc 
= NULL
; 
 386     XVisualInfo 
*vi 
= NULL
; 
 389         isSupported 
= wxGLCanvasX11::InitXVisualInfo(attribList
, &fbc
, &vi
); 
 399 // ---------------------------------------------------------------------------- 
 400 // default visual management 
 401 // ---------------------------------------------------------------------------- 
 403 XVisualInfo 
*wxGLCanvasX11::ms_glVisualInfo 
= NULL
; 
 404 GLXFBConfig 
*wxGLCanvasX11::ms_glFBCInfo 
= NULL
; 
 407 bool wxGLCanvasX11::InitDefaultVisualInfo(const int *attribList
) 
 409     FreeDefaultVisualInfo(); 
 411     return InitXVisualInfo(attribList
, &ms_glFBCInfo
, &ms_glVisualInfo
); 
 415 void wxGLCanvasX11::FreeDefaultVisualInfo() 
 423     if ( ms_glVisualInfo 
) 
 425         XFree(ms_glVisualInfo
); 
 426         ms_glVisualInfo 
= NULL
; 
 430 // ---------------------------------------------------------------------------- 
 432 // ---------------------------------------------------------------------------- 
 435 int wxGLCanvasX11::GetGLXVersion() 
 437     static int s_glxVersion 
= 0; 
 438     if ( s_glxVersion 
== 0 ) 
 440         // check the GLX version 
 441         int glxMajorVer
, glxMinorVer
; 
 442         bool ok 
= glXQueryVersion(wxGetX11Display(), &glxMajorVer
, &glxMinorVer
); 
 443         wxASSERT_MSG( ok
, wxT("GLX version not found") ); 
 445             s_glxVersion 
= 10; // 1.0 by default 
 447             s_glxVersion 
= glxMajorVer
*10 + glxMinorVer
; 
 453 bool wxGLCanvasX11::SwapBuffers() 
 455     const Window xid 
= GetXWindow(); 
 456     wxCHECK2_MSG( xid
, return false, wxT("window must be shown") ); 
 458     glXSwapBuffers(wxGetX11Display(), xid
); 
 462 bool wxGLCanvasX11::IsShownOnScreen() const 
 464     return GetXWindow() && wxGLCanvasBase::IsShownOnScreen(); 
 467 #endif // wxUSE_GLCANVAS