1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0029874: Visualization - capping plane transparency does not work

Interface OpenGl_RenderFilter and its implementations have been merged into OpenGl_Workspace.
This limits flexibility of interface, but simplifies logic.
- OpenGl_RenderFilter_FillModeOnly flag replaces OpenGl_CappingAlgoFilter;
- OpenGl_RenderFilter_NonRaytraceableOnly flag replaces OpenGl_RaytraceFilter;
- OpenGl_RenderFilter_OpaqueOnly flag replaces OpenGl_OpaqueFilter;
- OpenGl_RenderFilter_TransparentOnly flag replaces OpenGl_TransparentFilter.

OpenGl_CappingAlgo now:
- avoids redundant Stencil clearing when Layer contains at least one transparent Element;
- renders semitransparent capping plane within transparent elements pass.

vclipplane command has been extended by new argument -transparency.
This commit is contained in:
kgv 2018-06-15 19:39:31 +03:00 committed by bugmaster
parent 14823c6f5e
commit 1b661a81d5
15 changed files with 249 additions and 363 deletions

View File

@ -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

View File

@ -24,23 +24,48 @@
#include <OpenGl_Structure.hxx>
#include <OpenGl_ShaderManager.hxx>
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);
}

View File

@ -16,16 +16,12 @@
#ifndef _OpenGl_CappingAlgo_H__
#define _OpenGl_CappingAlgo_H__
#include <OpenGl_RenderFilter.hxx>
#include <OpenGl_Group.hxx>
// 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

View File

@ -17,6 +17,7 @@
#define OpenGl_Element_Header
#include <OpenGl_RenderFilter.hxx>
#include <Standard_Type.hxx>
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();

View File

@ -27,9 +27,31 @@
#include <Graphic3d_ArrayOfPrimitives.hxx>
#include <Graphic3d_GroupDefinitionError.hxx>
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

View File

@ -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<const OpenGl_AspectFace*> (theGlElement) != NULL;
}
return OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(),
theWorkspace->HighlightStyle());
}

View File

@ -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

View File

@ -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 <OpenGl_RenderFilter.hxx>
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RenderFilter,Standard_Transient)

View File

@ -16,31 +16,16 @@
#ifndef _OpenGl_RenderFilter_H__
#define _OpenGl_RenderFilter_H__
#include <Standard_Type.hxx>
#include <Standard_Transient.hxx>
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

View File

@ -1027,9 +1027,6 @@ protected: //! @name fields related to ray-tracing
//! Set of IDs of non-raytracable elements (to detect updates).
std::set<Standard_Integer> myNonRaytraceStructureIDs;
//! Render filter to filter out all raytracable structures.
Handle(OpenGl_RaytraceFilter) myRaytraceFilter;
//! Marks if environment map should be updated.
Standard_Boolean myToUpdateEnvironmentMap;

View File

@ -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)

View File

@ -37,7 +37,6 @@
#include <NCollection_AlignedAllocator.hxx>
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<const OpenGl_AspectFace*> (theElement) == NULL)
{
return false;
}
}
else if (!OpenGl_Context::CheckIsTransparent (myAspectFaceSet, myHighlightStyle))
{
return false;
}
}
return true;
}

View File

@ -23,56 +23,17 @@
#include <OpenGl_FrameBuffer.hxx>
#include <OpenGl_Material.hxx>
#include <OpenGl_Matrix.hxx>
#include <OpenGl_RenderFilter.hxx>
#include <OpenGl_ShaderObject.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_TextParam.hxx>
#include <OpenGl_TextureBufferArb.hxx>
#include <OpenGl_RenderFilter.hxx>
#include <OpenGl_Vec.hxx>
#include <OpenGl_Window.hxx>
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;

View File

@ -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"

23
tests/bugs/vis/bug29874 Normal file
View File

@ -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