]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/glcanvas.mm
using terminate: terminates prematurely, OnExit is not called anymore
[wxWidgets.git] / src / osx / cocoa / glcanvas.mm
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/glcanvas.mm
3 // Purpose: wxGLCanvas, for using OpenGL with wxWidgets under Macintosh
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // Copyright: (c) Stefan Csomor
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 #include "wx/wxprec.h"
20
21 #if defined(__BORLANDC__)
22 #pragma hdrstop
23 #endif
24
25 #if wxUSE_GLCANVAS
26
27 #include "wx/glcanvas.h"
28
29 #ifndef WX_PRECOMP
30 #include "wx/frame.h"
31 #include "wx/log.h"
32 #include "wx/settings.h"
33 #endif
34
35 #include "wx/osx/private.h"
36
37 WXGLContext WXGLCreateContext( WXGLPixelFormat pixelFormat, WXGLContext shareContext )
38 {
39 WXGLContext context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext: shareContext];
40 if ( !context )
41 {
42 wxFAIL_MSG("NSOpenGLContext creation failed");
43 }
44 return context ;
45 }
46
47 void WXGLDestroyContext( WXGLContext context )
48 {
49 if ( context )
50 {
51 [context release];
52 }
53 }
54
55 void WXGLSwapBuffers( WXGLContext context )
56 {
57 [context flushBuffer];
58 }
59
60 WXGLContext WXGLGetCurrentContext()
61 {
62 return [NSOpenGLContext currentContext];
63 }
64
65 bool WXGLSetCurrentContext(WXGLContext context)
66 {
67 [context makeCurrentContext];
68
69 return true;
70 }
71
72 void WXGLDestroyPixelFormat( WXGLPixelFormat pixelFormat )
73 {
74 if ( pixelFormat )
75 {
76 [pixelFormat release];
77 }
78 }
79
80
81 WXGLPixelFormat WXGLChoosePixelFormat(const int *attribList)
82 {
83 NSOpenGLPixelFormatAttribute data[512];
84 const NSOpenGLPixelFormatAttribute defaultAttribs[] =
85 {
86 NSOpenGLPFADoubleBuffer,
87 NSOpenGLPFAMinimumPolicy,
88 NSOpenGLPFAColorSize,(NSOpenGLPixelFormatAttribute)8,
89 NSOpenGLPFAAlphaSize,(NSOpenGLPixelFormatAttribute)0,
90 NSOpenGLPFADepthSize,(NSOpenGLPixelFormatAttribute)8,
91 (NSOpenGLPixelFormatAttribute)nil
92 };
93
94 const NSOpenGLPixelFormatAttribute *attribs;
95 if ( !attribList )
96 {
97 attribs = defaultAttribs;
98 }
99 else
100 {
101 unsigned p = 0;
102 data[p++] = NSOpenGLPFAMinimumPolicy; // make _SIZE tags behave more like GLX
103
104 for ( unsigned arg = 0; attribList[arg] !=0 && p < WXSIZEOF(data); )
105 {
106 switch ( attribList[arg++] )
107 {
108 case WX_GL_RGBA:
109 //data[p++] = AGL_RGBA;
110 break;
111
112 case WX_GL_BUFFER_SIZE:
113 //data[p++] = AGL_BUFFER_SIZE;
114 //data[p++] = attribList[arg++];
115 break;
116
117 case WX_GL_LEVEL:
118 //data[p++]=AGL_LEVEL;
119 //data[p++]=attribList[arg++];
120 break;
121
122 case WX_GL_DOUBLEBUFFER:
123 data[p++] = NSOpenGLPFADoubleBuffer;
124 break;
125
126 case WX_GL_STEREO:
127 data[p++] = NSOpenGLPFAStereo;
128 break;
129
130 case WX_GL_AUX_BUFFERS:
131 data[p++] = NSOpenGLPFAAuxBuffers;
132 data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
133 break;
134
135 case WX_GL_MIN_RED:
136 data[p++] = NSOpenGLPFAColorSize;
137 data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
138 break;
139
140 case WX_GL_MIN_GREEN:
141 //data[p++] = AGL_GREEN_SIZE;
142 //data[p++] = attribList[arg++];
143 break;
144
145 case WX_GL_MIN_BLUE:
146 //data[p++] = AGL_BLUE_SIZE;
147 //data[p++] = attribList[arg++];
148 break;
149
150 case WX_GL_MIN_ALPHA:
151 data[p++] = NSOpenGLPFAAlphaSize;
152 data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
153 break;
154
155 case WX_GL_DEPTH_SIZE:
156 data[p++] = NSOpenGLPFADepthSize;
157 data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
158 break;
159
160 case WX_GL_STENCIL_SIZE:
161 data[p++] = NSOpenGLPFAStencilSize;
162 data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
163 break;
164
165 case WX_GL_MIN_ACCUM_RED:
166 data[p++] = NSOpenGLPFAAccumSize;
167 data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
168 break;
169
170 case WX_GL_MIN_ACCUM_GREEN:
171 //data[p++] = AGL_ACCUM_GREEN_SIZE;
172 //data[p++] = attribList[arg++];
173 break;
174
175 case WX_GL_MIN_ACCUM_BLUE:
176 //data[p++] = AGL_ACCUM_BLUE_SIZE;
177 //data[p++] = attribList[arg++];
178 break;
179
180 case WX_GL_MIN_ACCUM_ALPHA:
181 //data[p++] = AGL_ACCUM_ALPHA_SIZE;
182 //data[p++] = attribList[arg++];
183 break;
184
185 case WX_GL_SAMPLE_BUFFERS:
186 if ( !wxGLCanvas::IsAGLMultiSampleAvailable() )
187 {
188 if ( !attribList[arg++] )
189 break;
190
191 return nil;
192 }
193
194 data[p++] = NSOpenGLPFASampleBuffers;
195 if ( (data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++]) == true )
196 {
197 // don't use software fallback
198 data[p++] = NSOpenGLPFANoRecovery;
199 }
200 break;
201
202 case WX_GL_SAMPLES:
203 if ( !wxGLCanvas::IsAGLMultiSampleAvailable() )
204 {
205 if ( !attribList[arg++] )
206 break;
207
208 return nil;
209 }
210
211 data[p++] = NSOpenGLPFASamples;
212 data[p++] = (NSOpenGLPixelFormatAttribute) attribList[arg++];
213 break;
214 }
215 }
216
217 data[p] = (NSOpenGLPixelFormatAttribute)nil;
218
219 attribs = data;
220 }
221
222 return [[NSOpenGLPixelFormat alloc] initWithAttributes:(NSOpenGLPixelFormatAttribute*) attribs];
223 }
224
225 @interface wxNSCustomOpenGLView : NSView
226 {
227 NSOpenGLContext* context;
228 }
229
230 @end
231
232 @implementation wxNSCustomOpenGLView
233
234 + (void)initialize
235 {
236 static BOOL initialized = NO;
237 if (!initialized)
238 {
239 initialized = YES;
240 wxOSXCocoaClassAddWXMethods( self );
241 }
242 }
243
244 - (BOOL)isOpaque
245 {
246 return YES;
247 }
248
249 @end
250
251 bool wxGLCanvas::Create(wxWindow *parent,
252 wxWindowID id,
253 const wxPoint& pos,
254 const wxSize& size,
255 long style,
256 const wxString& name,
257 const int *attribList,
258 const wxPalette& WXUNUSED(palette))
259 {
260 m_glFormat = WXGLChoosePixelFormat(attribList);
261 if ( !m_glFormat )
262 return false;
263
264 // DontCreatePeer();
265
266 if ( !wxWindow::Create(parent, id, pos, size, style, name) )
267 return false;
268
269 /*
270 NSRect r = wxOSXGetFrameForControl( this, pos , size ) ;
271 wxNSCustomOpenGLView* v = [[wxNSCustomOpenGLView alloc] initWithFrame:r];
272 m_peer = new wxWidgetCocoaImpl( this, v );
273
274 MacPostControlCreate(pos, size) ;
275 */
276 return true;
277 }
278
279 wxGLCanvas::~wxGLCanvas()
280 {
281 if ( m_glFormat )
282 WXGLDestroyPixelFormat(m_glFormat);
283 }
284
285 bool wxGLCanvas::SwapBuffers()
286 {
287 WXGLContext context = WXGLGetCurrentContext();
288 wxCHECK_MSG(context, false, wxT("should have current context"));
289
290 [context flushBuffer];
291
292 return true;
293 }
294
295 bool wxGLContext::SetCurrent(const wxGLCanvas& win) const
296 {
297 if ( !m_glContext )
298 return false;
299
300 [m_glContext setView: win.GetHandle() ];
301 [m_glContext update];
302
303 [m_glContext makeCurrentContext];
304
305 return true;
306 }
307
308 #endif // wxUSE_GLCANVAS