1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00

0024224: Suspicious logics in changing clipping planes at OpenGl_Structure

1) Resolved buggy situation of shared clip planes between view and structure;
2) Added clipping plane equation space identification - to be used with shaders;
3) Code refactoring to resolve performance issue reported by 0024189;
4) Attachment of stencil buffer to FBO.

Added test case bugs/vis/bug24224
This commit is contained in:
apl 2013-10-10 17:14:52 +04:00 committed by bugmaster
parent cbf1862449
commit b859a34d22
14 changed files with 461 additions and 247 deletions

View File

@ -57,3 +57,4 @@ Graphic3d_ClipPlane.hxx
Graphic3d_ClipPlane.cxx Graphic3d_ClipPlane.cxx
Graphic3d_ClipPlane_Handle.hxx Graphic3d_ClipPlane_Handle.hxx
Graphic3d_SetOfHClipPlane.hxx Graphic3d_SetOfHClipPlane.hxx
Graphic3d_SetOfHClipPlane_Handle.hxx

View File

@ -41,9 +41,10 @@ class Handle(Graphic3d_AspectFillArea3d);
//! Depending on usage context the class can be used to specify: //! Depending on usage context the class can be used to specify:
//! - Global clipping applied over the whole scene. //! - Global clipping applied over the whole scene.
//! - Object-level clipping applied for each particular object. //! - Object-level clipping applied for each particular object.
//! The plane equation is specified in "world" coordinate system.
//! Please note that the set of planes can define convex clipping volume. //! Please note that the set of planes can define convex clipping volume.
//! Be aware that number of clip planes supported by OpenGl is implementation //! Be aware that number of clip planes supported by OpenGl is implementation
//! dependant: at least 6 planes are available. Thus, take into account //! dependent: at least 6 planes are available. Thus, take into account
//! number of clipping planes passed for rendering: the object planes plus //! number of clipping planes passed for rendering: the object planes plus
//! the view defined ones. //! the view defined ones.
class Graphic3d_ClipPlane : public Standard_Transient class Graphic3d_ClipPlane : public Standard_Transient
@ -72,16 +73,18 @@ public:
//! @param theEquation [in] the plane equation. //! @param theEquation [in] the plane equation.
Standard_EXPORT Graphic3d_ClipPlane (const Equation& theEquation); Standard_EXPORT Graphic3d_ClipPlane (const Equation& theEquation);
//! Construct clip plane from the passed geomertical definition. //! Construct clip plane from the passed geometrical definition.
//! By default the plane is on, capping is turned off. //! By default the plane is on, capping is turned off.
//! @param thePlane [in] the plane. //! @param thePlane [in] the plane.
Standard_EXPORT Graphic3d_ClipPlane (const gp_Pln& thePlane); Standard_EXPORT Graphic3d_ClipPlane (const gp_Pln& thePlane);
//! Set plane equation by its geometrical definition. //! Set plane equation by its geometrical definition.
//! The equation is specified in "world" coordinate system.
//! @param thePlane [in] the plane. //! @param thePlane [in] the plane.
Standard_EXPORT void SetEquation (const gp_Pln& thePlane); Standard_EXPORT void SetEquation (const gp_Pln& thePlane);
//! Set 4-component equation vector for clipping plane. //! Set 4-component equation vector for clipping plane.
//! The equation is specified in "world" coordinate system.
//! @param theEquation [in] the XYZW (or "ABCD") equation vector. //! @param theEquation [in] the XYZW (or "ABCD") equation vector.
Standard_EXPORT void SetEquation (const Equation& theEquation); Standard_EXPORT void SetEquation (const Equation& theEquation);
@ -108,7 +111,7 @@ public:
//! @param theIsOn [in] the flag specifying whether the graphic driver should //! @param theIsOn [in] the flag specifying whether the graphic driver should
//! perform rendering of capping surface produced by this plane. The graphic //! perform rendering of capping surface produced by this plane. The graphic
//! driver produces this surface for convex graphics by means of stencil-test //! driver produces this surface for convex graphics by means of stencil-test
//! and multipass rendering. //! and multi-pass rendering.
Standard_EXPORT void SetCapping(const Standard_Boolean theIsOn); Standard_EXPORT void SetCapping(const Standard_Boolean theIsOn);
//! Check state of capping surface rendering. //! Check state of capping surface rendering.
@ -118,7 +121,7 @@ public:
return myIsCapping; return myIsCapping;
} }
//! Get geomertical definition. The plane is built up //! Get geometrical definition. The plane is built up
//! from the equation clipping plane equation vector. //! from the equation clipping plane equation vector.
//! @return geometrical definition of clipping plane. //! @return geometrical definition of clipping plane.
Standard_EXPORT gp_Pln ToPlane() const; Standard_EXPORT gp_Pln ToPlane() const;
@ -185,11 +188,11 @@ public: // @name user-defined graphical attributes
return myId; return myId;
} }
//! Compute and return capping apsect from the graphical attributes. //! Compute and return capping aspect from the graphical attributes.
//! @return capping surface rendering aspect. //! @return capping surface rendering aspect.
Standard_EXPORT Handle(Graphic3d_AspectFillArea3d) CappingAspect() const; Standard_EXPORT Handle(Graphic3d_AspectFillArea3d) CappingAspect() const;
public: // @name modificaton counters public: // @name modification counters
//! @return modification counter for equation. //! @return modification counter for equation.
unsigned int MCountEquation() const unsigned int MCountEquation() const

View File

@ -0,0 +1,28 @@
// Created on: 2013-10-08
// Created by: Anton POLETAEV
// Copyright (c) 2013 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 65 (the "License") You may not use the content of this file
// except in compliance with the License Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file
//
// The Initial Developer of the Original Code is Open CASCADE SAS, having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement Please see the License for the specific terms
// and conditions governing the rights and limitations under the License
#ifndef _Graphic3d_SetOfHClipPlane_Handle_HeaderFile
#define _Graphic3d_SetOfHClipPlane_Handle_HeaderFile
#include <NCollection_Handle.hxx>
#include <Graphic3d_SetOfHClipPlane.hxx>
typedef NCollection_Handle<Graphic3d_SetOfHClipPlane> Handle(Graphic3d_SetOfHClipPlane);
#endif

View File

@ -70,15 +70,11 @@ namespace
void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace, void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace,
const OpenGl_ListOfGroup& theGroups) const OpenGl_ListOfGroup& theGroups)
{ {
// do not draw capping surface for second transparency pass
if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSDO)
return;
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
// check whether algorithm need to be runned // check whether algorithm need to be performed
Standard_Boolean isCapping = Standard_False; Standard_Boolean isCapping = Standard_False;
Graphic3d_SetOfHClipPlane aContextPlanes = aContext->Clipping().Planes(); const Graphic3d_SetOfHClipPlane& aContextPlanes = aContext->Clipping().Planes();
Graphic3d_SetOfHClipPlane::Iterator aCappingIt (aContextPlanes); Graphic3d_SetOfHClipPlane::Iterator aCappingIt (aContextPlanes);
for (; aCappingIt.More(); aCappingIt.Next()) for (; aCappingIt.More(); aCappingIt.Next())
{ {
@ -92,7 +88,9 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
// do not perform algorithm is there is nothing to render // do not perform algorithm is there is nothing to render
if (!isCapping) if (!isCapping)
{
return; return;
}
// init internal data // init internal data
Init(); Init();
@ -146,7 +144,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
aGroupIt.Value()->Render (theWorkspace); aGroupIt.Value()->Render (theWorkspace);
} }
// override material, cull backfaces // override material, cull back faces
theWorkspace->SetAspectFace (FrontCulling()); theWorkspace->SetAspectFace (FrontCulling());
theWorkspace->AspectFace (Standard_True); theWorkspace->AspectFace (Standard_True);

View File

@ -19,6 +19,7 @@
#include <OpenGl_ClippingState.hxx> #include <OpenGl_ClippingState.hxx>
#include <OpenGl_GlCore11.hxx> #include <OpenGl_GlCore11.hxx>
#include <OpenGl_Workspace.hxx>
namespace namespace
{ {
@ -49,90 +50,34 @@ void OpenGl_ClippingState::Init (const Standard_Integer theMaxPlanes)
} }
// ======================================================================= // =======================================================================
// function : Planes // function : Add
// purpose : // purpose :
// ======================================================================= // =======================================================================
Graphic3d_SetOfHClipPlane OpenGl_ClippingState::Planes() const void OpenGl_ClippingState::Add (Graphic3d_SetOfHClipPlane& thePlanes,
{ const EquationCoords& theCoordSpace,
Graphic3d_SetOfHClipPlane aRes; const Handle(OpenGl_Workspace)& theWS)
OpenGl_MapOfContextPlanes::Iterator anIt (myPlanes);
for (; anIt.More(); anIt.Next())
{
aRes.Add (anIt.Key());
}
return aRes;
}
// =======================================================================
// function : IsSet
// purpose :
// =======================================================================
Standard_Boolean OpenGl_ClippingState::IsSet (const Handle(Graphic3d_ClipPlane)& thePlane) const
{
return myPlanes.IsBound (thePlane);
}
// =======================================================================
// function : Set
// purpose :
// =======================================================================
void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes,
const Standard_Boolean theToEnable)
{
Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
for (; aPlaneIt.More() && myEmptyPlaneIds->Available() > 0; aPlaneIt.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
if (IsSet (aPlane))
return;
Standard_Integer anId = myEmptyPlaneIds->Next();
myPlanes.Bind (aPlane, anId);
myPlaneStates.Bind (aPlane, theToEnable);
const GLenum anOpenGlId = (GLenum)anId;
if (theToEnable)
{
glEnable (anOpenGlId);
}
else
{
glDisable (anOpenGlId);
}
glClipPlane (anOpenGlId, aPlane->GetEquation());
}
}
// =======================================================================
// function : Set
// purpose :
// =======================================================================
void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes,
const OpenGl_Matrix* theViewMatrix,
const Standard_Boolean theToEnable)
{ {
GLint aMatrixMode; GLint aMatrixMode;
glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
OpenGl_Matrix aCurrentMat; OpenGl_Matrix aCurrentMx;
glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*)aCurrentMat.mat); glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*) &aCurrentMx);
if (aMatrixMode != GL_MODELVIEW) if (aMatrixMode != GL_MODELVIEW)
{ {
glMatrixMode (GL_MODELVIEW); glMatrixMode (GL_MODELVIEW);
} }
// load equation transform matrices switch (theCoordSpace)
glLoadMatrixf ((theViewMatrix != NULL) {
? (const GLfloat*)theViewMatrix->mat case EquationCoords_View: glLoadMatrixf ((const GLfloat*) &OpenGl_IdentityMatrix); break;
: (const GLfloat*)OpenGl_IdentityMatrix.mat); case EquationCoords_World: glLoadMatrixf ((const GLfloat*) theWS->ViewMatrix()); break;
}
Set (thePlanes, theToEnable); Add (thePlanes, theCoordSpace);
// restore model-view matrix // restore model-view matrix
glLoadMatrixf ((GLfloat*)aCurrentMat.mat); glLoadMatrixf ((GLfloat*) &aCurrentMx);
// restore context matrix state // restore context matrix state
if (aMatrixMode != GL_MODELVIEW) if (aMatrixMode != GL_MODELVIEW)
@ -142,86 +87,72 @@ void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes,
} }
// ======================================================================= // =======================================================================
// function : Unset // function : Add
// purpose : // purpose :
// ======================================================================= // =======================================================================
void OpenGl_ClippingState::Unset (const Graphic3d_SetOfHClipPlane& thePlanes) void OpenGl_ClippingState::Add (Graphic3d_SetOfHClipPlane& thePlanes, const EquationCoords& theCoordSpace)
{
Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
while (aPlaneIt.More() && myEmptyPlaneIds->Available() > 0)
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
if (Contains (aPlane))
{
thePlanes.Remove (aPlaneIt);
continue;
}
Standard_Integer anID = myEmptyPlaneIds->Next();
myPlanes.Add (aPlane);
myPlaneStates.Bind (aPlane, PlaneProps (theCoordSpace, anID, Standard_True));
glEnable ((GLenum)anID);
glClipPlane ((GLenum)anID, aPlane->GetEquation());
aPlaneIt.Next();
}
while (aPlaneIt.More() && myEmptyPlaneIds->Available() == 0)
{
thePlanes.Remove (aPlaneIt);
}
}
// =======================================================================
// function : Remove
// purpose :
// =======================================================================
void OpenGl_ClippingState::Remove (const Graphic3d_SetOfHClipPlane& thePlanes)
{ {
Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes); Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
for (; aPlaneIt.More(); aPlaneIt.Next()) for (; aPlaneIt.More(); aPlaneIt.Next())
{ {
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
if (!IsSet (aPlane)) if (!Contains (aPlane))
{
continue; continue;
}
Standard_Integer anId = myPlanes.Find (aPlane); Standard_Integer anID = myPlaneStates.Find (aPlane).ContextID;
myEmptyPlaneIds->Free (anId); myEmptyPlaneIds->Free (anID);
myPlanes.UnBind (aPlane);
myPlaneStates.UnBind (aPlane); myPlaneStates.UnBind (aPlane);
const GLenum anOpenGlId = (GLenum)anId; glDisable ((GLenum)anID);
glDisable (anOpenGlId);
glClipPlane (anOpenGlId, OpenGl_DefaultPlaneEq);
} }
}
// // renew collection of planes
//// ======================================================================= aPlaneIt.Init (myPlanes);
//// function : SetPlane while (aPlaneIt.More())
//// purpose : {
//// ======================================================================= const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
//Standard_Boolean OpenGl_ClippingState::SetPlane (const Handle(Graphic3d_ClipPlane)& thePlane, if (!myPlaneStates.IsBound (aPlane))
// const Standard_Boolean theToEnable) {
//{ myPlanes.Remove (aPlaneIt);
// if (myEmptyPlaneIds->Available() == 0) }
// return Standard_False; else
// {
// if (IsPlaneSet (thePlane)) aPlaneIt.Next();
// return Standard_True; }
// }
// Standard_Integer aPlaneId = myEmptyPlaneIds->Next();
// myPlanes.Bind (thePlane, aPlaneId);
// myPlaneStates.Bind (thePlane, theToEnable);
// if (theToEnable)
// glEnable (aPlaneId);
// else
// glDisable (aPlaneId);
//
// glClipPlane (aPlaneId, thePlane->GetEquation());
//
// return Standard_True;
//}
//// =======================================================================
//// function : UnsetPlane
//// purpose :
//// =======================================================================
//void OpenGl_ClippingState::UnsetPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
//{
// if (!IsPlaneSet (thePlane))
// return;
//
// Standard_Integer aPlaneId = myPlanes.Find (thePlane);
//
// myEmptyPlaneIds->Free (aPlaneId);
// myPlanes.UnBind (thePlane);
// myPlaneStates.UnBind (thePlane);
//
// glDisable (aPlaneId);
// glClipPlane (aPlaneId, OpenGl_DefaultPlaneEq);
//}
// =======================================================================
// function : IsEnabled
// purpose :
// =======================================================================
Standard_Boolean OpenGl_ClippingState::IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const
{
Standard_Boolean isSet;
return IsSet (thePlane)
&& myPlaneStates.Find (thePlane, isSet)
&& isSet;
} }
// ======================================================================= // =======================================================================
@ -231,18 +162,26 @@ Standard_Boolean OpenGl_ClippingState::IsEnabled (const Handle(Graphic3d_ClipPla
void OpenGl_ClippingState::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane, void OpenGl_ClippingState::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
const Standard_Boolean theIsEnabled) const Standard_Boolean theIsEnabled)
{ {
if (!IsSet (thePlane)) if (!Contains (thePlane))
{
return; return;
}
Standard_Boolean& aState = myPlaneStates.ChangeFind (thePlane); PlaneProps& aProps = myPlaneStates.ChangeFind (thePlane);
if (theIsEnabled == aState) if (theIsEnabled == aProps.IsEnabled)
{
return; return;
}
Standard_Integer aPlaneId = myPlanes.Find (thePlane); GLenum anID = (GLenum)aProps.ContextID;
if (theIsEnabled) if (theIsEnabled)
glEnable (aPlaneId); {
glEnable (anID);
}
else else
glDisable (aPlaneId); {
glDisable (anID);
}
aState = theIsEnabled; aProps.IsEnabled = theIsEnabled;
} }

View File

@ -27,6 +27,7 @@
#include <NCollection_Handle.hxx> #include <NCollection_Handle.hxx>
#include <Standard_TypeDef.hxx> #include <Standard_TypeDef.hxx>
#include <OpenGl_Matrix.hxx> #include <OpenGl_Matrix.hxx>
#include <Handle_OpenGl_Workspace.hxx>
//! This class contains logics related to tracking and modification of clipping plane //! This class contains logics related to tracking and modification of clipping plane
//! state for particular OpenGl context. It contains information about enabled //! state for particular OpenGl context. It contains information about enabled
@ -37,67 +38,179 @@ class OpenGl_ClippingState
{ {
public: public:
//! Enumerates supported equation coordinate spaces.
enum EquationCoords
{
EquationCoords_View,
EquationCoords_World
};
public: //! @name general methods
//! Default constructor. //! Default constructor.
Standard_EXPORT OpenGl_ClippingState (); Standard_EXPORT OpenGl_ClippingState();
//! Initialize. //! Initialize.
//! @param theMaxPlanes [in] number of clipping planes supported by OpenGl context. //! @param theMaxPlanes [in] number of clipping planes supported by OpenGl context.
Standard_EXPORT void Init (const Standard_Integer theMaxPlanes); Standard_EXPORT void Init (const Standard_Integer theMaxPlanes);
//! @return sequence of set clipping planes. public: //! @name non-modifying getters
Standard_EXPORT Graphic3d_SetOfHClipPlane Planes() const;
//! Check whether the clipping plane has been set for the current context state. //! Check whether the clipping plane has been added to the current context state.
//! @param thePlane [in] the plane to check. //! @param thePlane [in] the plane to check.
//! @return True if plane is set. //! @return True if plane is set.
Standard_EXPORT Standard_Boolean IsSet (const Handle(Graphic3d_ClipPlane)& thePlane) const; inline Standard_Boolean Contains (const Handle(Graphic3d_ClipPlane)& thePlane) const
{
return myPlaneStates.IsBound (thePlane);
}
//! Set collection of clipping planes for available plane ids. Current model view matrix is used. //! Get clip planes defined for context.
//! @param thePlanes [in] collection of planes. //! @return sequence of set clipping planes.
//! @param theToEnable [in] the boolean flag notifying whether the planes should be enabled. inline const Graphic3d_SetOfHClipPlane& Planes() const
Standard_EXPORT void Set (const Graphic3d_SetOfHClipPlane& thePlanes, {
const Standard_Boolean theToEnable = Standard_True); return myPlanes;
}
//! Set collection of clipping planes for available plane ids. Identity matrix in case //! @return kind of equation coordinate space used for the clip plane.
//! if passed matrix pointer is NULL. inline EquationCoords GetEquationSpace (const Handle(Graphic3d_ClipPlane)& thePlane) const
//! @param thePlanes [in] collection of planes. {
//! @param theViewMatrix [in] view matrix to be used to define plane equation. return myPlaneStates.Find (thePlane).CoordSpace;
//! @param theToEnable [in] the boolean flag notifying whether the planes should be enabled. }
Standard_EXPORT void Set (const Graphic3d_SetOfHClipPlane& thePlanes,
const OpenGl_Matrix* theViewMatrix,
const Standard_Boolean theToEnable = Standard_True);
//! Unset and disable collection of clipping planes.
//! @param thePlanes [in] the plane to deactivate.
Standard_EXPORT void Unset (const Graphic3d_SetOfHClipPlane& thePlanes);
//! Check whether the clipping plane has been set and enabled for the current context state. //! Check whether the clipping plane has been set and enabled for the current context state.
//! @param thePlane [in] the plane to check. //! @param thePlane [in] the plane to check.
//! @return True if plane is enabled. //! @return True if plane is enabled.
Standard_EXPORT Standard_Boolean IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const; inline Standard_Boolean IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const
{
return myPlaneStates.Find (thePlane).IsEnabled;
}
//! Change enabled / disabled state of the clipping plane. public: //! @name clipping state modification commands
//! @param thePlane [in] the plane to change the state.
//! @param theIsEnabled [in] the flag indicating whether the plane should be enabled or not. //! Add planes to the context clipping at the specified system of coordinates.
//! @return False if plane is not set for the context. //! This methods loads appropriate transformation matrix from workspace to
Standard_EXPORT void SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane, const Standard_Boolean theIsEnabled); //! to transform equation coordinates. The planes become enabled in the context.
//! If the number of the passed planes exceeds capabilities of OpenGl, the last planes
//! are simply ignored.
//! @param thePlanes [in/out] the list of planes to be added.
//! The list then provides information on which planes were really added to clipping state.
//! This list then can be used to fall back to previous state.
//! @param theCoordSpace [in] the equation definition space.
//! @param theWS [in] the workspace to access the matrices.
Standard_EXPORT void Add (Graphic3d_SetOfHClipPlane& thePlanes,
const EquationCoords& theCoordSpace,
const Handle(OpenGl_Workspace)& theWS);
//! Add planes to the context clipping at the specified system of coordinates.
//! This method assumes that appropriate matrix is already set in context state.
//! If the number of the passed planes exceeds capabilities of OpenGl, the last planes
//! are simply ignored.
//! @param thePlanes [in/out] the list of planes to be added.
//! The list then provides information on which planes were really added to clipping state.
//! This list then can be used to fall back to previous state.
//! @param theCoordSpace [in] the equation definition space.
Standard_EXPORT void Add (Graphic3d_SetOfHClipPlane& thePlanes,
const EquationCoords& theCoordSpace);
//! Remove the passed set of clipping planes from the context state.
//! @param thePlanes [in] the planes to remove from list.
Standard_EXPORT void Remove (const Graphic3d_SetOfHClipPlane& thePlanes);
//! Enable or disable clipping plane in the OpenGl context.
//! @param thePlane [in] the plane to affect.
//! @param theIsEnabled [in] the state of the plane.
Standard_EXPORT void SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
const Standard_Boolean theIsEnabled);
public: //! @name Short-cuts
//! Add planes to the context clipping at the view system of coordinates.
//! If the number of the passed planes exceeds capabilities of OpenGl, the last planes
//! are simply ignored.
//! @param thePlanes [in/out] the list of planes to be added.
//! The list then provides information on which planes were really added to clipping state.
//! This list then can be used to fall back to previous state.
//! @param theWS [in] the workspace to access the matrices.
inline void AddView (Graphic3d_SetOfHClipPlane& thePlanes, const Handle(OpenGl_Workspace)& theWS)
{
Add (thePlanes, EquationCoords_View, theWS);
}
//! Add planes to the context clipping at the view system of coordinates.
//! If the number of the passed planes exceeds capabilities of OpenGl, the last planes
//! are simply ignored.
//! @param thePlanes [in/out] the list of planes to be added.
//! The list then provides information on which planes were really added to clipping state.
//! This list then can be used to fall back to previous state.
inline void AddView (Graphic3d_SetOfHClipPlane& thePlanes)
{
Add (thePlanes, EquationCoords_View);
}
//! Add planes to the context clipping at the world system of coordinates.
//! If the number of the passed planes exceeds capabilities of OpenGl, the last planes
//! are simply ignored.
//! @param thePlanes [in/out] the list of planes to be added.
//! The list then provides information on which planes were really added to clipping state.
//! This list then can be used to fall back to previous state.
//! @param theWS [in] the workspace to access the matrices.
inline void AddWorld (Graphic3d_SetOfHClipPlane& thePlanes, const Handle(OpenGl_Workspace)& theWS)
{
Add (thePlanes, EquationCoords_World, theWS);
}
//! Add planes to the context clipping at the world system of coordinates.
//! If the number of the passed planes exceeds capabilities of OpenGl, the last planes
//! are simply ignored.
//! @param thePlanes [in/out] the list of planes to be added.
//! The list then provides information on which planes were really added to clipping state.
//! This list then can be used to fall back to previous state.
inline void AddWorld (Graphic3d_SetOfHClipPlane& thePlanes)
{
Add (thePlanes, EquationCoords_World);
}
//! Remove all of the planes from context state.
inline void RemoveAll()
{
Remove (Planes());
}
private: private:
typedef NCollection_DataMap<Handle(Graphic3d_ClipPlane), Standard_Integer> OpenGl_MapOfContextPlanes; struct PlaneProps
typedef NCollection_DataMap<Handle(Graphic3d_ClipPlane), Standard_Boolean> OpenGl_MapOfPlaneStates; {
// declare default constructor
// to allow compilation of template collections
PlaneProps() {}
PlaneProps (const EquationCoords theCoords,
const Standard_Integer theID,
const Standard_Boolean theIsEnabled)
{
CoordSpace = theCoords;
ContextID = theID;
IsEnabled = theIsEnabled;
}
EquationCoords CoordSpace;
Standard_Integer ContextID;
Standard_Boolean IsEnabled;
};
private:
typedef NCollection_DataMap<Handle(Graphic3d_ClipPlane), PlaneProps> OpenGl_MapOfPlaneStates;
typedef NCollection_Handle<Aspect_GenId> OpenGl_EmptyPlaneIds; typedef NCollection_Handle<Aspect_GenId> OpenGl_EmptyPlaneIds;
OpenGl_MapOfContextPlanes myPlanes; //!< map of clip planes bound for the ids Graphic3d_SetOfHClipPlane myPlanes; //!< defined clipping planes.
OpenGl_MapOfPlaneStates myPlaneStates; //!< map of clip planes state (enabled/disabled). OpenGl_MapOfPlaneStates myPlaneStates; //!< map of clip planes bound for the props.
OpenGl_EmptyPlaneIds myEmptyPlaneIds; //!< generator of empty ids OpenGl_EmptyPlaneIds myEmptyPlaneIds; //!< generator of empty ids.
private: private:
//! Copying allowed only within Handles //! Copying allowed only within Handles
OpenGl_ClippingState (const OpenGl_ClippingState& ); OpenGl_ClippingState (const OpenGl_ClippingState& );
OpenGl_ClippingState& operator= (const OpenGl_ClippingState& ); OpenGl_ClippingState& operator= (const OpenGl_ClippingState& );
}; };
#endif #endif

View File

@ -88,6 +88,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
extGS (NULL), extGS (NULL),
extBgra(Standard_False), extBgra(Standard_False),
extAnis(Standard_False), extAnis(Standard_False),
extPDS(Standard_False),
atiMem (Standard_False), atiMem (Standard_False),
nvxMem (Standard_False), nvxMem (Standard_False),
mySharedResources (new OpenGl_ResourcesMap()), mySharedResources (new OpenGl_ResourcesMap()),
@ -640,6 +641,7 @@ void OpenGl_Context::init()
arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two"); arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
extBgra = CheckExtension ("GL_EXT_bgra"); extBgra = CheckExtension ("GL_EXT_bgra");
extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic"); extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
extPDS = CheckExtension ("GL_EXT_packed_depth_stencil");
atiMem = CheckExtension ("GL_ATI_meminfo"); atiMem = CheckExtension ("GL_ATI_meminfo");
nvxMem = CheckExtension ("GL_NVX_gpu_memory_info"); nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");

View File

@ -313,6 +313,7 @@ public: // extensions
OpenGl_ExtGS* extGS; //!< GL_EXT_geometry_shader4 OpenGl_ExtGS* extGS; //!< GL_EXT_geometry_shader4
Standard_Boolean extBgra; //!< GL_EXT_bgra Standard_Boolean extBgra; //!< GL_EXT_bgra
Standard_Boolean extAnis; //!< GL_EXT_texture_filter_anisotropic Standard_Boolean extAnis; //!< GL_EXT_texture_filter_anisotropic
Standard_Boolean extPDS; //!< GL_EXT_packed_depth_stencil
Standard_Boolean atiMem; //!< GL_ATI_meminfo Standard_Boolean atiMem; //!< GL_ATI_meminfo
Standard_Boolean nvxMem; //!< GL_NVX_gpu_memory_info Standard_Boolean nvxMem; //!< GL_NVX_gpu_memory_info

View File

@ -47,7 +47,8 @@ OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
myTextFormat (theTextureFormat), myTextFormat (theTextureFormat),
myGlTextureId (NO_TEXTURE), myGlTextureId (NO_TEXTURE),
myGlFBufferId (NO_FRAMEBUFFER), myGlFBufferId (NO_FRAMEBUFFER),
myGlDepthRBId (NO_RENDERBUFFER) myGlDepthRBId (NO_RENDERBUFFER),
myGlStencilRBId (NO_RENDERBUFFER)
{ {
// //
} }
@ -95,10 +96,26 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
return Standard_False; return Standard_False;
} }
// Create RenderBuffer (will be used as depth buffer) if (!theGlContext->extPDS)
theGlContext->extFBO->glGenRenderbuffersEXT (1, &myGlDepthRBId); {
theGlContext->extFBO->glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, myGlDepthRBId); // Create RenderBuffer to be used as depth buffer
theGlContext->extFBO->glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mySizeX, mySizeY); theGlContext->extFBO->glGenRenderbuffersEXT (1, &myGlDepthRBId);
theGlContext->extFBO->glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, myGlDepthRBId);
theGlContext->extFBO->glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mySizeX, mySizeY);
// Create RenderBuffer to be used as stencil buffer
theGlContext->extFBO->glGenRenderbuffersEXT (1, &myGlStencilRBId);
theGlContext->extFBO->glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, myGlStencilRBId);
theGlContext->extFBO->glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, mySizeX, mySizeY);
}
else
{
// Create combined depth stencil buffer
theGlContext->extFBO->glGenRenderbuffersEXT (1, &myGlDepthRBId);
theGlContext->extFBO->glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, myGlDepthRBId);
theGlContext->extFBO->glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, mySizeX, mySizeY);
myGlStencilRBId = myGlDepthRBId;
}
// Build FBO and setup it as texture // Build FBO and setup it as texture
theGlContext->extFBO->glGenFramebuffersEXT (1, &myGlFBufferId); theGlContext->extFBO->glGenFramebuffersEXT (1, &myGlFBufferId);
@ -107,6 +124,7 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
glBindTexture (GL_TEXTURE_2D, myGlTextureId); glBindTexture (GL_TEXTURE_2D, myGlTextureId);
theGlContext->extFBO->glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, myGlTextureId, 0); theGlContext->extFBO->glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, myGlTextureId, 0);
theGlContext->extFBO->glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, myGlDepthRBId); theGlContext->extFBO->glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, myGlDepthRBId);
theGlContext->extFBO->glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, myGlStencilRBId);
if (theGlContext->extFBO->glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) if (theGlContext->extFBO->glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{ {
if (!isPowerOfTwo (mySizeX) || !isPowerOfTwo (mySizeY)) if (!isPowerOfTwo (mySizeX) || !isPowerOfTwo (mySizeY))
@ -142,6 +160,18 @@ void OpenGl_FrameBuffer::Release (const Handle(OpenGl_Context)& theGlContext)
std::cerr << "OpenGl_FrameBuffer::Release() called with invalid OpenGl_Context!\n"; std::cerr << "OpenGl_FrameBuffer::Release() called with invalid OpenGl_Context!\n";
} }
} }
if (IsValidStencilBuffer())
{
if (!theGlContext.IsNull() && theGlContext->extFBO != NULL)
{
theGlContext->extFBO->glDeleteRenderbuffersEXT (1, &myGlStencilRBId);
myGlStencilRBId = NO_RENDERBUFFER;
}
else
{
std::cerr << "OpenGl_FrameBuffer::Release() called with invalid OpenGl_Context!\n";
}
}
if (IsValidTexture()) if (IsValidTexture())
{ {
glDeleteTextures (1, &myGlTextureId); glDeleteTextures (1, &myGlTextureId);

View File

@ -72,7 +72,7 @@ public:
//! Returns true if current object was initialized //! Returns true if current object was initialized
Standard_Boolean IsValid() const Standard_Boolean IsValid() const
{ {
return IsValidFrameBuffer() && IsValidTexture() && IsValidDepthBuffer(); return IsValidFrameBuffer() && IsValidTexture() && IsValidDepthBuffer() && IsValidStencilBuffer();
} }
//! Notice! Obsolete hardware (GeForce FX etc) //! Notice! Obsolete hardware (GeForce FX etc)
@ -154,16 +154,22 @@ private:
return myGlDepthRBId != NO_RENDERBUFFER; return myGlDepthRBId != NO_RENDERBUFFER;
} }
Standard_Boolean IsValidStencilBuffer() const
{
return myGlStencilRBId != NO_RENDERBUFFER;
}
private: private:
GLsizei mySizeX; // texture width GLsizei mySizeX; // texture width
GLsizei mySizeY; // texture height GLsizei mySizeY; // texture height
GLsizei myVPSizeX; // viewport width (should be <= texture width) GLsizei myVPSizeX; // viewport width (should be <= texture width)
GLsizei myVPSizeY; // viewport height (should be <= texture height) GLsizei myVPSizeY; // viewport height (should be <= texture height)
GLint myTextFormat; // GL_RGB, GL_RGBA,... GLint myTextFormat; // GL_RGB, GL_RGBA,...
GLuint myGlTextureId; // GL texture ID GLuint myGlTextureId; // GL texture ID
GLuint myGlFBufferId; // FBO object ID GLuint myGlFBufferId; // FBO object ID
GLuint myGlDepthRBId; // RenderBuffer object for depth ID GLuint myGlDepthRBId; // RenderBuffer object for depth ID
GLuint myGlStencilRBId; // RenderBuffer object for stencil ID
}; };

View File

@ -28,6 +28,8 @@
#include <OpenGl_Context.hxx> #include <OpenGl_Context.hxx>
#include <OpenGl_telem_util.hxx> #include <OpenGl_telem_util.hxx>
#include <Graphic3d_SetOfHClipPlane_Handle.hxx>
//! Auxiliary class for bounding box presentation //! Auxiliary class for bounding box presentation
class OpenGl_BndBoxPrs : public OpenGl_Element class OpenGl_BndBoxPrs : public OpenGl_Element
{ {
@ -459,20 +461,34 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
// Set up plane equations for non-structure transformed global model-view matrix // Set up plane equations for non-structure transformed global model-view matrix
const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext(); const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
// Collect planes which should be turned on for structure // List of planes to be applied to context state
Graphic3d_SetOfHClipPlane aPlanesOn; Handle(Graphic3d_SetOfHClipPlane) aUserPlanes;
Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (myClipPlanes);
for (; aPlaneIt.More(); aPlaneIt.Next()) // Collect clipping planes of structure scope
if (!myClipPlanes.IsEmpty())
{ {
const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value(); Graphic3d_SetOfHClipPlane::Iterator aClippingIt (myClipPlanes);
if (aUserPln->IsOn()) for (; aClippingIt.More(); aClippingIt.Next())
aPlanesOn.Add (aUserPln); {
const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
if (!aClipPlane->IsOn())
{
continue;
}
if (aUserPlanes.IsNull())
{
aUserPlanes = new Graphic3d_SetOfHClipPlane();
}
aUserPlanes->Add (aClipPlane);
}
} }
// set structure clipping planes if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
if (aPlanesOn.Size() > 0)
{ {
aContext->ChangeClipping().Set (aPlanesOn, AWorkspace->ViewMatrix()); // add planes at loaded view matrix state
aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
} }
// Render groups // Render groups
@ -483,13 +499,16 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
itg.Next(); itg.Next();
} }
// Render cappings for structure groups // Render capping for structure groups
OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups); if (!aContext->Clipping().Planes().IsEmpty())
// unset structure clipping planes
if (aPlanesOn.Size() > 0)
{ {
aContext->ChangeClipping().Unset (aPlanesOn); OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
}
// Revert structure clippings
if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
{
aContext->ChangeClipping().Remove (*aUserPlanes);
} }
// Restore highlight color // Restore highlight color

View File

@ -100,11 +100,6 @@ protected:
virtual ~OpenGl_Structure(); virtual ~OpenGl_Structure();
//! Draw capping surfaces by h/w for the clipping planes
//! enabled for the structure.
//! @param theWorkspace [in] the GL workspace, context state.
void DrawCapping (const Handle(OpenGl_Workspace)& theWorkspace) const;
protected: protected:
//Structure_LABBegin //Structure_LABBegin

View File

@ -989,42 +989,67 @@ D = -[Px,Py,Pz] dot |Nx|
// Apply clipping planes // Apply clipping planes
{ {
if ( myZClip.Back.IsOn || myZClip.Front.IsOn ) const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
{
Graphic3d_SetOfHClipPlane aZClipping;
if (myZClip.Back.IsOn || myZClip.Front.IsOn)
{
const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd; const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd;
if ( myZClip.Back.IsOn ) Handle(Graphic3d_ClipPlane) aPlaneBack;
Handle(Graphic3d_ClipPlane) aPlaneFront;
if (myZClip.Back.IsOn)
{ {
const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd; const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd;
const Graphic3d_ClipPlane::Equation aBack(0.0, 0.0, 1.0, -back); const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, -back);
aZClipping.Add (new Graphic3d_ClipPlane (aBack)); aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
} }
if ( myZClip.Front.IsOn ) if (myZClip.Front.IsOn)
{ {
const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd; const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd;
const Graphic3d_ClipPlane::Equation aFront (0.0, 0.0, -1.0, front); const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, front);
aZClipping.Add (new Graphic3d_ClipPlane (aFront)); aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
} }
aContext->ChangeClipping().Set (aZClipping, &OpenGl_IdentityMatrix); // do some "memory allocation"-wise optimization
if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
{
Graphic3d_SetOfHClipPlane aSlicingPlanes;
if (!aPlaneBack.IsNull())
{
aSlicingPlanes.Add (aPlaneBack);
}
if (!aPlaneFront.IsNull())
{
aSlicingPlanes.Add (aPlaneFront);
}
// add planes at loaded view matrix state
aContext->ChangeClipping().AddView (aSlicingPlanes, AWorkspace);
}
} }
// Apply user clipping planes // Apply user clipping planes
Graphic3d_SetOfHClipPlane aPlanesOn; if (!myClipPlanes.IsEmpty())
Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (myClipPlanes);
for (; aPlaneIt.More(); aPlaneIt.Next())
{ {
const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value(); Graphic3d_SetOfHClipPlane aUserPlanes;
if (aUserPln->IsOn ()) Graphic3d_SetOfHClipPlane::Iterator aClippingIt (myClipPlanes);
aPlanesOn.Add (aUserPln); for (; aClippingIt.More(); aClippingIt.Next())
} {
const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
if (aClipPlane->IsOn())
{
aUserPlanes.Add (aClipPlane);
}
}
if (aPlanesOn.Size() > 0) if (!aUserPlanes.IsEmpty())
{ {
aContext->ChangeClipping().Set (aPlanesOn); // add planes at actual matrix state.
aContext->ChangeClipping().AddWorld (aUserPlanes);
}
} }
} }
@ -1111,8 +1136,7 @@ D = -[Px,Py,Pz] dot |Nx|
// and invoking optional callbacks // and invoking optional callbacks
AWorkspace->ResetAppliedAspect(); AWorkspace->ResetAppliedAspect();
// Unset clip planes managed by driver aContext->ChangeClipping().RemoveAll();
aContext->ChangeClipping().Unset (aContext->Clipping().Planes());
// display global trihedron // display global trihedron
if (myTrihedron != NULL) if (myTrihedron != NULL)

55
tests/bugs/vis/bug24224 Normal file
View File

@ -0,0 +1,55 @@
puts "==========="
puts "OCC24224"
puts "==========="
puts ""
##########################################################################
# Suspicious logics in changing clipping planets at OpenGL_Structure
##########################################################################
## centre rectangle
set x1_coord 150
set y1_coord 250
## right rectangle
set x2_coord 255
set y2_coord 320
## left rectangle
set x3_coord 73
set y3_coord 150
vinit
box b1 0 0 0 10 10 10
box b2 30 0 0 10 40 10
box b3 -30 0 0 20 20 20
vsetdispmode 1
vdisplay b1 b2 b3
vfit
## test view-level clipping
vclipplane create pln1
vclipplane change pln1 equation 0 1 0 -5
vclipplane change pln1 capping on
vclipplane change pln1 capping color 0.9 0.9 0.9
vclipplane set pln1 view Driver1/Viewer1/View1
checkcolor $x1_coord $y1_coord 0.9 0.9 0.9
checkcolor $x2_coord $y2_coord 0.9 0.9 0.9
## test sharing of planes between view and object
vclipplane set pln1 object b1
## test object-level clipping
vclipplane create pln2
vclipplane change pln2 equation -0.707 0.707 0 -25
vclipplane change pln2 capping on
vclipplane change pln2 capping color 0.5 0.5 0.9
vclipplane change pln2 capping hatch on
vclipplane set pln2 object b3
checkcolor $x3_coord $y3_coord 0.5 0.5 0.9
set only_screen 1