0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[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
b69e576a 16#if defined(__APPLE__) && !defined(HAVE_XLIB)
4fe56619 17
896faa72 18#ifndef GL_GLEXT_LEGACY
0e9d3b83 19#define GL_GLEXT_LEGACY // To prevent inclusion of system glext.h on Mac OS X 10.6.8
896faa72 20#endif
0e9d3b83 21
42451ec0 22// macOS 10.4 deprecated OpenGL framework - suppress useless warnings
23#define GL_SILENCE_DEPRECATION
24
a2e4f780 25#import <TargetConditionals.h>
26
27#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
28 #import <UIKit/UIKit.h>
29#else
30 #import <Cocoa/Cocoa.h>
31
32#if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
33@interface NSView (LionAPI)
34- (NSSize )convertSizeToBacking: (NSSize )theSize;
35@end
36#endif
37
38#endif
4fe56619 39
4fe56619 40#include <OpenGl_Window.hxx>
a2e4f780 41#include <OpenGl_FrameBuffer.hxx>
4fe56619 42
43#include <OpenGl_Context.hxx>
4fe56619 44#include <Aspect_GraphicDeviceDefinitionError.hxx>
45#include <Cocoa_LocalPool.hxx>
46#include <TCollection_AsciiString.hxx>
4e1523ef 47#include <TCollection_ExtendedString.hxx>
4fe56619 48
a2e4f780 49#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
50 //
51#else
52 #include <OpenGL/CGLRenderers.h>
53#endif
abe46077 54
4fe56619 55// =======================================================================
56// function : OpenGl_Window
57// purpose :
58// =======================================================================
879768fb 59OpenGl_Window::OpenGl_Window()
60: myOwnGContext (false),
61 mySwapInterval (0)
62{
63 //
64}
65
66// =======================================================================
67// function : Init
68// purpose :
69// =======================================================================
70void OpenGl_Window::Init (const Handle(OpenGl_GraphicDriver)& theDriver,
71 const Handle(Aspect_Window)& thePlatformWindow,
72 const Handle(Aspect_Window)& theSizeWindow,
73 Aspect_RenderingContext theGContext,
74 const Handle(OpenGl_Caps)& theCaps,
75 const Handle(OpenGl_Context)& theShareCtx)
76{
77 myGlContext = new OpenGl_Context (theCaps);
78 myOwnGContext = (theGContext == 0);
79 myPlatformWindow = thePlatformWindow;
80 mySizeWindow = theSizeWindow;
c357e426 81#if defined(__APPLE__) && defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
879768fb 82 myUIView = NULL;
a2e4f780 83#endif
879768fb 84 mySwapInterval = theCaps->swapInterval;
85
5ef127d0 86 (void )theDriver;
879768fb 87 mySizeWindow->Size (mySize.x(), mySize.y());
c357e426 88
89#if defined(__APPLE__)
879768fb 90 mySizePt = mySize;
c357e426 91#endif
4fe56619 92
a2e4f780 93#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
94 EAGLContext* aGLContext = theGContext;
95 if (aGLContext == NULL)
4e1523ef 96 {
c357e426 97 void* aViewPtr = (void* )myPlatformWindow->NativeHandle();
a2e4f780 98
99 myUIView = (__bridge UIView* )aViewPtr;
100 CAEAGLLayer* anEaglLayer = (CAEAGLLayer* )myUIView.layer;
101 anEaglLayer.opaque = TRUE;
102 anEaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
103 [NSNumber numberWithBool: FALSE], kEAGLDrawablePropertyRetainedBacking,
104 kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
105 NULL];
106
c68c346d 107 aGLContext = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES3];
a2e4f780 108 if (aGLContext == NULL
109 || ![EAGLContext setCurrentContext: aGLContext])
110 {
c68c346d 111 aGLContext = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
112
113 if (aGLContext == NULL
114 || ![EAGLContext setCurrentContext: aGLContext])
115 {
116 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext creation failed");
117 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
c68c346d 118 }
a2e4f780 119 }
120
121 myGlContext->Init (aGLContext, Standard_False);
4e1523ef 122 }
123 else
abe46077 124 {
a2e4f780 125 if (![EAGLContext setCurrentContext: aGLContext])
126 {
127 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext can not be assigned");
9775fa61 128 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
a2e4f780 129 }
130
131 myGlContext->Init (aGLContext, Standard_False);
4e1523ef 132 }
a2e4f780 133#else
134
135 Cocoa_LocalPool aLocalPool;
136
137 // all GL context within one OpenGl_GraphicDriver should be shared!
138 NSOpenGLContext* aGLCtxShare = theShareCtx.IsNull() ? NULL : theShareCtx->myGContext;
139 NSOpenGLContext* aGLContext = theGContext;
140 bool isCore = false;
141 if (aGLContext == NULL)
4e1523ef 142 {
a2e4f780 143 NSOpenGLPixelFormatAttribute anAttribs[32] = {};
144 Standard_Integer aLastAttrib = 0;
145 //anAttribs[aLastAttrib++] = NSOpenGLPFAColorSize; anAttribs[aLastAttrib++] = 32,
146 anAttribs[aLastAttrib++] = NSOpenGLPFADepthSize; anAttribs[aLastAttrib++] = 24;
147 anAttribs[aLastAttrib++] = NSOpenGLPFAStencilSize; anAttribs[aLastAttrib++] = 8;
148 anAttribs[aLastAttrib++] = NSOpenGLPFADoubleBuffer;
149 if (theCaps->contextNoAccel)
4e1523ef 150 {
a2e4f780 151 anAttribs[aLastAttrib++] = NSOpenGLPFARendererID;
152 anAttribs[aLastAttrib++] = (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID;
4e1523ef 153 }
a2e4f780 154 else
155 {
156 anAttribs[aLastAttrib++] = NSOpenGLPFAAccelerated;
157 }
158 anAttribs[aLastAttrib] = 0;
159 const Standard_Integer aLastMainAttrib = aLastAttrib;
160 Standard_Integer aTryCore = 0;
161 Standard_Integer aTryStereo = 0;
162 for (aTryCore = 1; aTryCore >= 0; --aTryCore)
4e1523ef 163 {
a2e4f780 164 aLastAttrib = aLastMainAttrib;
165 if (aTryCore == 1)
4e1523ef 166 {
a2e4f780 167 if (theCaps->contextCompatible)
4e1523ef 168 {
169 continue;
170 }
a2e4f780 171
172 // supported since OS X 10.7+
173 anAttribs[aLastAttrib++] = 99; // NSOpenGLPFAOpenGLProfile
174 anAttribs[aLastAttrib++] = 0x3200; // NSOpenGLProfileVersion3_2Core
4e1523ef 175 }
176
a2e4f780 177 for (aTryStereo = 1; aTryStereo >= 0; --aTryStereo)
178 {
179 if (aTryStereo == 1)
180 {
181 if (!theCaps->contextStereo)
182 {
183 continue;
184 }
e2b4dea2 185
186 // deprecated since macOS 10.12 without replacement
187 Standard_DISABLE_DEPRECATION_WARNINGS
a2e4f780 188 anAttribs[aLastAttrib++] = NSOpenGLPFAStereo;
e2b4dea2 189 Standard_ENABLE_DEPRECATION_WARNINGS
a2e4f780 190 }
191
192 anAttribs[aLastAttrib] = 0;
193
194 NSOpenGLPixelFormat* aGLFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease];
195 aGLContext = [[NSOpenGLContext alloc] initWithFormat: aGLFormat
196 shareContext: aGLCtxShare];
197 if (aGLContext != NULL)
198 {
199 break;
200 }
201 }
4e1523ef 202
4e1523ef 203 if (aGLContext != NULL)
204 {
205 break;
206 }
207 }
208
a2e4f780 209 if (aGLContext == NULL)
4e1523ef 210 {
a2e4f780 211 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: NSOpenGLContext creation failed");
9775fa61 212 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
4e1523ef 213 }
4e1523ef 214
a2e4f780 215 if (aTryStereo == 0
216 && theCaps->contextStereo)
217 {
218 TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: QuadBuffer is unavailable!");
3b523c4c 219 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
a2e4f780 220 }
221 if (aTryCore == 0
222 && !theCaps->contextCompatible)
223 {
224 TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed.");
3b523c4c 225 myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
a2e4f780 226 }
4fe56619 227
c357e426 228 NSView* aView = (NSView* )myPlatformWindow->NativeHandle();
e2d6f0e3 229 Standard_DISABLE_DEPRECATION_WARNINGS
a2e4f780 230 [aGLContext setView: aView];
e2d6f0e3 231 Standard_ENABLE_DEPRECATION_WARNINGS
a2e4f780 232 isCore = (aTryCore == 1);
4e1523ef 233 }
234
a2e4f780 235 myGlContext->Init (aGLContext, isCore);
236#endif
4fe56619 237
4fe56619 238 myGlContext->Share (theShareCtx);
f978241f 239 myGlContext->SetSwapInterval (mySwapInterval);
879768fb 240 init();
4fe56619 241}
242
243// =======================================================================
244// function : ~OpenGl_Window
245// purpose :
246// =======================================================================
247OpenGl_Window::~OpenGl_Window()
248{
a2e4f780 249 if (!myOwnGContext
250 || myGlContext.IsNull())
251 {
252 myGlContext.Nullify();
253 return;
254 }
255
256#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
257 myGlContext.Nullify();
258 [EAGLContext setCurrentContext: NULL];
259 myUIView = NULL;
260#else
261 NSOpenGLContext* aGLCtx = myGlContext->myGContext;
4fe56619 262 myGlContext.Nullify();
263
264 [NSOpenGLContext clearCurrentContext];
a2e4f780 265 [aGLCtx clearDrawable];
266 [aGLCtx release];
267#endif
4fe56619 268}
269
270// =======================================================================
271// function : Resize
272// purpose : call_subr_resize
273// =======================================================================
c357e426 274void OpenGl_Window::Resize()
4fe56619 275{
4fe56619 276 // If the size is not changed - do nothing
812afe4e 277 Graphic3d_Vec2i aWinSize;
278 mySizeWindow->Size (aWinSize.x(), aWinSize.y());
279 if (myPlatformWindow->IsVirtual()
280 || mySizeWindow != myPlatformWindow)
281 {
282 if (mySize == aWinSize)
283 {
284 return;
285 }
286 mySize = aWinSize;
287 }
288 else if (mySizePt == aWinSize)
4fe56619 289 {
5501f9a9 290 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
4fe56619 291 return;
5501f9a9 292 #else
293 // check backing store change (moving to another screen)
294 NSOpenGLContext* aGLCtx = myGlContext->myGContext;
e2d6f0e3 295 Standard_DISABLE_DEPRECATION_WARNINGS
5501f9a9 296 NSView* aView = [aGLCtx view];
e2d6f0e3 297 Standard_ENABLE_DEPRECATION_WARNINGS
5501f9a9 298 if (![aView respondsToSelector: @selector(convertSizeToBacking:)])
299 {
300 return;
301 }
302
303 NSRect aBounds = [aView bounds];
304 NSSize aRes = [aView convertSizeToBacking: aBounds.size];
879768fb 305 if (mySize.x() == Standard_Integer(aRes.width)
306 && mySize.y() == Standard_Integer(aRes.height))
5501f9a9 307 {
308 return;
309 }
310 #endif
4fe56619 311 }
312
812afe4e 313 mySizePt = aWinSize;
4fe56619 314
879768fb 315 init();
4fe56619 316}
317
318// =======================================================================
879768fb 319// function : init
4fe56619 320// purpose :
321// =======================================================================
879768fb 322void OpenGl_Window::init()
4fe56619 323{
324 if (!Activate())
325 {
326 return;
327 }
328
a2e4f780 329#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
330 Handle(OpenGl_FrameBuffer) aDefFbo = myGlContext->SetDefaultFrameBuffer (NULL);
331 if (!aDefFbo.IsNull())
332 {
333 aDefFbo->Release (myGlContext.operator->());
334 }
335 else
336 {
337 aDefFbo = new OpenGl_FrameBuffer();
338 }
4fe56619 339
a2e4f780 340 if (myOwnGContext)
341 {
342 EAGLContext* aGLCtx = myGlContext->myGContext;
343 CAEAGLLayer* anEaglLayer = (CAEAGLLayer* )myUIView.layer;
344 GLuint aWinRBColor = 0;
4d476dd2 345 myGlContext->Functions()->glGenRenderbuffers (1, &aWinRBColor);
346 myGlContext->Functions()->glBindRenderbuffer (GL_RENDERBUFFER, aWinRBColor);
a2e4f780 347 [aGLCtx renderbufferStorage: GL_RENDERBUFFER fromDrawable: anEaglLayer];
879768fb 348 myGlContext->Functions()->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mySize.x());
349 myGlContext->Functions()->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mySize.y());
4d476dd2 350 myGlContext->Functions()->glBindRenderbuffer (GL_RENDERBUFFER, 0);
a2e4f780 351
879768fb 352 if (!aDefFbo->InitWithRB (myGlContext, mySize, GL_RGBA8, GL_DEPTH24_STENCIL8, aWinRBColor))
a2e4f780 353 {
354 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed");
9775fa61 355 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
a2e4f780 356 return;
357 }
358 }
359 else
360 {
361 if (!aDefFbo->InitWrapper (myGlContext))
362 {
363 TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO wrapper creation failed");
9775fa61 364 throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
a2e4f780 365 return;
366 }
4fe56619 367
879768fb 368 mySize.x() = aDefFbo->GetVPSizeX();
369 mySize.y() = aDefFbo->GetVPSizeY();
a2e4f780 370 }
371 myGlContext->SetDefaultFrameBuffer (aDefFbo);
372 aDefFbo->BindBuffer (myGlContext);
373 aDefFbo.Nullify();
374#else
812afe4e 375 if (!myPlatformWindow->IsVirtual()
376 && mySizeWindow == myPlatformWindow)
377 {
378 NSOpenGLContext* aGLCtx = myGlContext->myGContext;
379 Standard_DISABLE_DEPRECATION_WARNINGS
380 NSView* aView = [aGLCtx view];
381 Standard_ENABLE_DEPRECATION_WARNINGS
382 NSRect aBounds = [aView bounds];
4fe56619 383
812afe4e 384 // we should call this method each time when window is resized
385 [aGLCtx update];
4fe56619 386
812afe4e 387 if ([aView respondsToSelector: @selector(convertSizeToBacking:)])
388 {
389 NSSize aRes = [aView convertSizeToBacking: aBounds.size];
390 mySize.x() = Standard_Integer(aRes.width);
391 mySize.y() = Standard_Integer(aRes.height);
392 }
393 else
394 {
395 mySize.x() = Standard_Integer(aBounds.size.width);
396 mySize.y() = Standard_Integer(aBounds.size.height);
397 }
398 mySizePt.x() = Standard_Integer(aBounds.size.width);
399 mySizePt.y() = Standard_Integer(aBounds.size.height);
a2e4f780 400 }
a2e4f780 401#endif
402
4d476dd2 403 myGlContext->core11fwd->glDisable (GL_DITHER);
404 myGlContext->core11fwd->glDisable (GL_SCISSOR_TEST);
812afe4e 405 const Standard_Integer aViewport[4] = { 0, 0, mySize.x(), mySize.y() };
406 myGlContext->ResizeViewport (aViewport);
407 myGlContext->SetDrawBuffer (GL_BACK);
408 if (myGlContext->core11ffp != NULL)
a2e4f780 409 {
812afe4e 410 myGlContext->core11ffp->glMatrixMode (GL_MODELVIEW);
a2e4f780 411 }
4fe56619 412}
413
c357e426 414// =======================================================================
415// function : SetSwapInterval
416// purpose :
417// =======================================================================
b40cdc2b 418void OpenGl_Window::SetSwapInterval (Standard_Boolean theToForceNoSync)
c357e426 419{
b40cdc2b 420 const Standard_Integer aSwapInterval = theToForceNoSync ? 0 : myGlContext->caps->swapInterval;
421 if (mySwapInterval != aSwapInterval)
c357e426 422 {
b40cdc2b 423 mySwapInterval = aSwapInterval;
c357e426 424 myGlContext->SetSwapInterval (mySwapInterval);
425 }
426}
427
4fe56619 428#endif // __APPLE__