]>
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"
27 #include "wx/glcanvas.h"
29 // ============================================================================
30 // wxGLContext implementation
31 // ============================================================================
33 IMPLEMENT_CLASS(wxGLContext
, wxObject
)
35 wxGLContext::wxGLContext(wxGLCanvas
*gc
, const wxGLContext
*other
)
37 if ( wxGLCanvas::GetGLXVersion() >= 13 )
39 GLXFBConfig
*fbc
= gc
->GetGLXFBConfig();
40 wxCHECK_RET( fbc
, _T("invalid GLXFBConfig for OpenGL") );
42 m_glContext
= glXCreateNewContext( wxGetX11Display(), fbc
[0], GLX_RGBA_TYPE
,
43 other
? other
->m_glContext
: None
,
48 XVisualInfo
*vi
= gc
->GetXVisualInfo();
49 wxCHECK_RET( vi
, _T("invalid visual for OpenGL") );
51 m_glContext
= glXCreateContext( wxGetX11Display(), vi
,
52 other
? other
->m_glContext
: None
,
56 wxASSERT_MSG( m_glContext
, _T("Couldn't create OpenGL context") );
59 wxGLContext::~wxGLContext()
64 if ( m_glContext
== glXGetCurrentContext() )
65 MakeCurrent(None
, NULL
);
67 glXDestroyContext( wxGetX11Display(), m_glContext
);
70 void wxGLContext::SetCurrent(const wxGLCanvas
& win
) const
75 const Window xid
= win
.GetXWindow();
76 wxCHECK_RET( xid
, _T("window must be shown") );
78 MakeCurrent(xid
, m_glContext
);
81 // wrapper around glXMakeContextCurrent/glXMakeCurrent depending on GLX
84 void wxGLContext::MakeCurrent(GLXDrawable drawable
, GLXContext context
)
86 if (wxGLCanvas::GetGLXVersion() >= 13)
87 glXMakeContextCurrent( wxGetX11Display(), drawable
, drawable
, context
);
88 else // GLX <= 1.2 doesn't have glXMakeContextCurrent()
89 glXMakeCurrent( wxGetX11Display(), drawable
, context
);
92 // ============================================================================
93 // wxGLCanvasX11 implementation
94 // ============================================================================
96 // ----------------------------------------------------------------------------
97 // initialization methods and dtor
98 // ----------------------------------------------------------------------------
100 wxGLCanvasX11::wxGLCanvasX11()
106 bool wxGLCanvasX11::InitVisual(const int *attribList
)
108 return InitXVisualInfo(attribList
, &m_fbc
, &m_vi
);
111 wxGLCanvasX11::~wxGLCanvasX11()
113 if ( m_fbc
&& m_fbc
!= ms_glFBCInfo
)
116 if ( m_vi
&& m_vi
!= ms_glVisualInfo
)
120 // ----------------------------------------------------------------------------
121 // working with GL attributes
122 // ----------------------------------------------------------------------------
125 wxGLCanvasX11::ConvertWXAttrsToGL(const int *wxattrs
, int *glattrs
, size_t n
)
127 wxCHECK_MSG( n
>= 16, false, _T("GL attributes buffer too small") );
131 if ( GetGLXVersion() >= 13 )
133 // leave GLX >= 1.3 choose the default attributes
138 // default settings if attriblist = 0
140 glattrs
[i
++] = GLX_RGBA
;
141 glattrs
[i
++] = GLX_DOUBLEBUFFER
;
142 glattrs
[i
++] = GLX_DEPTH_SIZE
; glattrs
[i
++] = 1;
143 glattrs
[i
++] = GLX_RED_SIZE
; glattrs
[i
++] = 1;
144 glattrs
[i
++] = GLX_GREEN_SIZE
; glattrs
[i
++] = 1;
145 glattrs
[i
++] = GLX_BLUE_SIZE
; glattrs
[i
++] = 1;
146 glattrs
[i
++] = GLX_ALPHA_SIZE
; glattrs
[i
++] = 0;
149 wxASSERT_MSG( i
< n
, _T("GL attributes buffer too small") );
152 else // have non-default attributes
155 for ( int arg
= 0; wxattrs
[arg
] != 0; )
157 // check if we have any space left, knowing that we may insert 2
158 // more elements during this loop iteration and we always need to
159 // terminate the list with None (hence -3)
163 // notice that for boolean attributes we use "continue" in the
164 // switch to skip the assignment of the attribute value at the end
165 // of the loop which is done for integer attributes
166 switch ( wxattrs
[arg
++] )
169 // for GLX >= 1.3, GLX_RGBA is useless and apparently
170 // harmful for some implementations
172 // FIXME: is this true?
173 if ( GetGLXVersion() <= 12 )
175 glattrs
[p
++] = GLX_RGBA
;
179 case WX_GL_BUFFER_SIZE
:
180 glattrs
[p
++] = GLX_BUFFER_SIZE
;
184 glattrs
[p
++] = GLX_LEVEL
;
187 case WX_GL_DOUBLEBUFFER
:
188 glattrs
[p
++] = GLX_DOUBLEBUFFER
;
192 glattrs
[p
++] = GLX_STEREO
;
195 case WX_GL_AUX_BUFFERS
:
196 glattrs
[p
++] = GLX_AUX_BUFFERS
;
200 glattrs
[p
++] = GLX_RED_SIZE
;
203 case WX_GL_MIN_GREEN
:
204 glattrs
[p
++] = GLX_GREEN_SIZE
;
208 glattrs
[p
++] = GLX_BLUE_SIZE
;
211 case WX_GL_MIN_ALPHA
:
212 glattrs
[p
++] = GLX_ALPHA_SIZE
;
215 case WX_GL_DEPTH_SIZE
:
216 glattrs
[p
++] = GLX_DEPTH_SIZE
;
219 case WX_GL_STENCIL_SIZE
:
220 glattrs
[p
++] = GLX_STENCIL_SIZE
;
223 case WX_GL_MIN_ACCUM_RED
:
224 glattrs
[p
++] = GLX_ACCUM_RED_SIZE
;
227 case WX_GL_MIN_ACCUM_GREEN
:
228 glattrs
[p
++] = GLX_ACCUM_GREEN_SIZE
;
231 case WX_GL_MIN_ACCUM_BLUE
:
232 glattrs
[p
++] = GLX_ACCUM_BLUE_SIZE
;
235 case WX_GL_MIN_ACCUM_ALPHA
:
236 glattrs
[p
++] = GLX_ACCUM_ALPHA_SIZE
;
240 wxLogDebug(_T("Unsupported OpenGL attribute %d"),
245 // copy attribute value as is
246 glattrs
[p
++] = wxattrs
[arg
++];
257 wxGLCanvasX11::InitXVisualInfo(const int *attribList
,
259 XVisualInfo
**pXVisual
)
262 if ( !ConvertWXAttrsToGL(attribList
, data
, WXSIZEOF(data
)) )
265 Display
* const dpy
= wxGetX11Display();
267 if ( GetGLXVersion() >= 13 )
270 *pFBC
= glXChooseFBConfig(dpy
, DefaultScreen(dpy
), data
, &returned
);
274 *pXVisual
= glXGetVisualFromFBConfig(wxGetX11Display(), **pFBC
);
285 *pXVisual
= glXChooseVisual(dpy
, DefaultScreen(dpy
), data
);
288 return *pXVisual
!= NULL
;
291 // ----------------------------------------------------------------------------
292 // default visual management
293 // ----------------------------------------------------------------------------
295 XVisualInfo
*wxGLCanvasX11::ms_glVisualInfo
= NULL
;
296 GLXFBConfig
*wxGLCanvasX11::ms_glFBCInfo
= NULL
;
299 bool wxGLCanvasX11::InitDefaultVisualInfo(const int *attribList
)
301 FreeDefaultVisualInfo();
303 return InitXVisualInfo(attribList
, &ms_glFBCInfo
, &ms_glVisualInfo
);
307 void wxGLCanvasX11::FreeDefaultVisualInfo()
315 if ( ms_glVisualInfo
)
317 XFree(ms_glVisualInfo
);
318 ms_glVisualInfo
= NULL
;
322 // ----------------------------------------------------------------------------
324 // ----------------------------------------------------------------------------
327 int wxGLCanvasX11::GetGLXVersion()
329 static int s_glxVersion
= 0;
330 if ( s_glxVersion
== 0 )
332 // check the GLX version
333 int glxMajorVer
, glxMinorVer
;
334 bool ok
= glXQueryVersion(wxGetX11Display(), &glxMajorVer
, &glxMinorVer
);
335 wxASSERT_MSG( ok
, _T("GLX version not found") );
337 s_glxVersion
= 10; // 1.0 by default
339 s_glxVersion
= glxMajorVer
*10 + glxMinorVer
;
345 void wxGLCanvasX11::SwapBuffers()
347 const Window xid
= GetXWindow();
348 wxCHECK_RET( xid
, _T("window must be shown") );
350 glXSwapBuffers(wxGetX11Display(), xid
);
353 bool wxGLCanvasX11::IsShownOnScreen() const
355 return GetXWindow() && wxGLCanvasBase::IsShownOnScreen();
358 #endif // wxUSE_GLCANVAS