]> git.saurik.com Git - wxWidgets.git/blame - src/mac/classic/glcanvas.cpp
correct access for virtuals, other minor corrections
[wxWidgets.git] / src / mac / classic / glcanvas.cpp
CommitLineData
2646f485 1/////////////////////////////////////////////////////////////////////////////
0ba6a836 2// Name: src/mac/classic/glcanvas.cpp
77ffb593 3// Purpose: wxGLCanvas, for using OpenGL with wxWidgets under Macintosh
2646f485
SC
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id$
8// Copyright: (c) Stefan Csomor
e4db172a 9// Licence: wxWindows licence
2646f485
SC
10/////////////////////////////////////////////////////////////////////////////
11
2646f485
SC
12#include "wx/wxprec.h"
13
14#if defined(__BORLANDC__)
e4db172a 15 #pragma hdrstop
2646f485
SC
16#endif
17
2646f485
SC
18#if wxUSE_GLCANVAS
19
e4db172a
WS
20#include "wx/glcanvas.h"
21
2646f485 22#ifndef WX_PRECOMP
e4db172a
WS
23 #include "wx/frame.h"
24 #include "wx/log.h"
2646f485
SC
25#endif
26
27#include "wx/settings.h"
2646f485 28
2646f485
SC
29#include "wx/mac/uma.h"
30
31// DLL options compatibility check:
32#include "wx/build.h"
33WX_CHECK_BUILD_OPTIONS("wxGL")
34
35/*
36* GLContext implementation
37*/
38
39wxGLContext::wxGLContext(
40 AGLPixelFormat fmt, wxGLCanvas *win,
41 const wxPalette& palette,
42 const wxGLContext *other /* for sharing display lists */
43 )
44{
45 m_window = win;
0ba6a836 46
2646f485 47 m_drawable = (AGLDrawable) UMAGetWindowPort(MAC_WXHWND(win->MacGetRootWindow()));
0ba6a836 48
2646f485
SC
49 m_glContext = aglCreateContext(fmt, other ? other->m_glContext : NULL);
50 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
0ba6a836 51
2646f485
SC
52 GLboolean b;
53 b = aglSetDrawable(m_glContext, m_drawable);
54 wxCHECK_RET( b, wxT("Couldn't bind OpenGl context") );
55 aglEnable(m_glContext , AGL_BUFFER_RECT ) ;
56 b = aglSetCurrentContext(m_glContext);
57 wxCHECK_RET( b, wxT("Couldn't activate OpenGl context") );
58}
59
60wxGLContext::~wxGLContext()
61{
62 if (m_glContext)
63 {
64 aglSetCurrentContext(NULL);
65 aglDestroyContext(m_glContext);
66 }
67}
68
69void wxGLContext::SwapBuffers()
70{
71 if (m_glContext)
72 {
73 aglSwapBuffers(m_glContext);
74 }
75}
76
77void wxGLContext::SetCurrent()
78{
79 if (m_glContext)
80 {
81 aglSetCurrentContext(m_glContext);
82 }
83}
84
85void wxGLContext::Update()
86{
87 if (m_glContext)
88 {
89 aglUpdateContext(m_glContext);
90 }
91}
92
93void wxGLContext::SetColour(const wxChar *colour)
94{
95 wxColour col = wxTheColourDatabase->Find(colour);
96 if (col.Ok())
97 {
98 float r = (float)(col.Red()/256.0);
99 float g = (float)(col.Green()/256.0);
100 float b = (float)(col.Blue()/256.0);
101 glColor3f( r, g, b);
102 }
103}
104
105
106/*
107* wxGLCanvas implementation
108*/
109
110IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
111
112BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
113 EVT_SIZE(wxGLCanvas::OnSize)
114END_EVENT_TABLE()
115
116wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
117 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
118 int *attribList, const wxPalette& palette)
119{
120 Create(parent, NULL, id, pos, size, style, name, attribList, palette);
121}
122
123wxGLCanvas::wxGLCanvas( wxWindow *parent,
124 const wxGLContext *shared, wxWindowID id,
125 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
126 int *attribList, const wxPalette& palette )
127{
128 Create(parent, shared, id, pos, size, style, name, attribList, palette);
129}
130
131wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID id,
132 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
133 int *attribList, const wxPalette& palette )
134{
135 Create(parent, shared ? shared->GetContext() : NULL, id, pos, size, style, name, attribList, palette);
136}
137
138wxGLCanvas::~wxGLCanvas()
139{
140 if (m_glContext != NULL) {
141 delete m_glContext;
142 m_glContext = NULL;
143 }
144}
145
146static AGLPixelFormat ChoosePixelFormat(const int *attribList)
147{
148 GLint data[512];
0ba6a836
WS
149 GLint defaultAttribs[] = { AGL_RGBA,
150 AGL_DOUBLEBUFFER,
151 AGL_MINIMUM_POLICY,
2646f485 152 AGL_DEPTH_SIZE, 1, // use largest available depth buffer
0ba6a836
WS
153 AGL_RED_SIZE, 1,
154 AGL_GREEN_SIZE, 1,
155 AGL_BLUE_SIZE, 1,
156 AGL_ALPHA_SIZE, 0,
2646f485
SC
157 AGL_NONE };
158 GLint *attribs;
159 if (!attribList)
160 {
161 attribs = defaultAttribs;
162 }
163 else
164 {
165 int arg=0, p=0;
0ba6a836 166
2646f485
SC
167 data[p++] = AGL_MINIMUM_POLICY; // make _SIZE tags behave more like GLX
168 while( (attribList[arg]!=0) && (p<512) )
169 {
170 switch( attribList[arg++] )
171 {
172 case WX_GL_RGBA: data[p++] = AGL_RGBA; break;
173 case WX_GL_BUFFER_SIZE:
174 data[p++]=AGL_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
175 case WX_GL_LEVEL:
176 data[p++]=AGL_LEVEL; data[p++]=attribList[arg++]; break;
177 case WX_GL_DOUBLEBUFFER: data[p++] = AGL_DOUBLEBUFFER; break;
178 case WX_GL_STEREO: data[p++] = AGL_STEREO; break;
179 case WX_GL_AUX_BUFFERS:
180 data[p++]=AGL_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
181 case WX_GL_MIN_RED:
182 data[p++]=AGL_RED_SIZE; data[p++]=attribList[arg++]; break;
183 case WX_GL_MIN_GREEN:
184 data[p++]=AGL_GREEN_SIZE; data[p++]=attribList[arg++]; break;
185 case WX_GL_MIN_BLUE:
186 data[p++]=AGL_BLUE_SIZE; data[p++]=attribList[arg++]; break;
187 case WX_GL_MIN_ALPHA:
188 data[p++]=AGL_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
0ba6a836 189 case WX_GL_DEPTH_SIZE:
2646f485 190 data[p++]=AGL_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
0ba6a836 191 case WX_GL_STENCIL_SIZE:
2646f485
SC
192 data[p++]=AGL_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
193 case WX_GL_MIN_ACCUM_RED:
194 data[p++]=AGL_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
195 case WX_GL_MIN_ACCUM_GREEN:
196 data[p++]=AGL_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
197 case WX_GL_MIN_ACCUM_BLUE:
198 data[p++]=AGL_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
199 case WX_GL_MIN_ACCUM_ALPHA:
200 data[p++]=AGL_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
201 default:
202 break;
203 }
0ba6a836
WS
204 }
205 data[p] = 0;
206
2646f485
SC
207 attribs = data;
208 }
0ba6a836 209
2646f485
SC
210 return aglChoosePixelFormat(NULL, 0, attribs);
211}
212
213bool wxGLCanvas::Create(wxWindow *parent, const wxGLContext *shared, wxWindowID id,
214 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
215 int *attribList, const wxPalette& palette)
216{
217 wxWindow::Create( parent, id, pos, size, style, name );
0ba6a836 218
2646f485
SC
219 AGLPixelFormat fmt = ChoosePixelFormat(attribList);
220 wxCHECK_MSG( fmt, false, wxT("Couldn't create OpenGl pixel format") );
0ba6a836 221
2646f485
SC
222 m_glContext = new wxGLContext(fmt, this, palette, shared);
223 m_macCanvasIsShown = true ;
224 aglDestroyPixelFormat(fmt);
0ba6a836 225
2646f485
SC
226 return true;
227}
228
229void wxGLCanvas::SwapBuffers()
230{
231 if (m_glContext)
232 m_glContext->SwapBuffers();
233}
234
235void wxGLCanvas::UpdateContext()
236{
237 if (m_glContext)
238 m_glContext->Update();
239}
240
241void wxGLCanvas::SetViewport()
242{
243 // viewport is initially set to entire port
244 // adjust glViewport to just this window
245 int x = 0 ;
246 int y = 0 ;
0ba6a836 247
2646f485
SC
248 wxWindow* iter = this ;
249 while( iter->GetParent() )
250 {
0ba6a836 251 iter = iter->GetParent() ;
2646f485 252 }
0ba6a836 253
2646f485
SC
254 if ( iter && iter->IsTopLevel() )
255 {
0ba6a836
WS
256 MacClientToRootWindow( &x , &y ) ;
257 int width, height;
258 GetClientSize(& width, & height);
259 Rect bounds ;
260 GetWindowPortBounds( MAC_WXHWND(MacGetRootWindow()) , &bounds ) ;
261 GLint parms[4] ;
262 parms[0] = x ;
263 parms[1] = bounds.bottom - bounds.top - ( y + height ) ;
264 parms[2] = width ;
265 parms[3] = height ;
266
267 if ( !m_macCanvasIsShown )
268 parms[0] += 20000 ;
269 aglSetInteger( m_glContext->m_glContext , AGL_BUFFER_RECT , parms ) ;
270 }
2646f485
SC
271}
272
273void wxGLCanvas::OnSize(wxSizeEvent& event)
274{
275 MacUpdateView() ;
276}
277
278void wxGLCanvas::MacUpdateView()
279{
280 if (m_glContext)
281 {
282 UpdateContext();
283 m_glContext->SetCurrent();
284 SetViewport();
285 }
286}
287
288void wxGLCanvas::MacSuperChangedPosition()
289{
290 MacUpdateView() ;
291 wxWindow::MacSuperChangedPosition() ;
292}
293
294void wxGLCanvas::MacTopLevelWindowChangedPosition()
295{
296 MacUpdateView() ;
297 wxWindow::MacTopLevelWindowChangedPosition() ;
298}
299
300void wxGLCanvas::SetCurrent()
301{
302 if (m_glContext)
303 {
304 m_glContext->SetCurrent();
305 }
306}
307
308void wxGLCanvas::SetColour(const wxChar *colour)
309{
310 if (m_glContext)
311 m_glContext->SetColour(colour);
312}
313
0ba6a836 314bool wxGLCanvas::Show(bool show)
2646f485
SC
315{
316 if ( !wxWindow::Show( show ) )
0ba6a836
WS
317 return false ;
318
2646f485
SC
319 if ( !show )
320 {
321 if ( m_macCanvasIsShown )
322 {
323 m_macCanvasIsShown = false ;
324 SetViewport() ;
325 }
326 }
327 else
328 {
329 if ( MacIsReallyShown() && !m_macCanvasIsShown )
330 {
331 m_macCanvasIsShown = true ;
332 SetViewport() ;
333 }
334 }
0ba6a836 335 return true ;
2646f485
SC
336}
337
0ba6a836 338void wxGLCanvas::MacSuperShown( bool show )
2646f485
SC
339{
340 if ( !show )
341 {
342 if ( m_macCanvasIsShown )
343 {
344 m_macCanvasIsShown = false ;
345 SetViewport() ;
346 }
347 }
348 else
349 {
350 if ( MacIsReallyShown() && !m_macCanvasIsShown )
351 {
352 m_macCanvasIsShown = true ;
353 SetViewport() ;
354 }
355 }
0ba6a836 356
2646f485
SC
357 wxWindow::MacSuperShown( show ) ;
358}
359
360//---------------------------------------------------------------------------
361// wxGLApp
362//---------------------------------------------------------------------------
363
364IMPLEMENT_CLASS(wxGLApp, wxApp)
365
366bool wxGLApp::InitGLVisual(int *attribList)
367{
368 AGLPixelFormat fmt = ChoosePixelFormat(attribList);
369 if (fmt != NULL) {
370 aglDestroyPixelFormat(fmt);
371 return true;
372 } else
373 return false;
374}
375
376wxGLApp::~wxGLApp(void)
377{
378}
379
380#endif // wxUSE_GLCANVAS