0024437: Visualization - silhouette edges based on OpenGL
[occt.git] / src / OpenGl / OpenGl_BackgroundArray.cxx
index ae59c9f..110512a 100644 (file)
@@ -18,6 +18,7 @@
 #include <Aspect_FillMethod.hxx>
 #include <NCollection_AlignedAllocator.hxx>
 #include <OpenGl_Texture.hxx>
+#include <OpenGl_View.hxx>
 #include <Graphic3d_TextureParams.hxx>
 
 // =======================================================================
 // =======================================================================
 OpenGl_BackgroundArray::OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground theType)
 : OpenGl_PrimitiveArray (NULL, Graphic3d_TOPA_TRIANGLESTRIPS, NULL, NULL, NULL),
-  myToUpdate (Standard_False),
+  myTrsfPers (Graphic3d_TMF_2d, theType == Graphic3d_TOB_TEXTURE ? Aspect_TOTP_CENTER : Aspect_TOTP_LEFT_LOWER),
   myType (theType),
+  myFillMethod (Aspect_FM_NONE),
   myViewWidth (0),
   myViewHeight (0),
-  myFillMethod (Aspect_FM_NONE)
+  myToUpdate (Standard_False)
 {
   Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
   myAttribs = new Graphic3d_Buffer (anAlloc);
 
   myDrawMode = GL_TRIANGLE_STRIP;
+  myIsFillType = true;
 
   myGradientParams.color1 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
   myGradientParams.color2 = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
@@ -131,10 +134,10 @@ void OpenGl_BackgroundArray::invalidateData()
 }
 
 // =======================================================================
-// method  : Init
+// method  : init
 // purpose :
 // =======================================================================
-Standard_Boolean OpenGl_BackgroundArray::Init (const Handle(OpenGl_Workspace)& theWorkspace)
+Standard_Boolean OpenGl_BackgroundArray::init (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
   switch (myType)
   {
@@ -148,8 +151,6 @@ Standard_Boolean OpenGl_BackgroundArray::Init (const Handle(OpenGl_Workspace)& t
     }
     case Graphic3d_TOB_TEXTURE:
     {
-      myViewWidth  = theWorkspace->Width();
-      myViewHeight = theWorkspace->Height();
       if (!createTextureArray (theWorkspace))
       {
         return Standard_False;
@@ -181,7 +182,7 @@ Standard_Boolean OpenGl_BackgroundArray::Init (const Handle(OpenGl_Workspace)& t
 // method  : createGradientArray
 // purpose :
 // =======================================================================
-Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
+Standard_Boolean OpenGl_BackgroundArray::createGradientArray() const
 {
   // Initialize data for primitive array
   Graphic3d_Attribute aGragientAttribInfo[] =
@@ -197,38 +198,38 @@ Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
 
   OpenGl_Vec2 aVertices[4] =
   {
-    OpenGl_Vec2( 1.0f, -1.0f),
-    OpenGl_Vec2( 1.0f,  1.0f),
-    OpenGl_Vec2(-1.0f, -1.0f),
-    OpenGl_Vec2(-1.0f,  1.0f)
+    OpenGl_Vec2(float(myViewWidth), 0.0f),
+    OpenGl_Vec2(float(myViewWidth), float(myViewHeight)),
+    OpenGl_Vec2(0.0f,               0.0f),
+    OpenGl_Vec2(0.0f,               float(myViewHeight))
   };
 
-  Tfloat* aCorners[4]     = {};
-  Tfloat  aDiagCorner1[3] = {};
-  Tfloat  aDiagCorner2[3] = {};
+  float* aCorners[4]     = {};
+  float  aDiagCorner1[3] = {};
+  float  aDiagCorner2[3] = {};
 
   switch (myGradientParams.type)
   {
     case Aspect_GFM_HOR:
     {
-      aCorners[0] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[1] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[2] = myGradientParams.color1.xyz().ChangeData();
-      aCorners[3] = myGradientParams.color1.xyz().ChangeData();
+      aCorners[0] = myGradientParams.color2.ChangeData();
+      aCorners[1] = myGradientParams.color2.ChangeData();
+      aCorners[2] = myGradientParams.color1.ChangeData();
+      aCorners[3] = myGradientParams.color1.ChangeData();
       break;
     }
     case Aspect_GFM_VER:
     {
-      aCorners[0] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[1] = myGradientParams.color1.xyz().ChangeData();
-      aCorners[2] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[3] = myGradientParams.color1.xyz().ChangeData();
+      aCorners[0] = myGradientParams.color2.ChangeData();
+      aCorners[1] = myGradientParams.color1.ChangeData();
+      aCorners[2] = myGradientParams.color2.ChangeData();
+      aCorners[3] = myGradientParams.color1.ChangeData();
       break;
     }
     case Aspect_GFM_DIAG1:
     {
-      aCorners[0] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[3] = myGradientParams.color1.xyz().ChangeData();
+      aCorners[0] = myGradientParams.color2.ChangeData();
+      aCorners[3] = myGradientParams.color1.ChangeData();
       aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[0][0] + aCorners[3][0]);
       aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[0][1] + aCorners[3][1]);
       aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[0][2] + aCorners[3][2]);
@@ -238,8 +239,8 @@ Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
     }
     case Aspect_GFM_DIAG2:
     {
-      aCorners[1] = myGradientParams.color1.xyz().ChangeData();
-      aCorners[2] = myGradientParams.color2.xyz().ChangeData();
+      aCorners[1] = myGradientParams.color1.ChangeData();
+      aCorners[2] = myGradientParams.color2.ChangeData();
       aDiagCorner1[0] = aDiagCorner2[0] = 0.5f * (aCorners[1][0] + aCorners[2][0]);
       aDiagCorner1[1] = aDiagCorner2[1] = 0.5f * (aCorners[1][1] + aCorners[2][1]);
       aDiagCorner1[2] = aDiagCorner2[2] = 0.5f * (aCorners[1][2] + aCorners[2][2]);
@@ -249,44 +250,44 @@ Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
     }
     case Aspect_GFM_CORNER1:
     {
-      aVertices[0] = OpenGl_Vec2( 1.0f,  1.0f);
-      aVertices[1] = OpenGl_Vec2(-1.0f,  1.0f);
-      aVertices[2] = OpenGl_Vec2( 1.0f, -1.0f);
-      aVertices[3] = OpenGl_Vec2(-1.0f, -1.0f);
-
-      aCorners[0] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[1] = myGradientParams.color1.xyz().ChangeData();
-      aCorners[2] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[3] = myGradientParams.color2.xyz().ChangeData();
+      aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight));
+      aVertices[1] = OpenGl_Vec2(0.0f,               float(myViewHeight));
+      aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f);
+      aVertices[3] = OpenGl_Vec2(0.0f,               0.0f);
+
+      aCorners[0] = myGradientParams.color2.ChangeData();
+      aCorners[1] = myGradientParams.color1.ChangeData();
+      aCorners[2] = myGradientParams.color2.ChangeData();
+      aCorners[3] = myGradientParams.color2.ChangeData();
       break;
     }
     case Aspect_GFM_CORNER2:
     {
-      aCorners[0] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[1] = myGradientParams.color1.xyz().ChangeData();
-      aCorners[2] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[3] = myGradientParams.color2.xyz().ChangeData();
+      aCorners[0] = myGradientParams.color2.ChangeData();
+      aCorners[1] = myGradientParams.color1.ChangeData();
+      aCorners[2] = myGradientParams.color2.ChangeData();
+      aCorners[3] = myGradientParams.color2.ChangeData();
       break;
     }
     case Aspect_GFM_CORNER3:
     {
-      aVertices[0] = OpenGl_Vec2( 1.0f,  1.0f);
-      aVertices[1] = OpenGl_Vec2(-1.0f,  1.0f);
-      aVertices[2] = OpenGl_Vec2( 1.0f, -1.0f);
-      aVertices[3] = OpenGl_Vec2(-1.0f, -1.0f);
-
-      aCorners[0] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[1] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[2] = myGradientParams.color1.xyz().ChangeData();
-      aCorners[3] = myGradientParams.color2.xyz().ChangeData();
+      aVertices[0] = OpenGl_Vec2(float(myViewWidth), float(myViewHeight));
+      aVertices[1] = OpenGl_Vec2(0.0f,               float(myViewHeight));
+      aVertices[2] = OpenGl_Vec2(float(myViewWidth), 0.0f);
+      aVertices[3] = OpenGl_Vec2(0.0f,               0.0f);
+
+      aCorners[0] = myGradientParams.color2.ChangeData();
+      aCorners[1] = myGradientParams.color2.ChangeData();
+      aCorners[2] = myGradientParams.color1.ChangeData();
+      aCorners[3] = myGradientParams.color2.ChangeData();
       break;
     }
     case Aspect_GFM_CORNER4:
     {
-      aCorners[0] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[1] = myGradientParams.color2.xyz().ChangeData();
-      aCorners[2] = myGradientParams.color1.xyz().ChangeData();
-      aCorners[3] = myGradientParams.color2.xyz().ChangeData();
+      aCorners[0] = myGradientParams.color2.ChangeData();
+      aCorners[1] = myGradientParams.color2.ChangeData();
+      aCorners[2] = myGradientParams.color1.ChangeData();
+      aCorners[3] = myGradientParams.color2.ChangeData();
       break;
     }
     case Aspect_GFM_NONE:
@@ -311,7 +312,7 @@ Standard_Boolean OpenGl_BackgroundArray::createGradientArray()
 // method  : createTextureArray
 // purpose :
 // =======================================================================
-Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace)
+Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
   Graphic3d_Attribute aTextureAttribInfo[] =
   {
@@ -328,8 +329,8 @@ Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl
   GLfloat aTexRangeY = 1.0f; // texture <t> coordinate
 
   // Set up for stretching or tiling
-  GLfloat anOffsetX = 1.0f;
-  GLfloat anOffsetY = 1.0f;
+  GLfloat anOffsetX = 0.5f * (float )myViewWidth;
+  GLfloat anOffsetY = 0.5f * (float )myViewHeight;
 
   // Setting this coefficient to -1.0f allows to tile textures relatively to the top-left corner of the view
   // (value 1.0f corresponds to the initial behavior - tiling from the bottom-left corner)
@@ -338,13 +339,13 @@ Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl
   // Get texture parameters
   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
   const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace();
-  GLfloat aTextureWidth  = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeX();
-  GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeY();
+  GLfloat aTextureWidth  = (GLfloat )anAspectFace->TextureSet (aCtx)->First()->SizeX();
+  GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureSet (aCtx)->First()->SizeY();
 
   if (myFillMethod == Aspect_FM_CENTERED)
   {
-    anOffsetX = aTextureWidth  / (GLfloat )myViewWidth;
-    anOffsetY = aTextureHeight / (GLfloat )myViewHeight;
+    anOffsetX = 0.5f * aTextureWidth;
+    anOffsetY = 0.5f * aTextureHeight;
   }
   else if (myFillMethod == Aspect_FM_TILED)
   {
@@ -375,3 +376,45 @@ Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl
 
   return Standard_True;
 }
+
+// =======================================================================
+// method  : createTextureArray
+// purpose :
+// =======================================================================
+void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+  const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+  Standard_Integer aViewSizeX = aCtx->Viewport()[2];
+  Standard_Integer aViewSizeY = aCtx->Viewport()[3];
+  if (theWorkspace->View()->Camera()->Tile().IsValid())
+  {
+    aViewSizeX = theWorkspace->View()->Camera()->Tile().TotalSize.x();
+    aViewSizeY = theWorkspace->View()->Camera()->Tile().TotalSize.y();
+  }
+  if (myToUpdate
+   || myViewWidth  != aViewSizeX
+   || myViewHeight != aViewSizeY)
+  {
+    myViewWidth  = aViewSizeX;
+    myViewHeight = aViewSizeY;
+    init (theWorkspace);
+  }
+
+  OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
+  OpenGl_Mat4 aWorldView  = aCtx->WorldViewState.Current();
+  myTrsfPers.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView,
+                    aCtx->Viewport()[2], aCtx->Viewport()[3]);
+
+  aCtx->ProjectionState.Push();
+  aCtx->WorldViewState.Push();
+  aCtx->ProjectionState.SetCurrent (aProjection);
+  aCtx->WorldViewState.SetCurrent (aWorldView);
+  aCtx->ApplyProjectionMatrix();
+  aCtx->ApplyModelViewMatrix();
+
+  OpenGl_PrimitiveArray::Render (theWorkspace);
+
+  aCtx->ProjectionState.Pop();
+  aCtx->WorldViewState.Pop();
+  aCtx->ApplyProjectionMatrix();
+}