0024819: TKOpenGl - extend the ray-tracing core by visualization of lines, text and...
authorosa <osa@opencascade.com>
Thu, 3 Jul 2014 11:49:48 +0000 (15:49 +0400)
committerapn <apn@opencascade.com>
Thu, 3 Jul 2014 11:50:27 +0000 (15:50 +0400)
OpenGl_GraphicDriver::Redraw() - do not recompute structures more than required
OpenGl_Workspace::Raytrace() - bind proper FBO before clearing it
Visual3d_View::Redraw() - perform automatic 2nd redraw on device lost

src/OpenGl/OpenGl_GraphicDriver_7.cxx
src/OpenGl/OpenGl_SceneGeometry.cxx
src/OpenGl/OpenGl_SceneGeometry.hxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_2.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/OpenGl/OpenGl_Workspace_Raytrace.cxx
src/Shaders/RaytraceBase.fs
src/Visual3d/Visual3d_View.cxx
tests/v3d/raytrace/bug24819 [new file with mode: 0644]

index 224813b..943e7ca 100644 (file)
@@ -103,7 +103,9 @@ void OpenGl_GraphicDriver::Redraw (const Graphic3d_CView& ACView,
                                    const Standard_Integer /*width*/, 
                                    const Standard_Integer /*height*/)
 {
-  if (!myCaps->vboDisable && ACView.RenderParams.Method == Graphic3d_RM_RAYTRACING)
+  if (ACView.RenderParams.Method == Graphic3d_RM_RAYTRACING
+  && !myCaps->vboDisable
+  && !myCaps->keepArrayData)
   {
     if (ACView.WasRedrawnGL)
     {
index 627b500..0dcbb8a 100755 (executable)
@@ -352,6 +352,17 @@ namespace OpenGl_Raytrace
         && anArray->DrawMode() >= GL_TRIANGLES;
   }
 
+  // =======================================================================
+  // function : IsRaytracedElement
+  // purpose  : Checks to see if the element contains ray-trace geometry
+  // =======================================================================
+  Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement)
+  {
+    const OpenGl_PrimitiveArray* anArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
+    return anArray != NULL
+        && anArray->DrawMode() >= GL_TRIANGLES;
+  }
+
   // =======================================================================
   // function : IsRaytracedGroup
   // purpose  : Checks to see if the group contains ray-trace geometry
index dea8471..58e2e02 100755 (executable)
@@ -20,6 +20,7 @@
 #include <BVH_Triangulation.hxx>
 #include <NCollection_StdAllocator.hxx>
 
+class  OpenGl_Element;
 struct OpenGl_ElementNode;
 class  OpenGl_Group;
 class  OpenGl_Structure;
@@ -33,6 +34,9 @@ namespace OpenGl_Raytrace
   //! Checks to see if the element contains ray-trace geometry.
   Standard_Boolean IsRaytracedElement (const OpenGl_ElementNode* theNode);
 
+  //! Checks to see if the element contains ray-trace geometry.
+  Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement);
+
   //! Checks to see if the structure contains ray-trace geometry.
   Standard_Boolean IsRaytracedStructure (const OpenGl_Structure* theStructure);
 }
index b3f2a12..527fa59 100644 (file)
@@ -221,6 +221,7 @@ protected:
   void RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
                       const Graphic3d_CView&               theCView,
                       const Aspect_CLayer2d&               theCLayer);
+  void RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace);
 
   //! Redraw contents of model scene: clipping planes,
   //! lights, structures. The peculiar properties of "scene" is that
@@ -296,6 +297,8 @@ public:
   DEFINE_STANDARD_ALLOC
   DEFINE_STANDARD_RTTI(OpenGl_View) // Type definition
 
+  friend class OpenGl_Workspace;
+
 };
 
 #endif // _OpenGl_View_Header
index 59c1dfd..3bd7bd5 100644 (file)
@@ -453,7 +453,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   // ====================================
 
   // Render background
-  DrawBackground (*theWorkspace);
+  if (theWorkspace->ToRedrawGL())
+  {
+    DrawBackground (*theWorkspace);
+  }
 
   // Switch off lighting by default
   glDisable(GL_LIGHTING);
@@ -600,26 +603,22 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     OpenGl_ShaderProgram::Unbind (aContext);
   }
 
-  // display global trihedron
-  if (myTrihedron != NULL)
-  {
-    myTrihedron->Render (theWorkspace);
-  }
-  if (myGraduatedTrihedron != NULL)
+  // Render trihedron
+  if (theWorkspace->ToRedrawGL())
   {
-    myGraduatedTrihedron->Render (theWorkspace);
-  }
+    RedrawTrihedron (theWorkspace);
 
-  // Restore face culling
-  if ( myBackfacing )
-  {
-    if ( isCullFace )
+    // Restore face culling
+    if ( myBackfacing )
     {
-      glEnable   ( GL_CULL_FACE );
-      glCullFace ( GL_BACK      );
+      if ( isCullFace )
+      {
+        glEnable   ( GL_CULL_FACE );
+        glCullFace ( GL_BACK      );
+      }
+      else
+        glDisable ( GL_CULL_FACE );
     }
-    else
-      glDisable ( GL_CULL_FACE );
   }
 
   // ===============================
@@ -846,6 +845,21 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
 
 /*----------------------------------------------------------------------*/
 
+void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
+{
+  // display global trihedron
+  if (myTrihedron != NULL)
+  {
+    myTrihedron->Render (theWorkspace);
+  }
+  if (myGraduatedTrihedron != NULL)
+  {
+    myGraduatedTrihedron->Render (theWorkspace);
+  }
+}
+
+/*----------------------------------------------------------------------*/
+
 //call_togl_create_bg_texture
 void OpenGl_View::CreateBackgroundTexture (const Standard_CString  theFilePath,
                                            const Aspect_FillMethod theFillStyle)
index 61e4d13..29a931b 100644 (file)
@@ -151,6 +151,8 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theD
   myViewModificationStatus (0),
   myLayersModificationStatus (0),
   //
+  myRaytraceFilter       (new OpenGl_RaytraceFilter()),
+  myToRedrawGL           (Standard_True),
   myAntiAliasingMode     (3),
   myTransientDrawToFront (Standard_True),
   myBackBufferRestored   (Standard_False),
@@ -160,6 +162,7 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theD
   myUseDepthTest (Standard_True),
   myUseGLLight (Standard_True),
   myIsCullingEnabled (Standard_False),
+  myFrameCounter (0),
   //
   AspectLine_set (&myDefaultAspectLine),
   AspectLine_applied (NULL),
@@ -561,6 +564,7 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
     return;
   }
 
+  ++myFrameCounter;
   myIsCullingEnabled = theCView.IsCullingEnabled;
 
   // release pending GL resources
@@ -577,12 +581,67 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
   {
     glGetIntegerv (GL_VIEWPORT, aViewPortBack);
     aFrameBuffer->SetupViewport (aGlCtx);
-    aFrameBuffer->BindBuffer    (aGlCtx);
     toSwap = 0; // no need to swap buffers
   }
 
-  if (theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myComputeInitStatus == OpenGl_RT_FAIL)
+  myToRedrawGL = Standard_True;
+  if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
+   && myComputeInitStatus != OpenGl_RT_FAIL)
   {
+    if (UpdateRaytraceGeometry (OpenGl_GUM_CHECK) && myIsRaytraceDataValid)
+    {
+      myToRedrawGL = Standard_False;
+
+      // Only non-raytracable structures should be rendered in OpenGL mode.
+      Handle(OpenGl_RenderFilter) aRenderFilter = GetRenderFilter();
+      myRaytraceFilter->SetPrevRenderFilter (aRenderFilter);
+      SetRenderFilter (myRaytraceFilter);
+
+      Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
+      Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
+
+      if (myOpenGlFBO.IsNull())
+      {
+        myOpenGlFBO = new OpenGl_FrameBuffer();
+      }
+      if (myOpenGlFBO->GetVPSizeX() != aSizeX
+       || myOpenGlFBO->GetVPSizeY() != aSizeY)
+      {
+        myOpenGlFBO->Init (aGlCtx, aSizeX, aSizeY);
+      }
+
+      // OverLayer and UnderLayer shouldn't be drawn by OpenGL.
+      // They will be drawn during ray-tracing.
+      Aspect_CLayer2d anEmptyCLayer;
+      anEmptyCLayer.ptrLayer = NULL;
+
+      myOpenGlFBO->BindBuffer (aGlCtx);
+      redraw1 (theCView, anEmptyCLayer, anEmptyCLayer, 0);
+      myOpenGlFBO->UnbindBuffer (aGlCtx);
+
+      const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
+      Raytrace (theCView, aSizeX, aSizeY, isImmediate ? 0 : toSwap,
+                theCOverLayer, theCUnderLayer, aFrameBuffer);
+
+      if (isImmediate)
+      {
+        RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True);
+      }
+
+      SetRenderFilter (aRenderFilter);
+
+      theCView.WasRedrawnGL = Standard_False;
+    }
+  }
+
+  if (myToRedrawGL)
+  {
+    // draw entire frame using normal OpenGL pipeline
+    if (aFrameBuffer != NULL)
+    {
+      aFrameBuffer->BindBuffer (aGlCtx);
+    }
+
     const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty();
     redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
     if (isImmediate)
@@ -592,15 +651,6 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
 
     theCView.WasRedrawnGL = Standard_True;
   }
-  else
-  {
-    int aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
-    int aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
-
-    Raytrace (theCView, aSizeX, aSizeY, toSwap, aFrameBuffer);
-
-    theCView.WasRedrawnGL = Standard_False;
-  }
 
   if (aFrameBuffer != NULL)
   {
@@ -670,15 +720,24 @@ void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
     glDisable (GL_DEPTH_TEST);
   }
 
-  if (NamedStatus & OPENGL_NS_WHITEBACK)
+  if (!ToRedrawGL())
   {
-    // set background to white
-    glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
-    toClear |= GL_DEPTH_BUFFER_BIT;
+    // set background to black
+    glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
+    toClear |= GL_DEPTH_BUFFER_BIT; //
   }
   else
   {
-    glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
+    if (NamedStatus & OPENGL_NS_WHITEBACK)
+    {
+        // set background to white
+      glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
+      toClear |= GL_DEPTH_BUFFER_BIT;
+    }
+    else
+    {
+      glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
+    }
   }
   glClear (toClear);
 
@@ -694,9 +753,9 @@ void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
   }
   else
   {
-    glFlush();
-    myBackBufferRestored = Standard_True;
-    myIsImmediateDrawn   = Standard_False;
+    glFlush(); //
+    myBackBufferRestored = Standard_True;//
+    myIsImmediateDrawn   = Standard_False;//
   }
 }
 
index 4267949..f9d848d 100755 (executable)
@@ -93,6 +93,37 @@ struct OpenGl_Material
 
 };
 
+DEFINE_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+
+//! Graphical raytracing filter.
+//! Filters out all raytracable structures.
+class OpenGl_RaytraceFilter : public OpenGl_RenderFilter
+{
+public:
+
+  //! Default constructor.
+  OpenGl_RaytraceFilter() {}
+
+  //! Remembers the previously set filter.
+  inline void SetPrevRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter)
+  {
+    myPrevRenderFilter = theFilter;
+  }
+
+  //! Checks whether the element can be rendered or not.
+  //! @param theElement [in] the element to check.
+  //! @return True if element can be rendered.
+  virtual Standard_Boolean CanRender (const OpenGl_Element* theElement);
+
+private:
+
+  Handle(OpenGl_RenderFilter) myPrevRenderFilter;
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_RaytraceFilter)
+};
+
 //! Represents window with GL context.
 //! Provides methods to render primitives and maintain GL state.
 class OpenGl_Workspace : public OpenGl_Window
@@ -228,6 +259,9 @@ public:
   //! @return true if clipping algorithm enabled
   inline Standard_Boolean IsCullingEnabled() const { return myIsCullingEnabled; }
 
+  //! Returns a flag whether to redraw the scene using OpenGL rasterization
+  Standard_Boolean ToRedrawGL() const { return myToRedrawGL; }
+
 protected:
 
   //! Copy content of Back buffer to the Front buffer
@@ -277,6 +311,7 @@ protected:
     OpenGl_RT_uDirectLB,
     OpenGl_RT_uDirectRT,
     OpenGl_RT_uDirectRB,
+    OpenGl_RT_uInvModelProj,
     
     OpenGl_RT_uSceneRad,
     OpenGl_RT_uSceneEps,
@@ -320,7 +355,10 @@ protected:
 
     OpenGl_RT_FSAAInputTexture = 12,
 
-    OpenGl_RT_SceneTransformTexture = 13
+    OpenGl_RT_SceneTransformTexture = 13,
+
+    OpenGl_RT_OpenGlColorTexture = 14,
+    OpenGl_RT_OpenGlDepthTexture = 15
   };
 
   //! Tool class for management of shader sources.
@@ -489,7 +527,8 @@ protected: //! @name methods related to ray-tracing
   void UpdateCamera (const NCollection_Mat4<GLdouble>& theOrientation,
                      const NCollection_Mat4<GLdouble>& theViewMapping,
                      OpenGl_Vec3                       theOrigins[4],
-                     OpenGl_Vec3                       theDirects[4]);
+                     OpenGl_Vec3                       theDirects[4],
+                     NCollection_Mat4<GLdouble>&       theInvModelProj);
 
   //! Runs ray-tracing shader programs.
   Standard_Boolean RunRaytraceShaders (const Graphic3d_CView& theCView,
@@ -497,6 +536,7 @@ protected: //! @name methods related to ray-tracing
                                        const Standard_Integer theSizeY,
                                        const OpenGl_Vec3      theOrigins[4],
                                        const OpenGl_Vec3      theDirects[4],
+                                       const OpenGl_Matrix&   theInvModelProj,
                                        OpenGl_FrameBuffer*    theFrameBuffer);
 
   //! Redraws the window using OpenGL/GLSL ray-tracing.
@@ -504,6 +544,8 @@ protected: //! @name methods related to ray-tracing
                              const Standard_Integer theSizeX,
                              const Standard_Integer theSizeY,
                              const Standard_Boolean theToSwap,
+                             const Aspect_CLayer2d& theCOverLayer,
+                             const Aspect_CLayer2d& theCUnderLayer,
                              OpenGl_FrameBuffer*    theFrameBuffer);
 
 protected: //! @name fields related to ray-tracing
@@ -575,6 +617,8 @@ protected: //! @name fields related to ray-tracing
   Handle(OpenGl_FrameBuffer) myRaytraceFBO1;
   //! Framebuffer (FBO) to perform adaptive FSAA.
   Handle(OpenGl_FrameBuffer) myRaytraceFBO2;
+  //! Framebuffer (FBO) for pre-raytrace rendering by OpenGL.
+  Handle(OpenGl_FrameBuffer) myOpenGlFBO;
 
   //! State of OpenGL view.
   Standard_Size myViewModificationStatus;
@@ -590,6 +634,12 @@ protected: //! @name fields related to ray-tracing
   //! Cached locations of frequently used uniform variables.
   Standard_Integer myUniformLocations[2][OpenGl_RT_NbVariables];
 
+  //! Graphical raytracing filter to filter out all raytracable structures.
+  Handle(OpenGl_RaytraceFilter) myRaytraceFilter;
+
+  //! Redraw the scene using OpenGL rasterization or raytracing?
+  Standard_Boolean myToRedrawGL;
+
 protected: //! @name protected fields
 
   Handle(OpenGl_PrinterContext) myPrintContext;
@@ -605,6 +655,8 @@ protected: //! @name protected fields
   Standard_Boolean       myUseGLLight;
   Standard_Boolean       myIsCullingEnabled;     //!< frustum culling flag
 
+  unsigned int           myFrameCounter;         //!< redraw counter, for debugging
+
 protected: //! @name fields related to status
 
   Handle(OpenGl_RenderFilter) myRenderFilter;
index 15dae2b..dbc45f8 100755 (executable)
@@ -221,7 +221,7 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
 
     const BVH_Vec4f aSize = myRaytraceGeometry.Box().Size();
 
-    myRaytraceSceneEpsilon = Max (1e-7f, 1e-4f * sqrtf (
+    myRaytraceSceneEpsilon = Max (1e-6f, 1e-4f * sqrtf (
       aSize.x() * aSize.x() + aSize.y() * aSize.y() + aSize.z() * aSize.z()));
 
     return UploadRaytraceData();
@@ -1402,6 +1402,11 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
       aShaderProgram->SetSampler (myGlContext,
         "uEnvironmentMapTexture", OpenGl_RT_EnvironmentMapTexture);
 
+      aShaderProgram->SetSampler (myGlContext,
+        "uOpenGlColorTexture", OpenGl_RT_OpenGlColorTexture);
+      aShaderProgram->SetSampler (myGlContext,
+        "uOpenGlDepthTexture", OpenGl_RT_OpenGlDepthTexture);
+
       if (anIndex == 1)
       {
         aShaderProgram->SetSampler (myGlContext,
@@ -1427,6 +1432,8 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
         aShaderProgram->GetUniformLocation (myGlContext, "uDirectLT");
       myUniformLocations[anIndex][OpenGl_RT_uDirectRT] =
         aShaderProgram->GetUniformLocation (myGlContext, "uDirectRT");
+      myUniformLocations[anIndex][OpenGl_RT_uInvModelProj] =
+        aShaderProgram->GetUniformLocation (myGlContext, "uInvModelProj");
 
       myUniformLocations[anIndex][OpenGl_RT_uLightCount] =
         aShaderProgram->GetUniformLocation (myGlContext, "uLightCount");
@@ -1506,6 +1513,7 @@ inline void NullifyResource (const Handle(OpenGl_Context)& theContext,
 // =======================================================================
 void OpenGl_Workspace::ReleaseRaytraceResources()
 {
+  NullifyResource (myGlContext, myOpenGlFBO);
   NullifyResource (myGlContext, myRaytraceFBO1);
   NullifyResource (myGlContext, myRaytraceFBO2);
 
@@ -1869,12 +1877,11 @@ Standard_Boolean OpenGl_Workspace::ResizeRaytraceBuffers (const Standard_Integer
 void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrientation,
                                      const NCollection_Mat4<GLdouble>& theViewMapping,
                                      OpenGl_Vec3                       theOrigins[4],
-                                     OpenGl_Vec3                       theDirects[4])
+                                     OpenGl_Vec3                       theDirects[4],
+                                     NCollection_Mat4<GLdouble>&       theInvModelProj)
 {
-  NCollection_Mat4<GLdouble> aInvModelProj;
-
   // compute inverse model-view-projection matrix
-  (theViewMapping * theOrientation).Inverted (aInvModelProj);
+  (theViewMapping * theOrientation).Inverted (theInvModelProj);
 
   Standard_Integer aOriginIndex = 0;
   Standard_Integer aDirectIndex = 0;
@@ -1888,7 +1895,7 @@ void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrient
                            -1.0,
                             1.0);
 
-      aOrigin = aInvModelProj * aOrigin;
+      aOrigin = theInvModelProj * aOrigin;
 
       aOrigin.x() = aOrigin.x() / aOrigin.w();
       aOrigin.y() = aOrigin.y() / aOrigin.w();
@@ -1899,7 +1906,7 @@ void OpenGl_Workspace::UpdateCamera (const NCollection_Mat4<GLdouble>& theOrient
                             1.0,
                             1.0);
 
-      aDirect = aInvModelProj * aDirect;
+      aDirect = theInvModelProj * aDirect;
 
       aDirect.x() = aDirect.x() / aDirect.w();
       aDirect.y() = aDirect.y() / aDirect.w();
@@ -1931,6 +1938,7 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
                                                        const Standard_Integer theSizeY,
                                                        const OpenGl_Vec3      theOrigins[4],
                                                        const OpenGl_Vec3      theDirects[4],
+                                                       const OpenGl_Matrix&   theInvModelProj,
                                                        OpenGl_FrameBuffer*    theFrameBuffer)
 {
   mySceneMinPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
@@ -1942,9 +1950,12 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
   myGeometryVertexTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
   myGeometryNormalTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
   myGeometryTriangTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+  mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
   myRaytraceMaterialTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
   myRaytraceLightSrcTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
-  mySceneTransformTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+  
+  myOpenGlFBO->ColorTexture()->Bind        (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+  myOpenGlFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
 
   if (theCView.RenderParams.IsAntialiasingEnabled) // render source image to FBO
   {
@@ -1974,6 +1985,8 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
     myUniformLocations[0][OpenGl_RT_uDirectLT], theDirects[2]);
   myRaytraceProgram->SetUniform (myGlContext,
     myUniformLocations[0][OpenGl_RT_uDirectRT], theDirects[3]);
+  myRaytraceProgram->SetUniform (myGlContext,
+    myUniformLocations[0][OpenGl_RT_uInvModelProj], theInvModelProj);
   myRaytraceProgram->SetUniform (myGlContext,
     myUniformLocations[0][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
   myRaytraceProgram->SetUniform (myGlContext,
@@ -2002,6 +2015,23 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
   {
     myRaytraceProgram->Unbind (myGlContext);
 
+    myOpenGlFBO->ColorTexture()->Unbind        (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+    myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+    mySceneMinPointTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+    mySceneMaxPointTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+    mySceneNodeInfoTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+    myObjectMinPointTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMinPointTexture);
+    myObjectMaxPointTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMaxPointTexture);
+    myObjectNodeInfoTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
+    myGeometryVertexTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+    myGeometryNormalTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+    myGeometryTriangTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+    myRaytraceMaterialTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
+    myRaytraceLightSrcTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+    mySceneTransformTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+
+    myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
+
     return Standard_True;
   }
 
@@ -2025,6 +2055,8 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
     myUniformLocations[1][OpenGl_RT_uDirectLT], theDirects[2]);
   myPostFSAAProgram->SetUniform (myGlContext,
     myUniformLocations[1][OpenGl_RT_uDirectRT], theDirects[3]);
+  myRaytraceProgram->SetUniform (myGlContext,
+    myUniformLocations[1][OpenGl_RT_uInvModelProj], theInvModelProj);
   myPostFSAAProgram->SetUniform (myGlContext,
     myUniformLocations[1][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
   myPostFSAAProgram->SetUniform (myGlContext,
@@ -2099,6 +2131,23 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
     myUniformLocations[1][OpenGl_RT_aPosition]);
 
   myPostFSAAProgram->Unbind (myGlContext);
+  myRaytraceFBO1->ColorTexture()->Unbind     (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
+  myOpenGlFBO->ColorTexture()->Unbind        (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+  myOpenGlFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+  mySceneMinPointTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+  mySceneMaxPointTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+  mySceneNodeInfoTexture->UnbindTexture      (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+  myObjectMinPointTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMinPointTexture);
+  myObjectMaxPointTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectMaxPointTexture);
+  myObjectNodeInfoTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_ObjectNodeInfoTexture);
+  myGeometryVertexTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+  myGeometryNormalTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+  myGeometryTriangTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+  myRaytraceMaterialTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
+  myRaytraceLightSrcTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+  mySceneTransformTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+
+  myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
 
   return Standard_True;
 }
@@ -2111,11 +2160,10 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
                                              const Standard_Integer theSizeX,
                                              const Standard_Integer theSizeY,
                                              const Standard_Boolean theToSwap,
+                                             const Aspect_CLayer2d& theCOverLayer,
+                                             const Aspect_CLayer2d& theCUnderLayer,
                                              OpenGl_FrameBuffer*    theFrameBuffer)
 {
-  if (!UpdateRaytraceGeometry (OpenGl_GUM_CHECK))
-    return Standard_False;
-
   if (!InitRaytraceResources (theCView))
     return Standard_False;
 
@@ -2151,17 +2199,33 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
 
   OpenGl_Vec3 aOrigins[4];
   OpenGl_Vec3 aDirects[4];
+  NCollection_Mat4<GLdouble> anInvModelProj;
 
   UpdateCamera (aOrientationMatrix,
                 aViewMappingMatrix,
                 aOrigins,
-                aDirects);
+                aDirects,
+                anInvModelProj);
+
+  OpenGl_Matrix anInvModelProjMatrix;
+  for (Standard_Integer j = 0; j < 4; ++j)
+  {
+    for (Standard_Integer i = 0; i < 4; ++i)
+    {
+      anInvModelProjMatrix.mat[j][i] = static_cast<GLfloat>(anInvModelProj.GetValue(i,j));
+    }
+  }
 
   Standard_Boolean wasBlendingEnabled = glIsEnabled (GL_BLEND);
   Standard_Boolean wasDepthTestEnabled = glIsEnabled (GL_DEPTH_TEST);
 
   glDisable (GL_DEPTH_TEST);
 
+  if (theFrameBuffer != NULL)
+  {
+    theFrameBuffer->BindBuffer (myGlContext);
+  }
+
   if (NamedStatus & OPENGL_NS_WHITEBACK)
   {
     glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
@@ -2176,16 +2240,17 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
 
   glClear (GL_COLOR_BUFFER_BIT);
 
-  if (theFrameBuffer != NULL)
-    theFrameBuffer->BindBuffer (myGlContext);
-
   myView->DrawBackground (*this);
 
+  myView->RedrawLayer2d (myPrintContext, theCView, theCUnderLayer);
+
   // Generate ray-traced image
   glMatrixMode (GL_PROJECTION);
+  glPushMatrix();
   glLoadIdentity();
 
   glMatrixMode (GL_MODELVIEW);
+  glPushMatrix();
   glLoadIdentity();
 
   glEnable (GL_BLEND);
@@ -2200,6 +2265,7 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
                         theSizeY,
                         aOrigins,
                         aDirects,
+                        anInvModelProjMatrix,
                         theFrameBuffer);
 
     myRaytraceScreenQuad.Unbind (myGlContext);
@@ -2211,6 +2277,20 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
   if (wasDepthTestEnabled)
     glEnable (GL_DEPTH_TEST);
 
+  glMatrixMode (GL_PROJECTION);
+  glPopMatrix();
+  glMatrixMode (GL_MODELVIEW);
+  glPopMatrix();
+
+  // Redraw trihedron
+  myView->RedrawTrihedron (this);
+
+  // Redraw overlay
+  const int aMode = 0;
+  DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
+  myView->RedrawLayer2d (myPrintContext, theCView, theCOverLayer);
+  DisplayCallback (theCView, aMode);
+
   // Swap the buffers
   if (theToSwap)
   {
@@ -2224,3 +2304,21 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
 
   return Standard_True;
 }
+
+IMPLEMENT_STANDARD_HANDLE(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter, OpenGl_RenderFilter)
+
+// =======================================================================
+// function : CanRender
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
+{
+  Standard_Boolean aPrevFilterResult = Standard_True;
+  if (!myPrevRenderFilter.IsNull())
+  {
+    aPrevFilterResult = myPrevRenderFilter->CanRender(theElement);
+  }
+  return aPrevFilterResult &&
+         !OpenGl_Raytrace::IsRaytracedElement (theElement);
+}
index 38a8d88..ce6c1bc 100644 (file)
@@ -19,6 +19,8 @@ uniform vec3 uDirectRT;
 //! Direction of viewing ray in right-bottom corner.
 uniform vec3 uDirectRB;
 
+//! Inverse model-view-projection matrix.
+uniform mat4 uInvModelProj;
 //! Texture buffer of data records of high-level BVH nodes.
 uniform isamplerBuffer uSceneNodeInfoTexture;
 //! Texture buffer of minimum points of high-level BVH nodes.
@@ -49,6 +51,11 @@ uniform samplerBuffer uRaytraceLightSrcTexture;
 //! Environment map texture.
 uniform sampler2D uEnvironmentMapTexture;
 
+//! Input pre-raytracing image rendered by OpenGL.
+uniform sampler2D uOpenGlColorTexture;
+//! Input pre-raytracing depth image rendered by OpenGL.
+uniform sampler2D uOpenGlDepthTexture;
+
 //! Total number of light sources.
 uniform int uLightCount;
 //! Intensity of global ambient light.
@@ -160,9 +167,44 @@ SRay GenerateRay (in vec2 thePixel)
 
   vec3 aD0 = mix (uDirectLB, uDirectRB, thePixel.x);
   vec3 aD1 = mix (uDirectLT, uDirectRT, thePixel.x);
-  
-  return SRay (mix (aP0, aP1, thePixel.y),
-               mix (aD0, aD1, thePixel.y));
+
+  vec3 aDirection = normalize (mix (aD0, aD1, thePixel.y));
+
+  return SRay (mix (aP0, aP1, thePixel.y), aDirection);
+
+}
+
+// =======================================================================
+// function : ComputeOpenGlDepth
+// purpose  :
+// =======================================================================
+float ComputeOpenGlDepth (in SRay theRay)
+{
+  // a depth in range [0,1]
+  float anOpenGlDepth = texelFetch (uOpenGlDepthTexture, ivec2 (gl_FragCoord.xy), 0).r;
+  // pixel point in NDC-space [-1,1]
+  vec4 aPoint = vec4 (2.0f * vPixel.x - 1.0f,
+                      2.0f * vPixel.y - 1.0f,
+                      2.0f * anOpenGlDepth - 1.0f,
+                      1.0f);
+  vec4 aFinal = uInvModelProj * aPoint;
+  aFinal.xyz *= 1.f / aFinal.w;
+
+  return (anOpenGlDepth < 1.f) ? length (aFinal.xyz - theRay.Origin) : MAXFLOAT;
+}
+
+// =======================================================================
+// function : ComputeOpenGlColor
+// purpose  :
+// =======================================================================
+vec4 ComputeOpenGlColor (in SRay theRay)
+{
+  vec4 anOpenGlColor = texelFetch (uOpenGlColorTexture, ivec2 (gl_FragCoord.xy), 0);
+  // During blending with factors GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA (for text and markers)
+  // the alpha channel (written in the color buffer) was squared.
+  anOpenGlColor.a = 1.f - sqrt (anOpenGlColor.a);
+
+  return anOpenGlColor;
 }
 
 // =======================================================================
@@ -320,7 +362,7 @@ ivec4 ObjectNearestHit (in int theBVHOffset, in int theVrtOffset, in int theTrgO
         if (aTime < theHit.Time)
         {
           aTriIndex = aTriangle;
-          
+
           theHit = SIntersect (aTime, aParams, aNormal);
         }
       }
@@ -776,6 +818,9 @@ vec3 Refract (in vec3 theInput,
     (anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);
 }
 
+#define MIN_SLOPE 0.0001f
+#define EPS_SCALE 8.0000f
+
 #define THRESHOLD vec3 (0.1f)
 
 #define LIGHT_POS(index) (2 * index + 1)
@@ -791,17 +836,27 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
   vec4 aWeight = vec4 (1.0f);
 
   int anObjectId;
-  
+
+  float anOpenGlDepth = ComputeOpenGlDepth (theRay);
+
+  vec3 aViewDir = theRay.Direct;
+
   for (int aDepth = 0; aDepth < TRACE_DEPTH; ++aDepth)
   {
     SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
-    
+
     ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, anObjectId);
 
     if (aTriIndex.x == -1)
     {
       if (aWeight.w != 0.0f)
       {
+        if (anOpenGlDepth < MAXFLOAT)
+        {
+          vec4 anOpenGlColor = ComputeOpenGlColor (theRay);
+          aResult.xyz += aWeight.xyz * anOpenGlColor.xyz;
+          aWeight.w   *= anOpenGlColor.w;
+        }
         return vec4 (aResult.x,
                      aResult.y,
                      aResult.z,
@@ -821,7 +876,36 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
                    aResult.z,
                    aWeight.w);
     }
+
+    aHit.Normal = normalize (aHit.Normal);
+
+    if (anOpenGlDepth != MAXFLOAT)
+    {
+      float aDepthSlope = dot (theRay.Direct, aHit.Normal);
+      
+      // For polygons that are parallel to the screen plane, the depth slope
+      // is equal to 1, resulting in small polygon offset. For polygons that
+      // that are at a large angle to the screen, the depth slope tends to 1,
+      // resulting in a larger polygon offset
+      float aPolygonOffset = uSceneEpsilon * EPS_SCALE / max (MIN_SLOPE, abs (aDepthSlope));
     
+      if (anOpenGlDepth - aPolygonOffset < aHit.Time)
+      {
+        vec4 aColor = ComputeOpenGlColor (theRay);
+        
+        aResult.xyz += aWeight.xyz * aColor.xyz;
+        aWeight     *= aColor.w;
+        
+        if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))
+        {
+          return vec4 (aResult.x,
+                       aResult.y,
+                       aResult.z,
+                       aWeight.w);
+        }
+      }
+    }
+
     vec3 aPoint = theRay.Direct * aHit.Time + theRay.Origin;
     
     vec3 aAmbient  = texelFetch (
@@ -841,9 +925,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
 
     aNormal = normalize (MatrixRowMultiplyDir (
       aNormal, aInvTransf0, aInvTransf1, aInvTransf2));
-    
-    aHit.Normal = normalize (aHit.Normal);
-    
+
     for (int aLightIdx = 0; aLightIdx < uLightCount; ++aLightIdx)
     {
       vec4 aLight = texelFetch (
@@ -902,18 +984,25 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
     if (aOpacity.x != 1.0f)
     {
       aWeight *= aOpacity.y;
-      
+
       if (aOpacity.z != 1.0f)
       {
         theRay.Direct = Refract (theRay.Direct, aNormal, aOpacity.z, aOpacity.w);
 
         theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
-        
+      
         theInverse.x = theRay.Direct.x < 0.0f ? -theInverse.x : theInverse.x;
         theInverse.y = theRay.Direct.y < 0.0f ? -theInverse.y : theInverse.y;
         theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
-
-        aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);     
+      
+        aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
+        
+        // Disable combining image with OpenGL output
+        anOpenGlDepth = MAXFLOAT;
+      }
+      else
+      {
+        anOpenGlDepth -= aHit.Time + uSceneEpsilon;
       }
     }
     else
@@ -925,7 +1014,7 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
       
       if (dot (theRay.Direct, aHit.Normal) < 0.0f)
       {
-        theRay.Direct = reflect (theRay.Direct, aHit.Normal);      
+        theRay.Direct = reflect (theRay.Direct, aHit.Normal);
       }
 
       theInverse = 1.0f / max (abs (theRay.Direct), SMALL);
@@ -935,6 +1024,9 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
       theInverse.z = theRay.Direct.z < 0.0f ? -theInverse.z : theInverse.z;
       
       aPoint += aHit.Normal * (dot (aHit.Normal, theRay.Direct) >= 0.0f ? uSceneEpsilon : -uSceneEpsilon);
+
+      // Disable combining image with OpenGL output
+      anOpenGlDepth = MAXFLOAT;
     }
     
     if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))
index 1834df7..f33d6ea 100644 (file)
@@ -1051,35 +1051,43 @@ void Visual3d_View::Redraw (const Handle(Visual3d_Layer)& theUnderLayer,
     return;
   }
 
-  if (MyGraphicDriver->IsDeviceLost())
-  {
-    MyViewManager->RecomputeStructures();
-    MyViewManager->RecomputeStructures (myImmediateStructures);
-    MyGraphicDriver->ResetDeviceLostFlag();
-  }
+  Aspect_CLayer2d anOverCLayer, anUnderCLayer;
+  anOverCLayer.ptrLayer = anUnderCLayer.ptrLayer = NULL;
+  if (!theOverLayer .IsNull()) anOverCLayer  = theOverLayer ->CLayer();
+  if (!theUnderLayer.IsNull()) anUnderCLayer = theUnderLayer->CLayer();
 
-  // set up Z buffer state before redrawing
-  if (MyViewManager->ZBufferAuto())
+  for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
   {
-    const Standard_Boolean hasFacet   = ContainsFacet();
-    const Standard_Boolean hasZBuffer = ZBufferIsActivated();
-    // if the view contains facets and if ZBuffer is not active
-    if (hasFacet && !hasZBuffer)
+    if (MyGraphicDriver->IsDeviceLost())
     {
-      SetZBufferActivity (1);
+      MyViewManager->RecomputeStructures();
+      MyViewManager->RecomputeStructures (myImmediateStructures);
+      MyGraphicDriver->ResetDeviceLostFlag();
     }
-    // if the view contains only facets and if ZBuffer is active
-    if (!hasFacet && hasZBuffer)
+
+    // set up Z buffer state before redrawing
+    if (MyViewManager->ZBufferAuto())
     {
-      SetZBufferActivity (0);
+      const Standard_Boolean hasFacet   = ContainsFacet();
+      const Standard_Boolean hasZBuffer = ZBufferIsActivated();
+      // if the view contains facets and if ZBuffer is not active
+      if (hasFacet && !hasZBuffer)
+      {
+        SetZBufferActivity (1);
+      }
+      // if the view contains only facets and if ZBuffer is active
+      if (!hasFacet && hasZBuffer)
+      {
+        SetZBufferActivity (0);
+      }
     }
-  }
 
-  Aspect_CLayer2d anOverCLayer, anUnderCLayer;
-  anOverCLayer.ptrLayer = anUnderCLayer.ptrLayer = NULL;
-  if (!theOverLayer .IsNull()) anOverCLayer  = theOverLayer ->CLayer();
-  if (!theUnderLayer.IsNull()) anUnderCLayer = theUnderLayer->CLayer();
-  MyGraphicDriver->Redraw (MyCView, anUnderCLayer, anOverCLayer, theX, theY, theWidth, theHeight);
+    MyGraphicDriver->Redraw (MyCView, anUnderCLayer, anOverCLayer, theX, theY, theWidth, theHeight);
+    if (!MyGraphicDriver->IsDeviceLost())
+    {
+      return;
+    }
+  }
 }
 
 void Visual3d_View::RedrawImmediate()
diff --git a/tests/v3d/raytrace/bug24819 b/tests/v3d/raytrace/bug24819
new file mode 100644 (file)
index 0000000..fc829a1
--- /dev/null
@@ -0,0 +1,72 @@
+puts "========"
+puts "OCC24819: TKOpenGl - extend the ray-tracing core by visualization of lines, text and point sprites"
+puts "========"
+
+# setup 3D viewer content
+vinit name=View1 w=512 h=512
+vglinfo
+
+vvbo 0
+vsetdispmode 1
+vsetgradientbg 180 200 255 180 180 180 2
+# boxes
+box b1 1 1 1
+vdisplay b1
+vsetlocation b1 0 0 0.001
+vsetmaterial b1 Silver
+vsettransparency b1 0.5
+box b2 3 2 2 1 2 1
+vdisplay b2
+vsetmaterial b2 Pewter
+vsettransparency b2 0.8
+
+# brep text
+text2brep t "text" "Arial" 8
+vdisplay t
+
+# overlay objects
+voverlaytext "Overlay text!" 200 440 40
+
+# markers
+vpoint p 1 1 1
+vdisplay p
+vmarkerstest mTest 7 -3 0 PointsOnSide=5 MarkerType=5
+
+# 3d text
+vdrawtext 3D_Text 1 2 2 255 0 0 0 0 0 0 20 0
+
+vlight change 0 pos -1 1 1
+
+vfit
+
+# trihedron
+vzbufftrihedron
+
+# activate ray-tracing
+vrenderparams -raytrace
+
+# orthogonal projection
+set aModeNum 0
+foreach aFSAAMode {on off} {
+  foreach aReflMode {on off} {
+    foreach aShadMode {on off} {
+      vrenderparams -shadows $aShadMode -reflections $aReflMode -fsaa $aFSAAMode
+      vdump $imagedir/${casename}_${aModeNum}.png
+      incr aModeNum
+    }
+  }
+}
+
+# perspective projection
+vchangecamera proj persp
+set aModeNum 0
+foreach aFSAAMode {on off} {
+  foreach aReflMode {on off} {
+    foreach aShadMode {on off} {
+      vrenderparams -shadows $aShadMode -reflections $aReflMode -fsaa $aFSAAMode
+      vdump $imagedir/${casename}_${aModeNum}.png
+      incr aModeNum
+    }
+  }
+}
+