diff --git a/src/OpenGl/OpenGl_BackgroundArray.cxx b/src/OpenGl/OpenGl_BackgroundArray.cxx index 3bde2f9d15..866514d456 100644 --- a/src/OpenGl/OpenGl_BackgroundArray.cxx +++ b/src/OpenGl/OpenGl_BackgroundArray.cxx @@ -449,13 +449,13 @@ void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspac Standard_Integer aViewSizeY = aCtx->Viewport()[3]; Graphic3d_Vec2i aTileOffset, aTileSize; - if (theWorkspace->View()->Camera()->Tile().IsValid()) + if (aCtx->Camera()->Tile().IsValid()) { - aViewSizeX = theWorkspace->View()->Camera()->Tile().TotalSize.x(); - aViewSizeY = theWorkspace->View()->Camera()->Tile().TotalSize.y(); + aViewSizeX = aCtx->Camera()->Tile().TotalSize.x(); + aViewSizeY = aCtx->Camera()->Tile().TotalSize.y(); - aTileOffset = theWorkspace->View()->Camera()->Tile().OffsetLowerLeft(); - aTileSize = theWorkspace->View()->Camera()->Tile().TileSize; + aTileOffset = aCtx->Camera()->Tile().OffsetLowerLeft(); + aTileSize = aCtx->Camera()->Tile().TileSize; } if (myToUpdate || myViewWidth != aViewSizeX @@ -473,7 +473,7 @@ void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspac if (myType == Graphic3d_TOB_CUBEMAP) { - Graphic3d_Camera aCamera (theWorkspace->View()->Camera()); + Graphic3d_Camera aCamera (aCtx->Camera()); aCamera.SetZRange (0.01, 1.0); // is needed to avoid perspective camera exception // cancel translation @@ -514,7 +514,7 @@ void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspac { aProjection.InitIdentity(); aWorldView.InitIdentity(); - if (theWorkspace->View()->Camera()->Tile().IsValid()) + if (aCtx->Camera()->Tile().IsValid()) { aWorldView.SetDiagonal (OpenGl_Vec4 (2.0f / aTileSize.x(), 2.0f / aTileSize.y(), 1.0f, 1.0f)); if (myType == Graphic3d_TOB_GRADIENT) diff --git a/src/OpenGl/OpenGl_FrameStatsPrs.cxx b/src/OpenGl/OpenGl_FrameStatsPrs.cxx index 95a5d3b55f..664317b87f 100644 --- a/src/OpenGl/OpenGl_FrameStatsPrs.cxx +++ b/src/OpenGl/OpenGl_FrameStatsPrs.cxx @@ -405,7 +405,7 @@ void OpenGl_FrameStatsPrs::Render (const Handle(OpenGl_Workspace)& theWorkspace) aCtx->WorldViewState.Push(); if (!myChartTrsfPers.IsNull()) { - myChartTrsfPers->Apply (theWorkspace->View()->Camera(), + myChartTrsfPers->Apply (aCtx->Camera(), aCtx->ProjectionState.Current(), aCtx->WorldViewState.ChangeCurrent(), aCtx->VirtualViewport()[2], aCtx->VirtualViewport()[3]); } diff --git a/src/OpenGl/OpenGl_LayerList.cxx b/src/OpenGl/OpenGl_LayerList.cxx index 79b32cc789..563bc6726b 100644 --- a/src/OpenGl/OpenGl_LayerList.cxx +++ b/src/OpenGl/OpenGl_LayerList.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -604,7 +605,7 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace aManager->UpdateLightSourceStateTo (aLayerSettings.Lights(), theWorkspace->View()->SpecIBLMapLevels(), Handle(OpenGl_ShadowMapArray)()); } - const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera(); + const Handle(Graphic3d_Camera)& aWorldCamera = aCtx->Camera(); if (hasLocalCS) { // Apply local camera transformation. @@ -645,6 +646,15 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace NCollection_Mat4 aWorldView = aWorldCamera->OrientationMatrix(); Graphic3d_TransformUtils::Translate (aWorldView, aLayerSettings.Origin().X(), aLayerSettings.Origin().Y(), aLayerSettings.Origin().Z()); + if (!aManager->LightSourceState().ShadowMaps().IsNull()) + { + // shift shadowmap matrix + for (OpenGl_ShadowMapArray::Iterator aShadowIter (*aManager->LightSourceState().ShadowMaps()); aShadowIter.More(); aShadowIter.Next()) + { + aShadowIter.Value()->UpdateCamera (*theWorkspace->View(), &aLayerSettings.Origin()); + } + } + NCollection_Mat4 aWorldViewF; aWorldViewF.ConvertFrom (aWorldView); aCtx->WorldViewState.SetCurrent (aWorldViewF); @@ -676,6 +686,15 @@ void OpenGl_LayerList::renderLayer (const Handle(OpenGl_Workspace)& theWorkspace } if (hasLocalCS) { + if (!aManager->LightSourceState().ShadowMaps().IsNull()) + { + // restore shadowmap matrix + for (OpenGl_ShadowMapArray::Iterator aShadowIter (*aManager->LightSourceState().ShadowMaps()); aShadowIter.More(); aShadowIter.Next()) + { + aShadowIter.Value()->UpdateCamera (*theWorkspace->View(), &gp::Origin().XYZ()); + } + } + aCtx->ShaderManager()->RevertClippingState(); aCtx->ShaderManager()->UpdateLightSourceState(); diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index e024d39946..88c2519390 100644 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -1037,7 +1037,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace const Graphic3d_Vec2i aViewSize (aCtx->Viewport()[2], aCtx->Viewport()[3]); const Standard_Integer aMin = aViewSize.minComp(); const GLfloat anEdgeWidth = (GLfloat )anAspectFace->Aspect()->EdgeWidth() * aCtx->LineWidthScale() / (GLfloat )aMin; - const GLfloat anOrthoScale = theWorkspace->View()->Camera()->IsOrthographic() ? (GLfloat )theWorkspace->View()->Camera()->Scale() : -1.0f; + const GLfloat anOrthoScale = aCtx->Camera()->IsOrthographic() ? (GLfloat )aCtx->Camera()->Scale() : -1.0f; const Handle(OpenGl_ShaderProgram)& anOutlineProgram = aCtx->ActiveProgram(); anOutlineProgram->SetUniform (aCtx, anOutlineProgram->GetStateLocation (OpenGl_OCCT_SILHOUETTE_THICKNESS), anEdgeWidth); diff --git a/src/OpenGl/OpenGl_ShadowMap.cxx b/src/OpenGl/OpenGl_ShadowMap.cxx index 53d0a8b792..c1db3db21a 100644 --- a/src/OpenGl/OpenGl_ShadowMap.cxx +++ b/src/OpenGl/OpenGl_ShadowMap.cxx @@ -85,10 +85,11 @@ const Handle(OpenGl_Texture)& OpenGl_ShadowMap::Texture() const // function : UpdateCamera // purpose : // ======================================================================= -bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView) +bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView, + const gp_XYZ* theOrigin) { - const Bnd_Box aMinMaxBox = theView.MinMaxValues (false); // applicative min max boundaries - const Bnd_Box aGraphicBox = theView.MinMaxValues (true); // real graphical boundaries (not accounting infinite flag). + const Bnd_Box aMinMaxBox = theOrigin == NULL ? theView.MinMaxValues (false) : Bnd_Box(); // applicative min max boundaries + const Bnd_Box aGraphicBox = theOrigin == NULL ? theView.MinMaxValues (true) : Bnd_Box(); // real graphical boundaries (not accounting infinite flag) switch (myShadowLight->Type()) { @@ -98,6 +99,15 @@ bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView) } case Graphic3d_TOLS_DIRECTIONAL: { + if (theOrigin != NULL) + { + Graphic3d_Mat4d aTrans; + aTrans.Translate (Graphic3d_Vec3d (theOrigin->X(), theOrigin->Y(), theOrigin->Z())); + Graphic3d_Mat4d anOrientMat = myShadowCamera->OrientationMatrix() * aTrans; + myLightMatrix = myShadowCamera->ProjectionMatrixF() * Graphic3d_Mat4 (anOrientMat); + return true; + } + Graphic3d_Vec4d aDir (myShadowLight->Direction().X(), myShadowLight->Direction().Y(), myShadowLight->Direction().Z(), 0.0); if (myShadowLight->IsHeadlight()) { diff --git a/src/OpenGl/OpenGl_ShadowMap.hxx b/src/OpenGl/OpenGl_ShadowMap.hxx index d192c7a868..0aa2698a6c 100644 --- a/src/OpenGl/OpenGl_ShadowMap.hxx +++ b/src/OpenGl/OpenGl_ShadowMap.hxx @@ -19,6 +19,7 @@ #include #include +class gp_XYZ; class Graphic3d_Camera; class Graphic3d_CLight; class Graphic3d_CView; @@ -74,7 +75,10 @@ public: void SetShadowMapBias (Standard_ShortReal theBias) { myShadowMapBias = theBias; } //! Compute camera. - Standard_EXPORT bool UpdateCamera (const Graphic3d_CView& theView); + //! @param theView [in] active view + //! @param theOrigin [in] when not-NULL - displace shadow map camera to specified Z-Layer origin + Standard_EXPORT bool UpdateCamera (const Graphic3d_CView& theView, + const gp_XYZ* theOrigin = NULL); private: diff --git a/tests/v3d/shadows/double_precision b/tests/v3d/shadows/double_precision new file mode 100644 index 0000000000..34180aa85c --- /dev/null +++ b/tests/v3d/shadows/double_precision @@ -0,0 +1,23 @@ +puts "========" +puts "0032129: Visualization, TKOpenGl - shadowmap is broken for ZLayer having non-zero origin" +puts "========" + +pload MODELING VISUALIZATION +box b 0 0 1 100 200 300 +box bb -500 -500 0 1000 1000 0 -preview +vinit View1 +vrenderparams -shadingModel PHONG +vdisplay -dispMode 1 b bb +vaspects bb -material STONE +vfit +vlight -change 0 -castShadows 1 -head 0 -dir 1 1 -1 +vdump $::imagedir/${::casename}_1.png +vzlayer DEFAULT -origin 200 0 0 +vdump $::imagedir/${::casename}_2.png + +vlocation b -setLocation 1000000000 0 0 +vlocation bb -setLocation 1000000000 0 0 +vfit +vdump $::imagedir/${::casename}_3.png +vzlayer DEFAULT -origin 1000000000 0 0 +vdump $::imagedir/${::casename}_4.png