]> OCCT Git - occt.git/commitdiff
0032173: Visualization, TKOpenGl - implement simple shadow mapping for a point light...
authordrochalo <diogo.lopes@opencascade.com>
Mon, 5 Feb 2024 15:11:09 +0000 (15:11 +0000)
committerdrochalo <diogo.lopes@opencascade.com>
Tue, 5 Mar 2024 16:16:19 +0000 (16:16 +0000)
Modified shadowmap calculations to include multipass for point lights.
Added shader funtions to calculate point light shadows.
Added getter for default znear and zfar values in Graphic3d_Camera.
Added direction and up vector calulations on Graphic3d_CubeMap.
Added logical exception for opengles2.0 lack of support on some key features of cube shadow maps.
Added test case.

34 files changed:
src/Graphic3d/Graphic3d_CLight.cxx
src/Graphic3d/Graphic3d_Camera.cxx
src/Graphic3d/Graphic3d_Camera.hxx
src/Graphic3d/Graphic3d_CubeMap.cxx
src/Graphic3d/Graphic3d_CubeMap.hxx
src/Graphic3d/Graphic3d_LightSet.cxx
src/Graphic3d/Graphic3d_LightSet.hxx
src/Graphic3d/Graphic3d_ShaderManager.cxx
src/Graphic3d/Graphic3d_ShaderManager.hxx
src/Graphic3d/Graphic3d_ShaderProgram.cxx
src/Graphic3d/Graphic3d_ShaderProgram.hxx
src/Graphic3d/Graphic3d_TextureUnit.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_FrameBuffer.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderProgram.cxx
src/OpenGl/OpenGl_ShaderProgram.hxx
src/OpenGl/OpenGl_ShadowMap.cxx
src/OpenGl/OpenGl_ShadowMap.hxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/Shaders/Declarations.glsl
src/Shaders/FILES
src/Shaders/LightPointShadow.glsl [new file with mode: 0644]
src/Shaders/PBRPointLight.glsl
src/Shaders/PhongPointLight.glsl
src/Shaders/Shaders_Declarations_glsl.pxx
src/Shaders/Shaders_LightPointShadow_glsl.pxx [new file with mode: 0644]
src/Shaders/Shaders_PBRPointLight_glsl.pxx
src/Shaders/Shaders_PhongPointLight_glsl.pxx
tests/opengl/data/shadows/pointlight [new file with mode: 0644]

index 8283af632d76fbf533e2e6e55be8eb491266e3c8..ead85cb621ae6e29a5231597736f0ed6029be977 100644 (file)
@@ -150,7 +150,8 @@ void Graphic3d_CLight::SetEnabled (Standard_Boolean theIsOn)
 void Graphic3d_CLight::SetCastShadows (Standard_Boolean theToCast)
 {
   if (myType != Graphic3d_TypeOfLightSource_Directional
-   && myType != Graphic3d_TypeOfLightSource_Spot)
+   && myType != Graphic3d_TypeOfLightSource_Spot
+   && myType != Graphic3d_TypeOfLightSource_Positional)
   {
     throw Standard_NotImplemented ("Graphic3d_CLight::SetCastShadows() is not implemented for this light type");
   }
index ee7204fe8e3065ff573acfc3d69b90936f557e5b..8ff6dd47044e9bfbe9a7496e3ec6212191b6f270 100644 (file)
@@ -200,6 +200,24 @@ void Graphic3d_Camera::Copy (const Handle(Graphic3d_Camera)& theOther)
   CopyOrientationData (theOther);
 }
 
+// =======================================================================
+// function : GetDefaultZNear
+// purpose  :
+// =======================================================================
+Standard_Real Graphic3d_Camera::GetDefaultZNear()
+{
+  return DEFAULT_ZNEAR;
+}
+
+// =======================================================================
+// function : GetDefaultZFar
+// purpose  :
+// =======================================================================
+Standard_Real Graphic3d_Camera::GetDefaultZFar()
+{
+  return DEFAULT_ZFAR;
+}
+
 // =======================================================================
 // function : SetIdentityOrientation
 // purpose  :
index aeebc7cbf61f839f7ee111ae2eb61231d7a0045d..a44fe69d77142ab8a4369a3f34e95ef0411b0db2 100644 (file)
@@ -202,6 +202,12 @@ public:
 //! @name Public camera properties
 public:
 
+  //! return default valut for znear.
+  Standard_EXPORT Standard_Real GetDefaultZNear();
+
+  //! return default valut for zfar.
+  Standard_EXPORT Standard_Real GetDefaultZFar();
+
   //! Get camera look direction.
   //! @return camera look direction.
   const gp_Dir& Direction() const { return myDirection; }
index 4d2abb1b8438409f4bc7d8522f9c6872ac32ff09..4f8b40d929f602376a317ba1704c7e27af90a28e 100644 (file)
@@ -52,3 +52,89 @@ Graphic3d_CubeMap::~Graphic3d_CubeMap()
 {
   //
 }
+
+// =======================================================================
+// function : GetCubeDirection
+// purpose  :
+// =======================================================================
+gp_Dir Graphic3d_CubeMap::GetCubeDirection (Graphic3d_CubeMapSide theFace)
+{
+  gp_Dir aResult;
+  switch (theFace)
+  {
+    case (Graphic3d_CMS_POS_X):
+    {
+      aResult = gp_Dir(1.0, 0.0, 0.0);
+    }
+    break;
+    case (Graphic3d_CMS_NEG_X):
+    {
+      aResult = gp_Dir(-1.0, 0.0, 0.0);
+    }
+    break;
+    case (Graphic3d_CMS_POS_Y):
+    {
+      aResult = gp_Dir(0.0, 1.0, 0.0);
+    }
+    break;
+    case (Graphic3d_CMS_NEG_Y):
+    {
+      aResult = gp_Dir(0.0, -1.0, 0.0);
+    }
+    break;
+    case (Graphic3d_CMS_POS_Z):
+    {
+      aResult = gp_Dir(0.0, 0.0, 1.0);
+    }
+    break;
+    case (Graphic3d_CMS_NEG_Z):
+    {
+      aResult = gp_Dir(0.0, 0.0, -1.0);
+    }
+    break;
+  }
+  return aResult;
+}
+
+// =======================================================================
+// function : GetCubeUp
+// purpose  :
+// =======================================================================
+gp_Dir Graphic3d_CubeMap::GetCubeUp (Graphic3d_CubeMapSide theFace)
+{
+  gp_Dir aResult;
+  switch (theFace)
+  {
+    case (Graphic3d_CMS_POS_X):
+    {
+      aResult = -gp_Dir(0.0, -1.0, 0.0);
+    }
+    break;
+    case (Graphic3d_CMS_NEG_X):
+    {
+      aResult = -gp_Dir(0.0, -1.0, 0.0);
+    }
+    break;
+    case (Graphic3d_CMS_POS_Y):
+    {
+      aResult = gp_Dir(0.0, 0.0, 1.0);
+    }
+    break;
+    case (Graphic3d_CMS_NEG_Y):
+    {
+      aResult = gp_Dir(0.0, 0.0, -1.0);
+    }
+    break;
+    case (Graphic3d_CMS_POS_Z):
+    {
+      aResult = gp_Dir(0.0, -1.0, 0.0);
+    }
+    break;
+    case (Graphic3d_CMS_NEG_Z):
+    {
+      aResult = gp_Dir(0.0, -1.0, 0.0);
+    }
+    break;
+  }
+  return aResult;
+}
index 0566c97c844cd7456f3f9d1d3a25adc6c75bc627..d2f1b83b67f053e004b729bb031656ad78988670 100644 (file)
@@ -15,6 +15,7 @@
 #ifndef _Graphic3d_CubeMap_HeaderFile
 #define _Graphic3d_CubeMap_HeaderFile
 
+#include <gp_Dir.hxx>
 #include <Graphic3d_CubeMapOrder.hxx>
 #include <Graphic3d_TextureMap.hxx>
 
@@ -90,6 +91,12 @@ public:
   //! Empty destructor.
   Standard_EXPORT virtual ~Graphic3d_CubeMap();
 
+  //! Returns direction vector for cubemap's @theFace
+  Standard_EXPORT gp_Dir static GetCubeDirection (Graphic3d_CubeMapSide theFace);
+
+  //! Returns up vector for cubemap's @theFace
+  Standard_EXPORT gp_Dir static GetCubeUp (Graphic3d_CubeMapSide theFace);
+
 protected:
 
   Graphic3d_CubeMapSide myCurrentSide;  //!< Iterator state
index 103f31cabb63043d25a58e8410150c72c9688641..a4571f4f4cc61bf8b9acaf77dd9fa8015c851f93 100644 (file)
@@ -86,6 +86,35 @@ Standard_Boolean Graphic3d_LightSet::Remove (const Handle(Graphic3d_CLight)& the
   return Standard_True;
 }
 
+// =======================================================================
+// function : CalculateNbShadows
+// purpose  :
+// =======================================================================
+void Graphic3d_LightSet::CalculateNbShadows (Standard_Integer& theNb2DShadows, Standard_Integer& theNbPointShadows)
+{
+  theNb2DShadows = 0;
+  theNbPointShadows = 0;
+  for (NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator aLightIter(myLights); aLightIter.More(); aLightIter.Next())
+  {
+    const Handle(Graphic3d_CLight)& aLight = aLightIter.Key();
+    //if (!aLight->IsEnabled())
+    //{
+    //  continue;
+    //}
+    if (aLight->ToCastShadows())
+    {
+      if (aLight->Type() == Graphic3d_TypeOfLightSource_Positional)
+      {
+        ++theNbPointShadows;
+      }
+      else
+      {
+        ++theNb2DShadows;
+      }
+    }
+  }
+}
+
 // =======================================================================
 // function : UpdateRevision
 // purpose  :
index 584cb4c3fd1aebb3bd113e8207eed0d8000c29c8..5c020bc8022014c9e96a2c346caf7edabcecd95b 100644 (file)
@@ -143,6 +143,9 @@ public:
   //! Returns total amount of lights of specified type.
   Standard_Integer NbLightsOfType (Graphic3d_TypeOfLightSource theType) const { return myLightTypes[theType]; }
 
+  //! Calculates total amount of enabled lights castings shadows (point lights and others).
+  Standard_EXPORT void CalculateNbShadows (Standard_Integer& theNb2DShadows, Standard_Integer& theNbPointShadows);
+
 //! @name cached state of lights set updated by UpdateRevision()
 public:
 
index 8650a554dfcd70ed46e2d24dda5a1562a3ae9cf7..284d6a1f544a009e09667f942b70f9addfc6fd5a 100644 (file)
@@ -19,6 +19,7 @@
 #include <Message.hxx>
 
 #include "../Shaders/Shaders_LightShadow_glsl.pxx"
+#include "../Shaders/Shaders_LightPointShadow_glsl.pxx"
 #include "../Shaders/Shaders_PBRDistribution_glsl.pxx"
 #include "../Shaders/Shaders_PBRDirectionalLight_glsl.pxx"
 #include "../Shaders/Shaders_PBRGeometry_glsl.pxx"
@@ -516,6 +517,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramFont() con
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbShadowMaps (0);
+  aProgramSrc->SetNbShadowCubeMaps (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@@ -645,6 +647,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramFboBlit (S
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbShadowMaps (0);
+  aProgramSrc->SetNbShadowCubeMaps (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@@ -700,6 +703,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramOitComposi
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbShadowMaps (0);
+  aProgramSrc->SetNbShadowCubeMaps (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@@ -1137,6 +1141,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramUnlit (Sta
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbShadowMaps (0);
+  aProgramSrc->SetNbShadowCubeMaps (0);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
   aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
   const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
@@ -1152,10 +1157,11 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramUnlit (Sta
 // =======================================================================
 TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
                                                                      const Handle(Graphic3d_LightSet)& theLights,
-                                                                     Standard_Boolean  theHasVertColor,
-                                                                     Standard_Boolean  theIsPBR,
-                                                                     Standard_Boolean  theHasTexColor,
-                                                                     Standard_Integer  theNbShadowMaps) const
+                                                                     Standard_Boolean theHasVertColor,
+                                                                     Standard_Boolean theIsPBR,
+                                                                     Standard_Boolean theHasTexColor,
+                                                                     Standard_Integer theNbShadowMaps,
+                                                                     Standard_Integer theNbShadowCubeMaps) const
 {
   TCollection_AsciiString aLightsFunc, aLightsLoop;
   theNbLights = 0;
@@ -1165,6 +1171,8 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
     if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX)
     {
       Standard_Integer anIndex = 0;
+      Standard_Integer a2DSamplerIndex = 0;
+      Standard_Integer aCubeSamplerIndex = 0;
       for (Graphic3d_LightSet::Iterator aLightIter (theLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
            aLightIter.More(); aLightIter.Next())
       {
@@ -1181,7 +1189,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
             {
               aLightsLoop = aLightsLoop +
                 EOL"    occDirectionalLight (" + anIndex + ", theNormal, theView, theIsFront,"
-                EOL"                         occLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));";
+                EOL"                         occLightShadow (occShadowMapSamplers[" + a2DSamplerIndex++ + "], " + anIndex + ", theNormal));";
             }
             else
             {
@@ -1192,7 +1200,18 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
           }
           case Graphic3d_TypeOfLightSource_Positional:
           {
-            aLightsLoop = aLightsLoop + EOL"    occPointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
+            if (theNbShadowCubeMaps > 0
+              && aLightIter.Value()->ToCastShadows())
+            {
+              aLightsLoop = aLightsLoop +
+                EOL"    occPointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront,"
+                EOL"                   occLightPointShadow (occShadowCubeMapSamplers[" + aCubeSamplerIndex++ + "],"
+                EOL"                                        " + anIndex + ", aPoint, theNormal)); ";
+            }
+            else
+            {
+              aLightsLoop = aLightsLoop + EOL"    occPointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront, 1.0);";
+            }
             ++anIndex;
             break;
           }
@@ -1203,7 +1222,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
             {
               aLightsLoop = aLightsLoop +
                 EOL"    occSpotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront,"
-                EOL"                  occLightShadow (occShadowMapSamplers[" + anIndex + "], " + anIndex + ", theNormal));";
+                EOL"                  occLightShadow (occShadowMapSamplers[" + a2DSamplerIndex++ + "], " + anIndex + ", theNormal));";
             }
             else
             {
@@ -1242,7 +1261,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
         aLightsLoop +=
           EOL"      if (aType == OccLightType_Point)"
           EOL"      {"
-          EOL"        occPointLight (anIndex, theNormal, theView, aPoint, theIsFront);"
+          EOL"        occPointLight (anIndex, theNormal, theView, aPoint, theIsFront, 1.0);"
           EOL"      }";
       }
       if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0)
@@ -1271,6 +1290,7 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
     }
 
     bool isShadowShaderAdded = false;
+    bool isShadowCubeShaderAdded = false;
     if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Directional) == 1
      && theNbLights == 1
      && !theIsPBR
@@ -1291,6 +1311,11 @@ TCollection_AsciiString Graphic3d_ShaderManager::stdComputeLighting (Standard_In
     }
     if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Positional) > 0)
     {
+      if (theNbShadowCubeMaps > 0 && !isShadowCubeShaderAdded)
+      {
+        aLightsFunc += Shaders_LightPointShadow_glsl;
+        isShadowCubeShaderAdded = true;
+      }
       aLightsFunc += theIsPBR ? Shaders_PBRPointLight_glsl : Shaders_PhongPointLight_glsl;
     }
     if (theLights->NbEnabledLightsOfType (Graphic3d_TypeOfLightSource_Spot) > 0)
@@ -1475,7 +1500,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramGouraud (c
   aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 BackColor",  Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
 
   Standard_Integer aNbLights = 0;
-  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcVertColor.IsEmpty(), false, toUseTexColor, 0);
+  const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcVertColor.IsEmpty(), false, toUseTexColor, 0, 0);
   aSrcVert = TCollection_AsciiString()
     + THE_FUNC_transformNormal_world
     + EOL
@@ -1520,6 +1545,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramGouraud (c
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (aNbLights);
   aProgramSrc->SetNbShadowMaps (0);
+  aProgramSrc->SetNbShadowCubeMaps (0);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
   aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
   const Standard_Integer aNbGeomInputVerts = !aSrcGeom.IsEmpty() ? 3 : 0;
@@ -1537,7 +1563,8 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
                                                                              const Standard_Integer theBits,
                                                                              const Standard_Boolean theIsFlatNormal,
                                                                              const Standard_Boolean theIsPBR,
-                                                                             const Standard_Integer theNbShadowMaps) const
+                                                                             const Standard_Integer theNbShadowMaps,
+                                                                             const Standard_Integer theNbShadowCubeMaps) const
 {
   TCollection_AsciiString aPhongCompLight = TCollection_AsciiString() +
     "computeLighting (normalize (Normal), normalize (View), PositionWorld, gl_FrontFacing)";
@@ -1690,12 +1717,18 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
 
   aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PositionWorld", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
   aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec3 View",          Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
-  if (theNbShadowMaps > 0)
+  if (theNbShadowMaps + theNbShadowCubeMaps > 0)
   {
-    aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("mat4      occShadowMapMatrices[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX));
-    aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("sampler2D occShadowMapSamplers[THE_NB_SHADOWMAPS]", Graphic3d_TOS_FRAGMENT));
-    aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2      occShadowMapSizeBias",                    Graphic3d_TOS_FRAGMENT));
-
+    aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("mat4 occShadowMapMatrices[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX));
+    aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("vec2 occShadowMapSizeBias", Graphic3d_TOS_FRAGMENT));
+    if (theNbShadowMaps > 0)
+    {
+      aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("sampler2D occShadowMapSamplers[THE_NB_SHADOWMAPS2D]", Graphic3d_TOS_FRAGMENT));
+    }
+    if (theNbShadowCubeMaps > 0)
+    {
+      aUniforms.Append (Graphic3d_ShaderObject::ShaderVariable ("samplerCube occShadowCubeMapSamplers[THE_NB_SHADOWMAPSCUBE]", Graphic3d_TOS_FRAGMENT));
+    }
     aStageInOuts.Append (Graphic3d_ShaderObject::ShaderVariable ("vec4 PosLightSpace[THE_NB_SHADOWMAPS]", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
     aSrcVertExtraMain +=
       EOL"  for (int aShadowIter = 0; aShadowIter < THE_NB_SHADOWMAPS; ++aShadowIter)"
@@ -1729,7 +1762,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
 
   Standard_Integer aNbLights = 0;
   const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, theLights, !aSrcFragGetVertColor.IsEmpty(),
-                                                              theIsPBR, toUseTexColor, theNbShadowMaps);
+                                                              theIsPBR, toUseTexColor, theNbShadowMaps, theNbShadowCubeMaps);
   aSrcFrag += TCollection_AsciiString()
     + EOL
     + aSrcFragGetVertColor
@@ -1745,11 +1778,12 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramPhong (con
     + EOL"}";
 
   const TCollection_AsciiString aProgId = TCollection_AsciiString (theIsFlatNormal ? "flat-" : "phong-") + (theIsPBR ? "pbr-" : "")
-                                        + genLightKey (theLights, theNbShadowMaps > 0) + "-";
+                                        + genLightKey (theLights, (theNbShadowMaps + theNbShadowCubeMaps) > 0) + "-";
   defaultGlslVersion (aProgramSrc, aProgId, theBits, isFlatNormal);
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (aNbLights);
   aProgramSrc->SetNbShadowMaps (theNbShadowMaps);
+  aProgramSrc->SetNbShadowCubeMaps (theNbShadowCubeMaps);
   aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
   aProgramSrc->SetAlphaTest ((theBits & Graphic3d_ShaderFlags_AlphaTest) != 0);
 
@@ -1944,6 +1978,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramStereo (Gr
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbShadowMaps (0);
+  aProgramSrc->SetNbShadowCubeMaps (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@@ -1980,6 +2015,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getStdProgramBoundBox()
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbShadowMaps (0);
+  aProgramSrc->SetNbShadowCubeMaps (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@@ -2041,6 +2077,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getPBREnvBakingProgram
   aProgramSrc->SetDefaultSampler (false);
   aProgramSrc->SetNbLightsMax (0);
   aProgramSrc->SetNbShadowMaps (0);
+  aProgramSrc->SetNbShadowCubeMaps (0);
   aProgramSrc->SetNbClipPlanesMax (0);
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
   aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
@@ -2107,6 +2144,7 @@ Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderManager::getBgCubeMapProgram() c
   aProgSrc->SetDefaultSampler (false);
   aProgSrc->SetNbLightsMax (0);
   aProgSrc->SetNbShadowMaps (0);
+  aProgSrc->SetNbShadowCubeMaps (0);
   aProgSrc->SetNbClipPlanesMax (0);
   aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcVert, Graphic3d_TOS_VERTEX,   aUniforms, aStageInOuts));
   aProgSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
index 023b574260beb6282bb7d6af2f46926afbbd4fcc..176dbfaff2eb42edc721d961b58dde7ceac1da69 100644 (file)
@@ -134,7 +134,8 @@ protected:
                                                                       const Standard_Integer theBits,
                                                                       const Standard_Boolean theIsFlatNormal,
                                                                       const Standard_Boolean theIsPBR,
-                                                                      const Standard_Integer theNbShadowMaps) const;
+                                                                      const Standard_Integer theNbShadowMaps,
+                                                                      const Standard_Integer theNbShadowCubeMaps) const;
 
   //! Prepare standard GLSL program for bounding box.
   Standard_EXPORT Handle(Graphic3d_ShaderProgram) getStdProgramBoundBox() const;
@@ -207,10 +208,11 @@ protected:
   //! @param theNbShadowMaps [in]  flag to include shadow map
   Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights,
                                                               const Handle(Graphic3d_LightSet)& theLights,
-                                                              Standard_Boolean  theHasVertColor,
-                                                              Standard_Boolean  theIsPBR,
-                                                              Standard_Boolean  theHasTexColor,
-                                                              Standard_Integer  theNbShadowMaps) const;
+                                                              Standard_Boolean theHasVertColor,
+                                                              Standard_Boolean theIsPBR,
+                                                              Standard_Boolean theHasTexColor,
+                                                              Standard_Integer theNbShadowMaps,
+                                                              Standard_Integer theNbShadowCubeMaps) const;
 
 protected:
 
index c4575849f496391382bc33239b64125420fed5ca..e71ae76e0e4502b7b709e9798dbff3d685a7b84f 100755 (executable)
@@ -80,6 +80,7 @@ const TCollection_AsciiString& Graphic3d_ShaderProgram::ShadersFolder()
 Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
 : myNbLightsMax (THE_MAX_LIGHTS_DEFAULT),
   myNbShadowMaps (0),
+  myNbShadowCubeMaps (0),
   myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT),
   myNbFragOutputs (THE_NB_FRAG_OUTPUTS),
   myTextureSetBits (Graphic3d_TextureSetBits_NONE),
index 5432d1eb8cb3a998528b5656acd741a4dc58550f..2f2681f16801e96c3d02a647cb78c882dee8fc03 100755 (executable)
@@ -96,12 +96,18 @@ public:
   //! Specify the length of array of light sources (THE_MAX_LIGHTS).
   void SetNbLightsMax (Standard_Integer theNbLights) { myNbLightsMax = theNbLights; }
 
-  //! Return the length of array of shadow maps (THE_NB_SHADOWMAPS); 0 by default.
+  //! Return the length of array of 2D shadow maps (THE_NB_SHADOWMAP2D); 0 by default.
   Standard_Integer NbShadowMaps() const { return myNbShadowMaps; }
 
-  //! Specify the length of array of shadow maps (THE_NB_SHADOWMAPS).
+  //! Specify the length of array of 2D shadow maps (THE_NB_SHADOWMAP2D).
   void SetNbShadowMaps (Standard_Integer theNbMaps) { myNbShadowMaps = theNbMaps; }
 
+  //! Return the length of array of shadow cube maps (THE_NB_SHADOWMAPCUBE); 0 by default.
+  Standard_Integer NbShadowCubeMaps() const { return myNbShadowCubeMaps; }
+
+  //! Specify the length of array of shadow cube maps (THE_NB_SHADOWMAPCUBE).
+  void SetNbShadowCubeMaps (Standard_Integer theNbMaps) { myNbShadowCubeMaps = theNbMaps; }
+
   //! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES),
   //! to be used for initialization occClipPlaneEquations.
   //! Default value is THE_MAX_CLIP_PLANES_DEFAULT.
@@ -214,20 +220,21 @@ public:
 
 private:
 
-  TCollection_AsciiString       myID;            //!< the unique identifier of program object
-  Graphic3d_ShaderObjectList    myShaderObjects; //!< the list of attached shader objects
-  Graphic3d_ShaderVariableList  myVariables;     //!< the list of custom uniform variables
-  Graphic3d_ShaderAttributeList myAttributes;    //!< the list of custom vertex attributes
-  TCollection_AsciiString       myHeader;        //!< GLSL header with version code and used extensions
-  Standard_Integer              myNbLightsMax;   //!< length of array of light sources (THE_MAX_LIGHTS)
-  Standard_Integer              myNbShadowMaps;  //!< length of array of shadow maps (THE_NB_SHADOWMAPS)
-  Standard_Integer              myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
-  Standard_Integer              myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
-  Standard_Integer              myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits
-  Graphic3d_RenderTransparentMethod myOitOutput; //!< flag indicating that Fragment Shader includes OIT outputs
-  Standard_Boolean              myHasDefSampler; //!< flag indicating that program defines default texture sampler occSampler0
-  Standard_Boolean              myHasAlphaTest;       //!< flag indicating that Fragment Shader performs alpha test
-  Standard_Boolean              myIsPBR;         //!< flag indicating that program defines functions and variables used in PBR pipeline
+  TCollection_AsciiString       myID;               //!< the unique identifier of program object
+  Graphic3d_ShaderObjectList    myShaderObjects;    //!< the list of attached shader objects
+  Graphic3d_ShaderVariableList  myVariables;        //!< the list of custom uniform variables
+  Graphic3d_ShaderAttributeList myAttributes;       //!< the list of custom vertex attributes
+  TCollection_AsciiString       myHeader;           //!< GLSL header with version code and used extensions
+  Standard_Integer              myNbLightsMax;      //!< length of array of light sources (THE_MAX_LIGHTS)
+  Standard_Integer              myNbShadowMaps;     //!< length of array of shadow maps (THE_NB_SHADOWMAP2D)
+  Standard_Integer              myNbShadowCubeMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPCUBE)
+  Standard_Integer              myNbClipPlanesMax;  //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
+  Standard_Integer              myNbFragOutputs;    //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
+  Standard_Integer              myTextureSetBits;   //!< texture units declared within the program, @sa Graphic3d_TextureSetBits
+  Graphic3d_RenderTransparentMethod myOitOutput;    //!< flag indicating that Fragment Shader includes OIT outputs
+  Standard_Boolean              myHasDefSampler;    //!< flag indicating that program defines default texture sampler occSampler0
+  Standard_Boolean              myHasAlphaTest;     //!< flag indicating that Fragment Shader performs alpha test
+  Standard_Boolean              myIsPBR;            //!< flag indicating that program defines functions and variables used in PBR pipeline
 
 };
 
index 6916c4ada8796258b9b646b4c460e4c53f5c422d..3ea04fa235670f316160bdbbd99c6fdf46541457 100644 (file)
@@ -67,6 +67,10 @@ enum Graphic3d_TextureUnit
   //! Note that it can be overridden to Graphic3d_TextureUnit_0 for FFP fallback on hardware without multi-texturing.
   Graphic3d_TextureUnit_PointSprite = Graphic3d_TextureUnit_1,
 
+  //! samplerCube occShadowCubeMapSampler.
+  //! Point light source shadowmap texture.
+  Graphic3d_TextureUnit_ShadowCubeMap = -7,
+
   //! sampler2D occDepthPeelingDepth.
   //! 1st texture unit for Depth Peeling lookups.
   Graphic3d_TextureUnit_DepthPeelingDepth = -6,
index 9380b93672f9f2613b185eae15ff2696c773c559..460e6341a50d1461a2c53a69360248804ca0939d 100644 (file)
@@ -227,6 +227,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   myPBRDiffIBLMapSHTexUnit (Graphic3d_TextureUnit_PbrIblDiffuseSH),
   myPBRSpecIBLMapTexUnit   (Graphic3d_TextureUnit_PbrIblSpecular),
   myShadowMapTexUnit       (Graphic3d_TextureUnit_ShadowMap),
+  myShadowCubeMapTexUnit   (Graphic3d_TextureUnit_ShadowCubeMap),
   myDepthPeelingDepthTexUnit (Graphic3d_TextureUnit_DepthPeelingDepth),
   myDepthPeelingFrontColorTexUnit (Graphic3d_TextureUnit_DepthPeelingFrontColor),
   myFrameStats (new OpenGl_FrameStats()),
@@ -1653,6 +1654,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
     }
   }
 
+  myShadowCubeMapTexUnit          = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowCubeMap);          // -7
   myDepthPeelingDepthTexUnit      = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingDepth);      // -6
   myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_DepthPeelingFrontColor); // -5
   myShadowMapTexUnit              = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_ShadowMap);              // -4
@@ -1661,6 +1663,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
   myPBRSpecIBLMapTexUnit          = static_cast<Graphic3d_TextureUnit>(myMaxTexCombined + Graphic3d_TextureUnit_PbrIblSpecular);         // -1
   if (!myHasPBR)
   {
+    myShadowCubeMapTexUnit          = static_cast<Graphic3d_TextureUnit>(myShadowCubeMapTexUnit + 3);
     myDepthPeelingDepthTexUnit      = static_cast<Graphic3d_TextureUnit>(myDepthPeelingDepthTexUnit + 3);
     myDepthPeelingFrontColorTexUnit = static_cast<Graphic3d_TextureUnit>(myDepthPeelingFrontColorTexUnit + 3);
     myShadowMapTexUnit              = static_cast<Graphic3d_TextureUnit>(myShadowMapTexUnit + 3);
index f86c4cc4618be365f01633aa959596aae9dcb952..83008cfa48a6f0a45fce401c2ef8d6cdd3aa8c06 100644 (file)
@@ -605,6 +605,9 @@ public:
   //! Returns texture unit where shadow map is expected to be bound, or 0 if unavailable.
   Graphic3d_TextureUnit ShadowMapTexUnit() const { return myShadowMapTexUnit; }
 
+  //! Returns texture unit where shadow map is expected to be bound, or 0 if unavailable.
+  Graphic3d_TextureUnit ShadowCubeMapTexUnit() const { return myShadowCubeMapTexUnit; }
+
   //! Returns texture unit for occDepthPeelingDepth within enabled Depth Peeling.
   Graphic3d_TextureUnit DepthPeelingDepthTexUnit() const { return myDepthPeelingDepthTexUnit; }
 
@@ -1137,6 +1140,7 @@ private: // context info
                                                   //!  (0 if PBR is not supported)
   Graphic3d_TextureUnit myPBRSpecIBLMapTexUnit;   //!< samplerCube occSpecIBLMap, texture unit where specular IBL map is expected to  be binded (0 if PBR is not supported)
   Graphic3d_TextureUnit myShadowMapTexUnit;       //!< sampler2D occShadowMapSampler
+  Graphic3d_TextureUnit myShadowCubeMapTexUnit;   //!< samplerCube occShadowCubeMapSampler
 
   Graphic3d_TextureUnit myDepthPeelingDepthTexUnit;      //!< sampler2D occDepthPeelingDepth, texture unit for Depth Peeling lookups
   Graphic3d_TextureUnit myDepthPeelingFrontColorTexUnit; //!< sampler2D occDepthPeelingFrontColor, texture unit for Depth Peeling lookups
index ca4ac757e2dd1474929a21746defcb0618b108f4..e370a81576e7f9d8bea09738f4c38c0ad833c3c4 100644 (file)
@@ -330,7 +330,8 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
                                            const Graphic3d_Vec2i&        theSize,
                                            const OpenGl_ColorFormats&    theColorFormats,
                                            const Standard_Integer        theDepthFormat,
-                                           const Standard_Integer        theNbSamples)
+                                           const Standard_Integer        theNbSamples,
+                                           const Standard_Boolean        theIsCubeMap)
 {
   myColorFormats = theColorFormats;
 
@@ -423,9 +424,10 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
 
     // extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats
     // instead of just trying to create such texture
+    Graphic3d_TypeOfTexture aTypeOfTexture = theIsCubeMap ? Graphic3d_TypeOfTexture_CUBEMAP : Graphic3d_TypeOfTexture_2D;
     const OpenGl_TextureFormat aDepthFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, myDepthFormat);
     if (aDepthFormat.IsValid()
-    && !myDepthStencilTexture->Init (theGlContext, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TypeOfTexture_2D))
+    && !myDepthStencilTexture->Init (theGlContext, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), aTypeOfTexture))
     {
       theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
                                  "Warning! Depth textures are not supported by hardware!");
@@ -470,15 +472,42 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
   {
     if (hasDepthStencilAttach (theGlContext))
     {
-      theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
-                                                    myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
+      if (theIsCubeMap)
+      {
+        for (Standard_Integer aCubeFace = 0; aCubeFace < 6; ++aCubeFace)
+        {
+          theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                                        GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeFace),
+                                                        myDepthStencilTexture->TextureId(), 0);
+        }
+      }
+      else
+      {
+        theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                                      myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
+      }
     }
     else
     {
-      theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                                    myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
-      theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                                                    myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
+      if (theIsCubeMap)
+      {
+        for (Standard_Integer aCubeFace = 0; aCubeFace < 6; ++aCubeFace)
+        {
+          theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                                        GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeFace),
+                                                        myDepthStencilTexture->TextureId(), 0);
+          theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                                        GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeFace),
+                                                        myDepthStencilTexture->TextureId(), 0);
+        }
+      }
+      else
+      {
+        theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                                      myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
+        theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                                      myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
+      }
     }
   }
   else if (myGlDepthRBufferId != NO_RENDERBUFFER)
@@ -499,8 +528,17 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
       }
     }
   }
+  const GLenum aRendImgErr = theGlContext->core11fwd->glGetError();
+  if (aRendImgErr != GL_NO_ERROR)
+  {
+    theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+                               TCollection_AsciiString("Error: in setup of glFramebufferTexture2D: ") + OpenGl_Context::FormatGlError(aRendImgErr) + ".");
+    Release (theGlContext.get());
+    return Standard_False;
+  }
   if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   {
+    std::cout << "\n\nIncomplete framebuffer: " << theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) << "\n\n";
     Release (theGlContext.operator->());
     return Standard_False;
   }
@@ -907,6 +945,18 @@ void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx)
   theGlCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, myGlFBufferId);
 }
 
+// =======================================================================
+// function : BindBufferCube
+// purpose  :
+// =======================================================================
+void OpenGl_FrameBuffer::BindBufferCube (const Handle(OpenGl_Context)& theGlCtx, const Standard_Integer theFace)
+{
+  theGlCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myGlFBufferId);
+  theGlCtx->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                            GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + theFace),
+                                            myDepthStencilTexture->TextureId(), 0);
+}
+
 // =======================================================================
 // function : UnbindBuffer
 // purpose  :
@@ -957,7 +1007,8 @@ inline void convertRowFromRgba (T* theRgbRow,
 Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& theGlCtx,
                                                  const Handle(OpenGl_FrameBuffer)& theFbo,
                                                  Image_PixMap& theImage,
-                                                 Graphic3d_BufferType theBufferType)
+                                                 Graphic3d_BufferType theBufferType,
+                                                 const Standard_Integer theCubeFace)
 {
   if (theGlCtx.IsNull()
    || theImage.IsEmpty())
@@ -1119,6 +1170,38 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
     return Standard_False;
   }
 
+  if (theCubeFace >= 0)
+  {
+    theGlCtx->core11fwd->glBindTexture (GL_TEXTURE_CUBE_MAP, theFbo->DepthStencilTexture()->TextureId());
+    theFbo->BindBufferCube (theGlCtx, theCubeFace);
+    const GLint anAligment = Min(GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
+    theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
+    if (theGlCtx->hasPackRowLength)
+    {
+      theGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0);
+    }
+    theGlCtx->core11fwd->glGetTexImage (GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + theCubeFace),
+                                        0, aFormat, aType, theImage.ChangeData());
+    const bool hasErrors = theGlCtx->ResetErrors (true);
+    if (hasErrors)
+    {
+      std::cout << "\nError saving cubemap face texture to image.\n";
+      return Standard_False;
+    }
+
+    theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, 1);
+    
+    if (!theFbo.IsNull() && theFbo->IsValid())
+    {
+      theFbo->UnbindBuffer(theGlCtx);
+    }
+    else if (theGlCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES)
+    {
+      theGlCtx->core11fwd->glReadBuffer(aReadBufferPrev);
+    }
+    return Standard_True;
+  }
+
   // bind FBO if used
   if (!theFbo.IsNull() && theFbo->IsValid())
   {
index d3955eca002faf9995fb7f6ca03a64befd6ac619..0ce139f259a159206050371f3e1ff2fb1c2187fd 100644 (file)
@@ -48,11 +48,13 @@ public:
   //! @param theFbo        FBO to dump (or window buffer, if NULL)
   //! @param theImage      target image
   //! @param theBufferType buffer type (attachment) to dump
+  //! @param theCubeFace   id of the cubemap face (only used for fbo's rendering to cubemaps)
   //! @return TRUE on success
   Standard_EXPORT static Standard_Boolean BufferDump (const Handle(OpenGl_Context)& theGlCtx,
                                                       const Handle(OpenGl_FrameBuffer)& theFbo,
                                                       Image_PixMap& theImage,
-                                                      Graphic3d_BufferType theBufferType);
+                                                      Graphic3d_BufferType theBufferType,
+                                                      const Standard_Integer theCubeFace = -1);
 
 public:
 
@@ -142,12 +144,14 @@ public:
   //! @param theColorFormats list of color texture sized format (0 means no color attachment), e.g. GL_RGBA8
   //! @param theDepthFormat  depth-stencil texture sized format (0 means no depth attachment), e.g. GL_DEPTH24_STENCIL8
   //! @param theNbSamples    MSAA number of samples (0 means normal texture)
+  //! @param theIsCubeMap    flag to setup texture target to cubemap (FALSE by default)
   //! @return true on success
   Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Context)& theGlCtx,
                                          const Graphic3d_Vec2i&        theSize,
                                          const OpenGl_ColorFormats&    theColorFormats,
                                          const Standard_Integer        theDepthFormat,
-                                         const Standard_Integer        theNbSamples = 0);
+                                         const Standard_Integer        theNbSamples = 0,
+                                         const Standard_Boolean        theIsCubeMap = Standard_False);
 
   //! (Re-)initialize FBO with specified dimensions.
   Standard_EXPORT Standard_Boolean InitLazy (const Handle(OpenGl_Context)& theGlCtx,
@@ -225,6 +229,9 @@ public:
   //! Bind frame buffer for reading GL_READ_FRAMEBUFFER
   Standard_EXPORT virtual void BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx);
 
+  //! Bind frame buffer for reading cubemap with the target @theFace.
+  Standard_EXPORT virtual void BindBufferCube (const Handle(OpenGl_Context)& theGlCtx, const Standard_Integer theFace);
+
   //! Unbind frame buffer.
   Standard_EXPORT virtual void UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx);
 
index eff6bf9f3909747f91e262d960c9e6e360ed8d79..0dd894ff1d81ee61ac7c5d90c29285d46703610f 100644 (file)
@@ -554,9 +554,10 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
   // update shadow map variables
   if (const OpenGl_ShaderUniformLocation aShadowMatLoc = theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES))
   {
-    if (myShadowMatArray.Size() < theProgram->NbShadowMaps())
+    Standard_Integer aNbShadowMaps = theProgram->NbShadowMaps() + theProgram->NbShadowCubeMaps();
+    if (myShadowMatArray.Size() < aNbShadowMaps)
     {
-      myShadowMatArray.Resize (0, theProgram->NbShadowMaps() - 1, false);
+      myShadowMatArray.Resize (0, aNbShadowMaps - 1, false);
     }
 
     Graphic3d_Vec2 aSizeBias;
@@ -564,7 +565,7 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
     {
       aSizeBias.SetValues (1.0f / (float )myLightSourceState.ShadowMaps()->First()->Texture()->SizeX(),
                            myLightSourceState.ShadowMaps()->First()->ShadowMapBias());
-      const Standard_Integer aNbShadows = Min (theProgram->NbShadowMaps(), myLightSourceState.ShadowMaps()->Size());
+      const Standard_Integer aNbShadows = Min (aNbShadowMaps, myLightSourceState.ShadowMaps()->Size());
       for (Standard_Integer aShadowIter = 0; aShadowIter < aNbShadows; ++aShadowIter)
       {
         const Handle(OpenGl_ShadowMap)& aShadow = myLightSourceState.ShadowMaps()->Value (aShadowIter);
@@ -572,7 +573,7 @@ void OpenGl_ShaderManager::pushLightSourceState (const Handle(OpenGl_ShaderProgr
       }
     }
 
-    theProgram->SetUniform (myContext, aShadowMatLoc, theProgram->NbShadowMaps(), &myShadowMatArray.First());
+    theProgram->SetUniform (myContext, aShadowMatLoc, aNbShadowMaps, &myShadowMatArray.First());
     theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS), aSizeBias);
   }
 }
@@ -1229,10 +1230,16 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
                                                                const Standard_Boolean        theIsFlatNormal,
                                                                const Standard_Boolean        theIsPBR)
 {
-  Standard_Integer aNbShadowMaps = myLightSourceState.HasShadowMaps()
-                                 ? myLightSourceState.LightSources()->NbCastShadows()
-                                 : 0;
-  Handle(Graphic3d_ShaderProgram) aProgramSrc = getStdProgramPhong (myLightSourceState.LightSources(), theBits, theIsFlatNormal, theIsPBR, aNbShadowMaps);
+  Standard_Integer aNbShadowMaps, aNbShadowCubeMaps;
+  myLightSourceState.LightSources()->CalculateNbShadows (aNbShadowMaps, aNbShadowCubeMaps);
+  // point light shadows are not currently supported on opengles 2.0.
+  if (myContext->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES
+   && myContext->VersionMajor() <= 2)
+  {
+    aNbShadowCubeMaps = 0;
+  }
+  Handle(Graphic3d_ShaderProgram) aProgramSrc = getStdProgramPhong (myLightSourceState.LightSources(), theBits, theIsFlatNormal,
+                                                                    theIsPBR, aNbShadowMaps, aNbShadowCubeMaps);
   TCollection_AsciiString aKey;
   if (!Create (aProgramSrc, aKey, theProgram))
   {
index a5504af8aff720b08ad00e5fc84cd0cc5b42036c..211aa13e48587fea87403842a3425f31fec78fb8 100755 (executable)
@@ -50,43 +50,44 @@ Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
   "occWorldViewMatrixInverseTranspose",  // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
   "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
 
-  "occClipPlaneEquations",  // OpenGl_OCC_CLIP_PLANE_EQUATIONS
-  "occClipPlaneChains",     // OpenGl_OCC_CLIP_PLANE_CHAINS
-  "occClipPlaneCount",      // OpenGl_OCC_CLIP_PLANE_COUNT
-
-  "occLightSourcesCount",   // OpenGl_OCC_LIGHT_SOURCE_COUNT
-  "occLightSourcesTypes",   // OpenGl_OCC_LIGHT_SOURCE_TYPES
-  "occLightSources",        // OpenGl_OCC_LIGHT_SOURCE_PARAMS
-  "occLightAmbient",        // OpenGl_OCC_LIGHT_AMBIENT
-  "occShadowMapSizeBias",   // OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS
-  "occShadowMapSamplers",   // OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS,
-  "occShadowMapMatrices",   // OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES,
-
-  "occTextureEnable",       // OpenGl_OCCT_TEXTURE_ENABLE
-  "occDistinguishingMode",  // OpenGl_OCCT_DISTINGUISH_MODE
-  "occPbrMaterial",         // OpenGl_OCCT_PBR_MATERIAL
-  "occCommonMaterial",      // OpenGl_OCCT_COMMON_MATERIAL
-  "occAlphaCutoff",         // OpenGl_OCCT_ALPHA_CUTOFF
-  "occColor",               // OpenGl_OCCT_COLOR
-
-  "occOitOutput",           // OpenGl_OCCT_OIT_OUTPUT
-  "occOitDepthFactor",      // OpenGl_OCCT_OIT_DEPTH_FACTOR
-
-  "occTexTrsf2d",           // OpenGl_OCCT_TEXTURE_TRSF2D
-  "occPointSize",           // OpenGl_OCCT_POINT_SIZE
-
-  "occViewport",            // OpenGl_OCCT_VIEWPORT
-  "occLineWidth",           // OpenGl_OCCT_LINE_WIDTH
-  "occLineFeather",         // OpenGl_OCCT_LINE_FEATHER
-  "occStipplePattern",      // OpenGl_OCCT_LINE_STIPPLE_PATTERN
-  "occStippleFactor",       // OpenGl_OCCT_LINE_STIPPLE_FACTOR
-  "occWireframeColor",      // OpenGl_OCCT_WIREFRAME_COLOR
-  "occIsQuadMode",          // OpenGl_OCCT_QUAD_MODE_STATE
-
-  "occOrthoScale",          // OpenGl_OCCT_ORTHO_SCALE
-  "occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS
-
-  "occNbSpecIBLLevels"      // OpenGl_OCCT_NB_SPEC_IBL_LEVELS
+  "occClipPlaneEquations",    // OpenGl_OCC_CLIP_PLANE_EQUATIONS
+  "occClipPlaneChains",       // OpenGl_OCC_CLIP_PLANE_CHAINS
+  "occClipPlaneCount",        // OpenGl_OCC_CLIP_PLANE_COUNT
+
+  "occLightSourcesCount",     // OpenGl_OCC_LIGHT_SOURCE_COUNT
+  "occLightSourcesTypes",     // OpenGl_OCC_LIGHT_SOURCE_TYPES
+  "occLightSources",          // OpenGl_OCC_LIGHT_SOURCE_PARAMS
+  "occLightAmbient",          // OpenGl_OCC_LIGHT_AMBIENT
+  "occShadowMapSizeBias",     // OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS
+  "occShadowMapSamplers",     // OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS,
+  "occShadowCubeMapSamplers", // OpenGl_OCC_LIGHT_SHADOWCUBEMAP_SAMPLERS,
+  "occShadowMapMatrices",     // OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES,
+
+  "occTextureEnable",         // OpenGl_OCCT_TEXTURE_ENABLE
+  "occDistinguishingMode",    // OpenGl_OCCT_DISTINGUISH_MODE
+  "occPbrMaterial",           // OpenGl_OCCT_PBR_MATERIAL
+  "occCommonMaterial",        // OpenGl_OCCT_COMMON_MATERIAL
+  "occAlphaCutoff",           // OpenGl_OCCT_ALPHA_CUTOFF
+  "occColor",                 // OpenGl_OCCT_COLOR
+
+  "occOitOutput",             // OpenGl_OCCT_OIT_OUTPUT
+  "occOitDepthFactor",        // OpenGl_OCCT_OIT_DEPTH_FACTOR
+
+  "occTexTrsf2d",             // OpenGl_OCCT_TEXTURE_TRSF2D
+  "occPointSize",             // OpenGl_OCCT_POINT_SIZE
+
+  "occViewport",              // OpenGl_OCCT_VIEWPORT
+  "occLineWidth",             // OpenGl_OCCT_LINE_WIDTH
+  "occLineFeather",           // OpenGl_OCCT_LINE_FEATHER
+  "occStipplePattern",        // OpenGl_OCCT_LINE_STIPPLE_PATTERN
+  "occStippleFactor",         // OpenGl_OCCT_LINE_STIPPLE_FACTOR
+  "occWireframeColor",        // OpenGl_OCCT_WIREFRAME_COLOR
+  "occIsQuadMode",            // OpenGl_OCCT_QUAD_MODE_STATE
+
+  "occOrthoScale",            // OpenGl_OCCT_ORTHO_SCALE
+  "occSilhouetteThickness",   // OpenGl_OCCT_SILHOUETTE_THICKNESS
+
+  "occNbSpecIBLLevels"        // OpenGl_OCCT_NB_SPEC_IBL_LEVELS
 };
 
 namespace
@@ -165,6 +166,7 @@ OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram
   myShareCount(1),
   myNbLightsMax (0),
   myNbShadowMaps (0),
+  myNbShadowCubeMaps (0),
   myNbClipPlanesMax (0),
   myNbFragOutputs (1),
   myTextureSetBits (Graphic3d_TextureSetBits_NONE),
@@ -419,15 +421,24 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     }
 
     TCollection_AsciiString aHeaderConstants;
-    myNbLightsMax     = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
-    myNbShadowMaps    = !myProxy.IsNull() ? myProxy->NbShadowMaps() : 0;
-    myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
+    myNbLightsMax      = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
+    myNbShadowMaps     = !myProxy.IsNull() ? myProxy->NbShadowMaps() : 0;
+    myNbShadowCubeMaps = !myProxy.IsNull() ? myProxy->NbShadowCubeMaps() : 0;
+    myNbClipPlanesMax  = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
     aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
     aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
     aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n";
+    if (myNbShadowMaps + myNbShadowCubeMaps > 0)
+    {
+      aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPS ") + (myNbShadowMaps + myNbShadowCubeMaps) + "\n";
+    }
     if (myNbShadowMaps > 0)
     {
-      aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPS ") + myNbShadowMaps + "\n";
+      aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPS2D ") + myNbShadowMaps + "\n";
+    }
+    if (myNbShadowCubeMaps > 0)
+    {
+      aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPSCUBE ") + myNbShadowCubeMaps + "\n";
     }
     if (theCtx->caps->useZeroToOneDepth
      && theCtx->arbClipControl)
@@ -590,7 +601,16 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
     }
     SetUniform (theCtx, aLocSampler, myNbShadowMaps, &aShadowSamplers.front());
   }
-
+  if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occShadowCubeMapSamplers"))
+  {
+    std::vector<GLint> aShadowSamplers (myNbShadowCubeMaps);
+    const GLint aSamplFrom = GLint(theCtx->ShadowCubeMapTexUnit()) - myNbShadowCubeMaps + 1;
+    for (Standard_Integer aSamplerIter = 0; aSamplerIter < myNbShadowCubeMaps; ++aSamplerIter)
+    {
+      aShadowSamplers[aSamplerIter] = aSamplFrom + aSamplerIter;
+    }
+    SetUniform (theCtx, aLocSampler, myNbShadowCubeMaps, &aShadowSamplers.front());
+  }
   if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDepthPeelingDepth"))
   {
     SetUniform (theCtx, aLocSampler, GLint(theCtx->DepthPeelingDepthTexUnit()));
index 92d74e54efd80c54a37fe801f0d09da403583bb2..73d588b462bd016fab8446fda362106c9f9bc5c9 100755 (executable)
@@ -57,9 +57,10 @@ enum OpenGl_StateVariable
   OpenGl_OCC_LIGHT_SOURCE_TYPES,
   OpenGl_OCC_LIGHT_SOURCE_PARAMS,
   OpenGl_OCC_LIGHT_AMBIENT,
-  OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS,// occShadowMapSizeBias
-  OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS, // occShadowMapSamplers
-  OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES, // occShadowMapMatrices
+  OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS,    // occShadowMapSizeBias
+  OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS,     // occShadowMapSamplers
+  OpenGl_OCC_LIGHT_SHADOWCUBEMAP_SAMPLERS, // occShadowCubeMapSamplers
+  OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES,     // occShadowMapMatrices
 
   // Material state
   OpenGl_OCCT_TEXTURE_ENABLE,
@@ -283,9 +284,12 @@ public:
   //! to be used for initialization occLightSources (OpenGl_OCC_LIGHT_SOURCE_PARAMS).
   Standard_Integer NbLightsMax() const { return myNbLightsMax; }
 
-  //! Return the length of array of shadow maps (THE_NB_SHADOWMAPS); 0 by default.
+  //! Return the length of array of 2D shadow maps (THE_NB_SHADOWMAP2D); 0 by default.
   Standard_Integer NbShadowMaps() const { return myNbShadowMaps; }
 
+  //! Return the length of array of shadow cube maps (THE_NB_SHADOWMAPCUBE); 0 by default.
+  Standard_Integer NbShadowCubeMaps() const { return myNbShadowCubeMaps; }
+
   //! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES),
   //! to be used for initialization occClipPlaneEquations (OpenGl_OCC_CLIP_PLANE_EQUATIONS) and occClipPlaneChains (OpenGl_OCC_CLIP_PLANE_CHAINS).
   Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; }
@@ -643,18 +647,19 @@ protected:
 
 protected:
 
-  GLuint                          myProgramID;     //!< Handle of OpenGL shader program
-  OpenGl_ShaderList               myShaderObjects; //!< List of attached shader objects
-  Handle(Graphic3d_ShaderProgram) myProxy;         //!< Proxy shader program (from application layer)
-  Standard_Integer                myShareCount;    //!< program users count, initialized with 1 (already shared by one user)
-  Standard_Integer                myNbLightsMax;   //!< length of array of light sources (THE_MAX_LIGHTS)
-  Standard_Integer                myNbShadowMaps;  //!< length of array of shadow maps (THE_NB_SHADOWMAPS)
-  Standard_Integer                myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
-  Standard_Integer                myNbFragOutputs; //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
-  Standard_Integer                myTextureSetBits;//!< texture units declared within the program, @sa Graphic3d_TextureSetBits
-  Graphic3d_RenderTransparentMethod myOitOutput;   //!< flag indicating that Fragment Shader includes OIT outputs
-  Standard_Boolean                myHasAlphaTest;  //!< flag indicating that Fragment Shader should perform alpha-test
-  Standard_Boolean                myHasTessShader; //!< flag indicating that program defines tessellation stage
+  GLuint                          myProgramID;        //!< Handle of OpenGL shader program
+  OpenGl_ShaderList               myShaderObjects;    //!< List of attached shader objects
+  Handle(Graphic3d_ShaderProgram) myProxy;            //!< Proxy shader program (from application layer)
+  Standard_Integer                myShareCount;       //!< program users count, initialized with 1 (already shared by one user)
+  Standard_Integer                myNbLightsMax;      //!< length of array of light sources (THE_MAX_LIGHTS)
+  Standard_Integer                myNbShadowMaps;     //!< length of array of shadow maps (THE_NB_SHADOWMAP2D)
+  Standard_Integer                myNbShadowCubeMaps; //!< length of array of shadow maps (THE_NB_SHADOWMAPCUBE)
+  Standard_Integer                myNbClipPlanesMax;  //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
+  Standard_Integer                myNbFragOutputs;    //!< length of array of Fragment Shader outputs (THE_NB_FRAG_OUTPUTS)
+  Standard_Integer                myTextureSetBits;   //!< texture units declared within the program, @sa Graphic3d_TextureSetBits
+  Graphic3d_RenderTransparentMethod myOitOutput;      //!< flag indicating that Fragment Shader includes OIT outputs
+  Standard_Boolean                myHasAlphaTest;     //!< flag indicating that Fragment Shader should perform alpha-test
+  Standard_Boolean                myHasTessShader;    //!< flag indicating that program defines tessellation stage
 
 protected:
 
index 14854d91283a417ad4bfc73a099e38f75e47a194..296d205be88dc90ff49ddcb6ced1480ec7aca142 100644 (file)
@@ -83,7 +83,8 @@ const Handle(OpenGl_Texture)& OpenGl_ShadowMap::Texture() const
 // purpose  :
 // =======================================================================
 bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView,
-                                     const gp_XYZ* theOrigin)
+                                     const gp_XYZ* theOrigin,
+                                     const Standard_Integer theFace)
 {
   const Bnd_Box aMinMaxBox  = theOrigin == NULL ? theView.MinMaxValues (false) : Bnd_Box(); // applicative min max boundaries
   const Bnd_Box aGraphicBox = aMinMaxBox;
@@ -134,7 +135,19 @@ bool OpenGl_ShadowMap::UpdateCamera (const Graphic3d_CView& theView,
     case Graphic3d_TypeOfLightSource_Positional:
     {
       // render into cubemap shadowmap texture
-      return false; // not implemented
+      myShadowCamera->SetZeroToOneDepth (theView.Camera()->IsZeroToOneDepth());
+      myShadowCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
+      myShadowCamera->SetFOVy (90.0);
+      const gp_Pnt& aLightPos = myShadowLight->Position();
+      myShadowCamera->MoveEyeTo (aLightPos);
+      // calculate direction and up vector for the given cubemap face
+      myShadowCamera->SetDirectionFromEye (Graphic3d_CubeMap::GetCubeDirection ((Graphic3d_CubeMapSide)theFace));
+      myShadowCamera->SetUp (Graphic3d_CubeMap::GetCubeUp ((Graphic3d_CubeMapSide)theFace));
+      // setup znear and zfar (default value)
+      myShadowCamera->SetZRange (1.0, myShadowCamera->GetDefaultZFar());
+      myLightMatrix = myShadowCamera->ProjectionMatrixF() * myShadowCamera->OrientationMatrixF();
+
+      return true;
     }
     case Graphic3d_TypeOfLightSource_Spot:
     {
index 309fbce1e1812ebab8d4a9557f2548bbc4e9a097..5f04392aad8b7d2ed1590f8e1dd386befa42bd58 100644 (file)
@@ -76,8 +76,10 @@ public:
   //! Compute camera.
   //! @param theView   [in] active view
   //! @param theOrigin [in] when not-NULL - displace shadow map camera to specified Z-Layer origin
+  //! @param theFace   [in] if light is point light calculate for given cubemap face index
   Standard_EXPORT bool UpdateCamera (const Graphic3d_CView& theView,
-                                     const gp_XYZ* theOrigin = NULL);
+                                     const gp_XYZ* theOrigin = NULL,
+                                     const Standard_Integer theFace = -1);
 
 private:
 
index 4d90a8e96bd84b0cf2b702990aa9eced7297f718..1e00967edc7f079bab2482751e418d950be567bf 100644 (file)
@@ -443,7 +443,6 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
           return false;
         }
       }
-
       theCtx->core11fwd->glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
                                        theSizeXYZ.x(), theSizeXYZ.y(), 0,
                                        theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
@@ -520,9 +519,48 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
     }
     case Graphic3d_TypeOfTexture_CUBEMAP:
     {
-      Unbind (theCtx);
-      Release (theCtx.get());
-      return false;
+      Bind (theCtx);
+      applyDefaultSamplerParams (theCtx);
+      if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGL)
+      {
+        // use proxy to check texture could be created or not
+        theCtx->core11fwd->glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
+                                         theSizeXYZ.x(), theSizeXYZ.y(), 0,
+                                         theFormat.PixelFormat(), theFormat.DataType(), NULL);
+        theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
+        theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
+        theCtx->core11fwd->glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
+        if (aTestWidth == 0 || aTestHeight == 0)
+        {
+          // no memory or broken input parameters
+          Unbind(theCtx);
+          Release(theCtx.get());
+          return false;
+        }
+      }
+      for (Standard_Integer aCubeIndex = 0; aCubeIndex < 6; ++aCubeIndex)
+      {
+        theCtx->core11fwd->glTexImage2D (GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeIndex), 0, anIntFormat,
+                                         theSizeXYZ.x(), theSizeXYZ.y(), 0,
+                                         theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
+        GLenum anErr = theCtx->core11fwd->glGetError();
+        if (anErr != GL_NO_ERROR)
+        {
+          theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+                               TCollection_AsciiString ("Error: Cubemap texture ") + theSizeXYZ.x() + "x" + theSizeXYZ.y()
+                                                     + " IF: " + OpenGl_TextureFormat::FormatFormat (anIntFormat)
+                                                     + " PF: " + OpenGl_TextureFormat::FormatFormat (theFormat.PixelFormat())
+                                                     + " DT: " + OpenGl_TextureFormat::FormatDataType (theFormat.DataType())
+                                                     + " can not be created with error " + OpenGl_Context::FormatGlError (anErr)
+                                                     + " [" + myResourceId + "]");
+          Unbind (theCtx);
+          Release (theCtx.get());
+          return false;
+        }
+      }
+
+      mySize.SetValues (theSizeXYZ.xy(), 1);
+      break;
     }
   }
 
index 790779556779e7b528070c0260fd90a6d41729f5..22ee42fad0acefde0b8c112ab01ddf60fed6069c 100644 (file)
@@ -1583,31 +1583,73 @@ bool OpenGl_View::prepareFrameBuffers (Graphic3d_Camera::Projection& theProj)
                      && myRenderParams.Method != Graphic3d_RM_RAYTRACING;
   if (toUseShadowMap)
   {
+    Standard_Integer aNbShadows = 0;
+    Standard_Integer aNbPointShadows = 0;
+    Standard_Boolean aToReviewLights = Standard_False;
+    for (Graphic3d_LightSet::Iterator aLightIter(myLights); aLightIter.More(); aLightIter.Next())
+    {
+      Handle(Graphic3d_CLight) aLight = aLightIter.Value();
+      if (aLight->Type() == Graphic3d_TypeOfLightSource_Positional)
+      {
+        // point lights shadows are not currently supported on opengles 2.0
+        if (aCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES
+         && aCtx->VersionMajor() <= 2)
+        {
+          aLight->SetCastShadows (Standard_False);
+          aToReviewLights = Standard_True;
+        }
+        else if (aLight->ToCastShadows())
+        {
+          ++aNbPointShadows;
+        }
+      }
+      else
+      {
+        if (aLight->ToCastShadows())
+        {
+          ++aNbShadows;
+        }
+      }
+    }
+    if (aToReviewLights)
+    {
+      myLights->UpdateRevision();
+    }
     if (myShadowMaps->Size() != myLights->NbCastShadows())
     {
       myShadowMaps->Release (aCtx.get());
       myShadowMaps->Resize (0, myLights->NbCastShadows() - 1, true);
     }
-
-    const GLint aSamplFrom = GLint(aCtx->ShadowMapTexUnit()) - myLights->NbCastShadows() + 1;
-    for (Standard_Integer aShadowIter = 0; aShadowIter < myShadowMaps->Size(); ++aShadowIter)
+    const GLint aSampleFrom = GLint(aCtx->ShadowMapTexUnit()) - myLights->NbCastShadows() + aNbPointShadows + 1;
+    const GLint aSampleCubeFrom = GLint(aCtx->ShadowCubeMapTexUnit()) - aNbPointShadows + 1;
+    Standard_Integer aLightIndex = 0;
+    Standard_Integer a2DShadowIndex = 0;
+    Standard_Integer aCubeShadowIndex = 0;
+    for (Graphic3d_LightSet::Iterator aLightIter(myLights); aLightIter.More(); aLightIter.Next())
     {
-      Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->ChangeValue (aShadowIter);
-      if (aShadow.IsNull())
-      {
-        aShadow = new OpenGl_ShadowMap();
-      }
-      aShadow->SetShadowMapBias (myRenderParams.ShadowMapBias);
-      aShadow->Texture()->Sampler()->Parameters()->SetTextureUnit ((Graphic3d_TextureUnit )(aSamplFrom + aShadowIter));
-
-      const Handle(OpenGl_FrameBuffer)& aShadowFbo = aShadow->FrameBuffer();
-      if (aShadowFbo->GetVPSizeX() != myRenderParams.ShadowMapResolution
-       && toUseShadowMap)
+      Handle(Graphic3d_CLight) aLight = aLightIter.Value();
+      if (aLight->ToCastShadows())
       {
-        OpenGl_ColorFormats aDummy;
-        if (!aShadowFbo->Init (aCtx, Graphic3d_Vec2i (myRenderParams.ShadowMapResolution), aDummy, myFboDepthFormat, 0))
+        Handle(OpenGl_ShadowMap)& aShadow = myShadowMaps->ChangeValue (aLightIndex++);
+        if (aShadow.IsNull())
         {
-          toUseShadowMap = false;
+          aShadow = new OpenGl_ShadowMap();
+        }
+        aShadow->SetShadowMapBias (myRenderParams.ShadowMapBias);
+        Standard_Integer aTexUnit = aLight->Type() == Graphic3d_TypeOfLightSource_Positional
+                                                    ? aSampleCubeFrom + aCubeShadowIndex++
+                                                    : aSampleFrom + a2DShadowIndex++;
+        aShadow->Texture()->Sampler()->Parameters()->SetTextureUnit ((Graphic3d_TextureUnit)(aTexUnit));
+        const Handle(OpenGl_FrameBuffer)& aShadowFbo = aShadow->FrameBuffer();
+        if (aShadowFbo->GetVPSizeX() != myRenderParams.ShadowMapResolution
+          && toUseShadowMap)
+        {
+          OpenGl_ColorFormats aDummy;
+          if (!aShadowFbo->Init (aCtx, Graphic3d_Vec2i(myRenderParams.ShadowMapResolution), aDummy, myFboDepthFormat, 0,
+                                 aLight->Type() == Graphic3d_TypeOfLightSource_Positional))
+          {
+            toUseShadowMap = false;
+          }
         }
       }
     }
@@ -1688,7 +1730,22 @@ void OpenGl_View::Redraw()
       {
         const Handle(OpenGl_ShadowMap)& aShadowMap = myShadowMaps->ChangeValue (aShadowIndex);
         aShadowMap->SetLightSource (aLight);
-        renderShadowMap (aShadowMap);
+        if (aLight->Type() == Graphic3d_TypeOfLightSource_Positional)
+        {
+          // point light shadows are not currently supported on opengles 2.0.
+          if (aCtx->GraphicsLibrary() != Aspect_GraphicsLibrary_OpenGLES
+           || aCtx->VersionMajor() >= 3)
+          {
+            for (Standard_Integer aCubeFace = 0; aCubeFace < 6; ++aCubeFace)
+            {
+              renderShadowMap (aShadowMap, aCubeFace);
+            }
+          }
+        }
+        else
+        {
+          renderShadowMap (aShadowMap, -1);
+        }
         ++aShadowIndex;
       }
     }
@@ -2297,10 +2354,11 @@ bool OpenGl_View::blitSubviews (const Graphic3d_Camera::Projection ,
 //function : renderShadowMap
 //purpose  :
 //=======================================================================
-void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap)
+void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap,
+                                   const Standard_Integer theFace)
 {
   const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
-  if (!theShadowMap->UpdateCamera (*this))
+  if (!theShadowMap->UpdateCamera (*this, NULL, theFace))
   {
     return;
   }
@@ -2319,7 +2377,14 @@ void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap)
   aCtx->ShaderManager()->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit);
 
   const Handle(OpenGl_FrameBuffer)& aShadowBuffer = theShadowMap->FrameBuffer();
-  aShadowBuffer->BindBuffer    (aCtx);
+  if (theFace < 0)
+  {
+    aShadowBuffer->BindBuffer (aCtx);
+  }
+  else 
+  {
+    aShadowBuffer->BindBufferCube (aCtx, theFace);
+  }
   aShadowBuffer->SetupViewport (aCtx);
 
   aCtx->SetColorMask (false);
@@ -2329,9 +2394,9 @@ void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap)
   myWorkspace->UseZBuffer()    = true;
   myWorkspace->UseDepthWrite() = true;
   aCtx->core11fwd->glDepthFunc (GL_LEQUAL);
-  aCtx->core11fwd->glDepthMask (GL_TRUE);
   aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
   aCtx->core11fwd->glClearDepth (1.0);
+  aCtx->core11fwd->glDepthMask (GL_TRUE);
   aCtx->core11fwd->glClear (GL_DEPTH_BUFFER_BIT);
 
   Graphic3d_Camera::Projection aProjection = theShadowMap->LightSource()->Type() == Graphic3d_TypeOfLightSource_Directional
@@ -2345,10 +2410,9 @@ void OpenGl_View::renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap)
   myWorkspace->ResetAppliedAspect();
   aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
 
-//Image_AlienPixMap anImage; anImage.InitZero (Image_Format_Gray, aShadowBuffer->GetVPSizeX(), aShadowBuffer->GetVPSizeY());
-//OpenGl_FrameBuffer::BufferDump (aCtx, aShadowBuffer, anImage, Graphic3d_BT_Depth);
-//anImage.Save (TCollection_AsciiString ("shadow") + theShadowMap->Texture()->Sampler()->Parameters()->TextureUnit() + ".png");
-
+  //Image_AlienPixMap anImage; anImage.InitZero (Image_Format_GrayF, aShadowBuffer->GetVPSizeX(), aShadowBuffer->GetVPSizeY());
+  //OpenGl_FrameBuffer::BufferDump (aCtx, aShadowBuffer, anImage, Graphic3d_BT_Depth);
+  //anImage.Save (TCollection_AsciiString("shadow") + theShadowMap->Texture()->Sampler()->Parameters()->TextureUnit() + ".png");
   bindDefaultFbo();
 }
 
index 17768a06d13b2e91ac03685fbd68db8d339c1dde..878e7d276c20c9cc432353e7c6dd2c8c2ec28d51 100644 (file)
@@ -354,7 +354,9 @@ protected: //! @name Rendering of GL graphics (with prepared drawing buffer).
 
   //! Renders the graphical contents of the view into the preprepared shadowmap framebuffer.
   //! @param theShadowMap [in] the framebuffer for rendering shadowmap.
-  Standard_EXPORT virtual void renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap);
+  //! @param theFace      [in] value for cubemap face.
+  Standard_EXPORT virtual void renderShadowMap (const Handle(OpenGl_ShadowMap)& theShadowMap,
+                                                const Standard_Integer theFace);
 
   //! Renders the graphical contents of the view into the preprepared window or framebuffer.
   //! @param theProjection [in] the projection that should be used for rendering.
index ea4bc6ca151a058d510a7f7608391e4776841e01..ae38e0a8486ec7271b78944e62c3f7852ef8a650 100644 (file)
 #define INV_PI   0.318309886
 #define INV_PI_2 0.159154943
 
+// Point light depth range values
+#define POINTLIGHT_ZNEAR 1.0
+#define POINTLIGHT_ZFAR  3000.0
+
 // Matrix state
 uniform mat4 occWorldViewMatrix;  //!< World-view  matrix
 uniform mat4 occProjectionMatrix; //!< Projection  matrix
index f509a2387733155044fe3c1f34078221f7dbf73e..ba9211bf5d6ec8bdb7ae4255387bc102e2e9b016 100644 (file)
@@ -1,6 +1,7 @@
 srcinc:::Declarations.glsl
 srcinc:::DeclarationsImpl.glsl
 srcinc:::LightShadow.glsl
+srcinc:::LightPointShadow.glsl
 srcinc:::PBRCookTorrance.glsl
 srcinc:::PBRDirectionalLight.glsl
 srcinc:::PBRDistribution.glsl
@@ -28,6 +29,7 @@ srcinc:::SkydomBackground.fs
 Shaders_Declarations_glsl.pxx
 Shaders_DeclarationsImpl_glsl.pxx
 Shaders_LightShadow_glsl.pxx
+Shaders_LightPointShadow_glsl.pxx
 Shaders_Display_fs.pxx
 Shaders_PBRCookTorrance_glsl.pxx
 Shaders_PBRDirectionalLight_glsl.pxx
diff --git a/src/Shaders/LightPointShadow.glsl b/src/Shaders/LightPointShadow.glsl
new file mode 100644 (file)
index 0000000..463287c
--- /dev/null
@@ -0,0 +1,24 @@
+//! Function computes point light shadow attenuation (1.0 means no shadow).
+float occLightPointShadow (in samplerCube theShadow,
+                           //in vec2 theDepthRange,
+                           in int  theId,
+                           in vec3 thePoint,
+                           in vec3 theNormal)
+{
+  vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];
+  vec3 aLightDir = thePoint - occLight_Position (theId);
+  // convert light-to-fragment vector to a depth value.
+  vec3 anAbsVec = abs (aLightDir);
+  float aLocalZcomp = max (anAbsVec.x, max (anAbsVec.y, anAbsVec.z));
+  // set znear and zfar
+  float aNear = POINTLIGHT_ZNEAR;
+  float aFar = POINTLIGHT_ZFAR;
+  float aNormZComp = (aFar + aNear) / (aFar - aNear) - (2.0 * aFar * aNear) / (aFar - aNear) / aLocalZcomp;
+  float aDist = (aNormZComp + 1.0) * 0.5;
+  // calculate bias and test depth.
+  aLightDir = normalize (aLightDir);
+  float aBias = min (occShadowMapSizeBias.y * (1.0 - dot (theNormal, aLightDir)), occShadowMapSizeBias.y * 0.1);
+  float aClosestDepth = occTextureCube (theShadow, aLightDir).r;
+  float aShadow = (aDist - aBias) > aClosestDepth ? 1.0 : 0.0;
+  return 1.0 - aShadow;
+}
index d6c0fca936a81853a7aeeb53025964fe58008b51..2d71dc1963a63e60ffe799e0fbe1c2c14fc8181e 100644 (file)
@@ -9,7 +9,8 @@ void occPointLight (in int  theId,
                     in vec3 theNormal,
                     in vec3 theView,
                     in vec3 thePoint,
-                    in bool theIsFront)
+                    in bool theIsFront,
+                    in float theShadow)
 {
   vec3 aLight = occLight_Position (theId) - thePoint;
 
@@ -23,5 +24,5 @@ void occPointLight (in int  theId,
   DirectLighting += occPBRIllumination (theView, aLight, theNormal,
                                         BaseColor, Metallic, Roughness, IOR,
                                         occLight_Specular (theId),
-                                        occLight_Intensity(theId) * anAtten);
+                                        occLight_Intensity(theId) * anAtten) * theShadow;
 }
index 1b49bfe7ddeb815c4b2b418a701880f77425d37c..67ae629ad7f38589cf602c7b3210082e1bfe3846 100644 (file)
@@ -9,7 +9,8 @@ void occPointLight (in int  theId,
                     in vec3 theNormal,
                     in vec3 theView,
                     in vec3 thePoint,
-                    in bool theIsFront)
+                    in bool theIsFront,
+                    in float theShadow)
 {
   vec3 aLight = occLight_Position (theId) - thePoint;
 
@@ -31,6 +32,6 @@ void occPointLight (in int  theId,
     aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));
   }
 
-  Diffuse  += occLight_Diffuse (theId) * aNdotL * anAtten;
-  Specular += occLight_Specular(theId) * aSpecl * anAtten;
+  Diffuse  += occLight_Diffuse (theId) * aNdotL * anAtten * theShadow;
+  Specular += occLight_Specular(theId) * aSpecl * anAtten * theShadow;
 }
index 0485a491c67c7e65317e355e9245f3e6792d00fb..e1083c6308ac551f8403e0da61a62a745d1dae71 100644 (file)
@@ -116,6 +116,10 @@ static const char Shaders_Declarations_glsl[] =
   "#define INV_PI   0.318309886\n"
   "#define INV_PI_2 0.159154943\n"
   "\n"
+  "// Point light depth range values\n"
+  "#define POINTLIGHT_ZNEAR 1.0\n"
+  "#define POINTLIGHT_ZFAR  3000.0\n"
+  "\n"
   "// Matrix state\n"
   "uniform mat4 occWorldViewMatrix;  //!< World-view  matrix\n"
   "uniform mat4 occProjectionMatrix; //!< Projection  matrix\n"
diff --git a/src/Shaders/Shaders_LightPointShadow_glsl.pxx b/src/Shaders/Shaders_LightPointShadow_glsl.pxx
new file mode 100644 (file)
index 0000000..1389d6b
--- /dev/null
@@ -0,0 +1,27 @@
+// This file has been automatically generated from resource file src/Shaders/LightShadow.glsl
+
+static const char Shaders_LightPointShadow_glsl[] =
+  "//! Function computes point light shadow attenuation (1.0 means no shadow).\n"
+  "float occLightPointShadow (in samplerCube theShadow,\n"
+  "                           //in vec2 theDepthRange,\n"
+  "                           in int  theId,\n"
+  "                           in vec3 thePoint,\n"
+  "                           in vec3 theNormal)\n"
+  "{\n"
+  "  vec4 aPosLightSpace = PosLightSpace[occLight_Index(theId)];\n"
+  "  vec3 aLightDir = thePoint - occLight_Position (theId);\n"
+  "  // convert light-to-fragment vector to a depth value.\n"
+  "  vec3 anAbsVec = abs (aLightDir);\n"
+  "  float aLocalZcomp = max (anAbsVec.x, max (anAbsVec.y, anAbsVec.z));\n"
+  "  // set znear and zfar\n"
+  "  float aNear = POINTLIGHT_ZNEAR;\n"
+  "  float aFar = POINTLIGHT_ZFAR;\n"
+  "  float aNormZComp = (aFar + aNear) / (aFar-aNear) - (2.0 * aFar * aNear) / (aFar - aNear) / aLocalZcomp;\n"
+  "  float aDist = (aNormZComp + 1.0) * 0.5;\n"
+  "  // calculate bias and test depth.\n"
+  "  aLightDir = normalize (aLightDir);\n"
+  "  float aBias = min (occShadowMapSizeBias.y * (1.0 - dot (theNormal, aLightDir)), occShadowMapSizeBias.y * 0.1);\n"
+  "  float aClosestDepth = occTextureCube (theShadow, aLightDir).r;\n"
+  "  float aShadow = (aDist - aBias) > aClosestDepth ? 1.0 : 0.0;\n"
+  "  return 1.0 - aShadow;\n"
+  "}\n";
index d08f5908e87b5e98b3e430ce097baff9fdb84460..909fc3dba23af1da86a4795c6a3bddd77be12f57 100644 (file)
@@ -12,7 +12,8 @@ static const char Shaders_PBRPointLight_glsl[] =
   "                    in vec3 theNormal,\n"
   "                    in vec3 theView,\n"
   "                    in vec3 thePoint,\n"
-  "                    in bool theIsFront)\n"
+  "                    in bool theIsFront,\n"
+  "                    in float theShadow)\n"
   "{\n"
   "  vec3 aLight = occLight_Position (theId) - thePoint;\n"
   "\n"
@@ -26,5 +27,5 @@ static const char Shaders_PBRPointLight_glsl[] =
   "  DirectLighting += occPBRIllumination (theView, aLight, theNormal,\n"
   "                                        BaseColor, Metallic, Roughness, IOR,\n"
   "                                        occLight_Specular (theId),\n"
-  "                                        occLight_Intensity(theId) * anAtten);\n"
+  "                                        occLight_Intensity(theId) * anAtten) * theShadow;\n"
   "}\n";
index 9b48db353db37de821ad74d1995ae0bb2149a718..87b784e6930438181c8ae09d2a4595c3ef60b793 100644 (file)
@@ -12,7 +12,8 @@ static const char Shaders_PhongPointLight_glsl[] =
   "                    in vec3 theNormal,\n"
   "                    in vec3 theView,\n"
   "                    in vec3 thePoint,\n"
-  "                    in bool theIsFront)\n"
+  "                    in bool theIsFront,\n"
+  "                    in float theShadow)\n"
   "{\n"
   "  vec3 aLight = occLight_Position (theId) - thePoint;\n"
   "\n"
@@ -34,6 +35,6 @@ static const char Shaders_PhongPointLight_glsl[] =
   "    aSpecl = pow (aNdotH, occMaterial_Shininess (theIsFront));\n"
   "  }\n"
   "\n"
-  "  Diffuse  += occLight_Diffuse (theId) * aNdotL * anAtten;\n"
-  "  Specular += occLight_Specular(theId) * aSpecl * anAtten;\n"
+  "  Diffuse  += occLight_Diffuse (theId) * aNdotL * anAtten * theShadow;\n"
+  "  Specular += occLight_Specular(theId) * aSpecl * anAtten * theShadow;\n"
   "}\n";
diff --git a/tests/opengl/data/shadows/pointlight b/tests/opengl/data/shadows/pointlight
new file mode 100644 (file)
index 0000000..0c5ae9f
--- /dev/null
@@ -0,0 +1,58 @@
+puts "========"
+puts "0032173: Visualization, TKOpenGl - implement simple shadow mapping for a point light source"
+puts "Test shadow map from a point light source on multiple boxes."
+puts "========"
+
+pload MODELING VISUALIZATION
+if { $::tcl_platform(os) == "Darwin" } { vcaps -core }
+vclear
+vinit View1
+vrenderparams -shadingModel phong
+# add geometry
+box b1 20 0 0 10 10 10
+box b2 -20 0 0 10 10 10
+box b3 -50 -20 -25 100 5 50
+box b4 0 10 0 5 5 5
+box b5 0 0 5 3 3 3
+box b6 0 0 -5 7 7 7
+box b7 0 -5 -10 3 3 3
+vdisplay -dispmode 1 b1 b2 b3 b4 b5 b6 b7
+vfit
+# add colors
+vsetcolor b1 RED3
+vsetcolor b2 GREEN3
+vsetcolor b3 BLUE3
+vsetcolor b4 ORANGE3
+vsetcolor b5 YELLOW3
+vsetcolor b6 SALMON3
+vsetcolor b7 PURPLE3
+# add light
+vlight -clear
+vlight pntlight1 -type POSITIONAL -pos 0 100 0 -intensity 1000 -castShadows 1
+
+#dump single light phong
+vviewparams -scale 8.0 -proj 0.0 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
+vdump $imagedir/${casename}_single_pointlight_phong1.png
+vviewparams -scale 8.0 -proj 0.5 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
+vdump $imagedir/${casename}_single_pointlight_phong2.png
+#dump single light pbr
+vrenderparams -shadingModel pbr
+vviewparams -scale 10.0 -proj 0.0 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
+vdump $imagedir/${casename}_single_pointlight_pbr1.png
+vviewparams -scale 10.0 -proj 0.2 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
+vdump $imagedir/${casename}_single_pointlight_pbr2.png
+
+#add second light
+vlight pntlight2 -type POSITIONAL -pos 40 100 0 -intensity 1000 -castShadows 1
+#dump double light phong
+vrenderparams -shadingModel phong
+vviewparams -scale 8.0 -proj 0.0 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
+vdump $imagedir/${casename}_double_pointlight_phong1.png
+vviewparams -scale 8.0 -proj 0.5 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
+vdump $imagedir/${casename}_double_pointlight_phong2.png
+#dump double light pbr
+vrenderparams -shadingModel pbr
+vviewparams -scale 10.0 -proj 0.0 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
+vdump $imagedir/${casename}_double_pointlight_pbr1.png
+vviewparams -scale 10.0 -proj -0.2 1.0 0.0 -up 0.0 0.0 1.0 -at 0.0 0.0 0.0
+vdump $imagedir/${casename}_double_pointlight_pbr2.png