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