1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0030640: Visualization, Graphic3d_Camera - add option creating Projection matrix with [0,1] depth range

Added new property Graphic3d_Camera::IsZeroToOneDepth() and OpenGl_Caps::useZeroToOneDepth
for activating [0,1] depth range instead of [-1,1] range using glClipControl() within OpenGL 4.5+.
This commit is contained in:
kgv
2021-03-03 14:58:46 +03:00
committed by bugmaster
parent 395d00e058
commit e70625d6b1
25 changed files with 226 additions and 71 deletions

View File

@@ -41,7 +41,7 @@ void SelectMgr_BaseFrustum::SetCamera (const Handle(Graphic3d_Camera)& theCamera
{
myCamera = theCamera;
myBuilder->SetWorldViewMatrix (theCamera->OrientationMatrix());
myBuilder->SetProjectionMatrix (theCamera->ProjectionMatrix());
myBuilder->SetProjectionMatrix (theCamera->ProjectionMatrix(), theCamera->IsZeroToOneDepth());
myBuilder->SetWorldViewProjState (theCamera->WorldViewProjState());
myIsOrthographic = theCamera->IsOrthographic();
myBuilder->InvalidateViewport();
@@ -58,7 +58,7 @@ void SelectMgr_BaseFrustum::SetCamera (const Graphic3d_Mat4d& theProjection,
{
myCamera.Nullify();
myBuilder->SetWorldViewMatrix (theWorldView);
myBuilder->SetProjectionMatrix (theProjection);
myBuilder->SetProjectionMatrix (theProjection, false);
myBuilder->SetWorldViewProjState (theWVPState);
myIsOrthographic = theIsOrthographic;
}

View File

@@ -31,7 +31,8 @@ SelectMgr_FrustumBuilder::SelectMgr_FrustumBuilder()
myWorldViewProjState(),
myWidth (INT_MAX),
myHeight (INT_MAX),
myIsViewportSet (Standard_False)
myIsViewportSet (Standard_False),
myIsZeroToOneDepth (Standard_False)
{
//
}
@@ -58,9 +59,11 @@ const Graphic3d_Mat4d& SelectMgr_FrustumBuilder::WorldViewMatrix() const
// function : SetProjectionMatrix
// purpose : Stores current projection matrix
//=======================================================================
void SelectMgr_FrustumBuilder::SetProjectionMatrix (const Graphic3d_Mat4d& theProjection)
void SelectMgr_FrustumBuilder::SetProjectionMatrix (const Graphic3d_Mat4d& theProjection,
const Standard_Boolean theIsZeroToOneDepth)
{
myProjection = theProjection;
myIsZeroToOneDepth = theIsZeroToOneDepth;
}
//=======================================================================
@@ -180,23 +183,19 @@ static NCollection_Vec4<Standard_Real> safePointCast (const gp_Pnt& thePnt)
//=======================================================================
gp_Pnt SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
{
Graphic3d_Mat4d aInvView;
Graphic3d_Mat4d aInvProj;
// this case should never happen
// inversed matrices could be cached
Graphic3d_Mat4d aInvView, aInvProj;
if (!myWorldView.Inverted (aInvView) || !myProjection.Inverted (aInvProj))
{
return gp_Pnt (0.0, 0.0, 0.0);
return gp_Pnt (0.0, 0.0, 0.0); // this case should never happen
}
// use compatible type of point
NCollection_Vec4<Standard_Real> aPnt = safePointCast (thePnt);
aPnt = aInvProj * aPnt; // convert to view coordinate space
aPnt = aInvView * aPnt; // convert to world coordinate space
const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
}
@@ -210,23 +209,19 @@ gp_Pnt SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& the
const Standard_Real& theY,
const Standard_Real& theZ) const
{
Standard_Real aX, anY, aZ;
// map coords to NDC
gp_Pnt anXYZ;
if (!myIsViewportSet)
{
aX = 2.0 * theX / myWidth - 1.0;
anY = (myHeight - 1 - theY) / myHeight * 2.0 - 1.0;
aZ = 2.0 * theZ - 1.0;
anXYZ.SetCoord (2.0 * theX / myWidth - 1.0,
(myHeight - 1 - theY) / myHeight * 2.0 - 1.0,
myIsZeroToOneDepth ? theZ : (2.0 * theZ - 1.0));
}
else
{
aX = 2.0 * (theX - myWidth * myViewport.x()) /
(myWidth * (myViewport.z() - myViewport.x())) - 1.0;
anY = 2.0 * (theY - myHeight * myViewport.y()) /
(myHeight * (myViewport.w() - myViewport.y())) - 1.0;
aZ = theZ;
anXYZ.SetCoord (2.0 * (theX - myWidth * myViewport.x()) / (myWidth * (myViewport.z() - myViewport.x())) - 1.0,
2.0 * (theY - myHeight * myViewport.y()) / (myHeight * (myViewport.w() - myViewport.y())) - 1.0,
theZ);
}
return unProject (gp_Pnt (aX, anY, aZ));
return unProject (anXYZ);
}

View File

@@ -39,7 +39,8 @@ public:
Standard_EXPORT const Graphic3d_Mat4d& WorldViewMatrix() const;
//! Stores current projection matrix
Standard_EXPORT void SetProjectionMatrix (const Graphic3d_Mat4d& theProjection);
Standard_EXPORT void SetProjectionMatrix (const Graphic3d_Mat4d& theProjection,
const Standard_Boolean theIsZeroToOneDepth);
//! @return current projection matrix
Standard_EXPORT const Graphic3d_Mat4d& ProjectionMatrix() const;
@@ -93,6 +94,7 @@ private:
Standard_Integer myHeight;
NCollection_Vec4<Standard_Real> myViewport;
Standard_Boolean myIsViewportSet;
Standard_Boolean myIsZeroToOneDepth;
};
DEFINE_STANDARD_HANDLE(SelectMgr_FrustumBuilder, Standard_Transient)

View File

@@ -652,7 +652,8 @@ void SelectMgr_ViewerSelector::TraverseSensitives()
// define corresponding frustum builder parameters
Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix(),
!aCamera.IsNull() && aCamera->IsZeroToOneDepth());
aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT);
aBuilder->SetWindowSize (aWidth, aHeight);
aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);