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