diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index c9e4fa99b1..25b92ca86f 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -111,7 +111,6 @@ OpenGl_IndexBuffer.cxx OpenGl_IndexBuffer.hxx OpenGl_Layer.cxx OpenGl_Layer.hxx -OpenGl_RenderFilter.cxx OpenGl_RenderFilter.hxx OpenGl_Sampler.cxx OpenGl_Sampler.hxx diff --git a/src/OpenGl/OpenGl_CappingAlgo.cxx b/src/OpenGl/OpenGl_CappingAlgo.cxx index 0a438fbc35..4338d502d5 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.cxx +++ b/src/OpenGl/OpenGl_CappingAlgo.cxx @@ -24,23 +24,48 @@ #include #include -IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter,OpenGl_RenderFilter) - namespace { + //! Auxiliary sentry object managing stencil test. + struct StencilTestSentry + { + StencilTestSentry() : myDepthFuncPrev (0) {} + + //! Restore previous application state. + ~StencilTestSentry() + { + if (myDepthFuncPrev != 0) + { + glClear (GL_STENCIL_BUFFER_BIT); + glDepthFunc (myDepthFuncPrev); + glStencilFunc (GL_ALWAYS, 0, 0xFF); + glDisable (GL_STENCIL_TEST); + } + } + + //! Prepare for rendering the clip planes. + void Init() + { + if (myDepthFuncPrev == 0) + { + glEnable (GL_STENCIL_TEST); + glGetIntegerv (GL_DEPTH_FUNC, &myDepthFuncPrev); + glDepthFunc (GL_LESS); + } + } + + private: + GLint myDepthFuncPrev; + }; + //! Render infinite capping plane. //! @param theWorkspace [in] the GL workspace, context state. //! @param thePlane [in] the graphical plane, for which the capping surface is rendered. static void renderPlane (const Handle(OpenGl_Workspace)& theWorkspace, - const Handle(OpenGl_CappingPlaneResource)& thePlane, - const OpenGl_AspectFace* theAspectFace) + const Handle(OpenGl_CappingPlaneResource)& thePlane) { const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); - thePlane->Update (aContext, theAspectFace != NULL ? theAspectFace->Aspect() : Handle(Graphic3d_AspectFillArea3d)()); - - bool wasCullAllowed = theWorkspace->SetAllowFaceCulling (true); - const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace(); - theWorkspace->SetAspectFace (thePlane->AspectFace()); + const bool wasCullAllowed = theWorkspace->SetAllowFaceCulling (true); // set identity model matrix aContext->ModelWorldState.Push(); @@ -53,16 +78,19 @@ namespace aContext->ApplyModelViewMatrix(); theWorkspace->SetAllowFaceCulling (wasCullAllowed); - theWorkspace->SetAspectFace (aFaceAspect); } //! Render capping for specific structure. - static void renderCappingForStructure (const Handle(OpenGl_Workspace)& theWorkspace, + static void renderCappingForStructure (StencilTestSentry& theStencilSentry, + const Handle(OpenGl_Workspace)& theWorkspace, const OpenGl_Structure& theStructure, const Handle(Graphic3d_ClipPlane)& theClipChain, const Standard_Integer theSubPlaneIndex, const Handle(OpenGl_CappingPlaneResource)& thePlane) { + const Standard_Integer aPrevFilter = theWorkspace->RenderFilter(); + const Standard_Integer anAnyFilter = aPrevFilter & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly); + const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); const Handle(Graphic3d_ClipPlane)& aRenderPlane = thePlane->Plane(); for (OpenGl_Structure::GroupIterator aGroupIter (theStructure.Groups()); aGroupIter.More(); aGroupIter.Next()) @@ -72,6 +100,22 @@ namespace continue; } + // clear stencil only if something has been actually drawn + theStencilSentry.Init(); + + // check if capping plane should be rendered within current pass (only opaque / only transparent) + const OpenGl_AspectFace* anObjAspectFace = aRenderPlane->ToUseObjectProperties() ? aGroupIter.Value()->AspectFace() : NULL; + thePlane->Update (aContext, anObjAspectFace != NULL ? anObjAspectFace->Aspect() : Handle(Graphic3d_AspectFillArea3d)()); + theWorkspace->SetAspectFace (thePlane->AspectFace()); + theWorkspace->SetRenderFilter (aPrevFilter); + if (!theWorkspace->ShouldRender (&thePlane->Primitives())) + { + continue; + } + + // suppress only opaque/transparent filter since for filling stencil the whole geometry should be drawn + theWorkspace->SetRenderFilter (anAnyFilter); + // enable only the rendering plane to generate stencil mask aContext->ChangeClipping().DisableAllExcept (theClipChain, theSubPlaneIndex); aContext->ShaderManager()->UpdateClippingState(); @@ -132,8 +176,8 @@ namespace glEnable (GL_DEPTH_TEST); } - renderPlane (theWorkspace, thePlane, - aRenderPlane->ToUseObjectProperties() ? aGroupIter.Value()->AspectFace() : NULL); + theWorkspace->SetAspectFace (thePlane->AspectFace()); + renderPlane (theWorkspace, thePlane); // turn on the current plane to restore initial state aContext->ChangeClipping().ResetCappingFilter(); @@ -143,7 +187,7 @@ namespace if (theStructure.InstancedStructure() != NULL) { - renderCappingForStructure (theWorkspace, *theStructure.InstancedStructure(), theClipChain, theSubPlaneIndex, thePlane); + renderCappingForStructure (theStencilSentry, theWorkspace, *theStructure.InstancedStructure(), theClipChain, theSubPlaneIndex, thePlane); } } } @@ -165,20 +209,10 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks // remember current aspect face defined in workspace const OpenGl_AspectFace* aFaceAsp = theWorkspace->AspectFace(); - // replace primitive groups rendering filter - Handle(OpenGl_RenderFilter) aRenderFilter = theWorkspace->GetRenderFilter(); - Handle(OpenGl_CappingAlgoFilter) aCappingFilter = theWorkspace->DefaultCappingAlgoFilter(); - aCappingFilter->SetPreviousFilter (aRenderFilter); - theWorkspace->SetRenderFilter (aCappingFilter); - - // prepare for rendering the clip planes - glEnable (GL_STENCIL_TEST); - - // remember current state of depth - // function and change its value - GLint aDepthFuncPrev; - glGetIntegerv (GL_DEPTH_FUNC, &aDepthFuncPrev); - glDepthFunc (GL_LESS); + // only filled primitives should be rendered + const Standard_Integer aPrevFilter = theWorkspace->RenderFilter(); + theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_FillModeOnly); + StencilTestSentry aStencilSentry; // generate capping for every clip plane for (OpenGl_ClippingIterator aCappingIt (aContext->Clipping()); aCappingIt.More(); aCappingIt.Next()) @@ -204,7 +238,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks aContext->ShareResource (aResId, aPlaneRes); } - renderCappingForStructure (theWorkspace, theStructure, aClipChain, aSubPlaneIndex, aPlaneRes); + renderCappingForStructure (aStencilSentry, theWorkspace, theStructure, aClipChain, aSubPlaneIndex, aPlaneRes); // set delayed resource release aPlaneRes.Nullify(); @@ -212,28 +246,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks } } - // restore previous application state - glClear (GL_STENCIL_BUFFER_BIT); - glDepthFunc (aDepthFuncPrev); - glStencilFunc (GL_ALWAYS, 0, 0xFF); - glDisable (GL_STENCIL_TEST); - // restore rendering aspects theWorkspace->SetAspectFace (aFaceAsp); - theWorkspace->SetRenderFilter (aRenderFilter); -} - -// ======================================================================= -// function : CanRender -// purpose : -// ======================================================================= -Standard_Boolean OpenGl_CappingAlgoFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_Element* theGlElement) -{ - if (!myFilter.IsNull() && !myFilter->ShouldRender (theWorkspace, theGlElement)) - { - return Standard_False; - } - - return theGlElement->IsFillDrawMode(); + theWorkspace->SetRenderFilter (aPrevFilter); } diff --git a/src/OpenGl/OpenGl_CappingAlgo.hxx b/src/OpenGl/OpenGl_CappingAlgo.hxx index e936779d8c..9ad192da13 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.hxx +++ b/src/OpenGl/OpenGl_CappingAlgo.hxx @@ -16,16 +16,12 @@ #ifndef _OpenGl_CappingAlgo_H__ #define _OpenGl_CappingAlgo_H__ -#include #include // Forward declaration -class OpenGl_CappingAlgoFilter; class OpenGl_CappingPlaneResource; class OpenGl_Structure; -DEFINE_STANDARD_HANDLE (OpenGl_CappingAlgoFilter, OpenGl_RenderFilter) - //! Capping surface rendering algorithm. class OpenGl_CappingAlgo { @@ -40,32 +36,4 @@ public: }; -//! Graphical capping rendering algorithm filter. -//! Filters out everything except shaded primitives. -class OpenGl_CappingAlgoFilter : public OpenGl_RenderFilter -{ -public: - - //! Default constructor. - OpenGl_CappingAlgoFilter() {} - - //! Sets the current active filter in workspace. - //! @param thePrevFilter [in] the previously active filter that should have additive effect. - void SetPreviousFilter (const Handle(OpenGl_RenderFilter)& thePrevFitler) { myFilter = thePrevFitler; } - - //! Checks whether the element can be rendered or not. - //! @param theElement [in] the element to check. - //! @return True if element can be rendered. - virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_Element* theGlElement) Standard_OVERRIDE; - -private: - - Handle(OpenGl_RenderFilter) myFilter; //!< Previous active filter that should be combined. - -public: - - DEFINE_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter,OpenGl_RenderFilter) -}; - #endif diff --git a/src/OpenGl/OpenGl_Element.hxx b/src/OpenGl/OpenGl_Element.hxx index 1df5afec69..0708f42c14 100644 --- a/src/OpenGl/OpenGl_Element.hxx +++ b/src/OpenGl/OpenGl_Element.hxx @@ -17,6 +17,7 @@ #define OpenGl_Element_Header #include +#include class OpenGl_Workspace; class OpenGl_Context; @@ -59,30 +60,6 @@ public: //! Return TRUE if primitive type generates shaded triangulation (to be used in filters). virtual Standard_Boolean IsFillDrawMode() const { return false; } -public: - - //! Render element if it passes the filtering procedure. This method should - //! be used for elements which can be used in scope of rendering algorithms. - //! E.g. elements of groups during recursive rendering. - //! If render filter is null, pure rendering is performed. - //! @param theWorkspace [in] the rendering workspace. - //! @param theFilter [in] the rendering filter to check whether the element - //! should be rendered or not. - //! @return True if element passes the check and renders, - inline Standard_Boolean - RenderFiltered (const Handle(OpenGl_Workspace)& theWorkspace, - const Handle(OpenGl_RenderFilter)& theFilter) const - { - if (!theFilter.IsNull() && !theFilter->ShouldRender (theWorkspace, this)) - { - return Standard_False; - } - - Render (theWorkspace); - - return Standard_True; - } - protected: Standard_EXPORT virtual ~OpenGl_Element(); diff --git a/src/OpenGl/OpenGl_Group.cxx b/src/OpenGl/OpenGl_Group.cxx index 1d44dd97f5..c9211adcc5 100644 --- a/src/OpenGl/OpenGl_Group.cxx +++ b/src/OpenGl/OpenGl_Group.cxx @@ -27,9 +27,31 @@ #include #include - IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group) +namespace +{ + //! Render element if it passes the filtering procedure. This method should + //! be used for elements which can be used in scope of rendering algorithms. + //! E.g. elements of groups during recursive rendering. + //! If render filter is null, pure rendering is performed. + //! @param theWorkspace [in] the rendering workspace. + //! @param theFilter [in] the rendering filter to check whether the element + //! should be rendered or not. + //! @return True if element passes the check and renders, + static bool renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace, + OpenGl_Element* theElement) + { + if (!theWorkspace->ShouldRender (theElement)) + { + return false; + } + + theElement->Render (theWorkspace); + return true; + } +} + // ======================================================================= // function : OpenGl_Group // purpose : @@ -393,8 +415,6 @@ void OpenGl_Group::AddElement (OpenGl_Element* theElem) // ======================================================================= void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const { - const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter(); - // Setup aspects theWorkspace->SetAllowFaceCulling (myIsClosed && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn()); @@ -402,15 +422,15 @@ void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace(); const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker(); const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText(); - Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter); - Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter); - Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter); - Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter); + const bool isLineSet = myAspectLine && renderFiltered (theWorkspace, myAspectLine); + const bool isFaceSet = myAspectFace && renderFiltered (theWorkspace, myAspectFace); + const bool isMarkerSet = myAspectMarker && renderFiltered (theWorkspace, myAspectMarker); + const bool isTextSet = myAspectText && renderFiltered (theWorkspace, myAspectText); // Render group elements for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next) { - aNodeIter->elem->RenderFiltered (theWorkspace, aFilter); + renderFiltered (theWorkspace, aNodeIter->elem); } // Restore aspects diff --git a/src/OpenGl/OpenGl_LayerList.cxx b/src/OpenGl/OpenGl_LayerList.cxx index 6a0856d6b9..c19ad51df6 100644 --- a/src/OpenGl/OpenGl_LayerList.cxx +++ b/src/OpenGl/OpenGl_LayerList.cxx @@ -148,9 +148,7 @@ OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities) myNbPriorities (theNbPriorities), myNbStructures (0), myImmediateNbStructures (0), - myModifStateOfRaytraceable (0), - myRenderOpaqueFilter (new OpenGl_OpaqueFilter()), - myRenderTranspFilter (new OpenGl_TransparentFilter()) + myModifStateOfRaytraceable (0) { // insert default priority layers myLayers.Append (new OpenGl_Layer (myNbPriorities, myBVHBuilder)); @@ -558,10 +556,8 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, // was preallocated before going into this method and has enough space to keep // maximum number of references to layers, therefore it will not increase memory // fragmentation during regular rendering. - const Handle(OpenGl_RenderFilter) aPrevFilter = theWorkspace->GetRenderFilter(); - myRenderOpaqueFilter->SetPreviousFilter (aPrevFilter); - myRenderTranspFilter->SetPreviousFilter (aPrevFilter); - theWorkspace->SetRenderFilter (myRenderOpaqueFilter); + const Standard_Integer aPrevFilter = theWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly); + theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_OpaqueOnly); myTransparentToProcess.Clear(); @@ -647,12 +643,12 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, // Render opaque OpenGl elements of a layer and count the number of skipped. // If a layer has skipped (e.g. transparent) elements it should be added into // the transparency post-processing stack. - myRenderOpaqueFilter->SetSkippedCounter (0); + theWorkspace->ResetSkippedCounter(); aLayer.Render (theWorkspace, aDefaultSettings); if (aPassIter != 0 - && myRenderOpaqueFilter->NbSkipped() > 0) + && theWorkspace->NbSkippedTransparentElements() > 0) { myTransparentToProcess.Push (&aLayer); } @@ -716,7 +712,8 @@ void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)& theW OpenGl_View* aView = theWorkspace->View(); const float aDepthFactor = aView != NULL ? aView->RenderingParams().OitDepthFactor : 0.0f; - theWorkspace->SetRenderFilter (myRenderTranspFilter); + const Standard_Integer aPrevFilter = theWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly); + theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_TransparentOnly); aCtx->core11fwd->glEnable (GL_BLEND); @@ -764,7 +761,7 @@ void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)& theW aCtx->SetDrawBuffers (1, aDrawBuffers); } - theWorkspace->SetRenderFilter (myRenderOpaqueFilter); + theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_OpaqueOnly); if (isEnabledOit) { const Standard_Boolean isMSAA = theReadDrawFbo && theReadDrawFbo->NbSamples() > 0; @@ -815,55 +812,3 @@ void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)& theW aCtx->core11fwd->glDepthMask (theGlobalSettings.DepthMask); aCtx->core11fwd->glDepthFunc (theGlobalSettings.DepthFunc); } - -//======================================================================= -//class : OpenGl_OpaqueFilter -//function : ShouldRender -//purpose : Checks whether the element should be rendered or skipped. -//======================================================================= -Standard_Boolean OpenGl_LayerList::OpenGl_OpaqueFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_Element* theGlElement) -{ - if (!myFilter.IsNull() - && !myFilter->ShouldRender (theWorkspace, theGlElement)) - { - return Standard_False; - } - - if (!theGlElement->IsFillDrawMode()) - { - return Standard_True; - } - - if (OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(), - theWorkspace->HighlightStyle())) - { - ++mySkippedCounter; - return Standard_False; - } - - return Standard_True; -} - -//======================================================================= -//class : OpenGl_TransparentFilter -//function : ShouldRender -//purpose : Checks whether the element should be rendered or skipped. -//======================================================================= -Standard_Boolean OpenGl_LayerList::OpenGl_TransparentFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_Element* theGlElement) -{ - if (!myFilter.IsNull() - && !myFilter->ShouldRender (theWorkspace, theGlElement)) - { - return Standard_False; - } - - if (!theGlElement->IsFillDrawMode()) - { - return dynamic_cast (theGlElement) != NULL; - } - - return OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(), - theWorkspace->HighlightStyle()); -} diff --git a/src/OpenGl/OpenGl_LayerList.hxx b/src/OpenGl/OpenGl_LayerList.hxx index bf4063c49b..3701607734 100644 --- a/src/OpenGl/OpenGl_LayerList.hxx +++ b/src/OpenGl/OpenGl_LayerList.hxx @@ -120,65 +120,6 @@ public: protected: - //! Filter of TKOpenGl elements for processing only shading geometry and - //! for collecting number of skipped elements to an external counter. - class OpenGl_OpaqueFilter : public OpenGl_RenderFilter - { - public: - - //! Constructor. - //! @param thePrevFilter [in] the previously active filter that should have additive effect. - OpenGl_OpaqueFilter() : mySkippedCounter (0) {} - - //! Sets the current active filter in workspace. - //! @param thePrevFilter [in] the previously active filter that should have additive effect. - void SetPreviousFilter (const Handle(OpenGl_RenderFilter)& thePrevFitler) { myFilter = thePrevFitler; } - - //! Sets the value of the skipped elements counter. - void SetSkippedCounter (const Standard_Size theCounter) { mySkippedCounter = theCounter; } - - //! Returns number of skipped elements. - Standard_Size NbSkipped() const { return mySkippedCounter; } - - //! Checks whether the element should be rendered or skipped. - //! @param theWorkspace [in] the currently used workspace for rendering. - //! @param theGlElement [in] the TKOpenGl rendering queue element that should be checked before streaming to GPU. - Standard_EXPORT virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_Element* theGlElement) Standard_OVERRIDE; - - DEFINE_STANDARD_RTTI_INLINE (OpenGl_OpaqueFilter, OpenGl_RenderFilter) - - private: - - Standard_Size mySkippedCounter; //!< Counter of skipped elements. - Handle(OpenGl_RenderFilter) myFilter; //!< Previous active filter that should be combined. - }; - - //! Filter of TKOpenGl elements for keeping only shading geometry with transparency. - class OpenGl_TransparentFilter : public OpenGl_RenderFilter - { - public: - - //! Constructor. - OpenGl_TransparentFilter() {} - - //! Sets the current active filter in workspace. - //! @param thePrevFilter [in] the previously active filter that should have additive effect. - void SetPreviousFilter (const Handle(OpenGl_RenderFilter)& thePrevFitler) { myFilter = thePrevFitler; } - - //! Checks whether the element should be rendered or skipped. - //! @param theWorkspace [in] the currently used workspace for rendering. - //! @param theGlElement [in] the TKOpenGl rendering queue element that should be checked before streaming to GPU. - Standard_EXPORT virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_Element* theGlElement) Standard_OVERRIDE; - - DEFINE_STANDARD_RTTI_INLINE (OpenGl_TransparentFilter, OpenGl_RenderFilter) - - private: - - Handle(OpenGl_RenderFilter) myFilter; //!< Previous active filter that should be combined. - }; - //! Stack of references to existing layers of predefined maximum size. class OpenGl_LayerStack { @@ -261,9 +202,6 @@ protected: //! Collection of references to layers with transparency gathered during rendering pass. mutable OpenGl_LayerStack myTransparentToProcess; - Handle(OpenGl_OpaqueFilter) myRenderOpaqueFilter; //!< rendering filter for opaque drawing pass (blended OIT). - Handle(OpenGl_TransparentFilter) myRenderTranspFilter; //!< rendering filter for transparency drawing pass (blended OIT). - public: DEFINE_STANDARD_ALLOC diff --git a/src/OpenGl/OpenGl_RenderFilter.cxx b/src/OpenGl/OpenGl_RenderFilter.cxx deleted file mode 100755 index 8e516dd766..0000000000 --- a/src/OpenGl/OpenGl_RenderFilter.cxx +++ /dev/null @@ -1,20 +0,0 @@ -// Created on: 2013-07-25 -// Created by: Anton POLETAEV -// Copyright (c) 2013-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 - - - -IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RenderFilter,Standard_Transient) \ No newline at end of file diff --git a/src/OpenGl/OpenGl_RenderFilter.hxx b/src/OpenGl/OpenGl_RenderFilter.hxx index ac1a156227..69344d0086 100755 --- a/src/OpenGl/OpenGl_RenderFilter.hxx +++ b/src/OpenGl/OpenGl_RenderFilter.hxx @@ -16,31 +16,16 @@ #ifndef _OpenGl_RenderFilter_H__ #define _OpenGl_RenderFilter_H__ -#include -#include - -class OpenGl_RenderFilter; -DEFINE_STANDARD_HANDLE (OpenGl_RenderFilter, Standard_Transient) - -class OpenGl_Element; -class OpenGl_Workspace; - -//! Base class for defining element rendering filters. -//! This class can be used in pair with advance rendering passes, and for -//! disabling rendering (setting up) graphical aspects. -class OpenGl_RenderFilter : public Standard_Transient +//! Filter for rendering elements. +enum OpenGl_RenderFilter { -public: + OpenGl_RenderFilter_Empty = 0x000, //!< disabled filter - //! Checks whether the element can be rendered or not. - //! @param theWorkspace [in] the current workspace. - //! @param theElement [in] the element to check. - //! @return True if element can be rendered. - virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, const OpenGl_Element* theElement) = 0; + OpenGl_RenderFilter_OpaqueOnly = 0x001, //!< render only opaque elements and any non-filling elements (conflicts with OpenGl_RenderFilter_TransparentOnly) + OpenGl_RenderFilter_TransparentOnly = 0x002, //!< render only semitransparent elements and OpenGl_AspectFace (conflicts with OpenGl_RenderFilter_OpaqueOnly) -public: - - DEFINE_STANDARD_RTTIEXT(OpenGl_RenderFilter, Standard_Transient) + OpenGl_RenderFilter_NonRaytraceableOnly = 0x004, //!< render only non-raytraceable elements + OpenGl_RenderFilter_FillModeOnly = 0x008, //!< render only filled elements }; #endif diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index be34e50c77..5154272a6f 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -1027,9 +1027,6 @@ protected: //! @name fields related to ray-tracing //! Set of IDs of non-raytracable elements (to detect updates). std::set myNonRaytraceStructureIDs; - //! Render filter to filter out all raytracable structures. - Handle(OpenGl_RaytraceFilter) myRaytraceFilter; - //! Marks if environment map should be updated. Standard_Boolean myToUpdateEnvironmentMap; diff --git a/src/OpenGl/OpenGl_View_Redraw.cxx b/src/OpenGl/OpenGl_View_Redraw.cxx index 247e44fac0..6db69341e2 100644 --- a/src/OpenGl/OpenGl_View_Redraw.cxx +++ b/src/OpenGl/OpenGl_View_Redraw.cxx @@ -1095,11 +1095,6 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, const Standard_Integer aSizeY = theReadDrawFbo != NULL ? theReadDrawFbo->GetVPSizeY() : myWindow->Height(); myOpenGlFBO ->InitLazy (aCtx, aSizeX, aSizeY, myFboColorFormat, myFboDepthFormat, 0); - if (myRaytraceFilter.IsNull()) - myRaytraceFilter = new OpenGl_RaytraceFilter; - - myRaytraceFilter->SetPrevRenderFilter (myWorkspace->GetRenderFilter()); - if (theReadDrawFbo != NULL) theReadDrawFbo->UnbindBuffer (aCtx); @@ -1109,7 +1104,8 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, // Render bottom OSD layer myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom, theReadDrawFbo, theOitAccumFbo); - myWorkspace->SetRenderFilter (myRaytraceFilter); + const Standard_Integer aPrevFilter = myWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_NonRaytraceableOnly); + myWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_NonRaytraceableOnly); { if (theReadDrawFbo != NULL) { @@ -1123,7 +1119,7 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection, // Render non-polygonal elements in default layer myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Default, theReadDrawFbo, theOitAccumFbo); } - myWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter()); + myWorkspace->SetRenderFilter (aPrevFilter); } if (theReadDrawFbo != NULL) diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 37060f3f41..7f5f59ceff 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -37,7 +37,6 @@ #include IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,Standard_Transient) -IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter,OpenGl_RenderFilter) namespace { @@ -126,6 +125,9 @@ OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Wi myUseZBuffer (Standard_True), myUseDepthWrite (Standard_True), // + myNbSkippedTranspElems (0), + myRenderFilter (OpenGl_RenderFilter_Empty), + // myAspectLineSet (&myDefaultAspectLine), myAspectFaceSet (&myDefaultAspectFace), myAspectMarkerSet (&myDefaultAspectMarker), @@ -158,8 +160,6 @@ OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Wi #endif } - myDefaultCappingAlgoFilter = new OpenGl_CappingAlgoFilter(); - myFontFaceAspect.Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Mask, 0.285f); myFontFaceAspect.Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT); @@ -483,14 +483,51 @@ Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& // function : ShouldRender // purpose : // ======================================================================= -Standard_Boolean OpenGl_RaytraceFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_Element* theElement) +bool OpenGl_Workspace::ShouldRender (const OpenGl_Element* theElement) { - Standard_Boolean aPrevFilterResult = Standard_True; - if (!myPrevRenderFilter.IsNull()) + // render only non-raytracable elements when RayTracing is enabled + if ((myRenderFilter & OpenGl_RenderFilter_NonRaytraceableOnly) != 0) { - aPrevFilterResult = myPrevRenderFilter->ShouldRender (theWorkspace, theElement); + if (OpenGl_Raytrace::IsRaytracedElement (theElement)) + { + return false; + } } - return aPrevFilterResult && - !OpenGl_Raytrace::IsRaytracedElement (theElement); + else if ((myRenderFilter & OpenGl_RenderFilter_FillModeOnly) != 0) + { + if (!theElement->IsFillDrawMode()) + { + return false; + } + } + + // handle opaque/transparency render passes + if ((myRenderFilter & OpenGl_RenderFilter_OpaqueOnly) != 0) + { + if (!theElement->IsFillDrawMode()) + { + return true; + } + + if (OpenGl_Context::CheckIsTransparent (myAspectFaceSet, myHighlightStyle)) + { + ++myNbSkippedTranspElems; + return false; + } + } + else if ((myRenderFilter & OpenGl_RenderFilter_TransparentOnly) != 0) + { + if (!theElement->IsFillDrawMode()) + { + if (dynamic_cast (theElement) == NULL) + { + return false; + } + } + else if (!OpenGl_Context::CheckIsTransparent (myAspectFaceSet, myHighlightStyle)) + { + return false; + } + } + return true; } diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index 7645942a51..33b97cee12 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -23,56 +23,17 @@ #include #include #include -#include #include #include #include #include +#include #include #include class OpenGl_View; class Image_PixMap; -class OpenGl_RaytraceFilter; -DEFINE_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter) - -//! Graphical ray-tracing filter. -//! Filters out all raytracable structures. -class OpenGl_RaytraceFilter : public OpenGl_RenderFilter -{ -public: - - //! Default constructor. - OpenGl_RaytraceFilter() {} - - //! Returns the previously set filter. - const Handle(OpenGl_RenderFilter)& PrevRenderFilter() - { - return myPrevRenderFilter; - } - - //! Remembers the previously set filter. - void SetPrevRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter) - { - myPrevRenderFilter = theFilter; - } - - //! Checks whether the element can be rendered or not. - //! @param theElement [in] the element to check. - //! @return True if element can be rendered. - virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, - const OpenGl_Element* theElement) Standard_OVERRIDE; - -private: - - Handle(OpenGl_RenderFilter) myPrevRenderFilter; - -public: - - DEFINE_STANDARD_RTTIEXT(OpenGl_RaytraceFilter,OpenGl_RenderFilter) -}; - class OpenGl_Workspace; DEFINE_STANDARD_HANDLE(OpenGl_Workspace,Standard_Transient) @@ -240,21 +201,26 @@ public: //! Clear the applied aspect state to default values. void ResetAppliedAspect(); - //! Set filter for restricting rendering of particular elements. - //! Filter can be applied for rendering passes used by recursive - //! rendering algorithms for rendering elements of groups. - //! @param theFilter [in] the filter instance. - inline void SetRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter) - { - myRenderFilter = theFilter; - } - //! Get rendering filter. - //! @return filter instance. - inline const Handle(OpenGl_RenderFilter)& GetRenderFilter() const - { - return myRenderFilter; - } + //! @sa ShouldRender() + Standard_Integer RenderFilter() const { return myRenderFilter; } + + //! Set filter for restricting rendering of particular elements. + //! @sa ShouldRender() + void SetRenderFilter (Standard_Integer theFilter) { myRenderFilter = theFilter; } + + //! Checks whether the element can be rendered or not. + //! @param theElement [in] the element to check + //! @return True if element can be rendered + bool ShouldRender (const OpenGl_Element* theElement); + + //! Return the number of skipped transparent elements within active OpenGl_RenderFilter_OpaqueOnly filter. + //! @sa OpenGl_LayerList::Render() + Standard_Integer NbSkippedTransparentElements() { return myNbSkippedTranspElems; } + + //! Reset skipped transparent elements counter. + //! @sa OpenGl_LayerList::Render() + void ResetSkippedCounter() { myNbSkippedTranspElems = 0; } //! @return applied view matrix. inline const OpenGl_Matrix* ViewMatrix() const { return ViewMatrix_applied; } @@ -265,9 +231,6 @@ public: //! Returns face aspect for textured font rendering. const OpenGl_AspectFace& FontFaceAspect() const { return myFontFaceAspect; } - //! Returns capping algorithm rendering filter. - const Handle(OpenGl_CappingAlgoFilter)& DefaultCappingAlgoFilter() const { return myDefaultCappingAlgoFilter; } - //! Returns face aspect for none culling mode. const OpenGl_AspectFace& NoneCulling() const { return myNoneCulling; } @@ -287,14 +250,15 @@ protected: //! @name protected fields Handle(OpenGl_Context) myGlContext; Standard_Boolean myUseZBuffer; Standard_Boolean myUseDepthWrite; - Handle(OpenGl_CappingAlgoFilter) myDefaultCappingAlgoFilter; OpenGl_AspectFace myNoneCulling; OpenGl_AspectFace myFrontCulling; OpenGl_AspectFace myFontFaceAspect; protected: //! @name fields related to status - Handle(OpenGl_RenderFilter) myRenderFilter; + Standard_Integer myNbSkippedTranspElems; //!< counter of skipped transparent elements for OpenGl_LayerList two rendering passes method + Standard_Integer myRenderFilter; //!< active filter for skipping rendering of elements by some criteria (multiple render passes) + const OpenGl_AspectLine* myAspectLineSet; const OpenGl_AspectFace* myAspectFaceSet; Handle(Graphic3d_AspectFillArea3d) myAspectFaceApplied; diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 76b261bad2..f408ac38e9 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -8539,6 +8539,49 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons aClipPlane->SetCappingMaterial (aMat); anArgIter += aNbParsed; } + else if ((aChangeArg == "-transparency" + || aChangeArg == "-transp") + && aNbChangeArgs >= 2) + { + TCollection_AsciiString aValStr (aChangeArgs[1]); + Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect(); + if (aValStr.IsRealValue()) + { + Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial(); + aMat.SetTransparency ((float )aValStr.RealValue()); + anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto); + aClipPlane->SetCappingMaterial (aMat); + } + else + { + aValStr.LowerCase(); + Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto; + if (aValStr == "opaque") + { + aMode = Graphic3d_AlphaMode_Opaque; + } + else if (aValStr == "mask") + { + aMode = Graphic3d_AlphaMode_Mask; + } + else if (aValStr == "blend") + { + aMode = Graphic3d_AlphaMode_Blend; + } + else if (aValStr == "blendauto") + { + aMode = Graphic3d_AlphaMode_BlendAuto; + } + else + { + std::cout << "Syntax error at '" << aValStr << "'\n"; + return 1; + } + anAspect->SetAlphaMode (aMode); + aClipPlane->SetCappingAspect (anAspect); + } + anArgIter += 1; + } else if (aChangeArg == "-texname" || aChangeArg == "texname") { @@ -12367,7 +12410,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "\n\t\t: [-set|-unset|-setOverrideGlobal [objects|views]]" "\n\t\t: [-maxPlanes]" "\n\t\t: [-capping {0|1}]" - "\n\t\t: [-color R G B] [-hatch {on|off|ID}]" + "\n\t\t: [-color R G B] [-transparency Value] [-hatch {on|off|ID}]" "\n\t\t: [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]" "\n\t\t: [-texRotate Angle]" "\n\t\t: [-useObjMaterial {0|1}] [-useObjTexture {0|1}]" @@ -12383,6 +12426,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "\n\t\t: Capping options:" "\n\t\t: -capping {off|on|0|1} turn capping on/off" "\n\t\t: -color R G B set capping color" + "\n\t\t: -transparency Value set capping transparency 0..1" "\n\t\t: -texName Texture set capping texture" "\n\t\t: -texScale SX SY set capping tex scale" "\n\t\t: -texOrigin TX TY set capping tex origin" diff --git a/tests/bugs/vis/bug29874 b/tests/bugs/vis/bug29874 new file mode 100644 index 0000000000..6e5f7db1d9 --- /dev/null +++ b/tests/bugs/vis/bug29874 @@ -0,0 +1,23 @@ +puts "============" +puts "0029874: Visualization - capping plane transparency does not work" +puts "============" +puts "" + +pload MODELING VISUALIZATION +box b1 -30 0 30 20 20 20 +box b2 -30 0 0 20 20 20 +box b3 -30 0 -30 20 20 20 +box b4 -30 0 -60 20 20 20 +vclear +vinit View1 +vzbufftrihedron +vdisplay -dispMode 1 b1 b2 b3 b4 +vviewparams -scale 12.7 -proj 0.6 -0.16 0.79 -up -0.65 0.5 0.58 -at -24 12.4 -1.1 +vaspects b1 b4 -setTransparency 0.5 +vaspects b2 -setColor RED +vaspects b3 -setColor GREEN + +vclipplane pln1 -set b1 b2 -equation -0.707 0.707 0 -25 -capping on -useObjMaterial 1 +vclipplane pln2 -set b3 b4 -equation -0.707 0.707 0 -25 -capping on -color 0.5 0.5 0.9 -transparency 0.2 + +vdump $imagedir/${casename}.png