0029477: Visualization, TKOpenGl - MSAA FBO initialization failure on OpenGL ES 3...
[occt.git] / src / OpenGl / OpenGl_View.cxx
index a616d30..8f68818 100644 (file)
 #include <OpenGl_Texture.hxx>
 #include <OpenGl_Window.hxx>
 #include <OpenGl_Workspace.hxx>
+#include <OSD_Parallel.hxx>
 #include <Standard_CLocaleSentry.hxx>
 
+#include "../Graphic3d/Graphic3d_Structure.pxx"
+
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView)
 
 #ifdef HAVE_GL2PS
@@ -46,12 +49,10 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,Graphic3d_CView)
 OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
                           const Handle(OpenGl_GraphicDriver)& theDriver,
                           const Handle(OpenGl_Caps)& theCaps,
-                          Standard_Boolean& theDeviceLostFlag,
                           OpenGl_StateCounter* theCounter)
 : Graphic3d_CView  (theMgr),
   myDriver         (theDriver.operator->()),
   myCaps           (theCaps),
-  myDeviceLostFlag (theDeviceLostFlag),
   myWasRedrawnGL   (Standard_False),
   myCulling        (Standard_True),
   myShadingModel   (Graphic3d_TOSM_FACET),
@@ -59,13 +60,18 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myBgColor        (Quantity_NOC_BLACK),
   myCamera         (new Graphic3d_Camera()),
   myToShowGradTrihedron  (false),
+  myZLayers        (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1),
   myStateCounter         (theCounter),
+  myCurrLightSourceState (theCounter->Increment()),
+  myLightsRevision       (0),
   myLastLightSourceState (0, 0),
   myFboColorFormat       (GL_RGBA8),
   myFboDepthFormat       (GL_DEPTH24_STENCIL8),
   myToFlipOutput         (Standard_False),
   myFrameCounter         (0),
   myHasFboBlit           (Standard_True),
+  myToDisableOIT         (Standard_False),
+  myToDisableOITMSAA     (Standard_False),
   myToDisableMSAA        (Standard_False),
   myTransientDrawToFront (Standard_True),
   myBackBufferRestored   (Standard_False),
@@ -77,30 +83,39 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myRaytraceInitStatus     (OpenGl_RT_NONE),
   myIsRaytraceDataValid    (Standard_False),
   myIsRaytraceWarnTextures (Standard_False),
+  myRaytraceBVHBuilder (new BVH_BinnedBuilder<Standard_ShortReal, 3, BVH_Constants_NbBinsBest> (BVH_Constants_LeafNodeSizeAverage,
+                                                                                                BVH_Constants_MaxTreeDepth,
+                                                                                                Standard_False,
+                                                                                                OSD_Parallel::NbLogicalProcessors() + 1)),
+  myRaytraceSceneRadius  (0.0f),
+  myRaytraceSceneEpsilon (1.0e-6f),
   myToUpdateEnvironmentMap (Standard_False),
-  myRaytraceLayerListState (0)
+  myRaytraceLayerListState (0),
+  myPrevCameraApertureRadius(0.f),
+  myPrevCameraFocalPlaneDist(0.f)
 {
   myWorkspace = new OpenGl_Workspace (this, NULL);
 
-  OpenGl_Light       aLight;
-  aLight.Type        = Graphic3d_TOLS_AMBIENT;
-  aLight.IsHeadlight = Standard_False;
-  aLight.Color.r()   = 1.;
-  aLight.Color.g()   = 1.;
-  aLight.Color.b()   = 1.;
-  myNoShadingLight.Append (aLight);
-
-  myCurrLightSourceState  = myStateCounter->Increment();
-  myMainSceneFbos[0]      = new OpenGl_FrameBuffer();
-  myMainSceneFbos[1]      = new OpenGl_FrameBuffer();
-  myImmediateSceneFbos[0] = new OpenGl_FrameBuffer();
-  myImmediateSceneFbos[1] = new OpenGl_FrameBuffer();
-  myOpenGlFBO             = new OpenGl_FrameBuffer();
-  myOpenGlFBO2            = new OpenGl_FrameBuffer();
-  myRaytraceFBO1[0]       = new OpenGl_FrameBuffer();
-  myRaytraceFBO1[1]       = new OpenGl_FrameBuffer();
-  myRaytraceFBO2[0]       = new OpenGl_FrameBuffer();
-  myRaytraceFBO2[1]       = new OpenGl_FrameBuffer();
+  Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
+  aLight->SetHeadlight (false);
+  aLight->SetColor (Quantity_NOC_WHITE);
+  myNoShadingLight = new Graphic3d_LightSet();
+  myNoShadingLight->Add (aLight);
+
+  myMainSceneFbos[0]         = new OpenGl_FrameBuffer();
+  myMainSceneFbos[1]         = new OpenGl_FrameBuffer();
+  myMainSceneFbosOit[0]      = new OpenGl_FrameBuffer();
+  myMainSceneFbosOit[1]      = new OpenGl_FrameBuffer();
+  myImmediateSceneFbos[0]    = new OpenGl_FrameBuffer();
+  myImmediateSceneFbos[1]    = new OpenGl_FrameBuffer();
+  myImmediateSceneFbosOit[0] = new OpenGl_FrameBuffer();
+  myImmediateSceneFbosOit[1] = new OpenGl_FrameBuffer();
+  myOpenGlFBO                = new OpenGl_FrameBuffer();
+  myOpenGlFBO2               = new OpenGl_FrameBuffer();
+  myRaytraceFBO1[0]          = new OpenGl_FrameBuffer();
+  myRaytraceFBO1[1]          = new OpenGl_FrameBuffer();
+  myRaytraceFBO2[0]          = new OpenGl_FrameBuffer();
+  myRaytraceFBO2[1]          = new OpenGl_FrameBuffer();
 }
 
 // =======================================================================
@@ -122,10 +137,15 @@ OpenGl_View::~OpenGl_View()
 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
 {
   myGraduatedTrihedron.Release (theCtx.operator->());
+  myFrameStatsPrs.Release (theCtx.operator->());
 
   if (!myTextureEnv.IsNull())
   {
-    theCtx->DelayedRelease (myTextureEnv);
+    for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
+    {
+      theCtx->DelayedRelease (aTextureIter.ChangeValue());
+      aTextureIter.ChangeValue().Nullify();
+    }
     myTextureEnv.Nullify();
   }
 
@@ -142,14 +162,18 @@ void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
     myBgTextureArray->Release (theCtx.operator->());
   }
 
-  myMainSceneFbos[0]     ->Release (theCtx.operator->());
-  myMainSceneFbos[1]     ->Release (theCtx.operator->());
-  myImmediateSceneFbos[0]->Release (theCtx.operator->());
-  myImmediateSceneFbos[1]->Release (theCtx.operator->());
-  myOpenGlFBO            ->Release (theCtx.operator->());
-  myOpenGlFBO2           ->Release (theCtx.operator->());
-  myFullScreenQuad        .Release (theCtx.operator->());
-  myFullScreenQuadFlip    .Release (theCtx.operator->());
+  myMainSceneFbos[0]        ->Release (theCtx.operator->());
+  myMainSceneFbos[1]        ->Release (theCtx.operator->());
+  myMainSceneFbosOit[0]     ->Release (theCtx.operator->());
+  myMainSceneFbosOit[1]     ->Release (theCtx.operator->());
+  myImmediateSceneFbos[0]   ->Release (theCtx.operator->());
+  myImmediateSceneFbos[1]   ->Release (theCtx.operator->());
+  myImmediateSceneFbosOit[0]->Release (theCtx.operator->());
+  myImmediateSceneFbosOit[1]->Release (theCtx.operator->());
+  myOpenGlFBO               ->Release (theCtx.operator->());
+  myOpenGlFBO2              ->Release (theCtx.operator->());
+  myFullScreenQuad           .Release (theCtx.operator->());
+  myFullScreenQuadFlip       .Release (theCtx.operator->());
 
   releaseRaytraceResources (theCtx);
 }
@@ -171,6 +195,29 @@ void OpenGl_View::Remove()
   Graphic3d_CView::Remove();
 }
 
+// =======================================================================
+// function : SetTextureEnv
+// purpose  :
+// =======================================================================
+void OpenGl_View::SetCamera(const Handle(Graphic3d_Camera)& theCamera)
+{
+  myCamera = theCamera;
+}
+
+// =======================================================================
+// function : SetLocalOrigin
+// purpose  :
+// =======================================================================
+void OpenGl_View::SetLocalOrigin (const gp_XYZ& theOrigin)
+{
+  myLocalOrigin = theOrigin;
+  const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
+  if (!aCtx.IsNull())
+  {
+    aCtx->ShaderManager()->SetLocalOrigin (theOrigin);
+  }
+}
+
 // =======================================================================
 // function : SetTextureEnv
 // purpose  :
@@ -180,7 +227,11 @@ void OpenGl_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTextureE
   Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
   if (!aCtx.IsNull() && !myTextureEnv.IsNull())
   {
-    aCtx->DelayedRelease (myTextureEnv);
+    for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
+    {
+      aCtx->DelayedRelease (aTextureIter.ChangeValue());
+      aTextureIter.ChangeValue().Nullify();
+    }
   }
 
   myToUpdateEnvironmentMap = Standard_True;
@@ -202,11 +253,13 @@ void OpenGl_View::initTextureEnv (const Handle(OpenGl_Context)& theContext)
     return;
   }
 
-  myTextureEnv = new OpenGl_Texture (myTextureEnvData->GetParams());
+  myTextureEnv = new OpenGl_TextureSet (1);
+  Handle(OpenGl_Texture)& aTextureEnv = myTextureEnv->ChangeFirst();
+  aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams());
   Handle(Image_PixMap) anImage = myTextureEnvData->GetImage();
   if (!anImage.IsNull())
   {
-    myTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type());
+    aTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type());
   }
 }
 
@@ -316,7 +369,58 @@ void OpenGl_View::GraduatedTrihedronMinMaxValues (const Graphic3d_Vec3 theMin, c
 // =======================================================================
 Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3d_BufferType& theBufferType)
 {
-  return myWorkspace->BufferDump (myFBO, theImage, theBufferType);
+  if (theBufferType != Graphic3d_BT_RGB_RayTraceHdrLeft)
+  {
+    return myWorkspace->BufferDump(myFBO, theImage, theBufferType);
+  }
+
+  if (!myRaytraceParameters.AdaptiveScreenSampling)
+  {
+    return myWorkspace->BufferDump(myAccumFrames % 2 ? myRaytraceFBO2[0] : myRaytraceFBO1[0], theImage, theBufferType);
+  }
+
+#if defined(GL_ES_VERSION_2_0)
+  return false;
+#else
+  if (theImage.Format() != Image_Format_RGBF)
+  {
+    return false;
+  }
+
+  const GLuint aW = myRaytraceOutputTexture[0]->SizeX();
+  const GLuint aH = myRaytraceOutputTexture[0]->SizeY();
+  if (aW / 3 != theImage.SizeX() || aH / 2 != theImage.SizeY())
+  {
+    return false;
+  }
+
+  std::vector<GLfloat> aValues;
+  try
+  {
+    aValues.resize (aW * aH);
+  }
+  catch (const std::bad_alloc&)
+  {
+    return false;
+  }
+
+  glBindTexture (GL_TEXTURE_RECTANGLE, myRaytraceOutputTexture[0]->TextureId());
+  glGetTexImage (GL_TEXTURE_RECTANGLE, 0, OpenGl_TextureFormat::Create<GLfloat, 1>().Format(), GL_FLOAT, &aValues[0]);
+  glBindTexture (GL_TEXTURE_RECTANGLE, 0);
+  for (unsigned int aRow = 0; aRow < aH; aRow += 2)
+  {
+    for (unsigned int aCol = 0; aCol < aW; aCol += 3)
+    {
+      float* anImageValue = theImage.ChangeValue<float[3]> ((aH - aRow) / 2 - 1, aCol / 3);
+      float aInvNbSamples = 1.f / aValues[aRow * aW + aCol + aW];
+      anImageValue[0] = aValues[aRow * aW + aCol] * aInvNbSamples;
+      anImageValue[1] = aValues[aRow * aW + aCol + 1] * aInvNbSamples;
+      anImageValue[2] = aValues[aRow * aW + aCol + 1 + aW] * aInvNbSamples;
+    }
+  }
+
+  return true;
+#endif
 }
 
 // =======================================================================
@@ -470,7 +574,8 @@ void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayer
   }
   else
   {
-    for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < ZLayerMax(); ++aLayerId)
+    const Standard_Integer aLayerMax = ZLayerMax();
+    for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId < aLayerMax; ++aLayerId)
     {
       if (myZLayers.LayerIDs().IsBound (aLayerId))
       {
@@ -488,13 +593,13 @@ void OpenGl_View::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayer
 //function : ZLayerBoundingBox
 //purpose  :
 //=======================================================================
-Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
-                                                   const Handle(Graphic3d_Camera)& theCamera,
-                                                   const Standard_Integer          theWindowWidth,
-                                                   const Standard_Integer          theWindowHeight,
-                                                   const Standard_Boolean          theToIncludeAuxiliary) const
+Bnd_Box OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId        theLayerId,
+                                        const Handle(Graphic3d_Camera)& theCamera,
+                                        const Standard_Integer          theWindowWidth,
+                                        const Standard_Integer          theWindowHeight,
+                                        const Standard_Boolean          theToIncludeAuxiliary) const
 {
-  Graphic3d_BndBox4f aBox;
+  Bnd_Box aBox;
   if (myZLayers.LayerIDs().IsBound (theLayerId))
   {
     aBox = myZLayers.Layer (theLayerId).BoundingBox (Identification(),
@@ -515,10 +620,10 @@ Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId
     // We add here full-screen plane with 2D transformation persistence
     // for simplicity (myBgTextureArray might define a little bit different options
     // but it is updated within ::Render())
-    const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
-    const Graphic3d_Mat4& aWorldViewMat  = theCamera->OrientationMatrixF();
-    Graphic3d_BndBox4f aBox2d (Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
-                               Graphic3d_Vec4 (float(theWindowWidth), float(theWindowHeight), 0.0f, 0.0f));
+    const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
+    const Graphic3d_Mat4d& aWorldViewMat  = theCamera->OrientationMatrix();
+    Graphic3d_BndBox3d aBox2d (Graphic3d_Vec3d (0.0, 0.0, 0.0),
+                               Graphic3d_Vec3d (double(theWindowWidth), double(theWindowHeight), 0.0));
 
     Graphic3d_TransformPers aTrsfPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER);
     aTrsfPers.Apply (theCamera,
@@ -527,7 +632,8 @@ Graphic3d_BndBox4f OpenGl_View::ZLayerBoundingBox (const Graphic3d_ZLayerId
                      theWindowWidth,
                      theWindowHeight,
                      aBox2d);
-    aBox.Combine (aBox2d);
+    aBox.Add (gp_Pnt (aBox2d.CornerMin().x(), aBox2d.CornerMin().y(), aBox2d.CornerMin().z()));
+    aBox.Add (gp_Pnt (aBox2d.CornerMax().x(), aBox2d.CornerMax().y(), aBox2d.CornerMax().z()));
   }
 
   return aBox;
@@ -774,8 +880,8 @@ void OpenGl_View::changeZLayer (const Handle(Graphic3d_CStructure)& theStructure
   const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer();
   const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure.operator->());
   myZLayers.ChangeLayer (aStruct, anOldLayer, theNewLayerId);
-  Update (Aspect_TOU_WAIT, anOldLayer);
-  Update (Aspect_TOU_WAIT, theNewLayerId);
+  Update (anOldLayer);
+  Update (theNewLayerId);
 }
 
 //=======================================================================