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