]>
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