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