From a2e4f780c213d38362cce3f739ef9104fab1e7b0 Mon Sep 17 00:00:00 2001 From: kgv Date: Thu, 2 Apr 2015 16:28:54 +0300 Subject: [PATCH] 0025973: Visualization, TKOpenGl - support EAGLContext as alternative to NSOpenGLContext OpenGl_FrameBuffer::InitWithRB() - add method to initialize FBO with Render Buffer Objects. OpenGl_FrameBuffer::InitWrapper() - add new method to initialize FBO from currently bound in context. Aspect_RenderingContext - define type explicitly to EAGLContext* / NSOpenGLContext* for ARC. OpenGl_Window - allow initialization from alien context for OS X / iOS. --- src/Aspect/Aspect_RenderingContext.hxx | 22 +- src/Cocoa/Cocoa_LocalPool.hxx | 18 +- src/Cocoa/Cocoa_LocalPool.mm | 19 +- src/Cocoa/Cocoa_Window.hxx | 43 ++- src/Cocoa/Cocoa_Window.mm | 98 +++++- .../NCollection_WinHeapAllocator.cxx | 2 +- src/OpenGl/FILES | 1 + src/OpenGl/Handle_OpenGl_FrameBuffer.hxx | 22 ++ src/OpenGl/OpenGl_Context.cxx | 36 +- src/OpenGl/OpenGl_Context.hxx | 49 ++- src/OpenGl/OpenGl_Context_1.mm | 47 ++- src/OpenGl/OpenGl_FrameBuffer.cxx | 167 ++++++++- src/OpenGl/OpenGl_FrameBuffer.hxx | 37 +- src/OpenGl/OpenGl_GlFunctions.hxx | 18 +- src/OpenGl/OpenGl_Window.hxx | 23 +- src/OpenGl/OpenGl_Window_1.mm | 324 +++++++++++++----- src/OpenGl/OpenGl_Workspace.cxx | 27 ++ src/Visual3d/Visual3d_ViewManager.cxx | 12 +- 18 files changed, 819 insertions(+), 146 deletions(-) create mode 100644 src/OpenGl/Handle_OpenGl_FrameBuffer.hxx diff --git a/src/Aspect/Aspect_RenderingContext.hxx b/src/Aspect/Aspect_RenderingContext.hxx index 0e55dfd50a..55b5e7c371 100644 --- a/src/Aspect/Aspect_RenderingContext.hxx +++ b/src/Aspect/Aspect_RenderingContext.hxx @@ -22,7 +22,25 @@ #ifndef _Aspect_RenderingContext_HeaderFile #define _Aspect_RenderingContext_HeaderFile - typedef void* Aspect_RenderingContext; /* GLXContext under UNIX */ - /* HGLRC under WNT */ +#if defined(__APPLE__) && !defined(MACOSX_USE_GLX) + #import + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #ifdef __OBJC__ + @class EAGLContext; + #else + struct EAGLContext; + #endif + typedef EAGLContext* Aspect_RenderingContext; + #else + #ifdef __OBJC__ + @class NSOpenGLContext; + #else + struct NSOpenGLContext; + #endif + typedef NSOpenGLContext* Aspect_RenderingContext; + #endif +#else + typedef void* Aspect_RenderingContext; // GLXContext under UNIX +#endif #endif /* _Aspect_RenderingContext_HeaderFile */ diff --git a/src/Cocoa/Cocoa_LocalPool.hxx b/src/Cocoa/Cocoa_LocalPool.hxx index b5667c49c0..8c8d0d79df 100644 --- a/src/Cocoa/Cocoa_LocalPool.hxx +++ b/src/Cocoa/Cocoa_LocalPool.hxx @@ -14,7 +14,19 @@ #ifndef __Cocoa_LocalPool_h_ #define __Cocoa_LocalPool_h_ -//! Auxiliary class to create +#if defined(__clang__) && (__clang_major__ >= 4) && __has_feature(objc_arc) + +// @autoreleasepool should be used within ARC + +#else + +#ifdef __OBJC__ + @class NSAutoreleasePool; +#else + struct NSAutoreleasePool; +#endif + +//! Auxiliary class to create local pool. class Cocoa_LocalPool { @@ -25,8 +37,10 @@ public: private: - void* myPoolObj; + NSAutoreleasePool* myPoolObj; }; +#endif // ARC + #endif // __Cocoa_LocalPool_h_ diff --git a/src/Cocoa/Cocoa_LocalPool.mm b/src/Cocoa/Cocoa_LocalPool.mm index 0cebeef4c2..e8aa236ed8 100644 --- a/src/Cocoa/Cocoa_LocalPool.mm +++ b/src/Cocoa/Cocoa_LocalPool.mm @@ -15,7 +15,17 @@ #include -#import +#import + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #import +#else + #import +#endif + +#if defined(__clang__) && (__clang_major__ >= 4) && __has_feature(objc_arc) + // ARC +#else // ======================================================================= // function : Cocoa_LocalPool @@ -33,9 +43,10 @@ Cocoa_LocalPool::Cocoa_LocalPool() // ======================================================================= Cocoa_LocalPool::~Cocoa_LocalPool() { - NSAutoreleasePool* aPool = (NSAutoreleasePool* )myPoolObj; - //[aPool drain]; - [aPool release]; + //[myPoolObj drain]; + [myPoolObj release]; } +#endif + #endif // __APPLE__ diff --git a/src/Cocoa/Cocoa_Window.hxx b/src/Cocoa/Cocoa_Window.hxx index e01a0eb50a..9ff3d6e48e 100644 --- a/src/Cocoa/Cocoa_Window.hxx +++ b/src/Cocoa/Cocoa_Window.hxx @@ -16,12 +16,26 @@ #ifndef _Cocoa_Window_H__ #define _Cocoa_Window_H__ -#ifdef __OBJC__ - @class NSView; - @class NSWindow; +#if defined(__APPLE__) + #import +#endif + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #ifdef __OBJC__ + @class UIView; + @class UIWindow; + #else + struct UIView; + struct UIWindow; + #endif #else - struct NSView; - struct NSWindow; + #ifdef __OBJC__ + @class NSView; + @class NSWindow; + #else + struct NSView; + struct NSWindow; + #endif #endif #include @@ -56,8 +70,13 @@ public: const Standard_Integer thePxWidth, const Standard_Integer thePxHeight); +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + //! Creates a wrapper over existing UIView handle + Standard_EXPORT Cocoa_Window (UIView* theViewUI); +#else //! Creates a wrapper over existing NSView handle Standard_EXPORT Cocoa_Window (NSView* theViewNS); +#endif //! Destroies the Window and all resourses attached to it Standard_EXPORT virtual void Destroy(); @@ -95,11 +114,19 @@ public: Standard_EXPORT virtual void Size (Standard_Integer& theWidth, Standard_Integer& theHeight) const; +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + //! @return associated UIView + UIView* HView() const { return myHView; } + + //! Setup new UIView. + Standard_EXPORT void SetHView (UIView* theView); +#else //! @return associated NSView - Standard_EXPORT NSView* HView() const; + NSView* HView() const { return myHView; } //! Setup new NSView. Standard_EXPORT void SetHView (NSView* theView); +#endif //! @return native Window handle virtual Aspect_Drawable NativeHandle() const @@ -115,8 +142,12 @@ public: protected: +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + UIView* myHView; +#else NSWindow* myHWindow; NSView* myHView; +#endif Standard_Integer myXLeft; Standard_Integer myYTop; Standard_Integer myXRight; diff --git a/src/Cocoa/Cocoa_Window.mm b/src/Cocoa/Cocoa_Window.mm index 594dedd6a6..0427b0e2b4 100644 --- a/src/Cocoa/Cocoa_Window.mm +++ b/src/Cocoa/Cocoa_Window.mm @@ -13,7 +13,13 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#import +#import + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #import +#else + #import +#endif #include @@ -26,6 +32,13 @@ IMPLEMENT_STANDARD_HANDLE (Cocoa_Window, Aspect_Window) IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window, Aspect_Window) +#if defined(__clang__) && (__clang_major__ >= 4) && __has_feature(objc_arc) + #define HAVE_OBJC_ARC +#endif + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + // +#else static Standard_Integer getScreenBottom() { Cocoa_LocalPool aLocalPool; @@ -48,6 +61,7 @@ static Standard_Integer getScreenBottom() CGRect aRect = CGDisplayBounds(aDispId); return Standard_Integer(aRect.origin.y + aRect.size.height); } +#endif // ======================================================================= // function : Cocoa_Window @@ -59,13 +73,18 @@ Cocoa_Window::Cocoa_Window (const Standard_CString theTitle, const Standard_Integer thePxWidth, const Standard_Integer thePxHeight) : Aspect_Window (), +#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) myHWindow (NULL), +#endif myHView (NULL), myXLeft (thePxLeft), myYTop (thePxTop), myXRight (thePxLeft + thePxWidth), myYBottom (thePxTop + thePxHeight) { +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + // +#else if (thePxWidth <= 0 || thePxHeight <= 0) { Aspect_WindowDefinitionError::Raise ("Coordinate(s) out of range"); @@ -99,21 +118,32 @@ Cocoa_Window::Cocoa_Window (const Standard_CString theTitle, // do not destroy NSWindow on close - we didn't handle it! [myHWindow setReleasedWhenClosed: NO]; +#endif } // ======================================================================= // function : Cocoa_Window // purpose : // ======================================================================= +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +Cocoa_Window::Cocoa_Window (UIView* theViewNS) +: Aspect_Window(), +#else Cocoa_Window::Cocoa_Window (NSView* theViewNS) -: Aspect_Window (), +: Aspect_Window(), myHWindow (NULL), - myHView ([theViewNS retain]), +#endif + myHView (NULL), myXLeft (0), myYTop (0), myXRight (512), myYBottom (512) { +#if defined(HAVE_OBJC_ARC) + myHView = theViewNS; +#else + myHView = [theViewNS retain]; +#endif DoResize(); } @@ -123,45 +153,54 @@ Cocoa_Window::Cocoa_Window (NSView* theViewNS) // ======================================================================= void Cocoa_Window::Destroy() { +#if !defined(HAVE_OBJC_ARC) Cocoa_LocalPool aLocalPool; +#endif +#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) if (myHWindow != NULL) { + #if !defined(HAVE_OBJC_ARC) //[myHWindow close]; [myHWindow release]; + #endif myHWindow = NULL; } +#endif if (myHView != NULL) { + #if !defined(HAVE_OBJC_ARC) [myHView release]; + #endif myHView = NULL; } } -// ======================================================================= -// function : HView -// purpose : -// ======================================================================= -NSView* Cocoa_Window::HView() const -{ - return myHView; -} - // ======================================================================= // function : SetHView // purpose : // ======================================================================= +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +void Cocoa_Window::SetHView (UIView* theView) +{ +#else void Cocoa_Window::SetHView (NSView* theView) { if (myHWindow != NULL) { [myHWindow setContentView: theView]; } +#endif + +#if defined(HAVE_OBJC_ARC) + myHView = theView; +#else if (myHView != NULL) { [myHView release]; myHView = NULL; } myHView = [theView retain]; +#endif } // ======================================================================= @@ -175,7 +214,12 @@ Standard_Boolean Cocoa_Window::IsMapped() const return Standard_True; } - return (myHView != NULL) && [[myHView window] isVisible]; +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + return myHView != NULL; +#else + return myHView != NULL + && [[myHView window] isVisible]; +#endif } // ======================================================================= @@ -191,7 +235,11 @@ void Cocoa_Window::Map() const if (myHView != NULL) { + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + // + #else [[myHView window] orderFront: NULL]; + #endif } } @@ -203,7 +251,11 @@ void Cocoa_Window::Unmap() const { if (myHView != NULL) { + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + // + #else [[myHView window] orderOut: NULL]; + #endif } } @@ -218,7 +270,11 @@ Aspect_TypeOfResize Cocoa_Window::DoResize() const return Aspect_TOR_UNKNOWN; } +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + CGRect aBounds = [myHView bounds]; +#else NSRect aBounds = [myHView bounds]; +#endif Standard_Integer aMask = 0; Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN; @@ -267,7 +323,11 @@ Quantity_Ratio Cocoa_Window::Ratio() const return 1.0; } +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + CGRect aBounds = [myHView bounds]; +#else NSRect aBounds = [myHView bounds]; +#endif return Quantity_Ratio (aBounds.size.width / aBounds.size.height); } @@ -278,12 +338,20 @@ Quantity_Ratio Cocoa_Window::Ratio() const void Cocoa_Window::Position (Standard_Integer& X1, Standard_Integer& Y1, Standard_Integer& X2, Standard_Integer& Y2) const { +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + CGRect aBounds = [myHView bounds]; + X1 = 0; + Y1 = 0; + X2 = (Standard_Integer )aBounds.size.width; + Y2 = (Standard_Integer )aBounds.size.height; +#else NSWindow* aWindow = [myHView window]; NSRect aWindowRect = [aWindow frame]; X1 = (Standard_Integer) aWindowRect.origin.x; Y1 = getScreenBottom() - (Standard_Integer) aWindowRect.origin.y - (Standard_Integer) aWindowRect.size.height; X2 = X1 + (Standard_Integer) aWindowRect.size.width; Y2 = Y1 + (Standard_Integer) aWindowRect.size.height; +#endif } // ======================================================================= @@ -298,7 +366,11 @@ void Cocoa_Window::Size (Standard_Integer& theWidth, return; } +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + CGRect aBounds = [myHView bounds]; +#else NSRect aBounds = [myHView bounds]; +#endif theWidth = (Standard_Integer )aBounds.size.width; theHeight = (Standard_Integer )aBounds.size.height; } diff --git a/src/NCollection/NCollection_WinHeapAllocator.cxx b/src/NCollection/NCollection_WinHeapAllocator.cxx index 12c9b00427..bc8f55dbc3 100644 --- a/src/NCollection/NCollection_WinHeapAllocator.cxx +++ b/src/NCollection/NCollection_WinHeapAllocator.cxx @@ -74,7 +74,7 @@ void* NCollection_WinHeapAllocator::Allocate (const Standard_Size theSize) if (aResult == NULL) { char aBuf[128]; - Sprintf (aBuf, "Failed to allocate "PRIuPTR" bytes in local dynamic heap", theSize); + Sprintf (aBuf, "Failed to allocate " PRIuPTR " bytes in local dynamic heap", theSize); Standard_OutOfMemory::Raise (aBuf); } return aResult; diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index 9e8664d9ac..26a4872c63 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -62,6 +62,7 @@ OpenGl_Window.cxx OpenGl_Window_1.mm OpenGl_AVIWriter.hxx OpenGl_AVIWriter.cxx +Handle_OpenGl_FrameBuffer.hxx OpenGl_FrameBuffer.hxx OpenGl_FrameBuffer.cxx OpenGl_Texture.cxx diff --git a/src/OpenGl/Handle_OpenGl_FrameBuffer.hxx b/src/OpenGl/Handle_OpenGl_FrameBuffer.hxx new file mode 100644 index 0000000000..a6b8972974 --- /dev/null +++ b/src/OpenGl/Handle_OpenGl_FrameBuffer.hxx @@ -0,0 +1,22 @@ +// Copyright (c) 2015 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Handle_OpenGl_FrameBuffer_Header +#define _Handle_OpenGl_FrameBuffer_Header + +#include + +class OpenGl_FrameBuffer; +DEFINE_STANDARD_HANDLE(OpenGl_FrameBuffer, OpenGl_Resource) + +#endif // _Handle_OpenGl_FrameBuffer_Header diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index fe233622e0..277e7f6f0d 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -145,13 +146,19 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps) // Notice that GL version / extension availability checks are required // because function pointers may be available but not functionality itself // (depends on renderer). +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + myGContext = NULL; + myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGLES.framework/OpenGLES", RTLD_LAZY); +#else myGContext = NULL; myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); +#endif #else myDisplay = NULL; myWindow = 0; myGContext = 0; #endif + memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions)); myShaderManager = new OpenGl_ShaderManager (this); } @@ -176,6 +183,13 @@ OpenGl_Context::~OpenGl_Context() myDefaultVao = 0; #endif + // release default FBO + if (!myDefaultFbo.IsNull()) + { + myDefaultFbo->Release (this); + myDefaultFbo.Nullify(); + } + // release shared resources if any if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1) { @@ -681,8 +695,15 @@ Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow, const Aspect_RenderingContext theGContext, const Standard_Boolean theIsCoreProfile) #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) -Standard_Boolean OpenGl_Context::Init (const void* theGContext, + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +Standard_Boolean OpenGl_Context::Init (EAGLContext* theGContext, const Standard_Boolean theIsCoreProfile) +#else +Standard_Boolean OpenGl_Context::Init (NSOpenGLContext* theGContext, + const Standard_Boolean theIsCoreProfile) +#endif + #else Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow, const Aspect_Display theDisplay, @@ -700,7 +721,7 @@ Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow, myGContext = theGContext; myWindowDC = theWindowDC; #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) - myGContext = (void* )theGContext; + myGContext = theGContext; #else myWindow = theWindow; myGContext = theGContext; @@ -2353,6 +2374,17 @@ void OpenGl_Context::BindDefaultVao() #endif } +// ======================================================================= +// function : SetDefaultFrameBuffer +// purpose : +// ======================================================================= +Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo) +{ + Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo; + myDefaultFbo = theFbo; + return aFbo; +} + // ======================================================================= // function : SetColor4fv // purpose : diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index ecb3c36ae0..84785a614f 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -34,12 +35,28 @@ #include #include #include -#include #include #include #include //! Forward declarations +#if defined(__APPLE__) + #import + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #ifdef __OBJC__ + @class EAGLContext; + #else + struct EAGLContext; + #endif + #else + #ifdef __OBJC__ + @class NSOpenGLContext; + #else + struct NSOpenGLContext; + #endif + #endif +#endif + struct OpenGl_GlFunctions; struct OpenGl_ArbTBO; struct OpenGl_ArbIns; @@ -222,10 +239,19 @@ public: } #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) - //! Initialize class from specified OpenGL context (NSOpenGLContext). Method should be called only once. - Standard_EXPORT Standard_Boolean Init (const void* theGContext, + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + + //! Initialize class from specified OpenGL ES context (EAGLContext). Method should be called only once. + Standard_EXPORT Standard_Boolean Init (EAGLContext* theGContext, const Standard_Boolean theIsCoreProfile = Standard_False); + #else + + //! Initialize class from specified OpenGL context (NSOpenGLContext). Method should be called only once. + Standard_EXPORT Standard_Boolean Init (NSOpenGLContext* theGContext, + const Standard_Boolean theIsCoreProfile = Standard_False); + #endif #else + //! Initialize class from specified window and rendering context. Method should be called only once. //! @return false if OpenGL context can not be bound to specified window Standard_EXPORT Standard_Boolean Init (const Aspect_Drawable theWindow, @@ -501,6 +527,16 @@ public: //! @name methods to alter or retrieve current state //! Bind default Vertex Array Object Standard_EXPORT void BindDefaultVao(); + //! Default Frame Buffer Object. + const Handle(OpenGl_FrameBuffer)& DefaultFrameBuffer() const + { + return myDefaultFbo; + } + + //! Setup new Default Frame Buffer Object and return previously set. + //! This call doesn't change Active FBO! + Standard_EXPORT Handle(OpenGl_FrameBuffer) SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo); + //! Return debug context initialization state. Standard_Boolean IsDebugContext() const { @@ -576,7 +612,11 @@ private: // system-dependent fields Aspect_Handle myWindowDC; //!< Device Descriptor handle : HDC Aspect_RenderingContext myGContext; //!< Rendering Context handle : HGLRC #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) - void* myGContext; //!< Rendering Context handle : NSOpenGLContext + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + EAGLContext* myGContext; //!< Rendering Context handle + #else + NSOpenGLContext* myGContext; //!< Rendering Context handle + #endif #else Aspect_Drawable myWindow; //!< window handle (owner of GL context) : GLXDrawable Aspect_Display myDisplay; //!< connection to the X-server : Display* @@ -618,6 +658,7 @@ private: //! @name fields tracking current state Handle(OpenGl_ShaderProgram) myActiveProgram; //!< currently active GLSL program Handle(OpenGl_Sampler) myTexSampler; //!< currently active sampler object + Handle(OpenGl_FrameBuffer) myDefaultFbo; //!< default Frame Buffer Object Standard_Integer myRenderMode; //!< value for active rendering mode Standard_Integer myDrawBuffer; //!< current draw buffer unsigned int myDefaultVao; //!< default Vertex Array Object diff --git a/src/OpenGl/OpenGl_Context_1.mm b/src/OpenGl/OpenGl_Context_1.mm index 0d882741fc..345a74142a 100644 --- a/src/OpenGl/OpenGl_Context_1.mm +++ b/src/OpenGl/OpenGl_Context_1.mm @@ -17,10 +17,17 @@ #define GL_GLEXT_LEGACY // To prevent inclusion of system glext.h on Mac OS X 10.6.8 -#import +#import + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #import +#else + #import +#endif #include #include +#include #include @@ -30,8 +37,13 @@ // ======================================================================= Standard_Boolean OpenGl_Context::IsCurrent() const { +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE return myGContext != NULL - && [NSOpenGLContext currentContext] == (NSOpenGLContext* )myGContext; + && [EAGLContext currentContext] == myGContext; +#else + return myGContext != NULL + && [NSOpenGLContext currentContext] == myGContext; +#endif } // ======================================================================= @@ -46,8 +58,12 @@ Standard_Boolean OpenGl_Context::MakeCurrent() return Standard_False; } - [(NSOpenGLContext* )myGContext makeCurrentContext]; +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + return [EAGLContext setCurrentContext: myGContext] == YES; +#else + [myGContext makeCurrentContext]; return Standard_True; +#endif } // ======================================================================= @@ -56,11 +72,26 @@ Standard_Boolean OpenGl_Context::MakeCurrent() // ======================================================================= void OpenGl_Context::SwapBuffers() { - if (myGContext != NULL) + if (myGContext == NULL) { - glFinish(); - [(NSOpenGLContext* )myGContext flushBuffer]; + return; } + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + if (myDefaultFbo.IsNull() + || !myDefaultFbo->IsValid() + || myDefaultFbo->ColorRenderBuffer() == 0) + { + return; + } + + ::glBindRenderbuffer (GL_RENDERBUFFER, myDefaultFbo->ColorRenderBuffer()); + [myGContext presentRenderbuffer: GL_RENDERBUFFER]; + //::glBindRenderbuffer (GL_RENDERBUFFER, 0); +#else + glFinish(); + [myGContext flushBuffer]; +#endif } // ======================================================================= @@ -74,7 +105,11 @@ Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile) return Standard_True; } +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + myGContext = [EAGLContext currentContext]; +#else myGContext = [NSOpenGLContext currentContext]; +#endif if (myGContext == NULL) { return Standard_False; diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index 6304afdee4..6667238126 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -16,6 +16,7 @@ #include #include +#include IMPLEMENT_STANDARD_HANDLE (OpenGl_FrameBuffer, OpenGl_Resource) IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_Resource) @@ -29,6 +30,9 @@ OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat) myVPSizeY (0), myTextFormat (theTextureFormat), myGlFBufferId (NO_FRAMEBUFFER), + myGlColorRBufferId (NO_RENDERBUFFER), + myGlDepthRBufferId (NO_RENDERBUFFER), + myIsOwnBuffer (false), myColorTexture (new OpenGl_Texture()), myDepthStencilTexture (new OpenGl_Texture()) { @@ -95,6 +99,143 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo return Standard_True; } +// ======================================================================= +// function : InitWithRB +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& theGlCtx, + const GLsizei theViewportSizeX, + const GLsizei theViewportSizeY, + const GLuint theColorRBufferFromWindow) +{ + if (theGlCtx->arbFBO == NULL) + { + return Standard_False; + } + + // clean up previous state + Release (theGlCtx.operator->()); + + // setup viewport sizes as is + myVPSizeX = theViewportSizeX; + myVPSizeY = theViewportSizeY; + + // Create the render-buffers + if (theColorRBufferFromWindow != NO_RENDERBUFFER) + { + myGlColorRBufferId = theColorRBufferFromWindow; + } + else + { + theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlColorRBufferId); + theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlColorRBufferId); + theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_RGBA8, myVPSizeX, myVPSizeY); + } + + theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId); + theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId); + theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, myVPSizeX, myVPSizeY); + + theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER); + + // create FBO + theGlCtx->arbFBO->glGenFramebuffers (1, &myGlFBufferId); + theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId); + theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, myGlColorRBufferId); +#ifdef GL_DEPTH_STENCIL_ATTACHMENT + theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, myGlDepthRBufferId); +#else + theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, myGlDepthRBufferId); + theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, myGlDepthRBufferId); +#endif + if (theGlCtx->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + UnbindBuffer (theGlCtx); + Release (theGlCtx.operator->()); + return Standard_False; + } + + UnbindBuffer (theGlCtx); + return Standard_True; +} + +// ======================================================================= +// function : InitWrapper +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_FrameBuffer::InitWrapper (const Handle(OpenGl_Context)& theGlCtx) +{ + if (theGlCtx->arbFBO == NULL) + { + return Standard_False; + } + + // clean up previous state + Release (theGlCtx.operator->()); + + GLint anFbo = GLint(NO_FRAMEBUFFER); + ::glGetIntegerv (GL_FRAMEBUFFER_BINDING, &anFbo); + if (anFbo == GLint(NO_FRAMEBUFFER)) + { + return Standard_False; + } + + GLint aColorType = 0; + GLint aColorId = 0; + GLint aDepthType = 0; + GLint aDepthId = 0; + theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &aColorType); + theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &aDepthType); + + myGlFBufferId = GLuint(anFbo); + myIsOwnBuffer = false; + if (aColorType == GL_RENDERBUFFER) + { + theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &aColorId); + myGlColorRBufferId = aColorId; + } + else if (aColorType != GL_NONE) + { + TCollection_ExtendedString aMsg = "OpenGl_FrameBuffer::InitWrapper(), color attachment of unsupported type has been skipped!"; + theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + aMsg); + } + + if (aDepthType == GL_RENDERBUFFER) + { + theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &aDepthId); + myGlDepthRBufferId = aDepthId; + } + else if (aDepthType != GL_NONE) + { + TCollection_ExtendedString aMsg = "OpenGl_FrameBuffer::InitWrapper(), depth attachment of unsupported type has been skipped!"; + theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + aMsg); + } + + // retrieve dimensions + GLuint aRBuffer = myGlColorRBufferId != NO_RENDERBUFFER ? myGlColorRBufferId : myGlDepthRBufferId; + if (aRBuffer != NO_RENDERBUFFER) + { + theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, aRBuffer); + theGlCtx->arbFBO->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &myVPSizeX); + theGlCtx->arbFBO->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &myVPSizeY); + theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER); + } + + return aRBuffer != NO_RENDERBUFFER; +} + // ======================================================================= // function : Release // purpose : @@ -106,11 +247,23 @@ void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx) // application can not handle this case by exception - this is bug in code Standard_ASSERT_RETURN (theGlCtx != NULL, "OpenGl_FrameBuffer destroyed without GL context! Possible GPU memory leakage...",); - if (theGlCtx->IsValid()) + if (theGlCtx->IsValid() + && myIsOwnBuffer) { theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId); + if (myGlColorRBufferId != NO_RENDERBUFFER) + { + theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlColorRBufferId); + } + if (myGlDepthRBufferId != NO_RENDERBUFFER) + { + theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlDepthRBufferId); + } } - myGlFBufferId = NO_FRAMEBUFFER; + myGlFBufferId = NO_FRAMEBUFFER; + myGlColorRBufferId = NO_RENDERBUFFER; + myGlDepthRBufferId = NO_RENDERBUFFER; + myIsOwnBuffer = false; } myColorTexture->Release (theGlCtx); @@ -184,5 +337,13 @@ void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx) // ======================================================================= void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx) { - theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER); + if (!theGlCtx->DefaultFrameBuffer().IsNull() + && theGlCtx->DefaultFrameBuffer().operator->() != this) + { + theGlCtx->DefaultFrameBuffer()->BindBuffer (theGlCtx); + } + else + { + theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER); + } } diff --git a/src/OpenGl/OpenGl_FrameBuffer.hxx b/src/OpenGl/OpenGl_FrameBuffer.hxx index b091e50aae..65bc08b324 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.hxx +++ b/src/OpenGl/OpenGl_FrameBuffer.hxx @@ -22,6 +22,8 @@ #include #include +#include + //! Class implements FrameBuffer Object (FBO) resource //! intended for off-screen rendering. class OpenGl_FrameBuffer : public OpenGl_Resource @@ -30,7 +32,8 @@ class OpenGl_FrameBuffer : public OpenGl_Resource public: //! Helpful constants - static const GLuint NO_FRAMEBUFFER = 0; + static const GLuint NO_FRAMEBUFFER = 0; + static const GLuint NO_RENDERBUFFER = 0; public: @@ -85,6 +88,21 @@ public: const GLsizei theViewportSizeX, const GLsizei theViewportSizeY); + //! (Re-)initialize FBO with specified dimensions. + //! The Render Buffer Objects will be used for Color, Depth and Stencil attachments (as opposite to textures). + //! @param theGlCtx currently bound OpenGL context + //! @param theViewportSizeX required viewport size, the actual dimensions of FBO might be greater + //! @param theViewportSizeY required viewport size, the actual dimensions of FBO might be greater + //! @param theColorRBufferFromWindow when specified - should be ID of already initialized RB object, which will be released within this class + Standard_EXPORT Standard_Boolean InitWithRB (const Handle(OpenGl_Context)& theGlCtx, + const GLsizei theViewportSizeX, + const GLsizei theViewportSizeY, + const GLuint theColorRBufferFromWindow = 0); + + //! Initialize class from currently bound FBO. + //! Retrieved OpenGL objects will not be destroyed on Release. + Standard_EXPORT Standard_Boolean InitWrapper (const Handle(OpenGl_Context)& theGlCtx); + //! Setup viewport to render into FBO Standard_EXPORT void SetupViewport (const Handle(OpenGl_Context)& theGlCtx); @@ -116,6 +134,18 @@ public: return myDepthStencilTexture; } + //! Returns the color Render Buffer. + GLuint ColorRenderBuffer() const + { + return myGlColorRBufferId; + } + + //! Returns the depth Render Buffer. + GLuint DepthStencilRenderBuffer() const + { + return myGlDepthRBufferId; + } + protected: //! Generate textures with undefined data @@ -132,6 +162,9 @@ protected: GLsizei myVPSizeY; //!< viewport height (should be <= texture height) GLint myTextFormat; //!< GL_RGB, GL_RGBA,... GLuint myGlFBufferId; //!< FBO object ID + GLuint myGlColorRBufferId; //!< color Render Buffer object (alternative to myColorTexture) + GLuint myGlDepthRBufferId; //!< depth-stencil Render Buffer object (alternative to myDepthStencilTexture) + bool myIsOwnBuffer; //!< flag indicating that FBO should be deallocated by this class Handle(OpenGl_Texture) myColorTexture; //!< color texture object Handle(OpenGl_Texture) myDepthStencilTexture; //!< depth-stencil texture object @@ -141,6 +174,4 @@ public: }; -DEFINE_STANDARD_HANDLE(OpenGl_FrameBuffer, OpenGl_Resource) - #endif // OPENGL_FRAME_BUFFER_H diff --git a/src/OpenGl/OpenGl_GlFunctions.hxx b/src/OpenGl/OpenGl_GlFunctions.hxx index 1cc3f037cb..40a539c4c6 100644 --- a/src/OpenGl/OpenGl_GlFunctions.hxx +++ b/src/OpenGl/OpenGl_GlFunctions.hxx @@ -38,13 +38,24 @@ // include main OpenGL header provided with system #if defined(__APPLE__) - #include - #include + #import + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #include + #else + #include + #include + #endif #define __X_GL_H // prevent chaotic gl.h inclusions to avoid compile errors #elif defined(HAVE_GLES2) || defined(__ANDROID__) #include //#include +#else + #include + #include +#endif +#if defined(GL_ES_VERSION_2_0) + // define items to unify code paths with desktop OpenGL typedef double GLdouble; typedef double GLclampd; typedef uint64_t GLuint64; @@ -128,9 +139,6 @@ // GL_EXT_texture_buffer for OpenGL ES 3.1+ #define GL_TEXTURE_BUFFER_ARB 0x8C2A -#else - #include - #include #endif #if defined(__ANDROID__) diff --git a/src/OpenGl/OpenGl_Window.hxx b/src/OpenGl/OpenGl_Window.hxx index 6b6869762d..7f7dee2a71 100644 --- a/src/OpenGl/OpenGl_Window.hxx +++ b/src/OpenGl/OpenGl_Window.hxx @@ -26,6 +26,18 @@ #include +#if defined(__APPLE__) + #import +#endif + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #ifdef __OBJC__ + @class UIView; + #else + struct UIView; + #endif +#endif + //! This class represents low-level wrapper over window with GL context. //! The window itself should be provided to constructor. class OpenGl_Window : public MMgt_TShared @@ -81,8 +93,15 @@ protected: Handle(OpenGl_Context) myGlContext; Standard_Boolean myOwnGContext; //!< set to TRUE if GL context was not created by this class - Standard_Integer myWidth; //!< window width - Standard_Integer myHeight; //!< window height +#if defined(__APPLE__) +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + UIView* myUIView; +#endif + Standard_Integer myWidthPt; //!< window width in logical units + Standard_Integer myHeightPt; //!< window height in logical units +#endif + Standard_Integer myWidth; //!< window width in pixels + Standard_Integer myHeight; //!< window height in pixels TEL_COLOUR myBgColor; //!< background color public: diff --git a/src/OpenGl/OpenGl_Window_1.mm b/src/OpenGl/OpenGl_Window_1.mm index e259b0dc31..6627c7d826 100644 --- a/src/OpenGl/OpenGl_Window_1.mm +++ b/src/OpenGl/OpenGl_Window_1.mm @@ -17,11 +17,25 @@ #define GL_GLEXT_LEGACY // To prevent inclusion of system glext.h on Mac OS X 10.6.8 -#import +#import + +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #import +#else + #import + +#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 #include +#include #include #include @@ -29,12 +43,16 @@ #include #include -#include +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + // +#else + #include +#endif namespace { static const TEL_COLOUR THE_DEFAULT_BG_COLOR = { { 0.F, 0.F, 0.F, 1.F } }; -}; +} // ======================================================================= // function : OpenGl_Window @@ -47,107 +65,157 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver, const Handle(OpenGl_Context)& theShareCtx) : myGlContext (new OpenGl_Context (theCaps)), myOwnGContext (theGContext == 0), - myWidth ((Standard_Integer )theCWindow.dx), - myHeight ((Standard_Integer )theCWindow.dy), +#if defined(__APPLE__) +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + myUIView (NULL), +#endif + myWidthPt (theCWindow.dx), + myHeightPt (theCWindow.dy), +#endif + myWidth (theCWindow.dx), + myHeight (theCWindow.dy), myBgColor (THE_DEFAULT_BG_COLOR) { myBgColor.rgb[0] = theCWindow.Background.r; myBgColor.rgb[1] = theCWindow.Background.g; myBgColor.rgb[2] = theCWindow.Background.b; - Cocoa_LocalPool aLocalPool; - //NSOpenGLContext* aGContext = (NSOpenGLContext* )theGContext; - - // 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* )theCWindow.XWindow; + + 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"); + Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString()); + return; + } + + myGlContext->Init (aGLContext, Standard_False); } else { - 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 (![EAGLContext setCurrentContext: aGLContext]) { - if (theCaps->contextCompatible) - { - continue; - } - - // supported since OS X 10.7+ - anAttribs[aLastAttrib++] = 99; // NSOpenGLPFAOpenGLProfile - anAttribs[aLastAttrib++] = 0x3200; // NSOpenGLProfileVersion3_2Core + TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: EAGLContext can not be assigned"); + Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString()); + return; } - for (aTryStereo = 1; aTryStereo >= 0; --aTryStereo) + myGlContext->Init (aGLContext, Standard_False); + } +#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) + { + 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 (aTryStereo == 1) + anAttribs[aLastAttrib++] = NSOpenGLPFARendererID; + anAttribs[aLastAttrib++] = (NSOpenGLPixelFormatAttribute )kCGLRendererGenericFloatID; + } + else + { + 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; + } + anAttribs[aLastAttrib++] = NSOpenGLPFAStereo; + } + + 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"); + 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_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* )theCWindow.XWindow; + [aGLContext setView: aView]; + isCore = (aTryCore == 1); } - if (aGLContext == NULL) - { - TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: NSOpenGLContext creation failed"); - Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString()); - return; - } + myGlContext->Init (aGLContext, isCore); +#endif - 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* )theCWindow.XWindow; - [aGLContext setView: aView]; - - myGlContext->Init (aGLContext, aTryCore == 1); myGlContext->Share (theShareCtx); Init(); } @@ -158,15 +226,25 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_GraphicDriver)& theDriver, // ======================================================================= 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 } // ======================================================================= @@ -176,14 +254,14 @@ OpenGl_Window::~OpenGl_Window() void OpenGl_Window::Resize (const CALL_DEF_WINDOW& theCWindow) { // If the size is not changed - do nothing - if (myWidth == (Standard_Integer )theCWindow.dx - && myHeight == (Standard_Integer )theCWindow.dy) + if (myWidthPt == theCWindow.dx + && myHeightPt == theCWindow.dy) { return; } - myWidth = (Standard_Integer )theCWindow.dx; - myHeight = (Standard_Integer )theCWindow.dy; + myWidthPt = theCWindow.dx; + myHeightPt = theCWindow.dy; Init(); } @@ -199,20 +277,84 @@ void OpenGl_Window::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, aWinRBColor)) + { + TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO creation failed"); + Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString()); + return; + } + } + else + { + if (!aDefFbo->InitWrapper (myGlContext)) + { + TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: default FBO wrapper creation failed"); + Aspect_GraphicDeviceDefinitionError::Raise (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); + 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 - glMatrixMode (GL_MODELVIEW); - glViewport (0, 0, myWidth, myHeight); - - glDisable (GL_SCISSOR_TEST); - glDrawBuffer (GL_BACK); + ::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 } #endif // __APPLE__ diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index a911d0f293..e6088476d4 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -699,6 +699,12 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView, Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth; Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight; + if (!myGlContext->DefaultFrameBuffer().IsNull() + && myGlContext->DefaultFrameBuffer()->IsValid()) + { + myGlContext->DefaultFrameBuffer()->BindBuffer (myGlContext); + } + if (myHasFboBlit && myTransientDrawToFront) { @@ -986,6 +992,12 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView, return; } + if (!myGlContext->DefaultFrameBuffer().IsNull() + && myGlContext->DefaultFrameBuffer()->IsValid()) + { + myGlContext->DefaultFrameBuffer()->BindBuffer (myGlContext); + } + if (redrawImmediate (theCView, theCUnderLayer, theCOverLayer, NULL, Standard_True) && !myGlContext->caps->buffersNoSwap) { @@ -1021,6 +1033,11 @@ bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView, { theTargetFBO->BindBuffer (myGlContext); } + else if (!myGlContext->DefaultFrameBuffer().IsNull() + && myGlContext->DefaultFrameBuffer()->IsValid()) + { + myGlContext->DefaultFrameBuffer()->BindBuffer (myGlContext); + } else { myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); @@ -1040,6 +1057,11 @@ bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView, { theTargetFBO->BindDrawBuffer (myGlContext); } + else if (!myGlContext->DefaultFrameBuffer().IsNull() + && myGlContext->DefaultFrameBuffer()->IsValid()) + { + myGlContext->DefaultFrameBuffer()->BindDrawBuffer (myGlContext); + } else { myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); @@ -1053,6 +1075,11 @@ bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView, { theTargetFBO->BindBuffer (myGlContext); } + else if (!myGlContext->DefaultFrameBuffer().IsNull() + && myGlContext->DefaultFrameBuffer()->IsValid()) + { + myGlContext->DefaultFrameBuffer()->BindBuffer (myGlContext); + } else { myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); diff --git a/src/Visual3d/Visual3d_ViewManager.cxx b/src/Visual3d/Visual3d_ViewManager.cxx index acc6cfee52..7be1c09518 100644 --- a/src/Visual3d/Visual3d_ViewManager.cxx +++ b/src/Visual3d/Visual3d_ViewManager.cxx @@ -445,7 +445,11 @@ Standard_Boolean Visual3d_ViewManager::ViewExists (const Handle(Aspect_Window)& Aspect_Handle TheSpecifiedWindowId = THEWindow->HWindow (); #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) const Handle(Cocoa_Window) THEWindow = Handle(Cocoa_Window)::DownCast (AWindow); - NSView* TheSpecifiedWindowId = THEWindow->HView(); + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + UIView* TheSpecifiedWindowId = THEWindow->HView(); + #else + NSView* TheSpecifiedWindowId = THEWindow->HView(); + #endif #elif defined(__ANDROID__) int TheSpecifiedWindowId = -1; #else @@ -464,7 +468,11 @@ Standard_Boolean Visual3d_ViewManager::ViewExists (const Handle(Aspect_Window)& Aspect_Handle TheWindowIdOfView = theWindow->HWindow (); #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX) const Handle(Cocoa_Window) theWindow = Handle(Cocoa_Window)::DownCast (AspectWindow); - NSView* TheWindowIdOfView = theWindow->HView(); + #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + UIView* TheWindowIdOfView = theWindow->HView(); + #else + NSView* TheWindowIdOfView = theWindow->HView(); + #endif #elif defined(__ANDROID__) int TheWindowIdOfView = 0; #else