1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-03 14:10:33 +03:00

0024070: OpenGL capped object-level clipping planes

Graphical clipping:
- Use "Graphic3d_ClipPlane" to defined clipping for PrsMgr_PresentableObject (local clipping), for V3d_View (global clipping).

Get rid of old implementations:
- Remove Visual3d_ClipPlane.
- Port V3d_Plane to Graphic3d_ClipPlane core.

Selection Sensitives:
- Port "Matches" method to add full set of arguments (SelectBasics_PickArgs), including min-max depth coming from selector.
- Get rid of transient data for pair Matches -> ComputeDepth.
- Extend SelectMgr_ViewerSelector::LoadResult to work with local clipping, add virtual callbacks to compute globa/local depth clipping for picking.

Capping rendering algorithm:
- Recursive rendering algorithm for OpenGl_Groups.
- Introduced Rendering filter for groups.

Clipping plane management in TKOpenGl:
- Added OpenGl_ClippingState to OpenGl_Context.

DRAWEXE commands:
- Ported "vclipplane" command for new approach.
- Added "vsettexturemode" command for changing texture details in views (enable / disable textures).

Correct DownCast syntax (compilation error)

Fix new compiler warnings

tests/bugs/vis/bug22906 migrated to the new vclipplane syntax
This commit is contained in:
apl
2013-09-19 16:58:00 +04:00
committed by bugmaster
parent 788cbaf4c4
commit 4269bd1b11
111 changed files with 4168 additions and 2293 deletions

View File

@@ -0,0 +1,284 @@
// Created on: 2013-09-05
// 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 6.5 (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 S.A.S., 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.
#include <OpenGl_CappingAlgo.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_PrimitiveArray.hxx>
#include <OpenGl_CappingPlaneResource.hxx>
#include <OpenGl_Vec.hxx>
IMPLEMENT_STANDARD_HANDLE(OpenGl_CappingAlgoFilter, OpenGl_RenderFilter)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter, OpenGl_RenderFilter)
Handle(OpenGl_RenderFilter) OpenGl_CappingAlgo::myRenderFilter;
OpenGl_AspectFace OpenGl_CappingAlgo::myFrontCulling;
OpenGl_AspectFace OpenGl_CappingAlgo::myNoneCulling;
Standard_Boolean OpenGl_CappingAlgo::myIsInit = Standard_False;
namespace
{
static const OpenGl_Vec4 THE_CAPPING_PLN_VERTS[12] =
{ OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 0.0f, 1.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
OpenGl_Vec4 ( 0.0f, 0.0f, 1.0f, 0.0f),
OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 0.0f,-1.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
OpenGl_Vec4 ( 0.0f, 0.0f,-1.0f, 0.0f),
OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f) };
static const OpenGl_Vec4 THE_CAPPING_PLN_TCOORD[12] =
{ OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 1.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
OpenGl_Vec4 ( 0.0f, 1.0f, 0.0f, 0.0f),
OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 0.0f,-1.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
OpenGl_Vec4 ( 0.0f,-1.0f, 0.0f, 0.0f),
OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f) };
};
// =======================================================================
// function : RenderCapping
// purpose :
// =======================================================================
void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace,
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();
// check whether algorithm need to be runned
Standard_Boolean isCapping = Standard_False;
Graphic3d_SetOfHClipPlane aContextPlanes = aContext->Clipping().Planes();
Graphic3d_SetOfHClipPlane::Iterator aCappingIt (aContextPlanes);
for (; aCappingIt.More(); aCappingIt.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aCappingIt.Value();
if (aPlane->IsCapping())
{
isCapping = Standard_True;
break;
}
}
// do not perform algorithm is there is nothing to render
if (!isCapping)
return;
// init internal data
Init();
// remember current aspect face defined in workspace
const OpenGl_AspectFace* aFaceAsp = theWorkspace->AspectFace (Standard_False);
// replace primitive groups rendering filter
static Handle(OpenGl_CappingAlgoFilter) aCappingFilter = new OpenGl_CappingAlgoFilter();
Handle(OpenGl_RenderFilter) aRenderFilter = theWorkspace->GetRenderFilter();
theWorkspace->SetRenderFilter (aCappingFilter);
// prepare for rendering the clip planes
glEnable (GL_STENCIL_TEST);
// generate capping for every clip plane
for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next())
{
// get plane being rendered
const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value();
if (!aRenderPlane->IsCapping())
{
continue;
}
// enable only the rendering plane to generate stencil mask
Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (aContextPlanes);
for (; aPlaneIt.More(); aPlaneIt.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
const Standard_Boolean isOn = (aPlane == aRenderPlane);
aContext->ChangeClipping().SetEnabled (aPlane, isOn);
}
glClear (GL_STENCIL_BUFFER_BIT);
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// override aspects, disable culling
theWorkspace->SetAspectFace (NoneCulling());
theWorkspace->AspectFace (Standard_True);
// evaluate number of pair faces
glDisable (GL_DEPTH_TEST);
glDepthMask (GL_FALSE);
glStencilFunc (GL_ALWAYS, 1, 0x01);
glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT);
OpenGl_ListOfGroup::Iterator aGroupIt (theGroups);
for (; aGroupIt.More(); aGroupIt.Next())
{
aGroupIt.Value()->Render (theWorkspace);
}
// override material, cull backfaces
theWorkspace->SetAspectFace (FrontCulling());
theWorkspace->AspectFace (Standard_True);
// enable all clip plane except the rendered one
for (aPlaneIt.Init (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next())
{
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
const Standard_Boolean isOn = (aPlane != aRenderPlane);
aContext->ChangeClipping().SetEnabled (aPlane, isOn);
}
// render capping plane using the generated stencil mask
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask (GL_TRUE);
glDepthFunc (GL_LESS);
glStencilFunc (GL_EQUAL, 1, 0x01);
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
glEnable (GL_DEPTH_TEST);
RenderPlane (theWorkspace, aRenderPlane);
}
// restore previous application state
glClear (GL_STENCIL_BUFFER_BIT);
glStencilFunc (GL_ALWAYS, 0, 0xFF);
glDisable (GL_STENCIL_TEST);
// enable clipping
for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next())
{
aContext->ChangeClipping().SetEnabled (aCappingIt.Value(), Standard_True);
}
// restore rendering aspects
theWorkspace->SetAspectFace (aFaceAsp);
theWorkspace->SetRenderFilter (aRenderFilter);
}
// =======================================================================
// function : RenderPlane
// purpose :
// =======================================================================
void OpenGl_CappingAlgo::RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
const Handle(Graphic3d_ClipPlane)& thePlane)
{
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
// get resource for the plane
TCollection_AsciiString aResId = thePlane->GetId();
Handle(OpenGl_CappingPlaneResource) aPlaneRes;
if (!aContext->GetResource (aResId, aPlaneRes))
{
// share and register for release once the resource is no longer used
aPlaneRes = new OpenGl_CappingPlaneResource (thePlane);
aContext->ShareResource (aResId, aPlaneRes);
}
aPlaneRes->Update (aContext);
const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace (Standard_False);
const OpenGl_AspectFace* aPlaneAspect = aPlaneRes->AspectFace();
if (aPlaneAspect != NULL)
{
theWorkspace->SetAspectFace (aPlaneAspect);
}
// apply aspect for rendering
theWorkspace->AspectFace (Standard_True);
// set identity model matrix
const OpenGl_Matrix* aModelMatrix = theWorkspace->SetStructureMatrix (&OpenGl_IdentityMatrix);
glMultMatrixf ((const GLfloat*)aPlaneRes->Orientation());
glNormal3f (0.0f, 1.0f, 0.0f);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (4, GL_FLOAT, 0, (GLfloat* )&THE_CAPPING_PLN_VERTS);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer (4, GL_FLOAT, 0, (GLfloat*)&THE_CAPPING_PLN_TCOORD);
glDrawArrays (GL_TRIANGLES, 0, 12);
glDisableClientState (GL_VERTEX_ARRAY);
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
theWorkspace->SetStructureMatrix (aModelMatrix);
theWorkspace->SetAspectFace (aFaceAspect);
// set delayed resource release
aPlaneRes.Nullify();
aContext->ReleaseResource (aResId, Standard_True);
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
void OpenGl_CappingAlgo::Init()
{
if (myIsInit)
return;
myRenderFilter = new OpenGl_CappingAlgoFilter();
myNoneCulling.CullingMode = TelCullNone;
myNoneCulling.Edge = 0;
myFrontCulling.CullingMode = TelCullBack;
myFrontCulling.Edge = 0;
myIsInit = Standard_True;
}
// =======================================================================
// function : CanRender
// purpose :
// =======================================================================
Standard_Boolean OpenGl_CappingAlgoFilter::CanRender (const OpenGl_Element* theElement)
{
const OpenGl_PrimitiveArray* aPArray =
dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
if (!aPArray)
return Standard_False;
switch (aPArray->PArray()->type)
{
case TelPolygonsArrayType :
case TelTrianglesArrayType :
case TelQuadranglesArrayType :
case TelTriangleStripsArrayType :
case TelQuadrangleStripsArrayType :
case TelTriangleFansArrayType :
return Standard_True;
default:
return Standard_False;
}
}