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