]>
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
6 // Copyright: (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
18 // for compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
27 #include "wx/glcanvas.h"
29 // IRIX headers call this differently
31 #ifndef GLX_SAMPLE_BUFFERS_ARB
32 #define GLX_SAMPLE_BUFFERS_ARB GLX_SAMPLE_BUFFERS_SGIS
34 #ifndef GLX_SAMPLES_ARB
35 #define GLX_SAMPLES_ARB GLX_SAMPLES_SGIS
39 // ============================================================================
40 // wxGLContext implementation
41 // ============================================================================
43 IMPLEMENT_CLASS(wxGLContext
, wxObject
)
45 wxGLContext::wxGLContext(wxGLCanvas
*gc
, const wxGLContext
*other
)
47 if ( wxGLCanvas::GetGLXVersion() >= 13 )
49 GLXFBConfig
*fbc
= gc
->GetGLXFBConfig();
50 wxCHECK_RET( fbc
, wxT("invalid GLXFBConfig for OpenGL") );
52 m_glContext
= glXCreateNewContext( wxGetX11Display(), fbc
[0], GLX_RGBA_TYPE
,
53 other
? other
->m_glContext
: None
,
58 XVisualInfo
*vi
= gc
->GetXVisualInfo();
59 wxCHECK_RET( vi
, wxT("invalid visual for OpenGL") );
61 m_glContext
= glXCreateContext( wxGetX11Display(), vi
,
62 other
? other
->m_glContext
: None
,
66 wxASSERT_MSG( m_glContext
, wxT("Couldn't create OpenGL context") );
69 wxGLContext::~wxGLContext()
74 if ( m_glContext
== glXGetCurrentContext() )
75 MakeCurrent(None
, NULL
);
77 glXDestroyContext( wxGetX11Display(), m_glContext
);
80 bool wxGLContext::SetCurrent(const wxGLCanvas
& win
) const
85 const Window xid
= win
.GetXWindow();
86 wxCHECK2_MSG( xid
, return false, wxT("window must be shown") );
88 return MakeCurrent(xid
, m_glContext
);
91 // wrapper around glXMakeContextCurrent/glXMakeCurrent depending on GLX
94 bool wxGLContext::MakeCurrent(GLXDrawable drawable
, GLXContext context
)
96 if (wxGLCanvas::GetGLXVersion() >= 13)
97 return glXMakeContextCurrent( wxGetX11Display(), drawable
, drawable
, context
);
98 else // GLX <= 1.2 doesn't have glXMakeContextCurrent()
99 return glXMakeCurrent( wxGetX11Display(), drawable
, context
);
102 // ============================================================================
103 // wxGLCanvasX11 implementation
104 // ============================================================================
106 // ----------------------------------------------------------------------------
107 // initialization methods and dtor
108 // ----------------------------------------------------------------------------
110 wxGLCanvasX11::wxGLCanvasX11()
116 bool wxGLCanvasX11::InitVisual(const int *attribList
)
118 return InitXVisualInfo(attribList
, &m_fbc
, &m_vi
);
121 wxGLCanvasX11::~wxGLCanvasX11()
123 if ( m_fbc
&& m_fbc
!= ms_glFBCInfo
)
126 if ( m_vi
&& m_vi
!= ms_glVisualInfo
)
130 // ----------------------------------------------------------------------------
131 // working with GL attributes
132 // ----------------------------------------------------------------------------
135 bool wxGLCanvasBase::IsExtensionSupported(const char *extension
)
137 Display
* const dpy
= wxGetX11Display();
139 return IsExtensionInList(glXQueryExtensionsString(dpy
, DefaultScreen(dpy
)),
145 bool wxGLCanvasX11::IsGLXMultiSampleAvailable()
147 static int s_isMultiSampleAvailable
= -1;
148 if ( s_isMultiSampleAvailable
== -1 )
149 s_isMultiSampleAvailable
= IsExtensionSupported("GLX_ARB_multisample");
151 return s_isMultiSampleAvailable
!= 0;
155 wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs
, int *glattrs
, size_t n
)
157 wxCHECK_MSG( n
>= 16, false, wxT("GL attributes buffer too small") );
160 Different versions of GLX API use rather different attributes lists, see
163 - <= 1.2: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseVisual.xml
164 - >= 1.3: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml
166 Notice in particular that
167 - GLX_RGBA is boolean attribute in the old version of the API but a
168 value of GLX_RENDER_TYPE in the new one
169 - Boolean attributes such as GLX_DOUBLEBUFFER don't take values in the
170 old version but must be followed by True or False in the new one.
177 // use double-buffered true colour by default
178 glattrs
[i
++] = GLX_DOUBLEBUFFER
;
180 if ( GetGLXVersion() < 13 )
182 // default settings if attriblist = 0
183 glattrs
[i
++] = GLX_RGBA
;
184 glattrs
[i
++] = GLX_DEPTH_SIZE
; glattrs
[i
++] = 1;
185 glattrs
[i
++] = GLX_RED_SIZE
; glattrs
[i
++] = 1;
186 glattrs
[i
++] = GLX_GREEN_SIZE
; glattrs
[i
++] = 1;
187 glattrs
[i
++] = GLX_BLUE_SIZE
; glattrs
[i
++] = 1;
188 glattrs
[i
++] = GLX_ALPHA_SIZE
; glattrs
[i
++] = 0;
190 else // recent GLX can choose the defaults on its own just fine
192 // we just need to have a value after GLX_DOUBLEBUFFER
198 wxASSERT_MSG( i
< n
, wxT("GL attributes buffer too small") );
200 else // have non-default attributes
203 for ( int arg
= 0; wxattrs
[arg
] != 0; )
205 // check if we have any space left, knowing that we may insert 2
206 // more elements during this loop iteration and we always need to
207 // terminate the list with None (hence -3)
211 // indicates whether we have a boolean attribute
212 bool isBoolAttr
= false;
214 switch ( wxattrs
[arg
++] )
216 case WX_GL_BUFFER_SIZE
:
217 glattrs
[p
++] = GLX_BUFFER_SIZE
;
221 glattrs
[p
++] = GLX_LEVEL
;
225 if ( GetGLXVersion() >= 13 )
227 // this is the default GLX_RENDER_TYPE anyhow
231 glattrs
[p
++] = GLX_RGBA
;
235 case WX_GL_DOUBLEBUFFER
:
236 glattrs
[p
++] = GLX_DOUBLEBUFFER
;
241 glattrs
[p
++] = GLX_STEREO
;
245 case WX_GL_AUX_BUFFERS
:
246 glattrs
[p
++] = GLX_AUX_BUFFERS
;
250 glattrs
[p
++] = GLX_RED_SIZE
;
253 case WX_GL_MIN_GREEN
:
254 glattrs
[p
++] = GLX_GREEN_SIZE
;
258 glattrs
[p
++] = GLX_BLUE_SIZE
;
261 case WX_GL_MIN_ALPHA
:
262 glattrs
[p
++] = GLX_ALPHA_SIZE
;
265 case WX_GL_DEPTH_SIZE
:
266 glattrs
[p
++] = GLX_DEPTH_SIZE
;
269 case WX_GL_STENCIL_SIZE
:
270 glattrs
[p
++] = GLX_STENCIL_SIZE
;
273 case WX_GL_MIN_ACCUM_RED
:
274 glattrs
[p
++] = GLX_ACCUM_RED_SIZE
;
277 case WX_GL_MIN_ACCUM_GREEN
:
278 glattrs
[p
++] = GLX_ACCUM_GREEN_SIZE
;
281 case WX_GL_MIN_ACCUM_BLUE
:
282 glattrs
[p
++] = GLX_ACCUM_BLUE_SIZE
;
285 case WX_GL_MIN_ACCUM_ALPHA
:
286 glattrs
[p
++] = GLX_ACCUM_ALPHA_SIZE
;
289 case WX_GL_SAMPLE_BUFFERS
:
290 #ifdef GLX_SAMPLE_BUFFERS_ARB
291 if ( IsGLXMultiSampleAvailable() )
293 glattrs
[p
++] = GLX_SAMPLE_BUFFERS_ARB
;
296 #endif // GLX_SAMPLE_BUFFERS_ARB
297 // if it was specified just to disable it, no problem
298 if ( !wxattrs
[arg
++] )
301 // otherwise indicate that it's not supported
305 #ifdef GLX_SAMPLES_ARB
306 if ( IsGLXMultiSampleAvailable() )
308 glattrs
[p
++] = GLX_SAMPLES_ARB
;
311 #endif // GLX_SAMPLES_ARB
313 if ( !wxattrs
[arg
++] )
319 wxLogDebug(wxT("Unsupported OpenGL attribute %d"),
326 // as explained above, for pre 1.3 API the attribute just needs
327 // to be present so we only add its value when using the new API
328 if ( GetGLXVersion() >= 13 )
331 else // attribute with real (non-boolean) value
333 // copy attribute value as is
334 glattrs
[p
++] = wxattrs
[arg
++];
346 wxGLCanvasX11::InitXVisualInfo(const int *attribList
,
348 XVisualInfo
**pXVisual
)
351 if ( !ConvertWXAttrsToGL(attribList
, data
, WXSIZEOF(data
)) )
354 Display
* const dpy
= wxGetX11Display();
356 if ( GetGLXVersion() >= 13 )
359 *pFBC
= glXChooseFBConfig(dpy
, DefaultScreen(dpy
), data
, &returned
);
363 *pXVisual
= glXGetVisualFromFBConfig(wxGetX11Display(), **pFBC
);
374 *pXVisual
= glXChooseVisual(dpy
, DefaultScreen(dpy
), data
);
377 return *pXVisual
!= NULL
;
382 wxGLCanvasBase::IsDisplaySupported(const int *attribList
)
384 GLXFBConfig
*fbc
= NULL
;
385 XVisualInfo
*vi
= NULL
;
388 isSupported
= wxGLCanvasX11::InitXVisualInfo(attribList
, &fbc
, &vi
);
398 // ----------------------------------------------------------------------------
399 // default visual management
400 // ----------------------------------------------------------------------------
402 XVisualInfo
*wxGLCanvasX11::ms_glVisualInfo
= NULL
;
403 GLXFBConfig
*wxGLCanvasX11::ms_glFBCInfo
= NULL
;
406 bool wxGLCanvasX11::InitDefaultVisualInfo(const int *attribList
)
408 FreeDefaultVisualInfo();
410 return InitXVisualInfo(attribList
, &ms_glFBCInfo
, &ms_glVisualInfo
);
414 void wxGLCanvasX11::FreeDefaultVisualInfo()
422 if ( ms_glVisualInfo
)
424 XFree(ms_glVisualInfo
);
425 ms_glVisualInfo
= NULL
;
429 // ----------------------------------------------------------------------------
431 // ----------------------------------------------------------------------------
434 int wxGLCanvasX11::GetGLXVersion()
436 static int s_glxVersion
= 0;
437 if ( s_glxVersion
== 0 )
439 // check the GLX version
440 int glxMajorVer
, glxMinorVer
;
441 bool ok
= glXQueryVersion(wxGetX11Display(), &glxMajorVer
, &glxMinorVer
);
442 wxASSERT_MSG( ok
, wxT("GLX version not found") );
444 s_glxVersion
= 10; // 1.0 by default
446 s_glxVersion
= glxMajorVer
*10 + glxMinorVer
;
452 bool wxGLCanvasX11::SwapBuffers()
454 const Window xid
= GetXWindow();
455 wxCHECK2_MSG( xid
, return false, wxT("window must be shown") );
457 glXSwapBuffers(wxGetX11Display(), xid
);
461 bool wxGLCanvasX11::IsShownOnScreen() const
463 return GetXWindow() && wxGLCanvasBase::IsShownOnScreen();
466 #endif // wxUSE_GLCANVAS