#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
+#ifndef GL_GLEXT_LEGACY
#define GL_GLEXT_LEGACY // To prevent inclusion of system glext.h on Mac OS X 10.6.8
+#endif
-#import <Cocoa/Cocoa.h>
+// macOS 10.4 deprecated OpenGL framework - suppress useless warnings
+#define GL_SILENCE_DEPRECATION
-#include <InterfaceGraphic.hxx>
+#import <TargetConditionals.h>
+
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ #import <UIKit/UIKit.h>
+#else
+ #import <Cocoa/Cocoa.h>
+
+#if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
+@interface NSView (LionAPI)
+- (NSSize )convertSizeToBacking: (NSSize )theSize;
+@end
+#endif
+
+#endif
#include <OpenGl_Window.hxx>
+#include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_Context.hxx>
#include <Aspect_GraphicDeviceDefinitionError.hxx>
#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
-#include <OpenGL/CGLRenderers.h>
-
-namespace
-{
- static const TEL_COLOUR THE_DEFAULT_BG_COLOR = { { 0.F, 0.F, 0.F, 1.F } };
-};
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ //
+#else
+ #include <OpenGL/CGLRenderers.h>
+#endif
// =======================================================================
// function : OpenGl_Window
// purpose :
// =======================================================================
OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver,
- const CALL_DEF_WINDOW& theCWindow,
+ const Handle(Aspect_Window)& thePlatformWindow,
Aspect_RenderingContext theGContext,
const Handle(OpenGl_Caps)& theCaps,
const Handle(OpenGl_Context)& theShareCtx)
: myGlContext (new OpenGl_Context (theCaps)),
myOwnGContext (theGContext == 0),
- myWidth ((Standard_Integer )theCWindow.dx),
- myHeight ((Standard_Integer )theCWindow.dy),
- myBgColor (THE_DEFAULT_BG_COLOR)
+ myPlatformWindow (thePlatformWindow),
+#if defined(__APPLE__) && defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ myUIView (NULL),
+#endif
+ mySwapInterval (theCaps->swapInterval)
{
- myBgColor.rgb[0] = theCWindow.Background.r;
- myBgColor.rgb[1] = theCWindow.Background.g;
- myBgColor.rgb[2] = theCWindow.Background.b;
+ (void )theDriver;
+ myPlatformWindow->Size (myWidth, myHeight);
- Cocoa_LocalPool aLocalPool;
- //NSOpenGLContext* aGContext = (NSOpenGLContext* )theGContext;
+#if defined(__APPLE__)
+ myWidthPt = myWidth;
+ myHeightPt = myHeight;
+#endif
- // all GL context within one OpenGl_GraphicDriver should be shared!
- NSOpenGLContext* aGLCtxShare = theShareCtx.IsNull() ? NULL : (NSOpenGLContext* )theShareCtx->myGContext;
- NSOpenGLContext* aGLContext = NULL;
-
- NSOpenGLPixelFormatAttribute anAttribs[32] = {};
- Standard_Integer aLastAttrib = 0;
- //anAttribs[aLastAttrib++] = NSOpenGLPFAColorSize; anAttribs[aLastAttrib++] = 32,
- anAttribs[aLastAttrib++] = NSOpenGLPFADepthSize; anAttribs[aLastAttrib++] = 24;
- anAttribs[aLastAttrib++] = NSOpenGLPFAStencilSize; anAttribs[aLastAttrib++] = 8;
- anAttribs[aLastAttrib++] = NSOpenGLPFADoubleBuffer;
- if (theCaps->contextNoAccel)
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ EAGLContext* aGLContext = theGContext;
+ if (aGLContext == NULL)
{
- anAttribs[aLastAttrib++] = NSOpenGLPFARendererID;
- anAttribs[aLastAttrib++] = (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID;
+ void* aViewPtr = (void* )myPlatformWindow->NativeHandle();
+
+ myUIView = (__bridge UIView* )aViewPtr;
+ CAEAGLLayer* anEaglLayer = (CAEAGLLayer* )myUIView.layer;
+ anEaglLayer.opaque = TRUE;
+ anEaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool: FALSE], kEAGLDrawablePropertyRetainedBacking,
+ kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
+ NULL];
+
+ aGLContext = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
+ if (aGLContext == NULL
+ || ![EAGLContext setCurrentContext: aGLContext])
+ {
+ TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext creation failed");
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
+ return;
+ }
+
+ myGlContext->Init (aGLContext, Standard_False);
}
else
{
- anAttribs[aLastAttrib++] = NSOpenGLPFAAccelerated;
+ if (![EAGLContext setCurrentContext: aGLContext])
+ {
+ TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext can not be assigned");
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
+ return;
+ }
+
+ myGlContext->Init (aGLContext, Standard_False);
}
- anAttribs[aLastAttrib] = 0;
- const Standard_Integer aLastMainAttrib = aLastAttrib;
- Standard_Integer aTryCore = 0;
- Standard_Integer aTryStereo = 0;
- for (aTryCore = 1; aTryCore >= 0; --aTryCore)
+#else
+
+ Cocoa_LocalPool aLocalPool;
+
+ // all GL context within one OpenGl_GraphicDriver should be shared!
+ NSOpenGLContext* aGLCtxShare = theShareCtx.IsNull() ? NULL : theShareCtx->myGContext;
+ NSOpenGLContext* aGLContext = theGContext;
+ bool isCore = false;
+ if (aGLContext == NULL)
{
- aLastAttrib = aLastMainAttrib;
- if (aTryCore == 1)
+ NSOpenGLPixelFormatAttribute anAttribs[32] = {};
+ Standard_Integer aLastAttrib = 0;
+ //anAttribs[aLastAttrib++] = NSOpenGLPFAColorSize; anAttribs[aLastAttrib++] = 32,
+ anAttribs[aLastAttrib++] = NSOpenGLPFADepthSize; anAttribs[aLastAttrib++] = 24;
+ anAttribs[aLastAttrib++] = NSOpenGLPFAStencilSize; anAttribs[aLastAttrib++] = 8;
+ anAttribs[aLastAttrib++] = NSOpenGLPFADoubleBuffer;
+ if (theCaps->contextNoAccel)
{
- if (theCaps->contextCompatible)
- {
- continue;
- }
-
- // supported since OS X 10.7+
- anAttribs[aLastAttrib++] = 99; // NSOpenGLPFAOpenGLProfile
- anAttribs[aLastAttrib++] = 0x3200; // NSOpenGLProfileVersion3_2Core
+ anAttribs[aLastAttrib++] = NSOpenGLPFARendererID;
+ anAttribs[aLastAttrib++] = (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID;
}
-
- for (aTryStereo = 1; aTryStereo >= 0; --aTryStereo)
+ else
{
- if (aTryStereo == 1)
+ anAttribs[aLastAttrib++] = NSOpenGLPFAAccelerated;
+ }
+ anAttribs[aLastAttrib] = 0;
+ const Standard_Integer aLastMainAttrib = aLastAttrib;
+ Standard_Integer aTryCore = 0;
+ Standard_Integer aTryStereo = 0;
+ for (aTryCore = 1; aTryCore >= 0; --aTryCore)
+ {
+ aLastAttrib = aLastMainAttrib;
+ if (aTryCore == 1)
{
- if (!theCaps->contextStereo)
+ if (theCaps->contextCompatible)
{
continue;
}
- anAttribs[aLastAttrib++] = NSOpenGLPFAStereo;
+
+ // supported since OS X 10.7+
+ anAttribs[aLastAttrib++] = 99; // NSOpenGLPFAOpenGLProfile
+ anAttribs[aLastAttrib++] = 0x3200; // NSOpenGLProfileVersion3_2Core
}
- anAttribs[aLastAttrib] = 0;
+ for (aTryStereo = 1; aTryStereo >= 0; --aTryStereo)
+ {
+ if (aTryStereo == 1)
+ {
+ if (!theCaps->contextStereo)
+ {
+ continue;
+ }
+
+ // deprecated since macOS 10.12 without replacement
+ Standard_DISABLE_DEPRECATION_WARNINGS
+ anAttribs[aLastAttrib++] = NSOpenGLPFAStereo;
+ Standard_ENABLE_DEPRECATION_WARNINGS
+ }
+
+ anAttribs[aLastAttrib] = 0;
+
+ NSOpenGLPixelFormat* aGLFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease];
+ aGLContext = [[NSOpenGLContext alloc] initWithFormat: aGLFormat
+ shareContext: aGLCtxShare];
+ if (aGLContext != NULL)
+ {
+ break;
+ }
+ }
- NSOpenGLPixelFormat* aGLFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes: anAttribs] autorelease];
- aGLContext = [[NSOpenGLContext alloc] initWithFormat: aGLFormat
- shareContext: aGLCtxShare];
if (aGLContext != NULL)
{
break;
}
}
- if (aGLContext != NULL)
+ if (aGLContext == NULL)
{
- break;
+ TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: NSOpenGLContext creation failed");
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
+ return;
}
- }
- if (aGLContext == NULL)
- {
- TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: NSOpenGLContext creation failed");
- Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
- return;
- }
+ if (aTryStereo == 0
+ && theCaps->contextStereo)
+ {
+ TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: QuadBuffer is unavailable!");
+ myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
+ }
+ if (aTryCore == 0
+ && !theCaps->contextCompatible)
+ {
+ TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed.");
+ myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
+ }
- if (aTryStereo == 0
- && theCaps->contextStereo)
- {
- TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: QuadBuffer is unavailable!");
- myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
- }
- if (aTryCore == 0
- && !theCaps->contextCompatible)
- {
- TCollection_ExtendedString aMsg("OpenGl_Window::CreateWindow: core profile creation failed.");
- myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
+ NSView* aView = (NSView* )myPlatformWindow->NativeHandle();
+ [aGLContext setView: aView];
+ isCore = (aTryCore == 1);
}
- NSView* aView = (NSView* )theCWindow.XWindow;
- [aGLContext setView: aView];
+ myGlContext->Init (aGLContext, isCore);
+#endif
- myGlContext->Init (aGLContext, aTryCore == 1);
myGlContext->Share (theShareCtx);
+ myGlContext->SetSwapInterval (mySwapInterval);
Init();
}
// =======================================================================
OpenGl_Window::~OpenGl_Window()
{
- NSOpenGLContext* aGLCtx = (NSOpenGLContext* )myGlContext->myGContext;
+ if (!myOwnGContext
+ || myGlContext.IsNull())
+ {
+ myGlContext.Nullify();
+ return;
+ }
+
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ myGlContext.Nullify();
+ [EAGLContext setCurrentContext: NULL];
+ myUIView = NULL;
+#else
+ NSOpenGLContext* aGLCtx = myGlContext->myGContext;
myGlContext.Nullify();
[NSOpenGLContext clearCurrentContext];
- if (myOwnGContext)
- {
- [aGLCtx clearDrawable];
- [aGLCtx release];
- }
+ [aGLCtx clearDrawable];
+ [aGLCtx release];
+#endif
}
// =======================================================================
// function : Resize
// purpose : call_subr_resize
// =======================================================================
-void OpenGl_Window::Resize (const CALL_DEF_WINDOW& theCWindow)
+void OpenGl_Window::Resize()
{
// If the size is not changed - do nothing
- if (myWidth == (Standard_Integer )theCWindow.dx
- && myHeight == (Standard_Integer )theCWindow.dy)
+ Standard_Integer aWidthPt = 0;
+ Standard_Integer aHeightPt = 0;
+ myPlatformWindow->Size (aWidthPt, aHeightPt);
+ if (myWidthPt == aWidthPt
+ && myHeightPt == aHeightPt)
{
+ #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
return;
+ #else
+ // check backing store change (moving to another screen)
+ NSOpenGLContext* aGLCtx = myGlContext->myGContext;
+ NSView* aView = [aGLCtx view];
+ if (![aView respondsToSelector: @selector(convertSizeToBacking:)])
+ {
+ return;
+ }
+
+ NSRect aBounds = [aView bounds];
+ NSSize aRes = [aView convertSizeToBacking: aBounds.size];
+ if (myWidth == Standard_Integer(aRes.width)
+ && myHeight == Standard_Integer(aRes.height))
+ {
+ return;
+ }
+ #endif
}
- myWidth = (Standard_Integer )theCWindow.dx;
- myHeight = (Standard_Integer )theCWindow.dy;
+ myWidthPt = aWidthPt;
+ myHeightPt = aHeightPt;
Init();
}
return;
}
- NSOpenGLContext* aGLCtx = (NSOpenGLContext* )myGlContext->myGContext;
- NSRect aBounds = [[aGLCtx view] bounds];
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+ Handle(OpenGl_FrameBuffer) aDefFbo = myGlContext->SetDefaultFrameBuffer (NULL);
+ if (!aDefFbo.IsNull())
+ {
+ aDefFbo->Release (myGlContext.operator->());
+ }
+ else
+ {
+ aDefFbo = new OpenGl_FrameBuffer();
+ }
+
+ if (myOwnGContext)
+ {
+ EAGLContext* aGLCtx = myGlContext->myGContext;
+ CAEAGLLayer* anEaglLayer = (CAEAGLLayer* )myUIView.layer;
+ GLuint aWinRBColor = 0;
+ ::glGenRenderbuffers (1, &aWinRBColor);
+ ::glBindRenderbuffer (GL_RENDERBUFFER, aWinRBColor);
+ [aGLCtx renderbufferStorage: GL_RENDERBUFFER fromDrawable: anEaglLayer];
+ ::glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &myWidth);
+ ::glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &myHeight);
+ ::glBindRenderbuffer (GL_RENDERBUFFER, 0);
+
+ if (!aDefFbo->InitWithRB (myGlContext, myWidth, myHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, aWinRBColor))
+ {
+ TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed");
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
+ return;
+ }
+ }
+ else
+ {
+ if (!aDefFbo->InitWrapper (myGlContext))
+ {
+ TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO wrapper creation failed");
+ throw Aspect_GraphicDeviceDefinitionError(aMsg.ToCString());
+ return;
+ }
+
+ myWidth = aDefFbo->GetVPSizeX();
+ myHeight = aDefFbo->GetVPSizeY();
+ }
+ myGlContext->SetDefaultFrameBuffer (aDefFbo);
+ aDefFbo->BindBuffer (myGlContext);
+ aDefFbo.Nullify();
+#else
+ NSOpenGLContext* aGLCtx = myGlContext->myGContext;
+ NSView* aView = [aGLCtx view];
+ NSRect aBounds = [aView bounds];
// we should call this method each time when window is resized
[aGLCtx update];
- myWidth = Standard_Integer(aBounds.size.width);
- myHeight = Standard_Integer(aBounds.size.height);
-
- glMatrixMode (GL_MODELVIEW);
- glViewport (0, 0, myWidth, myHeight);
+ if ([aView respondsToSelector: @selector(convertSizeToBacking:)])
+ {
+ NSSize aRes = [aView convertSizeToBacking: aBounds.size];
+ myWidth = Standard_Integer(aRes.width);
+ myHeight = Standard_Integer(aRes.height);
+ }
+ else
+ {
+ myWidth = Standard_Integer(aBounds.size.width);
+ myHeight = Standard_Integer(aBounds.size.height);
+ }
+ myWidthPt = Standard_Integer(aBounds.size.width);
+ myHeightPt = Standard_Integer(aBounds.size.height);
+#endif
+
+ ::glDisable (GL_DITHER);
+ ::glDisable (GL_SCISSOR_TEST);
+ ::glViewport (0, 0, myWidth, myHeight);
+#if !defined(GL_ES_VERSION_2_0)
+ ::glDrawBuffer (GL_BACK);
+ if (myGlContext->core11 != NULL)
+ {
+ ::glMatrixMode (GL_MODELVIEW);
+ }
+#endif
+}
- glDisable (GL_SCISSOR_TEST);
- glDrawBuffer (GL_BACK);
+// =======================================================================
+// function : SetSwapInterval
+// purpose :
+// =======================================================================
+void OpenGl_Window::SetSwapInterval()
+{
+ if (mySwapInterval != myGlContext->caps->swapInterval)
+ {
+ mySwapInterval = myGlContext->caps->swapInterval;
+ myGlContext->SetSwapInterval (mySwapInterval);
+ }
}
#endif // __APPLE__