// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#include <NCollection_Mat4.hxx>
+#include <OpenGl_View.hxx>
+#include <Aspect_RenderingContext.hxx>
+#include <Aspect_Window.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_Texture2Dmanual.hxx>
+#include <Graphic3d_TextureEnv.hxx>
+#include <Graphic3d_Mat4d.hxx>
+#include <NCollection_Mat4.hxx>
#include <OpenGl_Context.hxx>
+#include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_GlCore11.hxx>
#include <OpenGl_GraduatedTrihedron.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_Texture.hxx>
-#include <OpenGl_Trihedron.hxx>
-#include <OpenGl_transform_persistence.hxx>
-#include <OpenGl_View.hxx>
-#include <OpenGl_Utils.hxx>
+#include <OpenGl_Window.hxx>
#include <OpenGl_Workspace.hxx>
+#include <OSD_Parallel.hxx>
+#include <Standard_CLocaleSentry.hxx>
-#include <Graphic3d_TextureEnv.hxx>
-#include <Graphic3d_Mat4d.hxx>
+#include "../Graphic3d/Graphic3d_Structure.pxx"
+
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView)
-IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
-
-/*----------------------------------------------------------------------*/
-
-static const Tmatrix3 myDefaultMatrix = { { 1.F, 0.F, 0.F, 0.F }, { 0.F, 1.F, 0.F, 0.F }, { 0.F, 0.F, 1.F, 0.F }, { 0.F, 0.F, 0.F, 1.F } };
-static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
-
-static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
-static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
-static const GLdouble THE_IDENTITY_MATRIX[4][4] =
-{
- {1.0, 0.0, 0.0, 0.0},
- {0.0, 1.0, 0.0, 0.0},
- {0.0, 0.0, 1.0, 0.0},
- {0.0, 0.0, 0.0, 1.0}
-};
-
-/*----------------------------------------------------------------------*/
-
-OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
- OpenGl_StateCounter* theCounter)
-: mySurfaceDetail(Visual3d_TOD_ALL),
- myBackfacing(0),
- //shield_indicator = TOn,
- //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
- //border_indicator = TOff,
- //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
- //active_status = TOn,
- myZClip(myDefaultZClip),
- myCamera(AContext.Camera),
- myFog(myDefaultFog),
- myTrihedron(NULL),
- myGraduatedTrihedron(NULL),
- myVisualization(AContext.Visualization),
- myShadingModel ((Visual3d_TypeOfModel )AContext.Model),
- myAntiAliasing(Standard_False),
- myTransPers(&myDefaultTransPers),
- myIsTransPers(Standard_False),
- myProjectionState (0),
- myModelViewState (0),
- myStateCounter (theCounter),
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
+ const Handle(OpenGl_GraphicDriver)& theDriver,
+ const Handle(OpenGl_Caps)& theCaps,
+ OpenGl_StateCounter* theCounter)
+: Graphic3d_CView (theMgr),
+ myDriver (theDriver.operator->()),
+ myCaps (theCaps),
+ myWasRedrawnGL (Standard_False),
+ myBackfacing (Graphic3d_TOBM_AUTOMATIC),
+ myToShowGradTrihedron (false),
+ myZLayers (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1),
+ myStateCounter (theCounter),
+ myCurrLightSourceState (theCounter->Increment()),
+ myLightsRevision (0),
myLastLightSourceState (0, 0),
- myModificationState (1), // initial state
- myTextureParams (new OpenGl_AspectFace()),
+ myFboColorFormat (GL_RGBA8),
+ myFboDepthFormat (GL_DEPTH24_STENCIL8),
+ myToFlipOutput (Standard_False),
+ myFrameCounter (0),
+ myHasFboBlit (Standard_True),
+ myToDisableOIT (Standard_False),
+ myToDisableOITMSAA (Standard_False),
+ myToDisableMSAA (Standard_False),
+ myTransientDrawToFront (Standard_True),
+ myBackBufferRestored (Standard_False),
+ myIsImmediateDrawn (Standard_False),
+ myTextureParams (new OpenGl_Aspects()),
myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
- myBgTextureArray (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE))
+ myBgTextureArray (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
+ // ray-tracing fields initialization
+ myRaytraceInitStatus (OpenGl_RT_NONE),
+ myIsRaytraceDataValid (Standard_False),
+ myIsRaytraceWarnTextures (Standard_False),
+ myRaytraceBVHBuilder (new BVH_BinnedBuilder<Standard_ShortReal, 3, BVH_Constants_NbBinsBest> (BVH_Constants_LeafNodeSizeAverage,
+ BVH_Constants_MaxTreeDepth,
+ Standard_False,
+ OSD_Parallel::NbLogicalProcessors() + 1)),
+ myRaytraceSceneRadius (0.0f),
+ myRaytraceSceneEpsilon (1.0e-6f),
+ myToUpdateEnvironmentMap (Standard_False),
+ myRaytraceLayerListState (0),
+ myPrevCameraApertureRadius(0.f),
+ myPrevCameraFocalPlaneDist(0.f)
{
- myCurrLightSourceState = myStateCounter->Increment();
+ myWorkspace = new OpenGl_Workspace (this, NULL);
+
+ Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
+ aLight->SetHeadlight (false);
+ aLight->SetColor (Quantity_NOC_WHITE);
+ myNoShadingLight = new Graphic3d_LightSet();
+ myNoShadingLight->Add (aLight);
+
+ myMainSceneFbos[0] = new OpenGl_FrameBuffer();
+ myMainSceneFbos[1] = new OpenGl_FrameBuffer();
+ myMainSceneFbosOit[0] = new OpenGl_FrameBuffer();
+ myMainSceneFbosOit[1] = new OpenGl_FrameBuffer();
+ myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
+ myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
+ myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer();
+ myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer();
+ myOpenGlFBO = new OpenGl_FrameBuffer();
+ myOpenGlFBO2 = new OpenGl_FrameBuffer();
+ myRaytraceFBO1[0] = new OpenGl_FrameBuffer();
+ myRaytraceFBO1[1] = new OpenGl_FrameBuffer();
+ myRaytraceFBO2[0] = new OpenGl_FrameBuffer();
+ myRaytraceFBO2[1] = new OpenGl_FrameBuffer();
}
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Destructor
+// purpose :
+// =======================================================================
OpenGl_View::~OpenGl_View()
{
ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
- OpenGl_Element::Destroy (NULL, myTrihedron);
- OpenGl_Element::Destroy (NULL, myGraduatedTrihedron);
OpenGl_Element::Destroy (NULL, myBgGradientArray);
OpenGl_Element::Destroy (NULL, myBgTextureArray);
OpenGl_Element::Destroy (NULL, myTextureParams);
}
+// =======================================================================
+// function : ReleaseGlResources
+// purpose :
+// =======================================================================
void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
{
- if (myTrihedron != NULL)
- {
- myTrihedron->Release (theCtx.operator->());
- }
- if (myGraduatedTrihedron != NULL)
- {
- myGraduatedTrihedron->Release (theCtx.operator->());
- }
+ myGraduatedTrihedron.Release (theCtx.get());
+ myFrameStatsPrs.Release (theCtx.get());
if (!myTextureEnv.IsNull())
{
- theCtx->DelayedRelease (myTextureEnv);
+ if (!theCtx.IsNull())
+ {
+ for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
+ {
+ theCtx->DelayedRelease (aTextureIter.ChangeValue());
+ aTextureIter.ChangeValue().Nullify();
+ }
+ }
myTextureEnv.Nullify();
}
if (myTextureParams != NULL)
{
- myTextureParams->Release (theCtx.operator->());
+ myTextureParams->Release (theCtx.get());
}
if (myBgGradientArray != NULL)
{
- myBgGradientArray->Release (theCtx.operator->());
+ myBgGradientArray->Release (theCtx.get());
}
if (myBgTextureArray != NULL)
{
- myBgTextureArray->Release (theCtx.operator->());
+ myBgTextureArray->Release (theCtx.get());
}
+
+ myMainSceneFbos[0] ->Release (theCtx.get());
+ myMainSceneFbos[1] ->Release (theCtx.get());
+ myMainSceneFbosOit[0] ->Release (theCtx.get());
+ myMainSceneFbosOit[1] ->Release (theCtx.get());
+ myImmediateSceneFbos[0] ->Release (theCtx.get());
+ myImmediateSceneFbos[1] ->Release (theCtx.get());
+ myImmediateSceneFbosOit[0]->Release (theCtx.get());
+ myImmediateSceneFbosOit[1]->Release (theCtx.get());
+ myOpenGlFBO ->Release (theCtx.get());
+ myOpenGlFBO2 ->Release (theCtx.get());
+ myFullScreenQuad .Release (theCtx.get());
+ myFullScreenQuadFlip .Release (theCtx.get());
+
+ releaseRaytraceResources (theCtx);
}
-void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
- const Handle(Graphic3d_TextureEnv)& theTexture)
+// =======================================================================
+// function : Remove
+// purpose :
+// =======================================================================
+void OpenGl_View::Remove()
{
- if (!myTextureEnv.IsNull())
+ if (IsRemoved())
{
- theCtx->DelayedRelease (myTextureEnv);
- myTextureEnv.Nullify();
+ return;
+ }
+
+ myDriver->RemoveView (this);
+ myWindow.Nullify();
+
+ Graphic3d_CView::Remove();
+}
+
+// =======================================================================
+// function : SetLocalOrigin
+// purpose :
+// =======================================================================
+void OpenGl_View::SetLocalOrigin (const gp_XYZ& theOrigin)
+{
+ myLocalOrigin = theOrigin;
+ const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
+ if (!aCtx.IsNull())
+ {
+ aCtx->ShaderManager()->SetLocalOrigin (theOrigin);
+ }
+}
+
+// =======================================================================
+// function : SetTextureEnv
+// purpose :
+// =======================================================================
+void OpenGl_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureEnv)
+{
+ Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
+ if (!aCtx.IsNull() && !myTextureEnv.IsNull())
+ {
+ for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
+ {
+ aCtx->DelayedRelease (aTextureIter.ChangeValue());
+ aTextureIter.ChangeValue().Nullify();
+ }
}
- if (theTexture.IsNull())
+ myToUpdateEnvironmentMap = Standard_True;
+ myTextureEnvData = theTextureEnv;
+ myTextureEnv.Nullify();
+ initTextureEnv (aCtx);
+}
+
+// =======================================================================
+// function : initTextureEnv
+// purpose :
+// =======================================================================
+void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext)
+{
+ if (myTextureEnvData.IsNull()
+ || theContext.IsNull()
+ || !theContext->MakeCurrent())
{
return;
}
- myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
- Handle(Image_PixMap) anImage = theTexture->GetImage();
+ myTextureEnv = new OpenGl_TextureSet (1);
+ Handle(OpenGl_Texture)& aTextureEnv = myTextureEnv->ChangeFirst();
+ aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams());
+ Handle(Image_PixMap) anImage = myTextureEnvData->GetImage();
if (!anImage.IsNull())
- myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
-
- myModificationState++;
+ {
+ aTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type());
+ }
}
-void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
+// =======================================================================
+// function : SetImmediateModeDrawToFront
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_View::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer)
{
- mySurfaceDetail = theMode;
+ const Standard_Boolean aPrevMode = myTransientDrawToFront;
+ myTransientDrawToFront = theDrawToFrontBuffer;
+ return aPrevMode;
+}
- myModificationState++;
+// =======================================================================
+// function : SetWindow
+// purpose :
+// =======================================================================
+void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow,
+ const Aspect_RenderingContext theContext)
+{
+ myWindow = myDriver->CreateRenderWindow (theWindow, theContext);
+ Standard_ASSERT_RAISE (!myWindow.IsNull(),
+ "OpenGl_View::SetWindow, "
+ "Failed to create OpenGl window.");
+
+ myWorkspace = new OpenGl_Workspace (this, myWindow);
+ myWorldViewProjState.Reset();
+ myToUpdateEnvironmentMap = Standard_True;
+ myHasFboBlit = Standard_True;
+ Invalidate();
+
+ // Environment texture resource does not support lazy initialization.
+ initTextureEnv (myWorkspace->GetGlContext());
}
// =======================================================================
-// function : SetBackfacing
+// function : Resized
// purpose :
// =======================================================================
-void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
+void OpenGl_View::Resized()
{
- myBackfacing = theMode;
+ if (myWindow.IsNull())
+ return;
+
+ myWindow->Resize();
}
// =======================================================================
-// function : SetLights
+// function : SetMinMaxValuesCallback
// purpose :
// =======================================================================
-void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
+static void SetMinMaxValuesCallback (Graphic3d_CView* theView)
{
- myLights.Clear();
- for (Standard_Integer aLightIt = 0; aLightIt < theViewCtx.NbActiveLight; ++aLightIt)
+ OpenGl_View* aView = dynamic_cast<OpenGl_View*>(theView);
+ if (aView == NULL)
+ return;
+
+ Bnd_Box aBox = theView->MinMaxValues();
+ if (!aBox.IsVoid())
{
- myLights.Append (theViewCtx.ActiveLight[aLightIt]);
+ gp_Pnt aMin = aBox.CornerMin();
+ gp_Pnt aMax = aBox.CornerMax();
+
+ Graphic3d_Vec3 aMinVec ((Standard_ShortReal )aMin.X(), (Standard_ShortReal )aMin.Y(), (Standard_ShortReal )aMin.Z());
+ Graphic3d_Vec3 aMaxVec ((Standard_ShortReal )aMax.X(), (Standard_ShortReal )aMax.Y(), (Standard_ShortReal )aMax.Z());
+ aView->GraduatedTrihedronMinMaxValues (aMinVec, aMaxVec);
}
- myCurrLightSourceState = myStateCounter->Increment();
}
-/*----------------------------------------------------------------------*/
-
-//call_togl_setvisualisation
-void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
+// =======================================================================
+// function : GraduatedTrihedronDisplay
+// purpose :
+// =======================================================================
+void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData)
{
- myVisualization = AContext.Visualization;
- myShadingModel = (Visual3d_TypeOfModel )AContext.Model;
+ myGTrihedronData = theTrihedronData;
+ myGTrihedronData.PtrView = this;
+ myGTrihedronData.CubicAxesCallback = SetMinMaxValuesCallback;
+ myGraduatedTrihedron.SetValues (myGTrihedronData);
+ myToShowGradTrihedron = true;
}
-/*----------------------------------------------------------------------*/
-
-//call_togl_cliplimit
-void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
+// =======================================================================
+// function : GraduatedTrihedronErase
+// purpose :
+// =======================================================================
+void OpenGl_View::GraduatedTrihedronErase()
{
- myZClip.Back.Limit = theCView.Context.ZClipBackPlane;
- myZClip.Front.Limit = theCView.Context.ZClipFrontPlane;
-
- myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
- myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
+ myGTrihedronData.PtrView = NULL;
+ myGraduatedTrihedron.Release (myWorkspace->GetGlContext().operator->());
+ myToShowGradTrihedron = false;
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : GraduatedTrihedronMinMaxValues
+// purpose :
+// =======================================================================
+void OpenGl_View::GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, const Graphic3d_Vec3 theMax)
+{
+ myGraduatedTrihedron.SetMinMax (theMin, theMax);
+}
-void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
- const Standard_Boolean theFlag)
+// =======================================================================
+// function : BufferDump
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType)
{
- if (!theFlag)
+ if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft)
{
- myFog.IsOn = Standard_False;
+ return myWorkspace->BufferDump(myFBO, theImage, theBufferType);
}
- else
+
+ if (!myRaytraceParameters.AdaptiveScreenSampling)
{
- myFog.IsOn = Standard_True;
+ return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType);
+ }
- myFog.Front = theCView.Context.DepthFrontPlane;
- myFog.Back = theCView.Context.DepthBackPlane;
+#if defined(GL_ES_VERSION_2_0)
+ return false;
+#else
+ if (theImage.Format() != Image_Format_RGBF)
+ {
+ return false;
+ }
- myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
- myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
- myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
- myFog.Color.rgb[3] = 1.0f;
+ const GLuint aW = myRaytraceOutputTexture[0]->SizeX();
+ const GLuint aH = myRaytraceOutputTexture[0]->SizeY();
+ if (aW / 3 != theImage.SizeX() || aH / 2 != theImage.SizeY())
+ {
+ return false;
}
-}
-/*----------------------------------------------------------------------*/
+ std::vector<GLfloat> aValues;
+ try
+ {
+ aValues.resize (aW * aH);
+ }
+ catch (const std::bad_alloc&)
+ {
+ return false;
+ }
-void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)& theCtx,
- const Aspect_TypeOfTriedronPosition thePosition,
- const Quantity_NameOfColor theColor,
- const Standard_Real theScale,
- const Standard_Boolean theAsWireframe)
-{
- OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
- myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
-}
+ glBindTexture (GL_TEXTURE_RECTANGLE, myRaytraceOutputTexture[0]->TextureId());
+ glGetTexImage (GL_TEXTURE_RECTANGLE, 0, OpenGl_TextureFormat::Create<GLfloat, 1>().Format(), GL_FLOAT, &aValues[0]);
+ glBindTexture (GL_TEXTURE_RECTANGLE, 0);
+ for (unsigned int aRow = 0; aRow < aH; aRow += 2)
+ {
+ for (unsigned int aCol = 0; aCol < aW; aCol += 3)
+ {
+ float* anImageValue = theImage.ChangeValue<float[3]> ((aH - aRow) / 2 - 1, aCol / 3);
+ float aInvNbSamples = 1.f / aValues[aRow * aW + aCol + aW];
+ anImageValue[0] = aValues[aRow * aW + aCol] * aInvNbSamples;
+ anImageValue[1] = aValues[aRow * aW + aCol + 1] * aInvNbSamples;
+ anImageValue[2] = aValues[aRow * aW + aCol + 1 + aW] * aInvNbSamples;
+ }
+ }
-/*----------------------------------------------------------------------*/
+ return true;
+#endif
+}
-void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
+// =======================================================================
+// function : GradientBackground
+// purpose :
+// =======================================================================
+Aspect_GradientBackground OpenGl_View::GradientBackground() const
{
- OpenGl_Element::Destroy (theCtx.operator->(), myTrihedron);
+ Quantity_Color aColor1, aColor2;
+ aColor1.SetValues (myBgGradientArray->GradientColor (0).r(),
+ myBgGradientArray->GradientColor (0).g(),
+ myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB);
+ aColor2.SetValues (myBgGradientArray->GradientColor (1).r(),
+ myBgGradientArray->GradientColor (1).g(),
+ myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB);
+ return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod());
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
- const Graphic3d_CGraduatedTrihedron& theData)
+// =======================================================================
+// function : SetGradientBackground
+// purpose :
+// =======================================================================
+void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBackground)
{
- OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
- myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
+ Quantity_Color aColor1, aColor2;
+ theBackground.Colors (aColor1, aColor2);
+ myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
}
-/*----------------------------------------------------------------------*/
-
-void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
+// =======================================================================
+// function : SetBackgroundImage
+// purpose :
+// =======================================================================
+void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath)
{
- OpenGl_Element::Destroy (theCtx.operator->(), myGraduatedTrihedron);
+ // Prepare aspect for texture storage
+ myBackgroundImagePath = theFilePath;
+ Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
+ Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath));
+ aTextureMap->EnableRepeat();
+ aTextureMap->DisableModulate();
+ aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL,
+ Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
+ Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
+ anAspect->SetTextureMap (aTextureMap);
+ anAspect->SetInteriorStyle (Aspect_IS_SOLID);
+ anAspect->SetSuppressBackFaces (false);
+ // Enable texture mapping
+ if (aTextureMap->IsDone())
+ {
+ anAspect->SetTextureMapOn();
+ }
+ else
+ {
+ anAspect->SetTextureMapOff();
+ return;
+ }
+
+ // Set texture parameters
+ myTextureParams->SetAspect (anAspect);
}
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : BackgroundImageStyle
+// purpose :
+// =======================================================================
+Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
+{
+ return myBgTextureArray->TextureFillMethod();
+}
-//transform_persistence_end
-void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
+// =======================================================================
+// function : SetBackgroundImageStyle
+// purpose :
+// =======================================================================
+void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
{
- if (myIsTransPers)
- {
- theCtx->WorldViewState.Pop();
- theCtx->ProjectionState.Pop();
+ myBgTextureArray->SetTextureFillMethod (theFillStyle);
+}
- theCtx->ApplyProjectionMatrix();
+//=======================================================================
+//function : AddZLayer
+//purpose :
+//=======================================================================
+void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
+{
+ myZLayers.AddLayer (theLayerId);
+}
- myIsTransPers = Standard_False;
- }
+//=======================================================================
+//function : RemoveZLayer
+//purpose :
+//=======================================================================
+void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
+{
+ myZLayers.RemoveLayer (theLayerId);
}
-/*----------------------------------------------------------------------*/
+//=======================================================================
+//function : SetZLayerSettings
+//purpose :
+//=======================================================================
+void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
+ const Graphic3d_ZLayerSettings& theSettings)
+{
+ myZLayers.SetLayerSettings (theLayerId, theSettings);
+}
-//transform_persistence_begin
-const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
- const TEL_TRANSFORM_PERSISTENCE* theTransPers)
+//=======================================================================
+//function : ZLayerMax
+//purpose :
+//=======================================================================
+Standard_Integer OpenGl_View::ZLayerMax() const
{
- const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
- myTransPers = theTransPers;
- if (theTransPers->mode == 0)
+ Standard_Integer aLayerMax = Graphic3d_ZLayerId_Default;
+ for (OpenGl_LayerSeqIds::Iterator aMapIt(myZLayers.LayerIDs()); aMapIt.More(); aMapIt.Next())
{
- EndTransformPersistence (theCtx);
- return aTransPersPrev;
+ aLayerMax = Max (aLayerMax, aMapIt.Value());
}
- GLint aViewport[4];
- OpenGl_Mat4d aModelMatrix, aProjMatrix;
- theCtx->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport);
- aModelMatrix.Convert (theCtx->ModelWorldState.Current() * theCtx->WorldViewState.Current());
- aProjMatrix .Convert (theCtx->ProjectionState.Current());
+ return aLayerMax;
+}
- const GLdouble aViewportW = (GLdouble )aViewport[2];
- const GLdouble aViewportH = (GLdouble )aViewport[3];
- if (myIsTransPers)
+//=======================================================================
+//function : InvalidateZLayerBoundingBox
+//purpose :
+//=======================================================================
+void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId) const
+{
+ if (myZLayers.LayerIDs().IsBound (theLayerId))
{
- // pop matrix stack - it will be overridden later
- theCtx->WorldViewState.Pop();
- theCtx->ProjectionState.Pop();
+ myZLayers.Layer (theLayerId).InvalidateBoundingBox();
}
else
{
- myIsTransPers = Standard_True;
+ const Standard_Integer aLayerMax = ZLayerMax();
+ for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < aLayerMax; ++aLayerId)
+ {
+ if (myZLayers.LayerIDs().IsBound (aLayerId))
+ {
+ const OpenGl_Layer& aLayer = myZLayers.Layer (aLayerId);
+ if (aLayer.NbOfTransformPersistenceObjects() > 0)
+ {
+ aLayer.InvalidateBoundingBox();
+ }
+ }
+ }
}
+}
- // push matrices into stack and reset them
- theCtx->WorldViewState.Push();
- theCtx->ProjectionState.Push();
-
- // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
- GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
- if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
+//=======================================================================
+//function : ZLayerBoundingBox
+//purpose :
+//=======================================================================
+Bnd_Box OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight,
+ const Standard_Boolean theToIncludeAuxiliary) const
+{
+ Bnd_Box aBox;
+ if (myZLayers.LayerIDs().IsBound (theLayerId))
{
- OpenGl_Utils::Project<Standard_Real> (theTransPers->pointX,
- theTransPers->pointY,
- theTransPers->pointZ,
- aModelMatrix,
- aProjMatrix,
- aViewport,
- aWinZ,
- aWinY,
- aWinZ);
+ aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
+ theCamera,
+ theWindowWidth,
+ theWindowHeight,
+ theToIncludeAuxiliary);
}
- // prevent zooming
- if ((theTransPers->mode & TPF_ZOOM)
- || (theTransPers->mode == TPF_TRIEDRON))
+ // add bounding box of gradient/texture background for proper Z-fit
+ if (theToIncludeAuxiliary
+ && theLayerId == Graphic3d_ZLayerId_BotOSD
+ && (myBgTextureArray->IsDefined()
+ || myBgGradientArray->IsDefined()))
{
- // compute fixed-zoom multiplier
- // actually function works ugly with TelPerspective!
- const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix.GetValue (1, 1) : aProjMatrix.GetValue (0, 0));
- aProjMatrix.ChangeValue (0, 0) *= aDet2;
- aProjMatrix.ChangeValue (1, 1) *= aDet2;
- aProjMatrix.ChangeValue (2, 2) *= aDet2;
+ // Background is drawn using 2D transformation persistence
+ // (e.g. it is actually placed in 3D coordinates within active camera position).
+ // We add here full-screen plane with 2D transformation persistence
+ // for simplicity (myBgTextureArray might define a little bit different options
+ // but it is updated within ::Render())
+ const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
+ const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix();
+ Graphic3d_BndBox3d aBox2d (Graphic3d_Vec3d (0.0, 0.0, 0.0),
+ Graphic3d_Vec3d (double(theWindowWidth), double(theWindowHeight), 0.0));
+
+ Graphic3d_TransformPers aTrsfPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER);
+ aTrsfPers.Apply (theCamera,
+ aProjectionMat,
+ aWorldViewMat,
+ theWindowWidth,
+ theWindowHeight,
+ aBox2d);
+ aBox.Add (gp_Pnt (aBox2d.CornerMin().x(), aBox2d.CornerMin().y(), aBox2d.CornerMin().z()));
+ aBox.Add (gp_Pnt (aBox2d.CornerMax().x(), aBox2d.CornerMax().y(), aBox2d.CornerMax().z()));
}
- // prevent translation - annulate translate matrix
- if ((theTransPers->mode & TPF_PAN)
- || (theTransPers->mode == TPF_TRIEDRON))
+ return aBox;
+}
+
+//=======================================================================
+//function : considerZoomPersistenceObjects
+//purpose :
+//=======================================================================
+Standard_Real OpenGl_View::considerZoomPersistenceObjects (const Graphic3d_ZLayerId theLayerId,
+ const Handle(Graphic3d_Camera)& theCamera,
+ const Standard_Integer theWindowWidth,
+ const Standard_Integer theWindowHeight) const
+{
+ if (myZLayers.LayerIDs().IsBound (theLayerId))
{
- aModelMatrix.SetValue (0, 3, 0.0);
- aModelMatrix.SetValue (1, 3, 0.0);
- aModelMatrix.SetValue (2, 3, 0.0);
- aProjMatrix .SetValue (0, 3, 0.0);
- aProjMatrix .SetValue (1, 3, 0.0);
- aProjMatrix .SetValue (2, 3, 0.0);
+ return myZLayers.Layer (theLayerId).considerZoomPersistenceObjects (Identification(),
+ theCamera,
+ theWindowWidth,
+ theWindowHeight);
}
- // prevent scaling-on-axis
- if (theTransPers->mode & TPF_ZOOM)
+ return 1.0;
+}
+
+//=======================================================================
+//function : FBO
+//purpose :
+//=======================================================================
+Handle(Standard_Transient) OpenGl_View::FBO() const
+{
+ return Handle(Standard_Transient)(myFBO);
+}
+
+//=======================================================================
+//function : SetFBO
+//purpose :
+//=======================================================================
+void OpenGl_View::SetFBO (const Handle(Standard_Transient)& theFbo)
+{
+ myFBO = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
+}
+
+//=======================================================================
+//function : FBOCreate
+//purpose :
+//=======================================================================
+Handle(Standard_Transient) OpenGl_View::FBOCreate (const Standard_Integer theWidth,
+ const Standard_Integer theHeight)
+{
+ return myWorkspace->FBOCreate (theWidth, theHeight);
+}
+
+//=======================================================================
+//function : FBORelease
+//purpose :
+//=======================================================================
+void OpenGl_View::FBORelease (Handle(Standard_Transient)& theFbo)
+{
+ Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
+ if (aFrameBuffer.IsNull())
{
- const gp_Pnt anAxialScale = myCamera->AxialScale();
- const double aScaleX = anAxialScale.X();
- const double aScaleY = anAxialScale.Y();
- const double aScaleZ = anAxialScale.Z();
- for (int i = 0; i < 3; ++i)
- {
- aModelMatrix.ChangeValue (0, i) /= aScaleX;
- aModelMatrix.ChangeValue (1, i) /= aScaleY;
- aModelMatrix.ChangeValue (2, i) /= aScaleZ;
- }
+ return;
}
- // prevent rotating - annulate rotate matrix
- if (theTransPers->mode & TPF_ROTATE)
- {
- aModelMatrix.SetValue (0, 0, 1.0);
- aModelMatrix.SetValue (1, 1, 1.0);
- aModelMatrix.SetValue (2, 2, 1.0);
+ myWorkspace->FBORelease (aFrameBuffer);
+ theFbo.Nullify();
+}
- aModelMatrix.SetValue (1, 0, 0.0);
- aModelMatrix.SetValue (2, 0, 0.0);
- aModelMatrix.SetValue (0, 1, 0.0);
- aModelMatrix.SetValue (2, 1, 0.0);
- aModelMatrix.SetValue (0, 2, 0.0);
- aModelMatrix.SetValue (1, 2, 0.0);
+//=======================================================================
+//function : FBOGetDimensions
+//purpose :
+//=======================================================================
+void OpenGl_View::FBOGetDimensions (const Handle(Standard_Transient)& theFbo,
+ Standard_Integer& theWidth,
+ Standard_Integer& theHeight,
+ Standard_Integer& theWidthMax,
+ Standard_Integer& theHeightMax)
+{
+ const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
+ if (aFrameBuffer.IsNull())
+ {
+ return;
}
- // load computed matrices
- theCtx->ModelWorldState.SetIdentity();
- theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
- theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
+ theWidth = aFrameBuffer->GetVPSizeX(); // current viewport size
+ theHeight = aFrameBuffer->GetVPSizeY();
+ theWidthMax = aFrameBuffer->GetSizeX(); // texture size
+ theHeightMax = aFrameBuffer->GetSizeY();
+}
- if (theTransPers->mode == TPF_TRIEDRON)
+//=======================================================================
+//function : FBOChangeViewport
+//purpose :
+//=======================================================================
+void OpenGl_View::FBOChangeViewport (const Handle(Standard_Transient)& theFbo,
+ const Standard_Integer theWidth,
+ const Standard_Integer theHeight)
+{
+ const Handle(OpenGl_FrameBuffer) aFrameBuffer = Handle(OpenGl_FrameBuffer)::DownCast (theFbo);
+ if (aFrameBuffer.IsNull())
{
- // move to the window corner
- if (theTransPers->pointX != 0.0
- && theTransPers->pointY != 0.0)
- {
- GLdouble aW1, aH1, aW2, aH2, aDummy;
-
- OpenGl_Mat4d anIdentity;
-
- OpenGl_Utils::UnProject<Standard_Real> (0.5 * aViewportW,
- 0.5 * aViewportH,
- 0.0,
- anIdentity,
- aProjMatrix,
- aViewport,
- aW1,
- aH1,
- aDummy);
-
- OpenGl_Utils::UnProject<Standard_Real> (-0.5 * aViewportW,
- -0.5 * aViewportH,
- 0.0,
- anIdentity,
- aProjMatrix,
- aViewport,
- aW2,
- aH2,
- aDummy);
-
- GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
- GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
- aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
- aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
-
- OpenGl_Utils::Translate<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
- theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
- }
+ return;
}
- else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
- {
- // move to thePoint using saved win-coordinates ('marker-behaviour')
- GLdouble aMoveX, aMoveY, aMoveZ;
- OpenGl_Utils::UnProject<Standard_Real> (aWinX,
- aWinY,
- aWinZ,
- aModelMatrix,
- aProjMatrix,
- aViewport,
- aMoveX,
- aMoveY,
- aMoveZ);
+ aFrameBuffer->ChangeViewport (theWidth, theHeight);
+}
- OpenGl_Utils::Translate<Standard_Real> (aModelMatrix, aMoveX, aMoveY, aMoveZ);
- theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
+//=======================================================================
+//function : displayStructure
+//purpose :
+//=======================================================================
+void OpenGl_View::displayStructure (const Handle(Graphic3d_CStructure)& theStructure,
+ const Standard_Integer thePriority)
+{
+ const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
+ const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer();
+ myZLayers.AddStructure (aStruct, aZLayer, thePriority);
+}
+
+//=======================================================================
+//function : eraseStructure
+//purpose :
+//=======================================================================
+void OpenGl_View::eraseStructure (const Handle(Graphic3d_CStructure)& theStructure)
+{
+ const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
+ myZLayers.RemoveStructure (aStruct);
+}
+
+//=======================================================================
+//function : changeZLayer
+//purpose :
+//=======================================================================
+void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure,
+ const Graphic3d_ZLayerId theNewLayerId)
+{
+ const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
+ const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
+ myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
+ Update (anOldLayer);
+ Update (theNewLayerId);
+}
+
+//=======================================================================
+//function : changePriority
+//purpose :
+//=======================================================================
+void OpenGl_View::changePriority (const Handle(Graphic3d_CStructure)& theStructure,
+ const Standard_Integer theNewPriority)
+{
+ const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
+ const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
+ myZLayers.ChangePriority (aStruct, aLayerId, theNewPriority);
+}
+
+//=======================================================================
+//function : DiagnosticInformation
+//purpose :
+//=======================================================================
+void OpenGl_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
+ Graphic3d_DiagnosticInfo theFlags) const
+{
+ Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
+ if (!myWorkspace->Activate()
+ || aCtx.IsNull())
+ {
+ return;
}
- theCtx->ApplyProjectionMatrix();
- return aTransPersPrev;
+ aCtx->DiagnosticInformation (theDict, theFlags);
+ if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
+ {
+ TCollection_AsciiString aResRatio (myRenderParams.ResolutionRatio());
+ theDict.ChangeFromIndex (theDict.Add ("ResolutionRatio", aResRatio)) = aResRatio;
+ }
}
-/*----------------------------------------------------------------------*/
+//=======================================================================
+//function : StatisticInformation
+//purpose :
+//=======================================================================
+void OpenGl_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
+{
+ if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext())
+ {
+ const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats();
+ const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams();
+ aStats->FormatStats (theDict, aRendParams.CollectedStats);
+ }
+}
-void OpenGl_View::GetMatrices (OpenGl_Mat4& theOrientation,
- OpenGl_Mat4& theViewMapping) const
+//=======================================================================
+//function : StatisticInformation
+//purpose :
+//=======================================================================
+TCollection_AsciiString OpenGl_View::StatisticInformation() const
{
- theViewMapping = myCamera->ProjectionMatrixF();
- theOrientation = myCamera->OrientationMatrixF();
+ if (const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext())
+ {
+ const Handle(OpenGl_FrameStats)& aStats = aCtx->FrameStats();
+ const Graphic3d_RenderingParams& aRendParams = myWorkspace->View()->RenderingParams();
+ return aStats->FormatStats (aRendParams.CollectedStats);
+ }
+ return TCollection_AsciiString();
}
-/*----------------------------------------------------------------------*/