]>
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 void wxGLContext::SetCurrent(const wxGLCanvas
& win
) const 
  76     const Window xid 
= win
.GetXWindow(); 
  77     wxCHECK_RET( xid
, _T("window must be shown") ); 
  79     MakeCurrent(xid
, m_glContext
); 
  82 // wrapper around glXMakeContextCurrent/glXMakeCurrent depending on GLX 
  85 void wxGLContext::MakeCurrent(GLXDrawable drawable
, GLXContext context
) 
  87     if (wxGLCanvas::GetGLXVersion() >= 13) 
  88         glXMakeContextCurrent( wxGetX11Display(), drawable
, drawable
, context
); 
  89     else // GLX <= 1.2 doesn't have glXMakeContextCurrent() 
  90         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 wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs
, int *glattrs
, size_t n
) 
 128     wxCHECK_MSG( n 
>= 16, false, _T("GL attributes buffer too small") ); 
 132         if ( GetGLXVersion() >= 13 ) 
 134             // leave GLX >= 1.3 choose the default attributes 
 139             // default settings if attriblist = 0 
 141             glattrs
[i
++] = GLX_RGBA
; 
 142             glattrs
[i
++] = GLX_DOUBLEBUFFER
; 
 143             glattrs
[i
++] = GLX_DEPTH_SIZE
;   glattrs
[i
++] = 1; 
 144             glattrs
[i
++] = GLX_RED_SIZE
;     glattrs
[i
++] = 1; 
 145             glattrs
[i
++] = GLX_GREEN_SIZE
;   glattrs
[i
++] = 1; 
 146             glattrs
[i
++] = GLX_BLUE_SIZE
;    glattrs
[i
++] = 1; 
 147             glattrs
[i
++] = GLX_ALPHA_SIZE
;   glattrs
[i
++] = 0; 
 150             wxASSERT_MSG( i 
< n
, _T("GL attributes buffer too small") ); 
 153     else // have non-default attributes 
 156         for ( int arg 
= 0; wxattrs
[arg
] != 0; ) 
 158             // check if we have any space left, knowing that we may insert 2 
 159             // more elements during this loop iteration and we always need to 
 160             // terminate the list with None (hence -3) 
 164             switch ( wxattrs
[arg
++] ) 
 167                     // for GLX >= 1.3, GLX_RGBA is useless and apparently 
 168                     // harmful for some implementations 
 170                     // FIXME: is this true? 
 171                     if ( GetGLXVersion() <= 12 ) 
 173                         glattrs
[p
++] = GLX_RGBA
; 
 176                     // use "continue" to skip the assignment of the attribute 
 177                     // value at the end of the loop 
 180                 case WX_GL_BUFFER_SIZE
: 
 181                     glattrs
[p
++] = GLX_BUFFER_SIZE
; 
 185                     glattrs
[p
++] = GLX_LEVEL
; 
 188                     // the following boolean attributes don't have values in wx 
 189                     // API (they're turned on if specified) but do have them in 
 190                     // OpenGL, so do put them into glattrs and also skip the 
 191                     // copy of wx value after switch by using "continue" 
 192                     // instead of "break" 
 193                 case WX_GL_DOUBLEBUFFER
: 
 194                     glattrs
[p
++] = GLX_DOUBLEBUFFER
; 
 199                     glattrs
[p
++] = GLX_STEREO
; 
 204                 case WX_GL_AUX_BUFFERS
: 
 205                     glattrs
[p
++] = GLX_AUX_BUFFERS
; 
 209                     glattrs
[p
++] = GLX_RED_SIZE
; 
 212                 case WX_GL_MIN_GREEN
: 
 213                     glattrs
[p
++] = GLX_GREEN_SIZE
; 
 217                     glattrs
[p
++] = GLX_BLUE_SIZE
; 
 220                 case WX_GL_MIN_ALPHA
: 
 221                     glattrs
[p
++] = GLX_ALPHA_SIZE
; 
 224                 case WX_GL_DEPTH_SIZE
: 
 225                     glattrs
[p
++] = GLX_DEPTH_SIZE
; 
 228                 case WX_GL_STENCIL_SIZE
: 
 229                     glattrs
[p
++] = GLX_STENCIL_SIZE
; 
 232                 case WX_GL_MIN_ACCUM_RED
: 
 233                     glattrs
[p
++] = GLX_ACCUM_RED_SIZE
; 
 236                 case WX_GL_MIN_ACCUM_GREEN
: 
 237                     glattrs
[p
++] = GLX_ACCUM_GREEN_SIZE
; 
 240                 case WX_GL_MIN_ACCUM_BLUE
: 
 241                     glattrs
[p
++] = GLX_ACCUM_BLUE_SIZE
; 
 244                 case WX_GL_MIN_ACCUM_ALPHA
: 
 245                     glattrs
[p
++] = GLX_ACCUM_ALPHA_SIZE
; 
 249                     wxLogDebug(_T("Unsupported OpenGL attribute %d"), 
 254             // copy attribute value as is 
 255             glattrs
[p
++] = wxattrs
[arg
++]; 
 266 wxGLCanvasX11::InitXVisualInfo(const int *attribList
, 
 268                                XVisualInfo 
**pXVisual
) 
 271     if ( !ConvertWXAttrsToGL(attribList
, data
, WXSIZEOF(data
)) ) 
 274     Display 
* const dpy 
= wxGetX11Display(); 
 276     if ( GetGLXVersion() >= 13 ) 
 279         *pFBC 
= glXChooseFBConfig(dpy
, DefaultScreen(dpy
), data
, &returned
); 
 283             *pXVisual 
= glXGetVisualFromFBConfig(wxGetX11Display(), **pFBC
); 
 294         *pXVisual 
= glXChooseVisual(dpy
, DefaultScreen(dpy
), data
); 
 297     return *pXVisual 
!= NULL
; 
 300 // ---------------------------------------------------------------------------- 
 301 // default visual management 
 302 // ---------------------------------------------------------------------------- 
 304 XVisualInfo 
*wxGLCanvasX11::ms_glVisualInfo 
= NULL
; 
 305 GLXFBConfig 
*wxGLCanvasX11::ms_glFBCInfo 
= NULL
; 
 308 bool wxGLCanvasX11::InitDefaultVisualInfo(const int *attribList
) 
 310     FreeDefaultVisualInfo(); 
 312     return InitXVisualInfo(attribList
, &ms_glFBCInfo
, &ms_glVisualInfo
); 
 316 void wxGLCanvasX11::FreeDefaultVisualInfo() 
 324     if ( ms_glVisualInfo 
) 
 326         XFree(ms_glVisualInfo
); 
 327         ms_glVisualInfo 
= NULL
; 
 331 // ---------------------------------------------------------------------------- 
 333 // ---------------------------------------------------------------------------- 
 336 int wxGLCanvasX11::GetGLXVersion() 
 338     static int s_glxVersion 
= 0; 
 339     if ( s_glxVersion 
== 0 ) 
 341         // check the GLX version 
 342         int glxMajorVer
, glxMinorVer
; 
 343         bool ok 
= glXQueryVersion(wxGetX11Display(), &glxMajorVer
, &glxMinorVer
); 
 344         wxASSERT_MSG( ok
, _T("GLX version not found") ); 
 346             s_glxVersion 
= 10; // 1.0 by default 
 348             s_glxVersion 
= glxMajorVer
*10 + glxMinorVer
; 
 354 void wxGLCanvasX11::SwapBuffers() 
 356     const Window xid 
= GetXWindow(); 
 357     wxCHECK_RET( xid
, _T("window must be shown") ); 
 359     glXSwapBuffers(wxGetX11Display(), xid
); 
 362 bool wxGLCanvasX11::IsShownOnScreen() const 
 364     return GetXWindow() && wxGLCanvasBase::IsShownOnScreen(); 
 367 #endif // wxUSE_GLCANVAS