]> git.saurik.com Git - wxWidgets.git/blob - src/x11/glcanvas.cpp
Big wxGL classes refactoring/cleanup:
[wxWidgets.git] / src / x11 / glcanvas.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/x11/glcanvas.cpp
3 // Purpose: wxGLCanvas, for using OpenGL with wxWidgets
4 // Uses the GLX extension.
5 // Author: Julian Smart and Wolfram Gloger
6 // Modified by: Vadim Zeitlin to update to new API
7 // Created: 1995, 1999
8 // RCS-ID: $Id$
9 // Copyright: (c) Julian Smart, Wolfram Gloger
10 // Licence: wxWindows licence
11 ///////////////////////////////////////////////////////////////////////////////
12
13 // TODO: merge this with wxGTK version in some src/unix/glcanvasx11.cpp
14
15 // ============================================================================
16 // declarations
17 // ============================================================================
18
19 // ----------------------------------------------------------------------------
20 // headers
21 // ----------------------------------------------------------------------------
22
23 // for compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
25
26 #if defined(__BORLANDC__)
27 #pragma hdrstop
28 #endif
29
30 #if wxUSE_GLCANVAS
31
32 #include "wx/glcanvas.h"
33
34 #ifndef WX_PRECOMP
35 #include "wx/log.h"
36 #include "wx/app.h"
37 #include "wx/utils.h"
38 #endif
39
40 #ifdef __VMS
41 # pragma message disable nosimpint
42 #endif
43 #include <X11/Xlib.h>
44 #ifdef __VMS
45 # pragma message enable nosimpint
46 #endif
47 #include "wx/x11/private.h"
48
49 // ----------------------------------------------------------------------------
50 // local functions
51 // ----------------------------------------------------------------------------
52
53 static inline Window wxGetClientAreaWindow(const wxWindow* win)
54 {
55 return (Window)win->
56 #ifdef __WXMOTIF__
57 GetClientXWindow();
58 #else
59 GetClientAreaWindow();
60 #endif
61 }
62
63 // ============================================================================
64 // implementation
65 // ============================================================================
66
67 // ----------------------------------------------------------------------------
68 // wxGLContext
69 // ----------------------------------------------------------------------------
70
71 IMPLEMENT_CLASS(wxGLContext, wxObject)
72
73 wxGLContext::wxGLContext(wxGLCanvas *win, const wxGLContext *other)
74 {
75 XVisualInfo *vi = (XVisualInfo *) win->m_vi;
76 wxASSERT_MSG( vi, wxT("invalid visual in wxGLCanvas") );
77
78 m_glContext = glXCreateContext( (Display *)wxGetDisplay(),
79 vi,
80 other ? other->m_glContext : None,
81 GL_TRUE);
82
83 wxASSERT_MSG( m_glContext, wxT("Couldn't create OpenGL context") );
84 }
85
86 wxGLContext::~wxGLContext()
87 {
88 if (!m_glContext)
89 return;
90
91 if (m_glContext == glXGetCurrentContext())
92 {
93 glXMakeCurrent( (Display*) wxGetDisplay(), None, NULL);
94 }
95
96 glXDestroyContext( (Display*) wxGetDisplay(), m_glContext );
97 }
98
99 void wxGLContext::SetCurrent(const wxGLCanvas& win) const
100 {
101 if (m_glContext)
102 {
103 Display* display = (Display*) wxGetDisplay();
104 glXMakeCurrent(display, wxGetClientAreaWindow(&win), m_glContext);
105 }
106 }
107
108 // ----------------------------------------------------------------------------
109 // wxGLCanvas
110 // ----------------------------------------------------------------------------
111
112 IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
113
114 wxGLCanvas::wxGLCanvas(wxWindow *parent,
115 wxWindowID id,
116 const int *attribList,
117 const wxPoint& pos,
118 const wxSize& size,
119 long style,
120 const wxString& name,
121 const wxPalette& palette)
122 {
123 Create(parent, id, pos, size, style, name, attribList, palette);
124 }
125
126 bool wxGLCanvas::Create(wxWindow *parent,
127 wxWindowID id,
128 const wxPoint& pos,
129 const wxSize& size,
130 long style,
131 const wxString& name,
132 const int *attribList,
133 const wxPalette& palette)
134 {
135 m_vi = NULL;
136
137 if ( !wxWindow::Create(parent, id, pos, size, style, name) )
138 return false;
139
140 XVisualInfo *vi, vi_templ;
141 XWindowAttributes xwa;
142 int val, n;
143
144 Display* display = (Display*) wxGetDisplay();
145
146 // Check for the presence of the GLX extension
147 if(!glXQueryExtension(display, NULL, NULL))
148 {
149 wxLogDebug(wxT("wxGLCanvas: GLX extension is missing"));
150 return false;
151 }
152
153 if(attribList) {
154 int data[512], arg=0, p=0;
155
156 while( (attribList[arg]!=0) && (p<512) )
157 {
158 switch( attribList[arg++] )
159 {
160 case WX_GL_RGBA: data[p++] = GLX_RGBA; break;
161 case WX_GL_BUFFER_SIZE:
162 data[p++]=GLX_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
163 case WX_GL_LEVEL:
164 data[p++]=GLX_LEVEL; data[p++]=attribList[arg++]; break;
165 case WX_GL_DOUBLEBUFFER: data[p++] = GLX_DOUBLEBUFFER; break;
166 case WX_GL_STEREO: data[p++] = GLX_STEREO; break;
167 case WX_GL_AUX_BUFFERS:
168 data[p++]=GLX_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
169 case WX_GL_MIN_RED:
170 data[p++]=GLX_RED_SIZE; data[p++]=attribList[arg++]; break;
171 case WX_GL_MIN_GREEN:
172 data[p++]=GLX_GREEN_SIZE; data[p++]=attribList[arg++]; break;
173 case WX_GL_MIN_BLUE:
174 data[p++]=GLX_BLUE_SIZE; data[p++]=attribList[arg++]; break;
175 case WX_GL_MIN_ALPHA:
176 data[p++]=GLX_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
177 case WX_GL_DEPTH_SIZE:
178 data[p++]=GLX_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
179 case WX_GL_STENCIL_SIZE:
180 data[p++]=GLX_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
181 case WX_GL_MIN_ACCUM_RED:
182 data[p++]=GLX_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
183 case WX_GL_MIN_ACCUM_GREEN:
184 data[p++]=GLX_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
185 case WX_GL_MIN_ACCUM_BLUE:
186 data[p++]=GLX_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
187 case WX_GL_MIN_ACCUM_ALPHA:
188 data[p++]=GLX_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
189 default:
190 break;
191 }
192 }
193 data[p] = 0;
194
195 // Get an appropriate visual
196 vi = glXChooseVisual(display, DefaultScreen(display), data);
197 if(!vi) return false;
198
199 // Here we should make sure that vi is the same visual as the
200 // one used by the xwindow drawable in wxCanvas. However,
201 // there is currently no mechanism for this in wx_canvs.cc.
202 }
203 else // default attributes
204 {
205 // By default, we use the visual of xwindow
206 XGetWindowAttributes(display, wxGetClientAreaWindow(this), &xwa);
207 vi_templ.visualid = XVisualIDFromVisual(xwa.visual);
208 vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n);
209 if(!vi) return false;
210 glXGetConfig(display, vi, GLX_USE_GL, &val);
211 if(!val) return false;
212 }
213
214 m_vi = vi; // safe for later use
215
216 wxCHECK_MSG( m_vi, false, wxT("required visual couldn't be found") );
217
218 return true;
219 }
220
221 wxGLCanvas::~wxGLCanvas()
222 {
223 XVisualInfo *vi = (XVisualInfo *) m_vi;
224
225 if (vi)
226 XFree( vi );
227 }
228
229 void wxGLCanvas::SwapBuffers()
230 {
231 glXSwapBuffers((Display *)wxGetDisplay(), wxGetClientAreaWindow(this));
232 }
233
234 int wxGLCanvas::GetColourIndex(const wxColour& col_)
235 {
236 wxColour& col = wx_const_cast(wxColour&, col_);
237
238 #ifdef __WXMOTIF__
239 col.AllocColour(GetXDisplay());
240 #else
241 col.CalcPixel(wxTheApp->GetMainColormap(wxGetDisplay()));
242 #endif
243
244 return col.GetPixel();
245 }
246
247 #endif // wxUSE_GLCANVAS