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+.
myZNear (DEFAULT_ZNEAR),
myZFar (DEFAULT_ZFAR),
myAspect (1.0),
+ myIsZeroToOneDepth (false),
myScale (1000.0),
myZFocus (1.0),
myZFocusType (FocusType_Relative),
const Elem_t theTop,
const Elem_t theNear,
const Elem_t theFar,
- NCollection_Mat4<Elem_t>& theOutMx)
+ NCollection_Mat4<Elem_t>& theOutMx) const
{
// row 0
theOutMx.ChangeValue (0, 0) = Elem_t (2.0) / (theRight - theLeft);
// row 2
theOutMx.ChangeValue (2, 0) = Elem_t (0.0);
theOutMx.ChangeValue (2, 1) = Elem_t (0.0);
- theOutMx.ChangeValue (2, 2) = Elem_t (-2.0) / (theFar - theNear);
- theOutMx.ChangeValue (2, 3) = - (theFar + theNear) / (theFar - theNear);
+ if (myIsZeroToOneDepth)
+ {
+ theOutMx.ChangeValue (2, 2) = Elem_t (-1.0) / (theFar - theNear);
+ theOutMx.ChangeValue (2, 3) = -theNear / (theFar - theNear);
+ }
+ else
+ {
+ theOutMx.ChangeValue (2, 2) = Elem_t (-2.0) / (theFar - theNear);
+ theOutMx.ChangeValue (2, 3) = - (theFar + theNear) / (theFar - theNear);
+ }
// row 3
theOutMx.ChangeValue (3, 0) = Elem_t (0.0);
const Elem_t theTop,
const Elem_t theNear,
const Elem_t theFar,
- NCollection_Mat4<Elem_t>& theOutMx)
+ NCollection_Mat4<Elem_t>& theOutMx) const
{
// column 0
theOutMx.ChangeValue (0, 0) = (Elem_t (2.0) * theNear) / (theRight - theLeft);
// column 2
theOutMx.ChangeValue (0, 2) = (theRight + theLeft) / (theRight - theLeft);
theOutMx.ChangeValue (1, 2) = (theTop + theBottom) / (theTop - theBottom);
- theOutMx.ChangeValue (2, 2) = -(theFar + theNear) / (theFar - theNear);
+ if (myIsZeroToOneDepth)
+ {
+ theOutMx.ChangeValue (2, 2) = theFar / (theNear - theFar);
+ }
+ else
+ {
+ theOutMx.ChangeValue (2, 2) = -(theFar + theNear) / (theFar - theNear);
+ }
theOutMx.ChangeValue (3, 2) = Elem_t (-1.0);
// column 3
theOutMx.ChangeValue (0, 3) = Elem_t (0.0);
theOutMx.ChangeValue (1, 3) = Elem_t (0.0);
- theOutMx.ChangeValue (2, 3) = -(Elem_t (2.0) * theFar * theNear) / (theFar - theNear);
+ if (myIsZeroToOneDepth)
+ {
+ theOutMx.ChangeValue (2, 3) = -(theFar * theNear) / (theFar - theNear);
+ }
+ else
+ {
+ theOutMx.ChangeValue (2, 3) = -(Elem_t (2.0) * theFar * theNear) / (theFar - theNear);
+ }
theOutMx.ChangeValue (3, 3) = Elem_t (0.0);
}
const Elem_t theIOD,
const Elem_t theZFocus,
const Standard_Boolean theIsLeft,
- NCollection_Mat4<Elem_t>& theOutMx)
+ NCollection_Mat4<Elem_t>& theOutMx) const
{
Elem_t aDx = theIsLeft ? Elem_t (0.5) * theIOD : Elem_t (-0.5) * theIOD;
Elem_t aDXStereoShift = aDx * theNear / theZFocus;
Standard_Real nLeft = 0.0, nRight = 0.0, nTop = 0.0, nBottom = 0.0;
Standard_Real fLeft = 0.0, fRight = 0.0, fTop = 0.0, fBottom = 0.0;
- Standard_Real aNear = 0.0, aFar = 0.0;
+ Standard_Real aNear = myZNear, aFar = myZFar;
if (!IsOrthographic())
{
// handle perspective projection
- aNear = aProjectionMat.GetValue (2, 3) / (-1.0 + aProjectionMat.GetValue (2, 2));
- aFar = aProjectionMat.GetValue (2, 3) / ( 1.0 + aProjectionMat.GetValue (2, 2));
// Near plane
nLeft = aNear * (aProjectionMat.GetValue (0, 2) - 1.0) / aProjectionMat.GetValue (0, 0);
nRight = aNear * (aProjectionMat.GetValue (0, 2) + 1.0) / aProjectionMat.GetValue (0, 0);
else
{
// handle orthographic projection
- aNear = (1.0 / aProjectionMat.GetValue (2, 2)) * (aProjectionMat.GetValue (2, 3) + 1.0);
- aFar = (1.0 / aProjectionMat.GetValue (2, 2)) * (aProjectionMat.GetValue (2, 3) - 1.0);
// Near plane
nLeft = ( 1.0 + aProjectionMat.GetValue (0, 3)) / (-aProjectionMat.GetValue (0, 0));
fLeft = nLeft;
return myZFar;
}
+ //! Return TRUE if camera should calculate projection matrix for [0, 1] depth range or for [-1, 1] range.
+ //! FALSE by default.
+ Standard_Boolean IsZeroToOneDepth() const { return myIsZeroToOneDepth; }
+
+ //! Set using [0, 1] depth range or [-1, 1] range.
+ void SetZeroToOneDepth (Standard_Boolean theIsZeroToOne)
+ {
+ if (myIsZeroToOneDepth != theIsZeroToOne)
+ {
+ myIsZeroToOneDepth = theIsZeroToOne;
+ InvalidateProjection();
+ }
+ }
+
//! Changes width / height display ratio.
//! @param theAspect [in] the display ratio.
Standard_EXPORT void SetAspect (const Standard_Real theAspect);
//! @param theFar [in] the far mapping (clipping) coordinate.
//! @param theOutMx [out] the projection matrix.
template <typename Elem_t>
- static void
+ void
OrthoProj (const Elem_t theLeft,
const Elem_t theRight,
const Elem_t theBottom,
const Elem_t theTop,
const Elem_t theNear,
const Elem_t theFar,
- NCollection_Mat4<Elem_t>& theOutMx);
+ NCollection_Mat4<Elem_t>& theOutMx) const;
//! Compose perspective projection matrix for
//! the passed camera volume mapping.
//! @param theFar [in] the far mapping (clipping) coordinate.
//! @param theOutMx [out] the projection matrix.
template <typename Elem_t>
- static void
+ void
PerspectiveProj (const Elem_t theLeft,
const Elem_t theRight,
const Elem_t theBottom,
const Elem_t theTop,
const Elem_t theNear,
const Elem_t theFar,
- NCollection_Mat4<Elem_t>& theOutMx);
+ NCollection_Mat4<Elem_t>& theOutMx) const;
//! Compose projection matrix for L/R stereo eyes.
//! @param theLeft [in] the left mapping (clipping) coordinate.
//! @param theIsLeft [in] boolean flag to choose between L/R eyes.
//! @param theOutMx [out] the projection matrix.
template <typename Elem_t>
- static void
+ void
StereoEyeProj (const Elem_t theLeft,
const Elem_t theRight,
const Elem_t theBottom,
const Elem_t theIOD,
const Elem_t theZFocus,
const Standard_Boolean theIsLeft,
- NCollection_Mat4<Elem_t>& theOutMx);
+ NCollection_Mat4<Elem_t>& theOutMx) const;
//! Construct "look at" orientation transformation.
//! Reference point differs for perspective and ortho modes
Standard_Real myZNear; //!< Distance to near clipping plane.
Standard_Real myZFar; //!< Distance to far clipping plane.
Standard_Real myAspect; //!< Width to height display ratio.
+ Standard_Boolean myIsZeroToOneDepth; //!< use [0, 1] depth range or [-1, 1]
Standard_Real myScale; //!< Specifies parallel scale for orthographic projection.
Standard_Real myZFocus; //!< Stereographic focus value.
useSystemBuffer (Standard_True),
#endif
swapInterval (1),
+ useZeroToOneDepth (true), ///(Standard_False),
buffersNoSwap (Standard_False),
contextStereo (Standard_False),
#ifdef OCCT_DEBUG
ffpEnable = theCopy.ffpEnable;
useSystemBuffer = theCopy.useSystemBuffer;
swapInterval = theCopy.swapInterval;
+ useZeroToOneDepth = theCopy.useZeroToOneDepth;
buffersNoSwap = theCopy.buffersNoSwap;
contextStereo = theCopy.contextStereo;
contextDebug = theCopy.contextDebug;
Standard_Boolean usePolygonMode; //!< Enables Polygon Mode instead of built-in GLSL programs (OFF by default; unsupported on OpenGL ES)
Standard_Boolean useSystemBuffer; //!< Enables usage of system backbuffer for blitting (OFF by default on desktop OpenGL and ON on OpenGL ES for testing)
Standard_Integer swapInterval; //!< controls swap interval - 0 for VSync off and 1 for VSync on, 1 by default
+ Standard_Boolean useZeroToOneDepth; //!< use [0, 1] depth range instead of [-1, 1] range, when possible (OFF by default)
public: //! @name context creation parameters
arbTexBindless (NULL),
arbTBO (NULL),
arbTboRGB32 (Standard_False),
+ arbClipControl (Standard_False),
arbIns (NULL),
arbDbg (NULL),
arbFBO (NULL),
core45back = NULL;
arbTBO = NULL;
arbTboRGB32 = Standard_False;
+ arbClipControl = Standard_False;
arbIns = NULL;
arbDbg = NULL;
arbFBO = NULL;
arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
}
+ if (CheckExtension ("GL_ARB_clip_control")
+ && FindProcShort (glClipControl))
+ {
+ arbClipControl = Standard_True;
+ }
+
if (!has12)
{
checkWrongVersion (1, 2);
return;
}
core45 = (OpenGl_GlCore45* )(&(*myFuncs));
+ arbClipControl = Standard_True;
if (!isCoreProfile)
{
core45back = (OpenGl_GlCore45Back* )(&(*myFuncs));
OpenGl_ArbTexBindless* arbTexBindless; //!< GL_ARB_bindless_texture
OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object
Standard_Boolean arbTboRGB32; //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0
+ Standard_Boolean arbClipControl; //!< GL_ARB_clip_control, in core since 4.5
OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced
OpenGl_ArbDbg* arbDbg; //!< GL_ARB_debug_output
OpenGl_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object
//! Actual ray-tracing depth (number of ray bounces).
Standard_Integer NbBounces;
+ //! Define depth computation
+ Standard_Boolean IsZeroToOneDepth;
+
//! Enables/disables light propagation through transparent media.
Standard_Boolean TransparentShadows;
RaytracingParams()
: StackSize (THE_DEFAULT_STACK_SIZE),
NbBounces (THE_DEFAULT_NB_BOUNCES),
+ IsZeroToOneDepth (Standard_False),
TransparentShadows (Standard_False),
GlobalIllumination (Standard_False),
UseBindlessTextures (Standard_False),
TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
TCollection_AsciiString ("#define NB_BOUNCES ") + TCollection_AsciiString (myRaytraceParameters.NbBounces);
+ if (myRaytraceParameters.IsZeroToOneDepth)
+ {
+ aPrefixString += TCollection_AsciiString ("\n#define ZERO_TO_ONE_DEPTH");
+ }
+
if (myRaytraceParameters.TransparentShadows)
{
aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
}
}
- if (myRenderParams.RaytracingDepth != myRaytraceParameters.NbBounces
+ const bool isZeroToOneDepth = myCaps->useZeroToOneDepth
+ && myWorkspace->GetGlContext()->arbClipControl;
+ if (isZeroToOneDepth != myRaytraceParameters.IsZeroToOneDepth
+ || myRenderParams.RaytracingDepth != myRaytraceParameters.NbBounces
|| myRenderParams.IsTransparentShadowEnabled != myRaytraceParameters.TransparentShadows
|| myRenderParams.IsGlobalIlluminationEnabled != myRaytraceParameters.GlobalIllumination
|| myRenderParams.TwoSidedBsdfModels != myRaytraceParameters.TwoSidedBsdfModels
|| myRaytraceGeometry.HasTextures() != myRaytraceParameters.UseBindlessTextures)
{
+ myRaytraceParameters.IsZeroToOneDepth = isZeroToOneDepth;
myRaytraceParameters.NbBounces = myRenderParams.RaytracingDepth;
myRaytraceParameters.TransparentShadows = myRenderParams.IsTransparentShadowEnabled;
myRaytraceParameters.GlobalIllumination = myRenderParams.IsGlobalIlluminationEnabled;
aCtx->FrameStats()->FrameStart (myWorkspace->View(), false);
aCtx->SetLineFeather (myRenderParams.LineFeather);
+#if !defined(GL_ES_VERSION_2_0)
+ if (aCtx->arbClipControl)
+ {
+ if (myCaps->useZeroToOneDepth != myCamera->IsZeroToOneDepth())
+ {
+ myCamera->SetZeroToOneDepth (myCaps->useZeroToOneDepth);
+ }
+ aCtx->Functions()->glClipControl (GL_LOWER_LEFT, myCamera->IsZeroToOneDepth() ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE);
+ }
+#endif
+
// release pending GL resources
aCtx->ReleaseDelayed();
//=======================================================================
gp_Pnt SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
{
+ /// TODO why these are not cached?
Graphic3d_Mat4d aInvView;
Graphic3d_Mat4d aInvProj;
{
aX = 2.0 * theX / myWidth - 1.0;
anY = (myHeight - 1 - theY) / myHeight * 2.0 - 1.0;
+ /// TODO wrong NDC
aZ = 2.0 * theZ - 1.0;
}
else
vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);
float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);
+ #ifdef ZERO_TO_ONE_DEPTH
+ aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);
+ #else
aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;
+ #endif
}
SBSDF aBSDF;
vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);
float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);
+ #ifdef ZERO_TO_ONE_DEPTH
+ aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);
+ #else
aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;
+ #endif
}
vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
" vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);\n"
"\n"
" float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);\n"
+ " #ifdef ZERO_TO_ONE_DEPTH\n"
+ " aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);\n"
+ " #else\n"
" aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;\n"
+ " #endif\n"
" }\n"
"\n"
" SBSDF aBSDF;\n"
" vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);\n"
"\n"
" float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);\n"
+ " #ifdef ZERO_TO_ONE_DEPTH\n"
+ " aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);\n"
+ " #else\n"
" aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;\n"
+ " #endif\n"
" }\n"
"\n"
" vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);\n"
theDI << "SoftMode:" << (aCaps->contextNoAccel ? "1" : "0") << "\n";
theDI << "FFP: " << (aCaps->ffpEnable ? "1" : "0") << "\n";
theDI << "PolygonMode: " << (aCaps->usePolygonMode ? "1" : "0") << "\n";
+ theDI << "DepthZeroToOne: " << (aCaps->useZeroToOneDepth ? "1" : "0") << "\n";
theDI << "VSync: " << aCaps->swapInterval << "\n";
theDI << "Compatible:" << (aCaps->contextCompatible ? "1" : "0") << "\n";
theDI << "Stereo: " << (aCaps->contextStereo ? "1" : "0") << "\n";
}
aCaps->pntSpritesDisable = !toEnable;
}
+ else if (anArgCase == "-depthzerotoone"
+ || anArgCase == "-zerotoonedepth"
+ || anArgCase == "-usezerotoonedepth"
+ || anArgCase == "-iszerotoonedepth")
+ {
+ Standard_Boolean toEnable = Standard_True;
+ if (++anArgIter < theArgNb
+ && !ViewerTest::ParseOnOff (theArgVec[anArgIter], toEnable))
+ {
+ --anArgIter;
+ }
+ aCaps->useZeroToOneDepth = toEnable;
+ }
else if (anArgCase == "-softmode")
{
Standard_Boolean toEnable = Standard_True;
__FILE__, VStereo, group);
theCommands.Add ("vcaps",
"vcaps [-vbo {0|1}] [-sprites {0|1}] [-ffp {0|1}] [-polygonMode {0|1}]"
+ "\n\t\t: [-zeroToOneDepth {0|1}]"
"\n\t\t: [-compatibleProfile {0|1}]"
"\n\t\t: [-vsync {0|1}] [-useWinBuffer {0|1}]"
"\n\t\t: [-quadBuffer {0|1}] [-stereo {0|1}]"
"\n\t\t: sprite - use textured sprites instead of bitmaps"
"\n\t\t: vsync - switch VSync on or off"
"\n\t\t: winBuffer - allow using window buffer for rendering"
+ "\n\t\t: zeroToOneDepth - use [0,1] depth range instead of [-1,1] range"
"\n\t\t: Context creation options:"
"\n\t\t: softMode - software OpenGL implementation"
"\n\t\t: compatibleProfile - backward-compatible profile"