0026128: Visualization, TKOpenGl - fix misprint in external GLX context initialization
[occt.git] / src / OpenGl / OpenGl_Window_1.mm
CommitLineData
6aca4d39 1// Created on: 2012-11-12
4fe56619 2// Created by: Kirill Gavrilov
6aca4d39 3// Copyright (c) 2012-2014 OPEN CASCADE SAS
4fe56619 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
4fe56619 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
4fe56619 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
4fe56619 15
16#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
17
0e9d3b83 18#define GL_GLEXT_LEGACY // To prevent inclusion of system glext.h on Mac OS X 10.6.8
19
a2e4f780 20#import <TargetConditionals.h>
21
22#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
23 #import <UIKit/UIKit.h>
24#else
25 #import <Cocoa/Cocoa.h>
26
27#if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
28@interface NSView (LionAPI)
29- (NSSize )convertSizeToBacking: (NSSize )theSize;
30@end
31#endif
32
33#endif
4fe56619 34
35#include <InterfaceGraphic.hxx>
36
37#include <OpenGl_Window.hxx>
a2e4f780 38#include <OpenGl_FrameBuffer.hxx>
4fe56619 39
40#include <OpenGl_Context.hxx>
4fe56619 41#include <Aspect_GraphicDeviceDefinitionError.hxx>
42#include <Cocoa_LocalPool.hxx>
43#include <TCollection_AsciiString.hxx>
4e1523ef 44#include <TCollection_ExtendedString.hxx>
4fe56619 45
a2e4f780 46#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
47 //
48#else
49 #include <OpenGL/CGLRenderers.h>
50#endif
abe46077 51
4fe56619 52namespace
53{
54 static const TEL_COLOUR THE_DEFAULT_BG_COLOR = { { 0.F, 0.F, 0.F, 1.F } };
a2e4f780 55}
4fe56619 56
57// =======================================================================
58// function : OpenGl_Window
59// purpose :
60// =======================================================================
c7ccbb77 61OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
4fe56619 62 const CALL_DEF_WINDOW& theCWindow,
63 Aspect_RenderingContext theGContext,
58655684 64 const Handle(OpenGl_Caps)& theCaps,
4fe56619 65 const Handle(OpenGl_Context)& theShareCtx)
73192b37 66: myGlContext (new OpenGl_Context (theCaps)),
4fe56619 67 myOwnGContext (theGContext == 0),
a2e4f780 68#if defined(__APPLE__)
69#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
70 myUIView (NULL),
71#endif
72 myWidthPt (theCWindow.dx),
73 myHeightPt (theCWindow.dy),
74#endif
75 myWidth (theCWindow.dx),
76 myHeight (theCWindow.dy),
73192b37 77 myBgColor (THE_DEFAULT_BG_COLOR)
4fe56619 78{
79 myBgColor.rgb[0] = theCWindow.Background.r;
80 myBgColor.rgb[1] = theCWindow.Background.g;
81 myBgColor.rgb[2] = theCWindow.Background.b;
82
a2e4f780 83#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
84 EAGLContext* aGLContext = theGContext;
85 if (aGLContext == NULL)
4e1523ef 86 {
a2e4f780 87 void* aViewPtr = (void* )theCWindow.XWindow;
88
89 myUIView = (__bridge UIView* )aViewPtr;
90 CAEAGLLayer* anEaglLayer = (CAEAGLLayer* )myUIView.layer;
91 anEaglLayer.opaque = TRUE;
92 anEaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
93 [NSNumber numberWithBool: FALSE], kEAGLDrawablePropertyRetainedBacking,
94 kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
95 NULL];
96
97 aGLContext = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
98 if (aGLContext == NULL
99 || ![EAGLContext setCurrentContext: aGLContext])
100 {
101 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext creation failed");
102 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
103 return;
104 }
105
106 myGlContext->Init (aGLContext, Standard_False);
4e1523ef 107 }
108 else
abe46077 109 {
a2e4f780 110 if (![EAGLContext setCurrentContext: aGLContext])
111 {
112 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext can not be assigned");
113 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
114 return;
115 }
116
117 myGlContext->Init (aGLContext, Standard_False);
4e1523ef 118 }
a2e4f780 119#else
120
121 Cocoa_LocalPool aLocalPool;
122
123 // all GL context within one OpenGl_GraphicDriver should be shared!
124 NSOpenGLContext* aGLCtxShare = theShareCtx.IsNull() ? NULL : theShareCtx->myGContext;
125 NSOpenGLContext* aGLContext = theGContext;
126 bool isCore = false;
127 if (aGLContext == NULL)
4e1523ef 128 {
a2e4f780 129 NSOpenGLPixelFormatAttribute anAttribs[32] = {};
130 Standard_Integer aLastAttrib = 0;
131 //anAttribs[aLastAttrib++] = NSOpenGLPFAColorSize; anAttribs[aLastAttrib++] = 32,
132 anAttribs[aLastAttrib++] = NSOpenGLPFADepthSize; anAttribs[aLastAttrib++] = 24;
133 anAttribs[aLastAttrib++] = NSOpenGLPFAStencilSize; anAttribs[aLastAttrib++] = 8;
134 anAttribs[aLastAttrib++] = NSOpenGLPFADoubleBuffer;
135 if (theCaps->contextNoAccel)
4e1523ef 136 {
a2e4f780 137 anAttribs[aLastAttrib++] = NSOpenGLPFARendererID;
138 anAttribs[aLastAttrib++] = (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID;
4e1523ef 139 }
a2e4f780 140 else
141 {
142 anAttribs[aLastAttrib++] = NSOpenGLPFAAccelerated;
143 }
144 anAttribs[aLastAttrib] = 0;
145 const Standard_Integer aLastMainAttrib = aLastAttrib;
146 Standard_Integer aTryCore = 0;
147 Standard_Integer aTryStereo = 0;
148 for (aTryCore = 1; aTryCore >= 0; --aTryCore)
4e1523ef 149 {
a2e4f780 150 aLastAttrib = aLastMainAttrib;
151 if (aTryCore == 1)
4e1523ef 152 {
a2e4f780 153 if (theCaps->contextCompatible)
4e1523ef 154 {
155 continue;
156 }
a2e4f780 157
158 // supported since OS X 10.7+
159 anAttribs[aLastAttrib++] = 99; // NSOpenGLPFAOpenGLProfile
160 anAttribs[aLastAttrib++] = 0x3200; // NSOpenGLProfileVersion3_2Core
4e1523ef 161 }
162
a2e4f780 163 for (aTryStereo = 1; aTryStereo >= 0; --aTryStereo)
164 {
165 if (aTryStereo == 1)
166 {
167 if (!theCaps->contextStereo)
168 {
169 continue;
170 }
171 anAttribs[aLastAttrib++] = NSOpenGLPFAStereo;
172 }
173
174 anAttribs[aLastAttrib] = 0;
175
176 NSOpenGLPixelFormat* aGLFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease];
177 aGLContext = [[NSOpenGLContext alloc] initWithFormat: aGLFormat
178 shareContext: aGLCtxShare];
179 if (aGLContext != NULL)
180 {
181 break;
182 }
183 }
4e1523ef 184
4e1523ef 185 if (aGLContext != NULL)
186 {
187 break;
188 }
189 }
190
a2e4f780 191 if (aGLContext == NULL)
4e1523ef 192 {
a2e4f780 193 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: NSOpenGLContext creation failed");
194 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
195 return;
4e1523ef 196 }
4e1523ef 197
a2e4f780 198 if (aTryStereo == 0
199 && theCaps->contextStereo)
200 {
201 TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: QuadBuffer is unavailable!");
202 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
203 }
204 if (aTryCore == 0
205 && !theCaps->contextCompatible)
206 {
207 TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed.");
208 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
209 }
4fe56619 210
a2e4f780 211 NSView* aView = (NSView* )theCWindow.XWindow;
212 [aGLContext setView: aView];
213 isCore = (aTryCore == 1);
4e1523ef 214 }
215
a2e4f780 216 myGlContext->Init (aGLContext, isCore);
217#endif
4fe56619 218
4fe56619 219 myGlContext->Share (theShareCtx);
220 Init();
221}
222
223// =======================================================================
224// function : ~OpenGl_Window
225// purpose :
226// =======================================================================
227OpenGl_Window::~OpenGl_Window()
228{
a2e4f780 229 if (!myOwnGContext
230 || myGlContext.IsNull())
231 {
232 myGlContext.Nullify();
233 return;
234 }
235
236#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
237 myGlContext.Nullify();
238 [EAGLContext setCurrentContext: NULL];
239 myUIView = NULL;
240#else
241 NSOpenGLContext* aGLCtx = myGlContext->myGContext;
4fe56619 242 myGlContext.Nullify();
243
244 [NSOpenGLContext clearCurrentContext];
a2e4f780 245 [aGLCtx clearDrawable];
246 [aGLCtx release];
247#endif
4fe56619 248}
249
250// =======================================================================
251// function : Resize
252// purpose : call_subr_resize
253// =======================================================================
254void OpenGl_Window::Resize (const CALL_DEF_WINDOW& theCWindow)
255{
4fe56619 256 // If the size is not changed - do nothing
a2e4f780 257 if (myWidthPt == theCWindow.dx
258 && myHeightPt == theCWindow.dy)
4fe56619 259 {
260 return;
261 }
262
a2e4f780 263 myWidthPt = theCWindow.dx;
264 myHeightPt = theCWindow.dy;
4fe56619 265
266 Init();
267}
268
269// =======================================================================
270// function : Init
271// purpose :
272// =======================================================================
273void OpenGl_Window::Init()
274{
275 if (!Activate())
276 {
277 return;
278 }
279
a2e4f780 280#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
281 Handle(OpenGl_FrameBuffer) aDefFbo = myGlContext->SetDefaultFrameBuffer (NULL);
282 if (!aDefFbo.IsNull())
283 {
284 aDefFbo->Release (myGlContext.operator->());
285 }
286 else
287 {
288 aDefFbo = new OpenGl_FrameBuffer();
289 }
4fe56619 290
a2e4f780 291 if (myOwnGContext)
292 {
293 EAGLContext* aGLCtx = myGlContext->myGContext;
294 CAEAGLLayer* anEaglLayer = (CAEAGLLayer* )myUIView.layer;
295 GLuint aWinRBColor = 0;
296 ::glGenRenderbuffers (1, &aWinRBColor);
297 ::glBindRenderbuffer (GL_RENDERBUFFER, aWinRBColor);
298 [aGLCtx renderbufferStorage: GL_RENDERBUFFER fromDrawable: anEaglLayer];
299 ::glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &myWidth);
300 ::glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &myHeight);
301 ::glBindRenderbuffer (GL_RENDERBUFFER, 0);
302
303 if (!aDefFbo->InitWithRB (myGlContext, myWidth, myHeight, aWinRBColor))
304 {
305 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed");
306 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
307 return;
308 }
309 }
310 else
311 {
312 if (!aDefFbo->InitWrapper (myGlContext))
313 {
314 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO wrapper creation failed");
315 Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
316 return;
317 }
4fe56619 318
a2e4f780 319 myWidth = aDefFbo->GetVPSizeX();
320 myHeight = aDefFbo->GetVPSizeY();
321 }
322 myGlContext->SetDefaultFrameBuffer (aDefFbo);
323 aDefFbo->BindBuffer (myGlContext);
324 aDefFbo.Nullify();
325#else
326 NSOpenGLContext* aGLCtx = myGlContext->myGContext;
327 NSView* aView = [aGLCtx view];
328 NSRect aBounds = [aView bounds];
4fe56619 329
a2e4f780 330 // we should call this method each time when window is resized
331 [aGLCtx update];
4fe56619 332
a2e4f780 333 if ([aView respondsToSelector: @selector(convertSizeToBacking:)])
334 {
335 NSSize aRes = [aView convertSizeToBacking: aBounds.size];
336 myWidth = Standard_Integer(aRes.width);
337 myHeight = Standard_Integer(aRes.height);
338 }
339 else
340 {
341 myWidth = Standard_Integer(aBounds.size.width);
342 myHeight = Standard_Integer(aBounds.size.height);
343 }
344 myWidthPt = Standard_Integer(aBounds.size.width);
345 myHeightPt = Standard_Integer(aBounds.size.height);
346#endif
347
348 ::glDisable (GL_DITHER);
349 ::glDisable (GL_SCISSOR_TEST);
350 ::glViewport (0, 0, myWidth, myHeight);
351#if !defined(GL_ES_VERSION_2_0)
352 ::glDrawBuffer (GL_BACK);
353 if (myGlContext->core11 != NULL)
354 {
355 ::glMatrixMode (GL_MODELVIEW);
356 }
357#endif
4fe56619 358}
359
360#endif // __APPLE__