0030756: Visualization, TKOpenGl - capping plane does not work for ZLayer with non...
[occt.git] / src / OpenGl / OpenGl_CappingPlaneResource.cxx
index fe48301..6825aef 100755 (executable)
 #include <OpenGl_CappingPlaneResource.hxx>
 #include <OpenGl_Context.hxx>
 #include <OpenGl_Vec.hxx>
+#include <OpenGl_ShaderManager.hxx>
 #include <Precision.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource,OpenGl_Resource)
+
 namespace
 {
   //! 12 plane vertices, interleaved:
@@ -27,21 +30,21 @@ namespace
   //!  - 4 floats, UV texture coordinates
   static const GLfloat THE_CAPPING_PLN_VERTS[12 * (4 + 4 + 4)] =
   {
-    0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
-    1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.0f,
-    0.0f, 0.0f, 1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.0f,
+    0.0f, 0.0f, 0.0f, 1.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
+    0.0f, 0.0f, 1.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.0f,
+    1.0f, 0.0f, 0.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.0f,
 
-    0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
-    0.0f, 0.0f, 1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.0f,
-   -1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.0f,
+    0.0f, 0.0f, 0.0f, 1.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
+   -1.0f, 0.0f, 0.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.0f,
+    0.0f, 0.0f, 1.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f,-1.0f, 0.0f, 0.0f,
 
-    0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
-   -1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.0f,
-    0.0f, 0.0f,-1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.0f,
+    0.0f, 0.0f, 0.0f, 1.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
+    0.0f, 0.0f,-1.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.0f,
+   -1.0f, 0.0f, 0.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,  -1.0f, 0.0f, 0.0f, 0.0f,
 
-    0.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
-    0.0f, 0.0f,-1.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.0f,
-    1.0f, 0.0f, 0.0f, 0.0f,  0.0f, 1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.0f
+    0.0f, 0.0f, 0.0f, 1.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 0.0f, 0.0f, 1.0f,
+    1.0f, 0.0f, 0.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   1.0f, 0.0f, 0.0f, 0.0f,
+    0.0f, 0.0f,-1.0f, 0.0f,  0.0f,-1.0f, 0.0f, 0.0f,   0.0f, 1.0f, 0.0f, 0.0f
   };
 
   static const OpenGl_Matrix OpenGl_IdentityMatrix =
@@ -55,8 +58,6 @@ namespace
 
 }
 
-IMPLEMENT_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource, OpenGl_Resource)
 
 // =======================================================================
 // function : OpenGl_CappingPlaneResource
@@ -99,10 +100,11 @@ OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
 // function : Update
 // purpose  :
 // =======================================================================
-void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theContext)
+void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theCtx,
+                                          const Handle(Graphic3d_Aspects)& theObjAspect)
 {
-  UpdateTransform();
-  UpdateAspect (theContext);
+  updateTransform (theCtx);
+  updateAspect (theObjAspect);
 }
 
 // =======================================================================
@@ -118,93 +120,107 @@ void OpenGl_CappingPlaneResource::Release (OpenGl_Context* theContext)
 }
 
 // =======================================================================
-// function : UpdateAspect
+// function : updateAspect
 // purpose  :
 // =======================================================================
-void OpenGl_CappingPlaneResource::UpdateAspect (const Handle(OpenGl_Context)& theContext)
+void OpenGl_CappingPlaneResource::updateAspect (const Handle(Graphic3d_Aspects)& theObjAspect)
 {
-  Handle(Graphic3d_AspectFillArea3d) aCappingAsp = myPlaneRoot->CappingAspect();
-  if (myAspect != NULL && !aCappingAsp.IsNull())
+  if (myAspect == NULL)
   {
-    if (myAspectMod == myPlaneRoot->MCountAspect())
-      return; // noting to update
-    
-    myAspect->SetAspect (aCappingAsp);
-    myAspectMod = myPlaneRoot->MCountAspect();
-    return;
+    myAspect = new OpenGl_Aspects();
+    myAspectMod = myPlaneRoot->MCountAspect() - 1; // mark out of sync
   }
 
-  // no more used
-  if (myAspect != NULL && aCappingAsp.IsNull())
+  if (theObjAspect.IsNull())
   {
-    OpenGl_Element::Destroy (theContext.operator->(), myAspect);
-    myAspectMod = myPlaneRoot->MCountAspect();
+    if (myAspectMod != myPlaneRoot->MCountAspect())
+    {
+      myAspect->SetAspect (myPlaneRoot->CappingAspect());
+      myAspectMod = myPlaneRoot->MCountAspect();
+    }
     return;
   }
 
-  // first created
-  if (myAspect == NULL && !aCappingAsp.IsNull())
+  if (myFillAreaAspect.IsNull())
+  {
+    myFillAreaAspect = new Graphic3d_AspectFillArea3d();
+  }
+  if (myAspectMod != myPlaneRoot->MCountAspect())
+  {
+    *myFillAreaAspect = *myPlaneRoot->CappingAspect();
+  }
+
+  if (myPlaneRoot->ToUseObjectMaterial())
+  {
+    // only front material currently supported by capping rendering
+    myFillAreaAspect->SetFrontMaterial (theObjAspect->FrontMaterial());
+    myFillAreaAspect->SetInteriorColor (theObjAspect->InteriorColor());
+  }
+  if (myPlaneRoot->ToUseObjectTexture())
   {
-    myAspect = new OpenGl_AspectFace();
-    myAspect->SetAspect (aCappingAsp);
-    myAspectMod = myPlaneRoot->MCountAspect();
+    myFillAreaAspect->SetTextureSet (theObjAspect->TextureSet());
+    if (theObjAspect->ToMapTexture())
+    {
+      myFillAreaAspect->SetTextureMapOn();
+    }
+    else
+    {
+      myFillAreaAspect->SetTextureMapOff();
+    }
   }
+  if (myPlaneRoot->ToUseObjectShader())
+  {
+    myFillAreaAspect->SetShaderProgram (theObjAspect->ShaderProgram());
+  }
+
+  myAspect->SetAspect (myFillAreaAspect);
 }
 
 // =======================================================================
-// function : UpdateTransform
+// function : updateTransform
 // purpose  :
 // =======================================================================
-void OpenGl_CappingPlaneResource::UpdateTransform()
+void OpenGl_CappingPlaneResource::updateTransform (const Handle(OpenGl_Context)& theCtx)
 {
-  const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation();
-  if (myEquationMod == myPlaneRoot->MCountEquation())
+  if (myEquationMod == myPlaneRoot->MCountEquation()
+   && myLocalOrigin.IsEqual (theCtx->ShaderManager()->LocalOrigin(), gp::Resolution()))
   {
     return; // nothing to update
   }
 
-  // re-evaluate infinite plane transformation matrix
-  Standard_ShortReal N[3] = 
-    { (Standard_ShortReal)anEquation[0],
-      (Standard_ShortReal)anEquation[1],
-      (Standard_ShortReal)anEquation[2] };
+  myEquationMod = myPlaneRoot->MCountEquation();
+  myLocalOrigin = theCtx->ShaderManager()->LocalOrigin();
 
-  Standard_ShortReal T[3] = 
-    { (Standard_ShortReal)(anEquation[0] * -anEquation[3]),
-      (Standard_ShortReal)(anEquation[1] * -anEquation[3]),
-      (Standard_ShortReal)(anEquation[2] * -anEquation[3]) };
+  const Graphic3d_ClipPlane::Equation& anEq = myPlaneRoot->GetEquation();
+  const Standard_Real anEqW = theCtx->ShaderManager()->LocalClippingPlaneW (*myPlaneRoot);
 
-  Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f };
-  Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f };
+  // re-evaluate infinite plane transformation matrix
+  const Graphic3d_Vec3 aNorm (anEq.xyz());
+  const Graphic3d_Vec3 T (anEq.xyz() * -anEqW);
 
   // project plane normal onto OX to find left vector
-  Standard_ShortReal aConfusion = (Standard_ShortReal)Precision::Confusion();
-  Standard_ShortReal aProjLen = 
-    sqrt (  (Standard_ShortReal)(anEquation[0] * anEquation[0])
-          + (Standard_ShortReal)(anEquation[2] * anEquation[2]));
-  if (aProjLen < aConfusion)
+  const Standard_ShortReal aProjLen = sqrt ((Standard_ShortReal)anEq.xz().SquareModulus());
+  Graphic3d_Vec3 aLeft;
+  if (aProjLen < ShortRealSmall())
   {
-    L[0] = 1.0f;
+    aLeft[0] = 1.0f;
   }
   else
   {
-    L[0] =  N[2] / aProjLen;
-    L[2] = -N[0] / aProjLen;
+    aLeft[0] =  aNorm[2] / aProjLen;
+    aLeft[2] = -aNorm[0] / aProjLen;
   }
 
-  // (-aLeft) x aNorm
-  F[0] = (-L[1])*N[2] - (-L[2])*N[1];
-  F[1] = (-L[2])*N[0] - (-L[0])*N[2];
-  F[2] = (-L[0])*N[1] - (-L[1])*N[0];
+  const Graphic3d_Vec3 F = Graphic3d_Vec3::Cross (-aLeft, aNorm);
 
-  myOrientation.mat[0][0] = L[0];
-  myOrientation.mat[0][1] = L[1];
-  myOrientation.mat[0][2] = L[2];
+  myOrientation.mat[0][0] = aLeft[0];
+  myOrientation.mat[0][1] = aLeft[1];
+  myOrientation.mat[0][2] = aLeft[2];
   myOrientation.mat[0][3] = 0.0f;
 
-  myOrientation.mat[1][0] = N[0];
-  myOrientation.mat[1][1] = N[1];
-  myOrientation.mat[1][2] = N[2];
+  myOrientation.mat[1][0] = aNorm[0];
+  myOrientation.mat[1][1] = aNorm[1];
+  myOrientation.mat[1][2] = aNorm[2];
   myOrientation.mat[1][3] = 0.0f;
 
   myOrientation.mat[2][0] = F[0];
@@ -216,6 +232,4 @@ void OpenGl_CappingPlaneResource::UpdateTransform()
   myOrientation.mat[3][1] = T[1];
   myOrientation.mat[3][2] = T[2];
   myOrientation.mat[3][3] = 1.0f;
-
-  myEquationMod = myPlaneRoot->MCountEquation();
 }