mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
OpenGl_GlFunctions no more loads unused FFP functions. OpenGl_GlCoreXX function tables no more defined two hierarchies with and without FFP functions, and OpenGl_Context::coreXXback fields have been removed. Introduced OpenGl_Context::core11ffp as more straightforward naming for obsolete FFP function set.
685 lines
22 KiB
C++
685 lines
22 KiB
C++
// Created on: 2011-08-01
|
|
// Created by: Sergey ZERCHANINOV
|
|
// Copyright (c) 2011-2014 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.
|
|
|
|
#include <OpenGl_CappingAlgo.hxx>
|
|
#include <OpenGl_Context.hxx>
|
|
#include <OpenGl_GlCore11.hxx>
|
|
#include <OpenGl_ClippingIterator.hxx>
|
|
#include <OpenGl_GraphicDriver.hxx>
|
|
#include <OpenGl_ShaderManager.hxx>
|
|
#include <OpenGl_ShaderProgram.hxx>
|
|
#include <OpenGl_StructureShadow.hxx>
|
|
#include <OpenGl_Vec.hxx>
|
|
#include <OpenGl_View.hxx>
|
|
#include <OpenGl_Workspace.hxx>
|
|
|
|
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure,Graphic3d_CStructure)
|
|
|
|
// =======================================================================
|
|
// function : renderBoundingBox
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::renderBoundingBox (const Handle(OpenGl_Workspace)& theWorkspace) const
|
|
{
|
|
if (!myBndBox.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
|
|
const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)(), Handle(OpenGl_ShaderProgram)());
|
|
const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer);
|
|
const Graphic3d_Vec3d aMoveVec = myTrsfPers.IsNull()
|
|
&& !aLayer.OriginTransformation().IsNull()
|
|
? -Graphic3d_Vec3d (aLayer.Origin().X(), aLayer.Origin().Y(), aLayer.Origin().Z())
|
|
: Graphic3d_Vec3d (0.0, 0.0, 0.0);
|
|
if (aCtx->core20fwd != NULL
|
|
&& aCtx->ShaderManager()->BindBoundBoxProgram())
|
|
{
|
|
const Graphic3d_Vec3d aCenter = myBndBox.Center() + aMoveVec;
|
|
const Graphic3d_Vec3d aSize = myBndBox.Size();
|
|
aCtx->ActiveProgram()->SetUniform (aCtx, "occBBoxCenter", Graphic3d_Vec3 ((float )aCenter.x(), (float )aCenter.y(), (float )aCenter.z()));
|
|
aCtx->ActiveProgram()->SetUniform (aCtx, "occBBoxSize", Graphic3d_Vec3 ((float )aSize.x(), (float )aSize.y(), (float )aSize.z()));
|
|
aCtx->SetColor4fv (theWorkspace->InteriorColor());
|
|
|
|
const Handle(OpenGl_VertexBuffer)& aBoundBoxVertBuffer = aCtx->ShaderManager()->BoundBoxVertBuffer();
|
|
aBoundBoxVertBuffer->BindAttribute (aCtx, Graphic3d_TOA_POS);
|
|
aCtx->core20fwd->glDrawArrays (GL_LINES, 0, aBoundBoxVertBuffer->GetElemsNb());
|
|
aBoundBoxVertBuffer->UnbindAttribute(aCtx, Graphic3d_TOA_POS);
|
|
}
|
|
#if !defined(GL_ES_VERSION_2_0)
|
|
else if (aCtx->core11ffp != NULL)
|
|
{
|
|
const Graphic3d_Vec3d aMind = myBndBox.CornerMin() + aMoveVec;
|
|
const Graphic3d_Vec3d aMaxd = myBndBox.CornerMax() + aMoveVec;
|
|
const Graphic3d_Vec3 aMin ((float )aMind.x(), (float )aMind.y(), (float )aMind.z());
|
|
const Graphic3d_Vec3 aMax ((float )aMaxd.x(), (float )aMaxd.y(), (float )aMaxd.z());
|
|
const OpenGl_Vec3 aVerts[16] =
|
|
{
|
|
OpenGl_Vec3 (aMin.x(), aMin.y(), aMin.z()),
|
|
OpenGl_Vec3 (aMin.x(), aMin.y(), aMax.z()),
|
|
OpenGl_Vec3 (aMin.x(), aMax.y(), aMax.z()),
|
|
OpenGl_Vec3 (aMin.x(), aMax.y(), aMin.z()),
|
|
OpenGl_Vec3 (aMin.x(), aMin.y(), aMin.z()),
|
|
OpenGl_Vec3 (aMax.x(), aMin.y(), aMin.z()),
|
|
OpenGl_Vec3 (aMax.x(), aMin.y(), aMax.z()),
|
|
OpenGl_Vec3 (aMax.x(), aMax.y(), aMax.z()),
|
|
OpenGl_Vec3 (aMax.x(), aMax.y(), aMin.z()),
|
|
OpenGl_Vec3 (aMax.x(), aMin.y(), aMin.z()),
|
|
OpenGl_Vec3 (aMax.x(), aMax.y(), aMin.z()),
|
|
OpenGl_Vec3 (aMin.x(), aMax.y(), aMin.z()),
|
|
OpenGl_Vec3 (aMin.x(), aMax.y(), aMax.z()),
|
|
OpenGl_Vec3 (aMax.x(), aMax.y(), aMax.z()),
|
|
OpenGl_Vec3 (aMax.x(), aMin.y(), aMax.z()),
|
|
OpenGl_Vec3 (aMin.x(), aMin.y(), aMax.z())
|
|
};
|
|
|
|
aCtx->ShaderManager()->BindLineProgram (Handle(OpenGl_TextureSet)(), Aspect_TOL_SOLID, Graphic3d_TOSM_UNLIT, Graphic3d_AlphaMode_Opaque, false, Handle(OpenGl_ShaderProgram)());
|
|
aCtx->SetColor4fv (theWorkspace->InteriorColor());
|
|
aCtx->core11fwd->glDisable (GL_LIGHTING);
|
|
aCtx->core11ffp->glEnableClientState (GL_VERTEX_ARRAY);
|
|
aCtx->core11ffp->glVertexPointer (3, GL_FLOAT, 0, aVerts[0].GetData());
|
|
aCtx->core11fwd->glDrawArrays (GL_LINE_STRIP, 0, 16);
|
|
aCtx->core11ffp->glDisableClientState (GL_VERTEX_ARRAY);
|
|
}
|
|
#endif
|
|
aCtx->BindTextures (aPrevTexture, Handle(OpenGl_ShaderProgram)());
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : OpenGl_Structure
|
|
// purpose :
|
|
// =======================================================================
|
|
OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
|
|
: Graphic3d_CStructure (theManager),
|
|
myInstancedStructure (NULL),
|
|
myIsRaytracable (Standard_False),
|
|
myModificationState (0),
|
|
myIsMirrored (Standard_False)
|
|
{
|
|
updateLayerTransformation();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ~OpenGl_Structure
|
|
// purpose :
|
|
// =======================================================================
|
|
OpenGl_Structure::~OpenGl_Structure()
|
|
{
|
|
Release (Handle(OpenGl_Context)());
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetZLayer
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::SetZLayer (const Graphic3d_ZLayerId theLayerIndex)
|
|
{
|
|
Graphic3d_CStructure::SetZLayer (theLayerIndex);
|
|
updateLayerTransformation();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetTransformation
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::SetTransformation (const Handle(TopLoc_Datum3D)& theTrsf)
|
|
{
|
|
myTrsf = theTrsf;
|
|
myIsMirrored = Standard_False;
|
|
if (!myTrsf.IsNull())
|
|
{
|
|
// Determinant of transform matrix less then 0 means that mirror transform applied.
|
|
const gp_Trsf& aTrsf = myTrsf->Transformation();
|
|
const Standard_Real aDet = aTrsf.Value(1, 1) * (aTrsf.Value (2, 2) * aTrsf.Value (3, 3) - aTrsf.Value (3, 2) * aTrsf.Value (2, 3))
|
|
- aTrsf.Value(1, 2) * (aTrsf.Value (2, 1) * aTrsf.Value (3, 3) - aTrsf.Value (3, 1) * aTrsf.Value (2, 3))
|
|
+ aTrsf.Value(1, 3) * (aTrsf.Value (2, 1) * aTrsf.Value (3, 2) - aTrsf.Value (3, 1) * aTrsf.Value (2, 2));
|
|
myIsMirrored = aDet < 0.0;
|
|
}
|
|
|
|
updateLayerTransformation();
|
|
if (IsRaytracable())
|
|
{
|
|
++myModificationState;
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : SetTransformPersistence
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
|
|
{
|
|
if ((myTrsfPers.IsNull() || theTrsfPers.IsNull()) && myTrsfPers != theTrsfPers)
|
|
{
|
|
++myModificationState;
|
|
}
|
|
myTrsfPers = theTrsfPers;
|
|
updateLayerTransformation();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : updateLayerTransformation
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::updateLayerTransformation()
|
|
{
|
|
gp_Trsf aRenderTrsf;
|
|
if (!myTrsf.IsNull())
|
|
{
|
|
aRenderTrsf = myTrsf->Trsf();
|
|
}
|
|
|
|
const Graphic3d_ZLayerSettings& aLayer = myGraphicDriver->ZLayerSettings (myZLayer);
|
|
if (!aLayer.OriginTransformation().IsNull()
|
|
&& myTrsfPers.IsNull())
|
|
{
|
|
aRenderTrsf.SetTranslationPart (aRenderTrsf.TranslationPart() - aLayer.Origin());
|
|
}
|
|
aRenderTrsf.GetMat4 (myRenderTrsf);
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GraphicHighlight
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::GraphicHighlight (const Handle(Graphic3d_PresentationAttributes)& theStyle)
|
|
{
|
|
myHighlightStyle = theStyle;
|
|
highlight = 1;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : GraphicUnhighlight
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::GraphicUnhighlight()
|
|
{
|
|
highlight = 0;
|
|
myHighlightStyle.Nullify();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : OnVisibilityChanged
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::OnVisibilityChanged()
|
|
{
|
|
if (IsRaytracable())
|
|
{
|
|
++myModificationState;
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : IsRaytracable
|
|
// purpose :
|
|
// =======================================================================
|
|
Standard_Boolean OpenGl_Structure::IsRaytracable() const
|
|
{
|
|
if (!myGroups.IsEmpty()
|
|
&& myIsRaytracable
|
|
&& myTrsfPers.IsNull())
|
|
{
|
|
return Standard_True;
|
|
}
|
|
|
|
return myInstancedStructure != NULL
|
|
&& myInstancedStructure->IsRaytracable();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : UpdateRaytracableState
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const
|
|
{
|
|
myIsRaytracable = !toCheck;
|
|
if (!myIsRaytracable)
|
|
{
|
|
for (OpenGl_Structure::GroupIterator anIter (myGroups); anIter.More(); anIter.Next())
|
|
{
|
|
if (anIter.Value()->IsRaytracable())
|
|
{
|
|
myIsRaytracable = Standard_True;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsRaytracable())
|
|
{
|
|
++myModificationState;
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Connect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
|
|
{
|
|
OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
|
|
|
|
Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
|
|
"Error! Instanced structure is already defined");
|
|
|
|
myInstancedStructure = aStruct;
|
|
|
|
if (aStruct->IsRaytracable())
|
|
{
|
|
UpdateStateIfRaytracable (Standard_False);
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Disconnect
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
|
|
{
|
|
OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
|
|
|
|
if (myInstancedStructure == aStruct)
|
|
{
|
|
myInstancedStructure = NULL;
|
|
|
|
if (aStruct->IsRaytracable())
|
|
{
|
|
UpdateStateIfRaytracable();
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : NewGroup
|
|
// purpose :
|
|
// =======================================================================
|
|
Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct)
|
|
{
|
|
Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct);
|
|
myGroups.Append (aGroup);
|
|
return aGroup;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : RemoveGroup
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
|
|
{
|
|
if (theGroup.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
|
|
{
|
|
// Check for the given group
|
|
if (aGroupIter.Value() == theGroup)
|
|
{
|
|
const Standard_Boolean wasRaytracable =
|
|
static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable();
|
|
|
|
theGroup->Clear (Standard_False);
|
|
|
|
if (wasRaytracable)
|
|
{
|
|
UpdateStateIfRaytracable();
|
|
}
|
|
|
|
myGroups.Remove (aGroupIter);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Clear
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::Clear()
|
|
{
|
|
Clear (GlDriver()->GetSharedContext());
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Clear
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
|
|
{
|
|
Standard_Boolean aRaytracableGroupDeleted (Standard_False);
|
|
|
|
// Release groups
|
|
for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
|
|
{
|
|
aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
|
|
|
|
// Delete objects
|
|
aGroupIter.ChangeValue()->Release (theGlCtx);
|
|
}
|
|
myGroups.Clear();
|
|
|
|
if (aRaytracableGroupDeleted)
|
|
{
|
|
myIsRaytracable = Standard_False;
|
|
}
|
|
|
|
Is2dText = Standard_False;
|
|
IsForHighlight = Standard_False;
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : renderGeometry
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace,
|
|
bool& theHasClosed) const
|
|
{
|
|
if (myInstancedStructure != NULL)
|
|
{
|
|
myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
|
|
}
|
|
|
|
for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
|
|
{
|
|
theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
|
|
aGroupIter.Value()->Render (theWorkspace);
|
|
}
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Render
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
|
|
{
|
|
// Process the structure only if visible
|
|
if (!visible)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
|
|
|
|
// Render named status
|
|
if (highlight && !myHighlightStyle.IsNull() && myHighlightStyle->Method() != Aspect_TOHM_BOUNDBOX)
|
|
{
|
|
theWorkspace->SetHighlightStyle (myHighlightStyle);
|
|
}
|
|
|
|
// Apply local transformation
|
|
aCtx->ModelWorldState.Push();
|
|
OpenGl_Mat4& aModelWorld = aCtx->ModelWorldState.ChangeCurrent();
|
|
aModelWorld = myRenderTrsf;
|
|
|
|
const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
|
|
#if !defined(GL_ES_VERSION_2_0)
|
|
// detect scale transform
|
|
if (aCtx->core11ffp != NULL
|
|
&& !myTrsf.IsNull())
|
|
{
|
|
const Standard_Real aScale = myTrsf->Trsf().ScaleFactor();
|
|
if (Abs (aScale - 1.0) > Precision::Confusion())
|
|
{
|
|
aCtx->SetGlNormalizeEnabled (Standard_True);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
bool anOldCastShadows = false;
|
|
#ifdef GL_DEPTH_CLAMP
|
|
bool toRestoreDepthClamp = false;
|
|
#endif
|
|
if (!myTrsfPers.IsNull())
|
|
{
|
|
// temporarily disable shadows on non-3d objects
|
|
anOldCastShadows = aCtx->ShaderManager()->SetCastShadows (false);
|
|
|
|
aCtx->WorldViewState.Push();
|
|
OpenGl_Mat4& aWorldView = aCtx->WorldViewState.ChangeCurrent();
|
|
myTrsfPers->Apply (aCtx->Camera(),
|
|
aCtx->ProjectionState.Current(), aWorldView,
|
|
aCtx->VirtualViewport()[2], aCtx->VirtualViewport()[3]);
|
|
|
|
#if !defined(GL_ES_VERSION_2_0)
|
|
if (!aCtx->IsGlNormalizeEnabled()
|
|
&& aCtx->core11ffp != NULL)
|
|
{
|
|
const Standard_Real aScale = Graphic3d_TransformUtils::ScaleFactor<Standard_ShortReal> (aWorldView);
|
|
if (Abs (aScale - 1.0) > Precision::Confusion())
|
|
{
|
|
aCtx->SetGlNormalizeEnabled (Standard_True);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef GL_DEPTH_CLAMP
|
|
if (myTrsfPers->Mode() == Graphic3d_TMF_CameraPers
|
|
&& aCtx->arbDepthClamp)
|
|
{
|
|
toRestoreDepthClamp = true;
|
|
aCtx->core11fwd->glEnable (GL_DEPTH_CLAMP);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// Take into account transform persistence
|
|
aCtx->ApplyModelViewMatrix();
|
|
|
|
// remember aspects
|
|
const OpenGl_Aspects* aPrevAspectFace = theWorkspace->Aspects();
|
|
|
|
// Apply correction for mirror transform
|
|
if (myIsMirrored)
|
|
{
|
|
aCtx->core11fwd->glFrontFace (GL_CW);
|
|
}
|
|
|
|
// Collect clipping planes of structure scope
|
|
aCtx->ChangeClipping().SetLocalPlanes (myClipPlanes);
|
|
|
|
// True if structure is fully clipped
|
|
bool isClipped = false;
|
|
bool hasDisabled = false;
|
|
if (aCtx->Clipping().IsClippingOrCappingOn())
|
|
{
|
|
const Graphic3d_BndBox3d& aBBox = BoundingBox();
|
|
if (!myClipPlanes.IsNull()
|
|
&& myClipPlanes->ToOverrideGlobal())
|
|
{
|
|
aCtx->ChangeClipping().DisableGlobal();
|
|
hasDisabled = aCtx->Clipping().HasDisabled();
|
|
}
|
|
else if (!myTrsfPers.IsNull())
|
|
{
|
|
if (myTrsfPers->IsZoomOrRotate())
|
|
{
|
|
// Zoom/rotate persistence object lives in two worlds at the same time.
|
|
// Global clipping planes can not be trivially applied without being converted
|
|
// into local space of transformation persistence object.
|
|
// As more simple alternative - just clip entire object by its anchor point defined in the world space.
|
|
const gp_Pnt anAnchor = myTrsfPers->AnchorPoint();
|
|
for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More() && aPlaneIt.IsGlobal(); aPlaneIt.Next())
|
|
{
|
|
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
|
|
if (!aPlane->IsOn())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// check for clipping
|
|
const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
|
|
if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
|
|
{
|
|
isClipped = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
aCtx->ChangeClipping().DisableGlobal();
|
|
hasDisabled = aCtx->Clipping().HasDisabled();
|
|
}
|
|
|
|
// Set of clipping planes that do not intersect the structure,
|
|
// and thus can be disabled to improve rendering performance
|
|
if (aBBox.IsValid()
|
|
&& myTrsfPers.IsNull())
|
|
{
|
|
for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next())
|
|
{
|
|
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
|
|
if (aPlaneIt.IsDisabled())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const Graphic3d_ClipState aBoxState = aPlane->ProbeBox (aBBox);
|
|
if (aBoxState == Graphic3d_ClipState_In)
|
|
{
|
|
aCtx->ChangeClipping().SetEnabled (aPlaneIt, false);
|
|
hasDisabled = true;
|
|
}
|
|
else if (aBoxState == Graphic3d_ClipState_Out && myBndBoxClipCheck)
|
|
{
|
|
isClipped = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
|
|
|| hasDisabled)
|
|
{
|
|
// Set OCCT state uniform variables
|
|
aCtx->ShaderManager()->UpdateClippingState();
|
|
}
|
|
}
|
|
|
|
// Render groups
|
|
bool hasClosedPrims = false;
|
|
if (!isClipped)
|
|
{
|
|
renderGeometry (theWorkspace, hasClosedPrims);
|
|
}
|
|
|
|
// Reset correction for mirror transform
|
|
if (myIsMirrored)
|
|
{
|
|
aCtx->core11fwd->glFrontFace (GL_CCW);
|
|
}
|
|
|
|
// Render capping for structure groups
|
|
if (hasClosedPrims
|
|
&& aCtx->Clipping().IsCappingOn())
|
|
{
|
|
OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this);
|
|
}
|
|
|
|
// Revert structure clippings
|
|
if (hasDisabled)
|
|
{
|
|
// enable planes that were previously disabled
|
|
aCtx->ChangeClipping().RestoreDisabled();
|
|
}
|
|
aCtx->ChangeClipping().SetLocalPlanes (Handle(Graphic3d_SequenceOfHClipPlane)());
|
|
if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty())
|
|
|| hasDisabled)
|
|
{
|
|
// Set OCCT state uniform variables
|
|
aCtx->ShaderManager()->RevertClippingState();
|
|
}
|
|
|
|
// Restore local transformation
|
|
aCtx->ModelWorldState.Pop();
|
|
aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
|
|
|
|
// Restore aspects
|
|
theWorkspace->SetAspects (aPrevAspectFace);
|
|
|
|
// Apply highlight box
|
|
if (!isClipped
|
|
&& !myHighlightStyle.IsNull()
|
|
&& myHighlightStyle->Method() == Aspect_TOHM_BOUNDBOX)
|
|
{
|
|
aCtx->ApplyModelViewMatrix();
|
|
theWorkspace->SetHighlightStyle (myHighlightStyle);
|
|
renderBoundingBox (theWorkspace);
|
|
}
|
|
|
|
if (!myTrsfPers.IsNull())
|
|
{
|
|
aCtx->WorldViewState.Pop();
|
|
aCtx->ShaderManager()->SetCastShadows (anOldCastShadows);
|
|
#ifdef GL_DEPTH_CLAMP
|
|
if (toRestoreDepthClamp) { aCtx->core11fwd->glDisable (GL_DEPTH_CLAMP); }
|
|
#endif
|
|
}
|
|
|
|
// Restore named status
|
|
theWorkspace->SetHighlightStyle (Handle(Graphic3d_PresentationAttributes)());
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : Release
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
|
|
{
|
|
// Release groups
|
|
Clear (theGlCtx);
|
|
myHighlightStyle.Nullify();
|
|
}
|
|
|
|
// =======================================================================
|
|
// function : ReleaseGlResources
|
|
// purpose :
|
|
// =======================================================================
|
|
void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
|
|
{
|
|
for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
|
|
{
|
|
aGroupIter.ChangeValue()->Release (theGlCtx);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ShadowLink
|
|
//purpose :
|
|
//=======================================================================
|
|
Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
|
|
{
|
|
return new OpenGl_StructureShadow (theManager, this);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : DumpJson
|
|
//purpose :
|
|
//=======================================================================
|
|
void OpenGl_Structure::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
|
|
{
|
|
OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
|
|
|
|
OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Graphic3d_CStructure)
|
|
|
|
OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myInstancedStructure)
|
|
|
|
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsRaytracable)
|
|
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myModificationState)
|
|
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsMirrored)
|
|
}
|