0025885: Visualization, ray tracing - Improve layer processing
[occt.git] / src / OpenGl / OpenGl_View.cxx
index d3c006b..9694079 100644 (file)
@@ -16,7 +16,6 @@
 #include <NCollection_Mat4.hxx>
 
 #include <OpenGl_Context.hxx>
-#include <OpenGl_Display.hxx>
 #include <OpenGl_GlCore11.hxx>
 #include <OpenGl_GraduatedTrihedron.hxx>
 #include <OpenGl_GraphicDriver.hxx>
@@ -25,6 +24,7 @@
 #include <OpenGl_Trihedron.hxx>
 #include <OpenGl_transform_persistence.hxx>
 #include <OpenGl_View.hxx>
+#include <OpenGl_Utils.hxx>
 #include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_TextureEnv.hxx>
@@ -35,8 +35,6 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
 
 /*----------------------------------------------------------------------*/
 
-static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
-static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE };
 static const Tmatrix3 myDefaultMatrix = { { 1.F, 0.F, 0.F, 0.F }, { 0.F, 1.F, 0.F, 0.F }, { 0.F, 0.F, 1.F, 0.F }, { 0.F, 0.F, 0.F, 1.F } };
 static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
 
@@ -54,10 +52,8 @@ static const GLdouble THE_IDENTITY_MATRIX[4][4] =
 
 OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
                           OpenGl_StateCounter*       theCounter)
-: mySurfaceDetail(Visual3d_TOD_NONE),
+: mySurfaceDetail(Visual3d_TOD_ALL),
   myBackfacing(0),
-  myBgTexture(myDefaultBgTexture),
-  myBgGradient(myDefaultBgGradient),
   //shield_indicator = TOn,
   //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
   //border_indicator = TOff,
@@ -66,58 +62,65 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
   myZClip(myDefaultZClip),
   myCamera(AContext.Camera),
   myFog(myDefaultFog),
-  myTrihedron(NULL),
-  myGraduatedTrihedron(NULL),
+  myToShowTrihedron (false),
+  myToShowGradTrihedron (false),
   myVisualization(AContext.Visualization),
-  myIntShadingMethod(TEL_SM_GOURAUD),
+  myShadingModel ((Visual3d_TypeOfModel )AContext.Model),
   myAntiAliasing(Standard_False),
   myTransPers(&myDefaultTransPers),
   myIsTransPers(Standard_False),
   myProjectionState (0),
   myModelViewState (0),
   myStateCounter (theCounter),
-  myLastLightSourceState (0, 0)
+  myLastLightSourceState (0, 0),
+  myTextureParams   (new OpenGl_AspectFace()),
+  myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
+  myBgTextureArray  (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
+  // ray-tracing fields initialization
+  myRaytraceInitStatus (OpenGl_RT_NONE),
+  myIsRaytraceDataValid (Standard_False),
+  myIsRaytraceWarnTextures (Standard_False),
+  myToUpdateEnvironmentMap (Standard_False),
+  myLayersModificationStatus (0)
 {
-
-  // Shading method
-  switch (AContext.Model)
-  {
-    case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
-    case 3 : /* VISUAL3D_TOM_VERTEX */
-      myIntShadingMethod = TEL_SM_GOURAUD;
-      break;
-    default :
-      myIntShadingMethod = TEL_SM_FLAT;
-      break;
-  }
-
   myCurrLightSourceState = myStateCounter->Increment();
-
-  myModificationState = 1; // initial state
 }
 
 /*----------------------------------------------------------------------*/
 
-OpenGl_View::~OpenGl_View ()
+OpenGl_View::~OpenGl_View()
 {
   ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
+  OpenGl_Element::Destroy (NULL, myBgGradientArray);
+  OpenGl_Element::Destroy (NULL, myBgTextureArray);
+  OpenGl_Element::Destroy (NULL, myTextureParams);
 }
 
 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
 {
-  OpenGl_Element::Destroy (theCtx, myTrihedron);
-  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
+  myTrihedron         .Release (theCtx.operator->());
+  myGraduatedTrihedron.Release (theCtx.operator->());
 
   if (!myTextureEnv.IsNull())
   {
     theCtx->DelayedRelease (myTextureEnv);
     myTextureEnv.Nullify();
   }
-  if (myBgTexture.TexId != 0)
+
+  if (myTextureParams != NULL)
+  {
+    myTextureParams->Release (theCtx.operator->());
+  }
+  if (myBgGradientArray != NULL)
   {
-    glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
-    myBgTexture.TexId = 0;
+    myBgGradientArray->Release (theCtx.operator->());
   }
+  if (myBgTextureArray != NULL)
+  {
+    myBgTextureArray->Release (theCtx.operator->());
+  }
+
+  releaseRaytraceResources (theCtx);
 }
 
 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)&       theCtx,
@@ -139,14 +142,14 @@ void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)&       theCtx,
   if (!anImage.IsNull())
     myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
 
-  myModificationState++;
+  myToUpdateEnvironmentMap = Standard_True;
 }
 
 void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
 {
   mySurfaceDetail = theMode;
 
-  myModificationState++;
+  myToUpdateEnvironmentMap = Standard_True;
 }
 
 // =======================================================================
@@ -178,17 +181,7 @@ void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT& theViewCtx)
 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
 {
   myVisualization = AContext.Visualization;
-  // Shading method
-  switch (AContext.Model)
-  {
-    case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
-    case 3 : /* VISUAL3D_TOM_VERTEX */
-      myIntShadingMethod = TEL_SM_GOURAUD;
-      break;
-    default :
-      myIntShadingMethod = TEL_SM_FLAT;
-      break;
-  }
+  myShadingModel  = (Visual3d_TypeOfModel )AContext.Model;
 }
 
 /*----------------------------------------------------------------------*/
@@ -228,37 +221,41 @@ void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)&       theCtx,
-                                   const Aspect_TypeOfTriedronPosition thePosition,
+void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
                                    const Quantity_NameOfColor          theColor,
                                    const Standard_Real                 theScale,
                                    const Standard_Boolean              theAsWireframe)
 {
-  OpenGl_Element::Destroy (theCtx, myTrihedron);
-  myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
+  myToShowTrihedron = true;
+  myTrihedron.SetWireframe   (theAsWireframe);
+  myTrihedron.SetPosition    (thePosition);
+  myTrihedron.SetScale       (theScale);
+  myTrihedron.SetLabelsColor (theColor);
 }
 
 /*----------------------------------------------------------------------*/
 
 void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
 {
-  OpenGl_Element::Destroy (theCtx, myTrihedron);
+  myToShowTrihedron = false;
+  myTrihedron.Release (theCtx.operator->());
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)&        theCtx,
-                                             const Graphic3d_CGraduatedTrihedron& theData)
+void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)&       theCtx,
+                                             const Graphic3d_GraduatedTrihedron& theData)
 {
-  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
-  myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
+  myToShowGradTrihedron = true;
+  myGraduatedTrihedron.SetValues (theCtx, theData);
 }
 
 /*----------------------------------------------------------------------*/
 
 void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
 {
-  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
+  myToShowGradTrihedron = false;
+  myGraduatedTrihedron.Release (theCtx.operator->());
 }
 
 /*----------------------------------------------------------------------*/
@@ -268,25 +265,12 @@ void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
 {
   if (myIsTransPers)
   {
-    // restore matrix
-    glMatrixMode (GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode (GL_MODELVIEW);
-    glPopMatrix();
-    myIsTransPers = Standard_False;
+    theCtx->WorldViewState.Pop();
+    theCtx->ProjectionState.Pop();
 
-    // Note: the approach of accessing OpenGl matrices is used now since the matrix
-    // manipulation are made with help of OpenGl methods. This might be replaced by
-    // direct computation of matrices by OCC subroutines.
-    Tmatrix3 aResultWorldView;
-    glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
+    theCtx->ApplyProjectionMatrix();
 
-    Tmatrix3 aResultProjection;
-    glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
-
-    // Set OCCT state uniform variables
-    theCtx->ShaderManager()->RevertWorldViewStateTo (&aResultWorldView);
-    theCtx->ShaderManager()->RevertProjectionStateTo (&aResultProjection);
+    myIsTransPers = Standard_False;
   }
 }
 
@@ -305,21 +289,18 @@ const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const H
   }
 
   GLint aViewport[4];
-  GLdouble aModelMatrix[4][4];
-  GLdouble aProjMatrix[4][4];
-  glGetIntegerv (GL_VIEWPORT,          aViewport);
-  glGetDoublev  (GL_MODELVIEW_MATRIX,  (GLdouble* )aModelMatrix);
-  glGetDoublev  (GL_PROJECTION_MATRIX, (GLdouble *)aProjMatrix);
+  OpenGl_Mat4d aModelMatrix, aProjMatrix;
+  theCtx->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport);
+  aModelMatrix.Convert (theCtx->ModelWorldState.Current() * theCtx->WorldViewState.Current());
+  aProjMatrix .Convert (theCtx->ProjectionState.Current());
+
   const GLdouble aViewportW = (GLdouble )aViewport[2];
   const GLdouble aViewportH = (GLdouble )aViewport[3];
-
   if (myIsTransPers)
   {
     // pop matrix stack - it will be overridden later
-    glMatrixMode (GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode (GL_MODELVIEW);
-    glPopMatrix();
+    theCtx->WorldViewState.Pop();
+    theCtx->ProjectionState.Pop();
   }
   else
   {
@@ -327,21 +308,22 @@ const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const H
   }
 
   // push matrices into stack and reset them
-  glMatrixMode (GL_MODELVIEW);
-  glPushMatrix();
-  glLoadIdentity();
-
-  glMatrixMode (GL_PROJECTION);
-  glPushMatrix();
-  glLoadIdentity();
+  theCtx->WorldViewState.Push();
+  theCtx->ProjectionState.Push();
 
   // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
   GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
   if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
   {
-    gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
-                (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
-                &aWinX, &aWinY, &aWinZ);
+    OpenGl_Utils::Project<Standard_Real> (theTransPers->pointX,
+                                          theTransPers->pointY,
+                                          theTransPers->pointZ,
+                                          aModelMatrix,
+                                          aProjMatrix,
+                                          aViewport,
+                                          aWinX,
+                                          aWinY,
+                                          aWinZ);
   }
 
   // prevent zooming
@@ -350,22 +332,22 @@ const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const H
   {
     // compute fixed-zoom multiplier
     // actually function works ugly with TelPerspective!
-    const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix[1][1] : aProjMatrix[0][0]);
-    aProjMatrix[0][0] *= aDet2;
-    aProjMatrix[1][1] *= aDet2;
-    aProjMatrix[2][2] *= aDet2;
+    const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix.GetValue (1, 1) : aProjMatrix.GetValue (0, 0));
+    aProjMatrix.ChangeValue (0, 0) *= aDet2;
+    aProjMatrix.ChangeValue (1, 1) *= aDet2;
+    aProjMatrix.ChangeValue (2, 2) *= aDet2;
   }
 
   // prevent translation - annulate translate matrix
   if ((theTransPers->mode & TPF_PAN)
    || (theTransPers->mode == TPF_TRIEDRON))
   {
-    aModelMatrix[3][0] = 0.0;
-    aModelMatrix[3][1] = 0.0;
-    aModelMatrix[3][2] = 0.0;
-    aProjMatrix [3][0] = 0.0;
-    aProjMatrix [3][1] = 0.0;
-    aProjMatrix [3][2] = 0.0;
+    aModelMatrix.SetValue (0, 3, 0.0);
+    aModelMatrix.SetValue (1, 3, 0.0);
+    aModelMatrix.SetValue (2, 3, 0.0);
+    aProjMatrix .SetValue (0, 3, 0.0);
+    aProjMatrix .SetValue (1, 3, 0.0);
+    aProjMatrix .SetValue (2, 3, 0.0);
   }
 
   // prevent scaling-on-axis
@@ -377,33 +359,31 @@ const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const H
     const double aScaleZ = anAxialScale.Z();
     for (int i = 0; i < 3; ++i)
     {
-      aModelMatrix[0][i] /= aScaleX;
-      aModelMatrix[1][i] /= aScaleY;
-      aModelMatrix[2][i] /= aScaleZ;
+      aModelMatrix.ChangeValue (0, i) /= aScaleX;
+      aModelMatrix.ChangeValue (1, i) /= aScaleY;
+      aModelMatrix.ChangeValue (2, i) /= aScaleZ;
     }
   }
 
   // prevent rotating - annulate rotate matrix
   if (theTransPers->mode & TPF_ROTATE)
   {
-    aModelMatrix[0][0] = 1.0;
-    aModelMatrix[1][1] = 1.0;
-    aModelMatrix[2][2] = 1.0;
-
-    aModelMatrix[1][0] = 0.0;
-    aModelMatrix[2][0] = 0.0;
-    aModelMatrix[0][1] = 0.0;
-    aModelMatrix[2][1] = 0.0;
-    aModelMatrix[0][2] = 0.0;
-    aModelMatrix[1][2] = 0.0;
+    aModelMatrix.SetValue (0, 0, 1.0);
+    aModelMatrix.SetValue (1, 1, 1.0);
+    aModelMatrix.SetValue (2, 2, 1.0);
+
+    aModelMatrix.SetValue (1, 0, 0.0);
+    aModelMatrix.SetValue (2, 0, 0.0);
+    aModelMatrix.SetValue (0, 1, 0.0);
+    aModelMatrix.SetValue (2, 1, 0.0);
+    aModelMatrix.SetValue (0, 2, 0.0);
+    aModelMatrix.SetValue (1, 2, 0.0);
   }
 
   // load computed matrices
-  glMatrixMode (GL_MODELVIEW);
-  glMultMatrixd ((GLdouble* )aModelMatrix);
-
-  glMatrixMode (GL_PROJECTION);
-  glMultMatrixd ((GLdouble* )aProjMatrix);
+  theCtx->ModelWorldState.SetIdentity();
+  theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
+  theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
 
   if (theTransPers->mode == TPF_TRIEDRON)
   {
@@ -412,65 +392,67 @@ const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const H
      && theTransPers->pointY != 0.0)
     {
       GLdouble aW1, aH1, aW2, aH2, aDummy;
-      glMatrixMode (GL_PROJECTION);
-      gluUnProject ( 0.5 * aViewportW,  0.5 * aViewportH, 0.0,
-                    (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
-                    &aW1, &aH1, &aDummy);
-      gluUnProject (-0.5 * aViewportW, -0.5 * aViewportH, 0.0,
-                    (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
-                    &aW2, &aH2, &aDummy);
+
+      OpenGl_Mat4d anIdentity;
+
+      OpenGl_Utils::UnProject<Standard_Real> (0.5 * aViewportW,
+                                              0.5 * aViewportH,
+                                              0.0,
+                                              anIdentity,
+                                              aProjMatrix,
+                                              aViewport,
+                                              aW1,
+                                              aH1,
+                                              aDummy);
+
+      OpenGl_Utils::UnProject<Standard_Real> (-0.5 * aViewportW,
+                                              -0.5 * aViewportH,
+                                              0.0,
+                                              anIdentity,
+                                              aProjMatrix,
+                                              aViewport,
+                                              aW2,
+                                              aH2,
+                                              aDummy);
+
       GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
       GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
       aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
       aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
-      glTranslated (aMoveX, aMoveY, 0.0);
+
+      OpenGl_Utils::Translate<Standard_Real> (aProjMatrix, aMoveX, aMoveY, 0.0);
+      theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjMatrix);
     }
   }
   else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
   {
     // move to thePoint using saved win-coordinates ('marker-behaviour')
     GLdouble aMoveX, aMoveY, aMoveZ;
-    glGetDoublev (GL_MODELVIEW_MATRIX,  (GLdouble* )aModelMatrix);
-    glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble* )aProjMatrix);
-    gluUnProject (aWinX, aWinY, aWinZ,
-                  (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
-                  &aMoveX, &aMoveY, &aMoveZ);
-
-    glMatrixMode (GL_MODELVIEW);
-    glTranslated (aMoveX, aMoveY, aMoveZ);
-  }
 
-  // Note: the approach of accessing OpenGl matrices is used now since the matrix
-  // manipulation are made with help of OpenGl methods. This might be replaced by
-  // direct computation of matrices by OCC subroutines.
-  Tmatrix3 aResultWorldView;
-  glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
-
-  Tmatrix3 aResultProjection;
-  glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
-
-  // Set OCCT state uniform variables
-  theCtx->ShaderManager()->UpdateWorldViewStateTo (&aResultWorldView);
-  theCtx->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
+    OpenGl_Utils::UnProject<Standard_Real> (aWinX,
+                                            aWinY,
+                                            aWinZ,
+                                            aModelMatrix,
+                                            aProjMatrix,
+                                            aViewport,
+                                            aMoveX,
+                                            aMoveY,
+                                            aMoveZ);
+
+    OpenGl_Utils::Translate<Standard_Real> (aModelMatrix, aMoveX, aMoveY, aMoveZ);
+    theCtx->WorldViewState.SetCurrent<Standard_Real> (aModelMatrix);
+  }
 
+  theCtx->ApplyProjectionMatrix();
   return aTransPersPrev;
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::GetMatrices (TColStd_Array2OfReal&  theMatOrient,
-                               TColStd_Array2OfReal&  theMatMapping) const
+void OpenGl_View::GetMatrices (OpenGl_Mat4& theOrientation,
+                               OpenGl_Mat4& theViewMapping) const
 {
-  const Graphic3d_Mat4d& aProj   = myCamera->ProjectionMatrix();
-  const Graphic3d_Mat4d& aOrient = myCamera->OrientationMatrix();
-
-  for (Standard_Integer aRow = 0; aRow < 4; ++aRow)
-  {
-    for (Standard_Integer aCol = 0; aCol < 4; ++aCol)
-    {
-      theMatOrient  (aRow, aCol) = aOrient.GetValue (aRow, aCol);
-      theMatMapping (aRow, aCol) = aProj  .GetValue (aRow, aCol);
-    }
-  }
+  theViewMapping = myCamera->ProjectionMatrixF();
+  theOrientation = myCamera->OrientationMatrixF();
 }
 /*----------------------------------------------------------------------*/