]> git.saurik.com Git - wxWidgets.git/blame - src/mac/classic/glcanvas.cpp
EVT_CHAR_HOOK added
[wxWidgets.git] / src / mac / classic / glcanvas.cpp
CommitLineData
2646f485
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: 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
65571936 9// Licence: wxWindows licence
2646f485
SC
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 wxColour col = wxTheColourDatabase->Find(colour);
101 if (col.Ok())
102 {
103 float r = (float)(col.Red()/256.0);
104 float g = (float)(col.Green()/256.0);
105 float b = (float)(col.Blue()/256.0);
106 glColor3f( r, g, b);
107 }
108}
109
110
111/*
112* wxGLCanvas implementation
113*/
114
115IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
116
117BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
118 EVT_SIZE(wxGLCanvas::OnSize)
119END_EVENT_TABLE()
120
121wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
122 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
123 int *attribList, const wxPalette& palette)
124{
125 Create(parent, NULL, id, pos, size, style, name, attribList, palette);
126}
127
128wxGLCanvas::wxGLCanvas( wxWindow *parent,
129 const wxGLContext *shared, wxWindowID id,
130 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
131 int *attribList, const wxPalette& palette )
132{
133 Create(parent, shared, id, pos, size, style, name, attribList, palette);
134}
135
136wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID id,
137 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
138 int *attribList, const wxPalette& palette )
139{
140 Create(parent, shared ? shared->GetContext() : NULL, id, pos, size, style, name, attribList, palette);
141}
142
143wxGLCanvas::~wxGLCanvas()
144{
145 if (m_glContext != NULL) {
146 delete m_glContext;
147 m_glContext = NULL;
148 }
149}
150
151static AGLPixelFormat ChoosePixelFormat(const int *attribList)
152{
153 GLint data[512];
154 GLint defaultAttribs[] = { AGL_RGBA,
155 AGL_DOUBLEBUFFER,
156 AGL_MINIMUM_POLICY,
157 AGL_DEPTH_SIZE, 1, // use largest available depth buffer
158 AGL_RED_SIZE, 1,
159 AGL_GREEN_SIZE, 1,
160 AGL_BLUE_SIZE, 1,
161 AGL_ALPHA_SIZE, 0,
162 AGL_NONE };
163 GLint *attribs;
164 if (!attribList)
165 {
166 attribs = defaultAttribs;
167 }
168 else
169 {
170 int arg=0, p=0;
171
172 data[p++] = AGL_MINIMUM_POLICY; // make _SIZE tags behave more like GLX
173 while( (attribList[arg]!=0) && (p<512) )
174 {
175 switch( attribList[arg++] )
176 {
177 case WX_GL_RGBA: data[p++] = AGL_RGBA; break;
178 case WX_GL_BUFFER_SIZE:
179 data[p++]=AGL_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
180 case WX_GL_LEVEL:
181 data[p++]=AGL_LEVEL; data[p++]=attribList[arg++]; break;
182 case WX_GL_DOUBLEBUFFER: data[p++] = AGL_DOUBLEBUFFER; break;
183 case WX_GL_STEREO: data[p++] = AGL_STEREO; break;
184 case WX_GL_AUX_BUFFERS:
185 data[p++]=AGL_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
186 case WX_GL_MIN_RED:
187 data[p++]=AGL_RED_SIZE; data[p++]=attribList[arg++]; break;
188 case WX_GL_MIN_GREEN:
189 data[p++]=AGL_GREEN_SIZE; data[p++]=attribList[arg++]; break;
190 case WX_GL_MIN_BLUE:
191 data[p++]=AGL_BLUE_SIZE; data[p++]=attribList[arg++]; break;
192 case WX_GL_MIN_ALPHA:
193 data[p++]=AGL_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
194 case WX_GL_DEPTH_SIZE:
195 data[p++]=AGL_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
196 case WX_GL_STENCIL_SIZE:
197 data[p++]=AGL_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
198 case WX_GL_MIN_ACCUM_RED:
199 data[p++]=AGL_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
200 case WX_GL_MIN_ACCUM_GREEN:
201 data[p++]=AGL_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
202 case WX_GL_MIN_ACCUM_BLUE:
203 data[p++]=AGL_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
204 case WX_GL_MIN_ACCUM_ALPHA:
205 data[p++]=AGL_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
206 default:
207 break;
208 }
209 }
210 data[p] = 0;
211
212 attribs = data;
213 }
214
215 return aglChoosePixelFormat(NULL, 0, attribs);
216}
217
218bool wxGLCanvas::Create(wxWindow *parent, const wxGLContext *shared, wxWindowID id,
219 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
220 int *attribList, const wxPalette& palette)
221{
222 wxWindow::Create( parent, id, pos, size, style, name );
223
224 AGLPixelFormat fmt = ChoosePixelFormat(attribList);
225 wxCHECK_MSG( fmt, false, wxT("Couldn't create OpenGl pixel format") );
226
227 m_glContext = new wxGLContext(fmt, this, palette, shared);
228 m_macCanvasIsShown = true ;
229 aglDestroyPixelFormat(fmt);
230
231 return true;
232}
233
234void wxGLCanvas::SwapBuffers()
235{
236 if (m_glContext)
237 m_glContext->SwapBuffers();
238}
239
240void wxGLCanvas::UpdateContext()
241{
242 if (m_glContext)
243 m_glContext->Update();
244}
245
246void wxGLCanvas::SetViewport()
247{
248 // viewport is initially set to entire port
249 // adjust glViewport to just this window
250 int x = 0 ;
251 int y = 0 ;
252
253 wxWindow* iter = this ;
254 while( iter->GetParent() )
255 {
256 iter = iter->GetParent() ;
257 }
258
259 if ( iter && iter->IsTopLevel() )
260 {
261 MacClientToRootWindow( &x , &y ) ;
262 int width, height;
263 GetClientSize(& width, & height);
264 Rect bounds ;
265 GetWindowPortBounds( MAC_WXHWND(MacGetRootWindow()) , &bounds ) ;
266 GLint parms[4] ;
267 parms[0] = x ;
268 parms[1] = bounds.bottom - bounds.top - ( y + height ) ;
269 parms[2] = width ;
270 parms[3] = height ;
271
272 if ( !m_macCanvasIsShown )
273 parms[0] += 20000 ;
274 aglSetInteger( m_glContext->m_glContext , AGL_BUFFER_RECT , parms ) ;
275 }
276}
277
278void wxGLCanvas::OnSize(wxSizeEvent& event)
279{
280 MacUpdateView() ;
281}
282
283void wxGLCanvas::MacUpdateView()
284{
285 if (m_glContext)
286 {
287 UpdateContext();
288 m_glContext->SetCurrent();
289 SetViewport();
290 }
291}
292
293void wxGLCanvas::MacSuperChangedPosition()
294{
295 MacUpdateView() ;
296 wxWindow::MacSuperChangedPosition() ;
297}
298
299void wxGLCanvas::MacTopLevelWindowChangedPosition()
300{
301 MacUpdateView() ;
302 wxWindow::MacTopLevelWindowChangedPosition() ;
303}
304
305void wxGLCanvas::SetCurrent()
306{
307 if (m_glContext)
308 {
309 m_glContext->SetCurrent();
310 }
311}
312
313void wxGLCanvas::SetColour(const wxChar *colour)
314{
315 if (m_glContext)
316 m_glContext->SetColour(colour);
317}
318
319bool wxGLCanvas::Show(bool show)
320{
321 if ( !wxWindow::Show( show ) )
322 return FALSE ;
323
324 if ( !show )
325 {
326 if ( m_macCanvasIsShown )
327 {
328 m_macCanvasIsShown = false ;
329 SetViewport() ;
330 }
331 }
332 else
333 {
334 if ( MacIsReallyShown() && !m_macCanvasIsShown )
335 {
336 m_macCanvasIsShown = true ;
337 SetViewport() ;
338 }
339 }
340 return TRUE ;
341}
342
343void wxGLCanvas::MacSuperShown( bool show )
344{
345 if ( !show )
346 {
347 if ( m_macCanvasIsShown )
348 {
349 m_macCanvasIsShown = false ;
350 SetViewport() ;
351 }
352 }
353 else
354 {
355 if ( MacIsReallyShown() && !m_macCanvasIsShown )
356 {
357 m_macCanvasIsShown = true ;
358 SetViewport() ;
359 }
360 }
361
362 wxWindow::MacSuperShown( show ) ;
363}
364
365//---------------------------------------------------------------------------
366// wxGLApp
367//---------------------------------------------------------------------------
368
369IMPLEMENT_CLASS(wxGLApp, wxApp)
370
371bool wxGLApp::InitGLVisual(int *attribList)
372{
373 AGLPixelFormat fmt = ChoosePixelFormat(attribList);
374 if (fmt != NULL) {
375 aglDestroyPixelFormat(fmt);
376 return true;
377 } else
378 return false;
379}
380
381wxGLApp::~wxGLApp(void)
382{
383}
384
385#endif // wxUSE_GLCANVAS