Update OpenVMS makefile
[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