]>
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 wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs
, int *glattrs
, size_t n
)
128 wxCHECK_MSG( n
>= 16, false, _T("GL attributes buffer too small") );
131 Different versions of GLX API use rather different attributes lists, see
134 - <= 1.2: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseVisual.xml
135 - >= 1.3: http://www.opengl.org/sdk/docs/man/xhtml/glXChooseFBConfig.xml
137 Notice in particular that
138 - GLX_RGBA is boolean attribute in the old version of the API but a
139 value of GLX_RENDER_TYPE in the new one
140 - Boolean attributes such as GLX_DOUBLEBUFFER don't take values in the
141 old version but must be followed by True or False in the new one.
148 // use double-buffered true colour by default
149 glattrs
[i
++] = GLX_DOUBLEBUFFER
;
151 if ( GetGLXVersion() < 13 )
153 // default settings if attriblist = 0
154 glattrs
[i
++] = GLX_RGBA
;
155 glattrs
[i
++] = GLX_DEPTH_SIZE
; glattrs
[i
++] = 1;
156 glattrs
[i
++] = GLX_RED_SIZE
; glattrs
[i
++] = 1;
157 glattrs
[i
++] = GLX_GREEN_SIZE
; glattrs
[i
++] = 1;
158 glattrs
[i
++] = GLX_BLUE_SIZE
; glattrs
[i
++] = 1;
159 glattrs
[i
++] = GLX_ALPHA_SIZE
; glattrs
[i
++] = 0;
161 else // recent GLX can choose the defaults on its own just fine
163 // we just need to have a value after GLX_DOUBLEBUFFER
169 wxASSERT_MSG( i
< n
, _T("GL attributes buffer too small") );
171 else // have non-default attributes
174 for ( int arg
= 0; wxattrs
[arg
] != 0; )
176 // check if we have any space left, knowing that we may insert 2
177 // more elements during this loop iteration and we always need to
178 // terminate the list with None (hence -3)
182 // indicates whether we have a boolean attribute
183 bool isBoolAttr
= false;
185 switch ( wxattrs
[arg
++] )
187 case WX_GL_BUFFER_SIZE
:
188 glattrs
[p
++] = GLX_BUFFER_SIZE
;
192 glattrs
[p
++] = GLX_LEVEL
;
196 if ( GetGLXVersion() >= 13 )
198 // this is the default GLX_RENDER_TYPE anyhow
202 glattrs
[p
++] = GLX_RGBA
;
206 case WX_GL_DOUBLEBUFFER
:
207 glattrs
[p
++] = GLX_DOUBLEBUFFER
;
212 glattrs
[p
++] = GLX_STEREO
;
216 case WX_GL_AUX_BUFFERS
:
217 glattrs
[p
++] = GLX_AUX_BUFFERS
;
221 glattrs
[p
++] = GLX_RED_SIZE
;
224 case WX_GL_MIN_GREEN
:
225 glattrs
[p
++] = GLX_GREEN_SIZE
;
229 glattrs
[p
++] = GLX_BLUE_SIZE
;
232 case WX_GL_MIN_ALPHA
:
233 glattrs
[p
++] = GLX_ALPHA_SIZE
;
236 case WX_GL_DEPTH_SIZE
:
237 glattrs
[p
++] = GLX_DEPTH_SIZE
;
240 case WX_GL_STENCIL_SIZE
:
241 glattrs
[p
++] = GLX_STENCIL_SIZE
;
244 case WX_GL_MIN_ACCUM_RED
:
245 glattrs
[p
++] = GLX_ACCUM_RED_SIZE
;
248 case WX_GL_MIN_ACCUM_GREEN
:
249 glattrs
[p
++] = GLX_ACCUM_GREEN_SIZE
;
252 case WX_GL_MIN_ACCUM_BLUE
:
253 glattrs
[p
++] = GLX_ACCUM_BLUE_SIZE
;
256 case WX_GL_MIN_ACCUM_ALPHA
:
257 glattrs
[p
++] = GLX_ACCUM_ALPHA_SIZE
;
261 wxLogDebug(_T("Unsupported OpenGL attribute %d"),
268 // as explained above, for pre 1.3 API the attribute just needs
269 // to be present so we only add its value when using the new API
270 if ( GetGLXVersion() >= 13 )
273 else // attribute with real (non-boolean) value
275 // copy attribute value as is
276 glattrs
[p
++] = wxattrs
[arg
++];
288 wxGLCanvasX11::InitXVisualInfo(const int *attribList
,
290 XVisualInfo
**pXVisual
)
293 if ( !ConvertWXAttrsToGL(attribList
, data
, WXSIZEOF(data
)) )
296 Display
* const dpy
= wxGetX11Display();
298 if ( GetGLXVersion() >= 13 )
301 *pFBC
= glXChooseFBConfig(dpy
, DefaultScreen(dpy
), data
, &returned
);
305 *pXVisual
= glXGetVisualFromFBConfig(wxGetX11Display(), **pFBC
);
316 *pXVisual
= glXChooseVisual(dpy
, DefaultScreen(dpy
), data
);
319 return *pXVisual
!= NULL
;
324 wxGLCanvasBase::IsDisplaySupported(const int *attribList
)
326 GLXFBConfig
*fbc
= NULL
;
327 XVisualInfo
*vi
= NULL
;
330 isSupported
= wxGLCanvasX11::InitXVisualInfo(attribList
, &fbc
, &vi
);
340 // ----------------------------------------------------------------------------
341 // default visual management
342 // ----------------------------------------------------------------------------
344 XVisualInfo
*wxGLCanvasX11::ms_glVisualInfo
= NULL
;
345 GLXFBConfig
*wxGLCanvasX11::ms_glFBCInfo
= NULL
;
348 bool wxGLCanvasX11::InitDefaultVisualInfo(const int *attribList
)
350 FreeDefaultVisualInfo();
352 return InitXVisualInfo(attribList
, &ms_glFBCInfo
, &ms_glVisualInfo
);
356 void wxGLCanvasX11::FreeDefaultVisualInfo()
364 if ( ms_glVisualInfo
)
366 XFree(ms_glVisualInfo
);
367 ms_glVisualInfo
= NULL
;
371 // ----------------------------------------------------------------------------
373 // ----------------------------------------------------------------------------
376 int wxGLCanvasX11::GetGLXVersion()
378 static int s_glxVersion
= 0;
379 if ( s_glxVersion
== 0 )
381 // check the GLX version
382 int glxMajorVer
, glxMinorVer
;
383 bool ok
= glXQueryVersion(wxGetX11Display(), &glxMajorVer
, &glxMinorVer
);
384 wxASSERT_MSG( ok
, _T("GLX version not found") );
386 s_glxVersion
= 10; // 1.0 by default
388 s_glxVersion
= glxMajorVer
*10 + glxMinorVer
;
394 bool wxGLCanvasX11::SwapBuffers()
396 const Window xid
= GetXWindow();
397 wxCHECK2_MSG( xid
, return false, _T("window must be shown") );
399 glXSwapBuffers(wxGetX11Display(), xid
);
403 bool wxGLCanvasX11::IsShownOnScreen() const
405 return GetXWindow() && wxGLCanvasBase::IsShownOnScreen();
408 #endif // wxUSE_GLCANVAS