0025885: Visualization, ray tracing - Improve layer processing
authordbp <dbp@opencascade.com>
Thu, 9 Apr 2015 05:58:10 +0000 (08:58 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 9 Apr 2015 14:50:03 +0000 (17:50 +0300)
Move Ray-tracing core from OpenGl_Workspace to OpenGl_View.
This patch also contains a number of useful architectural changes.

14 files changed:
src/NCollection/NCollection_Vec2.hxx
src/NCollection/NCollection_Vec3.hxx
src/NCollection/NCollection_Vec4.hxx
src/OpenGl/FILES
src/OpenGl/OpenGl_LayerFilter.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_LayerList.cxx
src/OpenGl/OpenGl_LayerList.hxx
src/OpenGl/OpenGl_ShaderProgram.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_2.cxx
src/OpenGl/OpenGl_View_Raytrace.cxx [moved from src/OpenGl/OpenGl_Workspace_Raytrace.cxx with 55% similarity]
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx

index 9027e4d..5515a63 100644 (file)
@@ -175,6 +175,25 @@ public:
                              v[1] > theVec.v[1] ? v[1] : theVec.v[1]);
   }
 
+  //! Compute component-wise modulus of the vector.
+  NCollection_Vec2 cwiseAbs() const
+  {
+    return NCollection_Vec2 (std::abs (v[0]),
+                             std::abs (v[1]));
+  }
+
+  //! Compute maximum component of the vector.
+  Element_t maxComp() const
+  {
+    return v[0] > v[1] ? v[0] : v[1];
+  }
+
+  //! Compute minimum component of the vector.
+  Element_t minComp() const
+  {
+    return v[0] < v[1] ? v[0] : v[1];
+  }
+
   //! Compute per-component multiplication by scale factor.
   NCollection_Vec2& operator*= (const Element_t theFactor)
   {
index 35cb9e2..e0568a2 100644 (file)
@@ -250,6 +250,28 @@ public:
                              v[2] > theVec.v[2] ? v[2] : theVec.v[2]);
   }
 
+  //! Compute component-wise modulus of the vector.
+  NCollection_Vec3 cwiseAbs() const
+  {
+    return NCollection_Vec3 (std::abs (v[0]),
+                             std::abs (v[1]),
+                             std::abs (v[2]));
+  }
+
+  //! Compute maximum component of the vector.
+  Element_t maxComp() const
+  {
+    return v[0] > v[1] ? (v[0] > v[2] ? v[0] : v[2])
+                       : (v[1] > v[2] ? v[1] : v[2]);
+  }
+
+  //! Compute minimum component of the vector.
+  Element_t minComp() const
+  {
+    return v[0] < v[1] ? (v[0] < v[2] ? v[0] : v[2])
+                       : (v[1] < v[2] ? v[1] : v[2]);
+  }
+
   //! Compute per-component division by scale factor.
   NCollection_Vec3& operator/= (const Element_t theInvFactor)
   {
index 45aa2b0..65b38eb 100644 (file)
@@ -302,6 +302,33 @@ public:
                              v[3] > theVec.v[3] ? v[3] : theVec.v[3]);
   }
 
+  //! Compute component-wise modulus of the vector.
+  NCollection_Vec4 cwiseAbs() const
+  {
+    return NCollection_Vec4 (std::abs (v[0]),
+                             std::abs (v[1]),
+                             std::abs (v[2]),
+                             std::abs (v[3]));
+  }
+
+  //! Compute maximum component of the vector.
+  Element_t maxComp() const
+  {
+    const Element_t aMax1 = v[0] > v[1] ? v[0] : v[1];
+    const Element_t aMax2 = v[2] > v[3] ? v[2] : v[3];
+
+    return aMax1 > aMax2 ? aMax1 : aMax2;
+  }
+
+  //! Compute minimum component of the vector.
+  Element_t minComp() const
+  {
+    const Element_t aMin1 = v[0] < v[1] ? v[0] : v[1];
+    const Element_t aMin2 = v[2] < v[3] ? v[2] : v[3];
+
+    return aMin1 < aMin2 ? aMin1 : aMin2;
+  }
+
   //! Compute per-component division by scale factor.
   NCollection_Vec4& operator/= (const Element_t theInvFactor)
   {
index 26a4872..37d3e63 100755 (executable)
@@ -108,6 +108,7 @@ OpenGl_GlCore43.hxx
 OpenGl_GlCore44.hxx
 OpenGl_LayerList.cxx
 OpenGl_LayerList.hxx
+OpenGl_LayerFilter.hxx
 OpenGl_IndexBuffer.hxx
 OpenGl_IndexBuffer.cxx
 OpenGl_Layer.cxx
@@ -146,7 +147,7 @@ Handle_OpenGl_ShaderProgram.hxx
 Handle_OpenGl_ShaderManager.hxx
 OpenGl_SceneGeometry.hxx
 OpenGl_SceneGeometry.cxx
-OpenGl_Workspace_Raytrace.cxx
+OpenGl_View_Raytrace.cxx
 OpenGl_Flipper.hxx
 OpenGl_Flipper.cxx
 OpenGl_BVHTreeSelector.hxx
diff --git a/src/OpenGl/OpenGl_LayerFilter.hxx b/src/OpenGl/OpenGl_LayerFilter.hxx
new file mode 100644 (file)
index 0000000..1860431
--- /dev/null
@@ -0,0 +1,28 @@
+// Created on: 2015-03-20
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2012-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_LayerFilter_H__
+#define _OpenGl_LayerFilter_H__
+
+//! Tool object to specify processed OpenGL layers.
+enum OpenGl_LayerFilter
+{
+  OpenGl_LF_All,    //!< process all layers
+  OpenGl_LF_Upper,  //!< process only top layers
+  OpenGl_LF_Bottom, //!< process only bottom layer
+  OpenGl_LF_Default //!< process only default layer
+};
+
+#endif //_OpenGl_LayerFilter_H__
index 712a51c..485b6e9 100644 (file)
@@ -357,7 +357,8 @@ void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId        theLaye
 //purpose  :
 //=======================================================================
 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
-                               const Standard_Boolean          theToDrawImmediate) const
+                               const Standard_Boolean          theToDrawImmediate,
+                               const OpenGl_LayerFilter        theLayersToProcess) const
 {
   OpenGl_GlobalLayerSettings aDefaultSettings;
 
@@ -365,9 +366,22 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
   aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC,      &aDefaultSettings.DepthFunc);
   aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aDefaultSettings.DepthMask);
 
-  Standard_Integer aSeqId = myLayers.Lower();
+  Standard_Integer aSeqId = myLayers.Lower(), aMainId = myLayerIds.Find (Graphic3d_ZLayerId_Default);
   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
   {
+    if (theLayersToProcess == OpenGl_LF_Bottom)
+    {
+      if (aSeqId >= aMainId) continue;
+    }
+    else if (theLayersToProcess == OpenGl_LF_Upper)
+    {
+      if (aSeqId <= aMainId) continue;
+    }
+    else if (theLayersToProcess == OpenGl_LF_Default)
+    {
+      if (aSeqId != aMainId) continue;
+    }
+
     const OpenGl_Layer& aLayer = anIts.Value();
     if (aLayer.NbStructures() < 1)
     {
index e7c20ac..8d077fa 100644 (file)
@@ -17,6 +17,7 @@
 #define _OpenGl_LayerList_Header
 
 #include <OpenGl_Layer.hxx>
+#include <OpenGl_LayerFilter.hxx>
 
 #include <InterfaceGraphic_telem.hxx>
 
@@ -89,7 +90,8 @@ public:
 
   //! Render this element
   void Render (const Handle(OpenGl_Workspace)& theWorkspace,
-               const Standard_Boolean          theToDrawImmediate) const;
+               const Standard_Boolean          theToDrawImmediate,
+               const OpenGl_LayerFilter        theLayersToProcess) const;
 
   //! Returns the set of OpenGL Z-layers.
   const OpenGl_SequenceOfLayers& Layers() const { return myLayers; }
index 79a65b3..bb6d0ba 100755 (executable)
@@ -132,7 +132,7 @@ const int MaxStateTypes = 6;
 //! Wrapper for OpenGL program object.
 class OpenGl_ShaderProgram : public OpenGl_Resource
 {
-  friend class OpenGl_Workspace;
+  friend class OpenGl_View;
 
 public:
 
index edfa8a5..9694079 100644 (file)
@@ -73,10 +73,15 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext,
   myModelViewState (0),
   myStateCounter (theCounter),
   myLastLightSourceState (0, 0),
-  myModificationState (1), // initial state
   myTextureParams   (new OpenGl_AspectFace()),
   myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
-  myBgTextureArray  (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE))
+  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)
 {
   myCurrLightSourceState = myStateCounter->Increment();
 }
@@ -114,6 +119,8 @@ void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
   {
     myBgTextureArray->Release (theCtx.operator->());
   }
+
+  releaseRaytraceResources (theCtx);
 }
 
 void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)&       theCtx,
@@ -135,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;
 }
 
 // =======================================================================
index 3bddb4a..03dc77a 100644 (file)
@@ -213,17 +213,17 @@ class OpenGl_View : public MMgt_TShared
          || myZLayers.NbImmediateStructures() != 0;
   }
 
-  //! Returns modification state for ray-tracing.
-  Standard_Size ModificationState() const { return myModificationState; }
-
 protected:
 
   void RenderStructs (const Handle(OpenGl_Workspace)& theWorkspace,
+                      const Graphic3d_CView&          theCView,
                       const Standard_Boolean          theToDrawImmediate);
+
   void RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
-                      const Handle(OpenGl_Workspace) &theWorkspace,
+                      const Handle(OpenGl_Workspace)&      theWorkspace,
                       const Graphic3d_CView&               theCView,
                       const Aspect_CLayer2d&               theCLayer);
+
   void RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace);
 
   //! Redraw contents of model scene: clipping planes,
@@ -232,6 +232,7 @@ protected:
   //! matrices supplied by 3d view.
   void RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
                     const Handle(OpenGl_Workspace)&      theWorkspace,
+                    const Graphic3d_CView&               theCView,
                     const Standard_Boolean               theToDrawImmediate);
 
   Handle(OpenGl_LineAttributes) myLineAttribs;
@@ -286,14 +287,398 @@ protected:
   //! Is needed for selection of overlapping objects and storage of the current view volume
   OpenGl_BVHTreeSelector myBVHSelector;
 
-  Standard_Size myModificationState;
-
 protected: //! @name Background parameters
 
   OpenGl_AspectFace*      myTextureParams;   //!< Stores texture and its parameters for textured background
   OpenGl_BackgroundArray* myBgGradientArray; //!< Primitive array for gradient background
   OpenGl_BackgroundArray* myBgTextureArray;  //!< Primitive array for texture  background
 
+protected: //! @name data types related to ray-tracing
+
+  //! Result of OpenGL shaders initialization.
+  enum RaytraceInitStatus
+  {
+    OpenGl_RT_NONE,
+    OpenGl_RT_INIT,
+    OpenGl_RT_FAIL
+  };
+
+  //! Describes update mode (state).
+  enum RaytraceUpdateMode
+  {
+    OpenGl_GUM_CHECK,   //!< check geometry state
+    OpenGl_GUM_PREPARE, //!< collect unchanged objects
+    OpenGl_GUM_REBUILD  //!< rebuild changed and new objects
+  };
+
+  //! Defines frequently used shader variables.
+  enum ShaderVariableIndex
+  {
+    OpenGl_RT_aPosition,
+
+    OpenGl_RT_uOriginLT,
+    OpenGl_RT_uOriginLB,
+    OpenGl_RT_uOriginRT,
+    OpenGl_RT_uOriginRB,
+    OpenGl_RT_uDirectLT,
+    OpenGl_RT_uDirectLB,
+    OpenGl_RT_uDirectRT,
+    OpenGl_RT_uDirectRB,
+    OpenGl_RT_uUnviewMat,
+
+    OpenGl_RT_uSceneRad,
+    OpenGl_RT_uSceneEps,
+    OpenGl_RT_uLightAmbnt,
+    OpenGl_RT_uLightCount,
+
+    OpenGl_RT_uShadEnabled,
+    OpenGl_RT_uReflEnabled,
+    OpenGl_RT_uEnvMapEnable,
+
+    OpenGl_RT_uOffsetX,
+    OpenGl_RT_uOffsetY,
+    OpenGl_RT_uSamples,
+    OpenGl_RT_uWinSizeX,
+    OpenGl_RT_uWinSizeY,
+
+    OpenGl_RT_uTextures,
+
+    OpenGl_RT_NbVariables // special field
+  };
+
+  //! Defines texture samplers.
+  enum ShaderSamplerNames
+  {
+    OpenGl_RT_SceneNodeInfoTexture  = 0,
+    OpenGl_RT_SceneMinPointTexture  = 1,
+    OpenGl_RT_SceneMaxPointTexture  = 2,
+    OpenGl_RT_SceneTransformTexture = 3,
+
+    OpenGl_RT_GeometryVertexTexture = 4,
+    OpenGl_RT_GeometryNormalTexture = 5,
+    OpenGl_RT_GeometryTexCrdTexture = 6,
+    OpenGl_RT_GeometryTriangTexture = 7,
+
+    OpenGl_RT_EnvironmentMapTexture = 8,
+
+    OpenGl_RT_RaytraceMaterialTexture = 9,
+    OpenGl_RT_RaytraceLightSrcTexture = 10,
+
+    OpenGl_RT_FSAAInputTexture = 11,
+
+    OpenGl_RT_OpenGlColorTexture = 12,
+    OpenGl_RT_OpenGlDepthTexture = 13
+  };
+
+  //! Tool class for management of shader sources.
+  class ShaderSource
+  {
+  public:
+
+    //! Creates new uninitialized shader source.
+    ShaderSource()
+    {
+      //
+    }
+
+    //! Creates new shader source from specified file.
+    ShaderSource (const TCollection_AsciiString& theFileName)
+    {
+      Load (&theFileName, 1);
+    }
+
+  public:
+
+    //! Returns prefix to insert before the source.
+    const TCollection_AsciiString& Prefix() const
+    {
+      return myPrefix;
+    }
+
+    //! Sets prefix to insert before the source.
+    void SetPrefix (const TCollection_AsciiString& thePrefix)
+    {
+      myPrefix = thePrefix;
+    }
+
+    //! Returns shader source combined with prefix.
+    TCollection_AsciiString Source() const;
+
+    //! Loads shader source from specified files.
+    void Load (const TCollection_AsciiString* theFileNames, const Standard_Integer theCount);
+
+  private:
+
+    TCollection_AsciiString mySource; //!< Source string of the shader object
+    TCollection_AsciiString myPrefix; //!< Prefix to insert before the source
+
+  };
+
+  //! Default ray-tracing depth.
+  static const Standard_Integer THE_DEFAULT_NB_BOUNCES = 3;
+
+  //! Default size of traversal stack.
+  static const Standard_Integer THE_DEFAULT_STACK_SIZE = 24;
+
+  //! Compile-time ray-tracing parameters.
+  struct RaytracingParams
+  {
+    //! Actual size of traversal stack in shader program.
+    Standard_Integer StackSize;
+
+    //! Actual ray-tracing depth (number of ray bounces).
+    Standard_Integer NbBounces;
+
+    //! Sets light propagation through transparent media.
+    Standard_Boolean TransparentShadows;
+
+    //! Creates default compile-time ray-tracing parameters.
+    RaytracingParams()
+    : StackSize (THE_DEFAULT_STACK_SIZE),
+      NbBounces (THE_DEFAULT_NB_BOUNCES),
+      TransparentShadows (Standard_False)
+    {
+      //
+    }
+  };
+
+protected: //! @name methods related to ray-tracing
+
+  //! Updates 3D scene geometry for ray-tracing.
+  Standard_Boolean updateRaytraceGeometry (const RaytraceUpdateMode      theMode,
+                                           const Standard_Integer        theViewId,
+                                           const Handle(OpenGl_Context)& theGlContext);
+
+  //! Updates 3D scene light sources for ray-tracing.
+  Standard_Boolean updateRaytraceLightSources (const OpenGl_Mat4& theInvModelView, const Handle(OpenGl_Context)& theGlContext);
+
+  //! Updates environment map for ray-tracing.
+  Standard_Boolean updateRaytraceEnvironmentMap (const Handle(OpenGl_Context)& theGlContext);
+
+  //! Checks to see if the OpenGL structure is modified.
+  Standard_Boolean toUpdateStructure (const OpenGl_Structure* theStructure);
+
+  //! Adds OpenGL structure to ray-traced scene geometry.
+  Standard_Boolean addRaytraceStructure (const OpenGl_Structure*       theStructure,
+                                         const Handle(OpenGl_Context)& theGlContext);
+
+  //! Adds OpenGL groups to ray-traced scene geometry.
+  Standard_Boolean addRaytraceGroups (const OpenGl_Structure*       theStructure,
+                                      const Standard_Integer        theStructMat,
+                                      const Standard_ShortReal*     theTransform,
+                                      const Handle(OpenGl_Context)& theGlContext);
+
+  //! Creates ray-tracing material properties.
+  OpenGl_RaytraceMaterial convertMaterial (const OpenGl_AspectFace*      theAspect,
+                                           const Handle(OpenGl_Context)& theGlContext);
+
+  //! Adds OpenGL primitive array to ray-traced scene geometry.
+  OpenGl_TriangleSet* addRaytracePrimitiveArray (const OpenGl_PrimitiveArray* theArray,
+                                                 const Standard_Integer       theMatID,
+                                                 const OpenGl_Mat4*           theTrans);
+
+  //! Adds vertex indices from OpenGL primitive array to ray-traced scene geometry.
+  Standard_Boolean addRaytraceVertexIndices (OpenGl_TriangleSet&                  theSet,
+                                             const Standard_Integer               theMatID,
+                                             const Standard_Integer               theCount,
+                                             const Standard_Integer               theOffset,
+                                             const OpenGl_PrimitiveArray&         theArray);
+
+  //! Adds OpenGL triangle array to ray-traced scene geometry.
+  Standard_Boolean addRaytraceTriangleArray (OpenGl_TriangleSet&                  theSet,
+                                             const Standard_Integer               theMatID,
+                                             const Standard_Integer               theCount,
+                                             const Standard_Integer               theOffset,
+                                             const Handle(Graphic3d_IndexBuffer)& theIndices);
+
+  //! Adds OpenGL triangle fan array to ray-traced scene geometry.
+  Standard_Boolean addRaytraceTriangleFanArray (OpenGl_TriangleSet&                  theSet,
+                                                const Standard_Integer               theMatID,
+                                                const Standard_Integer               theCount,
+                                                const Standard_Integer               theOffset,
+                                                const Handle(Graphic3d_IndexBuffer)& theIndices);
+
+  //! Adds OpenGL triangle strip array to ray-traced scene geometry.
+  Standard_Boolean addRaytraceTriangleStripArray (OpenGl_TriangleSet&                  theSet,
+                                                  const Standard_Integer               theMatID,
+                                                  const Standard_Integer               theCount,
+                                                  const Standard_Integer               theOffset,
+                                                  const Handle(Graphic3d_IndexBuffer)& theIndices);
+
+  //! Adds OpenGL quadrangle array to ray-traced scene geometry.
+  Standard_Boolean addRaytraceQuadrangleArray (OpenGl_TriangleSet&                  theSet,
+                                               const Standard_Integer               theMatID,
+                                               const Standard_Integer               theCount,
+                                               const Standard_Integer               theOffset,
+                                               const Handle(Graphic3d_IndexBuffer)& theIndices);
+
+  //! Adds OpenGL quadrangle strip array to ray-traced scene geometry.
+  Standard_Boolean addRaytraceQuadrangleStripArray (OpenGl_TriangleSet&                  theSet,
+                                                    const Standard_Integer               theMatID,
+                                                    const Standard_Integer               theCount,
+                                                    const Standard_Integer               theOffset,
+                                                    const Handle(Graphic3d_IndexBuffer)& theIndices);
+
+  //! Adds OpenGL polygon array to ray-traced scene geometry.
+  Standard_Boolean addRaytracePolygonArray (OpenGl_TriangleSet&                  theSet,
+                                            const Standard_Integer               theMatID,
+                                            const Standard_Integer               theCount,
+                                            const Standard_Integer               theOffset,
+                                            const Handle(Graphic3d_IndexBuffer)& theIndices);
+
+  //! Uploads ray-trace data to the GPU.
+  Standard_Boolean uploadRaytraceData (const Handle(OpenGl_Context)& theGlContext);
+
+  //! Generates shader prefix based on current ray-tracing options.
+  TCollection_AsciiString generateShaderPrefix (const Handle(OpenGl_Context)& theGlContext) const;
+
+  //! Performs safe exit when shaders initialization fails.
+  Standard_Boolean safeFailBack (const TCollection_ExtendedString& theMessage,
+                                 const Handle(OpenGl_Context)&     theGlContext);
+
+  //! Loads and compiles shader object from specified source.
+  Handle(OpenGl_ShaderObject) initShader (const GLenum                  theType,
+                                          const ShaderSource&           theSource,
+                                          const Handle(OpenGl_Context)& theGlContext);
+
+  //! Initializes OpenGL/GLSL shader programs.
+  Standard_Boolean initRaytraceResources (const Graphic3d_CView&        theCView,
+                                          const Handle(OpenGl_Context)& theGlContext);
+
+  //! Releases OpenGL/GLSL shader programs.
+  void releaseRaytraceResources (const Handle(OpenGl_Context)& theGlContext);
+
+  //! Resizes OpenGL frame buffers.
+  Standard_Boolean resizeRaytraceBuffers (const Standard_Integer        theSizeX,
+                                          const Standard_Integer        theSizeY,
+                                          const Handle(OpenGl_Context)& theGlContext);
+
+  //! Generates viewing rays for corners of screen quad.
+  void updateCamera (const OpenGl_Mat4& theOrientation,
+                     const OpenGl_Mat4& theViewMapping,
+                     OpenGl_Vec3*       theOrigins,
+                     OpenGl_Vec3*       theDirects,
+                     OpenGl_Mat4&       theUnView);
+
+  //! Binds ray-trace textures to corresponding texture units.
+  void bindRaytraceTextures (const Handle(OpenGl_Context)& theGlContext);
+
+  //! Unbinds ray-trace textures from corresponding texture unit.
+  void unbindRaytraceTextures (const Handle(OpenGl_Context)& theGlContext);
+
+  //! Sets uniform state for the given ray-tracing shader program.
+  Standard_Boolean setUniformState (const Graphic3d_CView&        theCView,
+                                    const OpenGl_Vec3*            theOrigins,
+                                    const OpenGl_Vec3*            theDirects,
+                                    const OpenGl_Mat4&            theUnviewMat,
+                                    const Standard_Integer        theProgramId,
+                                    const Handle(OpenGl_Context)& theGlContext);
+
+  //! Runs ray-tracing shader programs.
+  Standard_Boolean runRaytraceShaders (const Graphic3d_CView&        theCView,
+                                       const Standard_Integer        theSizeX,
+                                       const Standard_Integer        theSizeY,
+                                       const OpenGl_Vec3*            theOrigins,
+                                       const OpenGl_Vec3*            theDirects,
+                                       const OpenGl_Mat4&            theUnviewMat,
+                                       OpenGl_FrameBuffer*           theOutputFBO,
+                                       const Handle(OpenGl_Context)& theGlContext);
+
+  //! Redraws the window using OpenGL/GLSL ray-tracing.
+  Standard_Boolean raytrace (const Graphic3d_CView&        theCView,
+                             const Standard_Integer        theSizeX,
+                             const Standard_Integer        theSizeY,
+                             OpenGl_FrameBuffer*           theOutputFBO,
+                             const Handle(OpenGl_Context)& theGlContext);
+
+protected: //! @name fields related to ray-tracing
+
+  //! Result of shaders initialization.
+  RaytraceInitStatus myRaytraceInitStatus;
+
+  //! Is geometry data valid?
+  Standard_Boolean myIsRaytraceDataValid;
+
+  //! Warning about missing extension GL_ARB_bindless_texture has been displayed?
+  Standard_Boolean myIsRaytraceWarnTextures;
+
+  //! 3D scene geometry data for ray-tracing.
+  OpenGl_RaytraceGeometry myRaytraceGeometry;
+
+  //! Compile-time ray-tracing parameters.
+  RaytracingParams myRaytraceParameters;
+
+  //! Radius of bounding sphere of the scene.
+  Standard_ShortReal myRaytraceSceneRadius;
+  //! Scene epsilon to prevent self-intersections.
+  Standard_ShortReal myRaytraceSceneEpsilon;
+
+  //! OpenGL/GLSL source of ray-tracing fragment shader.
+  ShaderSource myRaytraceShaderSource;
+  //! OpenGL/GLSL source of adaptive-AA fragment shader.
+  ShaderSource myPostFSAAShaderSource;
+
+  //! OpenGL/GLSL ray-tracing fragment shader.
+  Handle(OpenGl_ShaderObject) myRaytraceShader;
+  //! OpenGL/GLSL adaptive-AA fragment shader.
+  Handle(OpenGl_ShaderObject) myPostFSAAShader;
+
+  //! OpenGL/GLSL ray-tracing shader program.
+  Handle(OpenGl_ShaderProgram) myRaytraceProgram;
+  //! OpenGL/GLSL adaptive-AA shader program.
+  Handle(OpenGl_ShaderProgram) myPostFSAAProgram;
+
+  //! Texture buffer of data records of bottom-level BVH nodes.
+  Handle(OpenGl_TextureBufferArb) mySceneNodeInfoTexture;
+  //! Texture buffer of minimum points of bottom-level BVH nodes.
+  Handle(OpenGl_TextureBufferArb) mySceneMinPointTexture;
+  //! Texture buffer of maximum points of bottom-level BVH nodes.
+  Handle(OpenGl_TextureBufferArb) mySceneMaxPointTexture;
+  //! Texture buffer of transformations of high-level BVH nodes.
+  Handle(OpenGl_TextureBufferArb) mySceneTransformTexture;
+
+  //! Texture buffer of vertex coords.
+  Handle(OpenGl_TextureBufferArb) myGeometryVertexTexture;
+  //! Texture buffer of vertex normals.
+  Handle(OpenGl_TextureBufferArb) myGeometryNormalTexture;
+  //! Texture buffer of vertex UV coords.
+  Handle(OpenGl_TextureBufferArb) myGeometryTexCrdTexture;
+  //! Texture buffer of triangle indices.
+  Handle(OpenGl_TextureBufferArb) myGeometryTriangTexture;
+
+  //! Texture buffer of material properties.
+  Handle(OpenGl_TextureBufferArb) myRaytraceMaterialTexture;
+  //! Texture buffer of light source properties.
+  Handle(OpenGl_TextureBufferArb) myRaytraceLightSrcTexture;
+
+  //! 1st framebuffer (FBO) to perform adaptive FSAA.
+  Handle(OpenGl_FrameBuffer) myRaytraceFBO1;
+  //! 2nd framebuffer (FBO) to perform adaptive FSAA.
+  Handle(OpenGl_FrameBuffer) myRaytraceFBO2;
+  //! Framebuffer (FBO) for preliminary OpenGL output.
+  Handle(OpenGl_FrameBuffer) myOpenGlFBO;
+
+  //! Vertex buffer (VBO) for drawing dummy quad.
+  OpenGl_VertexBuffer myRaytraceScreenQuad;
+
+  //! Cached locations of frequently used uniform variables.
+  Standard_Integer myUniformLocations[2][OpenGl_RT_NbVariables];
+
+  //! State of OpenGL structures reflected to ray-tracing.
+  std::map<const OpenGl_Structure*, Standard_Size> myStructureStates;
+
+  //! PrimitiveArray to TriangleSet map for scene partial update.
+  std::map<Standard_Size, OpenGl_TriangleSet*> myArrayToTrianglesMap;
+
+  //! Graphical ray-tracing filter to filter out all raytracable structures.
+  Handle(OpenGl_RaytraceFilter) myRaytraceFilter;
+
+  //! Marks if environment map should be updated.
+  Standard_Boolean myToUpdateEnvironmentMap;
+
+  //! State of OpenGL layer list.
+  Standard_Size myLayersModificationStatus;
+
 public:
 
   DEFINE_STANDARD_ALLOC
index 2e79d4d..24b374a 100644 (file)
@@ -38,6 +38,7 @@
 #include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Structure.hxx>
+#include <OpenGl_ArbFBO.hxx>
 
 #define EPSI 0.0001
 
@@ -241,7 +242,7 @@ void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
   aCtx->ProjectionState.Pop();
   aCtx->ApplyProjectionMatrix();
 
-  if (theWorkspace->UseZBuffer() && theWorkspace->ToRedrawGL())
+  if (theWorkspace->UseZBuffer())
   {
     aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
   }
@@ -340,8 +341,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   // ====================================
 
   // Render background
-  if (theWorkspace->ToRedrawGL()
-  && !theToDrawImmediate)
+  if (!theToDrawImmediate)
   {
     DrawBackground (theWorkspace);
   }
@@ -456,7 +456,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   {
     // single-pass monographic rendering
     // redraw scene with normal orientation and projection
-    RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate);
+    RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
   }
   else
   {
@@ -469,7 +469,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     aContext->ApplyProjectionMatrix();
 
     // redraw left Eye
-    RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate);
+    RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
 
     // reset depth buffer of first rendering pass
     if (theWorkspace->UseDepthTest())
@@ -483,7 +483,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     aContext->ApplyProjectionMatrix();
 
     // redraw right Eye
-    RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate);
+    RedrawScene (thePrintContext, theWorkspace, theCView, theToDrawImmediate);
 
     // switch back to monographic rendering
     aContext->SetDrawBufferMono();
@@ -513,8 +513,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
   }
 
   // Render trihedron
-  if (theWorkspace->ToRedrawGL()
-  && !theToDrawImmediate)
+  if (!theToDrawImmediate)
   {
     RedrawTrihedron (theWorkspace);
 
@@ -587,6 +586,7 @@ void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
 
 //ExecuteViewDisplay
 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& theWorkspace,
+                                 const Graphic3d_CView&          theCView,
                                  const Standard_Boolean          theToDrawImmediate)
 {
   if ( myZLayers.NbStructures() <= 0 )
@@ -628,7 +628,109 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& theWorkspace,
     }
   }
 
-  myZLayers.Render (theWorkspace, theToDrawImmediate);
+  Standard_Boolean toRenderGL = theToDrawImmediate ||
+    theCView.RenderParams.Method != Graphic3d_RM_RAYTRACING || myRaytraceInitStatus == OpenGl_RT_FAIL;
+
+  if (!toRenderGL)
+  {
+    toRenderGL = !initRaytraceResources (theCView, aCtx) ||
+      !updateRaytraceGeometry (OpenGl_GUM_CHECK, theWorkspace->ActiveViewId(), aCtx);
+
+    OpenGl_FrameBuffer* anOutputFBO = NULL;
+
+    if (theWorkspace->ResultFBO()->IsValid())
+    {
+      anOutputFBO = theWorkspace->ResultFBO().operator->();
+    }
+    else if (theCView.ptrFBO != NULL)
+    {
+      anOutputFBO = (OpenGl_FrameBuffer* )theCView.ptrFBO;
+    }
+    else
+    {
+      //toRenderGL = Standard_True; // failed to get valid FBO
+    }
+
+    if (!toRenderGL && myIsRaytraceDataValid)
+    {
+      const Standard_Integer aSizeX = anOutputFBO != NULL ?
+        anOutputFBO->GetVPSizeX() : theWorkspace->Width();
+      const Standard_Integer aSizeY = anOutputFBO != NULL ?
+        anOutputFBO->GetVPSizeY() : theWorkspace->Height();
+
+      if (myOpenGlFBO.IsNull())
+        myOpenGlFBO = new OpenGl_FrameBuffer;
+
+      if (myOpenGlFBO->GetVPSizeX() != aSizeX
+       || myOpenGlFBO->GetVPSizeY() != aSizeY)
+      {
+        myOpenGlFBO->Init (aCtx, aSizeX, aSizeY);
+      }
+
+      if (myRaytraceFilter.IsNull())
+        myRaytraceFilter = new OpenGl_RaytraceFilter;
+
+      myRaytraceFilter->SetPrevRenderFilter (theWorkspace->GetRenderFilter());
+
+      if (anOutputFBO != NULL)
+        anOutputFBO->UnbindBuffer (aCtx);
+
+      // Prepare preliminary OpenGL output
+      if (aCtx->arbFBOBlit != NULL)
+      {
+        // Render bottom OSD layer
+        myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Bottom);
+
+        theWorkspace->SetRenderFilter (myRaytraceFilter);
+        {
+          if (anOutputFBO != NULL)
+          {
+            anOutputFBO->BindReadBuffer (aCtx);
+          }
+          else
+          {
+            aCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
+          }
+
+          myOpenGlFBO->BindDrawBuffer (aCtx);
+
+          aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aSizeX, aSizeY,
+                                               0, 0, aSizeX, aSizeY,
+                                               GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+                                               GL_NEAREST);
+
+          // Render non-polygonal elements in default layer
+          myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Default);
+        }
+        theWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
+      }
+
+      if (anOutputFBO != NULL)
+      {
+        anOutputFBO->BindBuffer (aCtx);
+      }
+      else
+      {
+        aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0);
+      }
+
+      // Ray-tracing polygonal primitive arrays
+      raytrace (theCView, aSizeX, aSizeY, anOutputFBO, aCtx);
+
+      // Render upper (top and topmost) OpenGL layers
+      myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_Upper);
+    }
+  }
+
+  // Redraw 3D scene using OpenGL in standard
+  // mode or in case of ray-tracing failure
+  if (toRenderGL)
+  {
+    myZLayers.Render (theWorkspace, theToDrawImmediate, OpenGl_LF_All);
+
+    // Set flag that scene was redrawn by standard pipeline
+    theCView.WasRedrawnGL = Standard_True;
+  }
 }
 
 /*----------------------------------------------------------------------*/
@@ -971,6 +1073,7 @@ void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
 
 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
                                const Handle(OpenGl_Workspace)&      theWorkspace,
+                               const Graphic3d_CView&               theCView,
                                const Standard_Boolean               theToDrawImmediate)
 {
   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
@@ -1103,14 +1206,14 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
       theWorkspace->DisableTexture();
       // Render the view
-      RenderStructs (theWorkspace, theToDrawImmediate);
+      RenderStructs (theWorkspace, theCView, theToDrawImmediate);
       break;
 
     case Visual3d_TOD_ENVIRONMENT:
       theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
       theWorkspace->EnableTexture (myTextureEnv);
       // Render the view
-      RenderStructs (theWorkspace, theToDrawImmediate);
+      RenderStructs (theWorkspace, theCView, theToDrawImmediate);
       theWorkspace->DisableTexture();
       break;
 
@@ -1118,7 +1221,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
       // First pass
       theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
       // Render the view
-      RenderStructs (theWorkspace, theToDrawImmediate);
+      RenderStructs (theWorkspace, theCView, theToDrawImmediate);
       theWorkspace->DisableTexture();
 
       // Second pass
@@ -1151,7 +1254,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
         theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
 
         // Render the view
-        RenderStructs (theWorkspace, theToDrawImmediate);
+        RenderStructs (theWorkspace, theCView, theToDrawImmediate);
         theWorkspace->DisableTexture();
 
         // Restore properties back
similarity index 55%
rename from src/OpenGl/OpenGl_Workspace_Raytrace.cxx
rename to src/OpenGl/OpenGl_View_Raytrace.cxx
index 71de483..7cde775 100644 (file)
@@ -1,6 +1,6 @@
-// Created on: 2013-08-27
+// Created on: 2015-02-20
 // Created by: Denis BOGOLEPOV
-// Copyright (c) 2013 OPEN CASCADE SAS
+// Copyright (c) 2015 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <OpenGl_Workspace.hxx>
-
 #include <Graphic3d_TextureParams.hxx>
+
 #include <OpenGl_FrameBuffer.hxx>
 #include <OpenGl_PrimitiveArray.hxx>
 #include <OpenGl_VertexBuffer.hxx>
 #include <OpenGl_View.hxx>
-#include <OSD_File.hxx>
+
 #include <OSD_Protection.hxx>
+#include <OSD_File.hxx>
 
 using namespace OpenGl_Raytrace;
 
@@ -34,26 +34,25 @@ using namespace OpenGl_Raytrace;
 
 // =======================================================================
 // function : UpdateRaytraceGeometry
-// purpose  : Updates 3D scene geometry for ray tracing
+// purpose  : Updates 3D scene geometry for ray-tracing
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMode)
+Standard_Boolean OpenGl_View::updateRaytraceGeometry (const RaytraceUpdateMode      theMode,
+                                                      const Standard_Integer        theViewId,
+                                                      const Handle(OpenGl_Context)& theGlContext)
 {
-  if (myView.IsNull())
-    return Standard_False;
-
-  // Note: In 'check' mode (OpenGl_GUM_CHECK) the scene geometry is analyzed for modifications
-  // This is light-weight procedure performed for each frame
-
+  // In 'check' mode (OpenGl_GUM_CHECK) the scene geometry is analyzed for
+  // modifications. This is light-weight procedure performed on each frame
   if (theMode == OpenGl_GUM_CHECK)
   {
-     if (myLayersModificationStatus != myView->LayerList().ModificationState())
-     {
-        return UpdateRaytraceGeometry (OpenGl_GUM_PREPARE);
-     }
-  } 
+    if (myLayersModificationStatus != myZLayers.ModificationState())
+    {
+      return updateRaytraceGeometry (OpenGl_GUM_PREPARE, theViewId, theGlContext);
+    }
+  }
   else if (theMode == OpenGl_GUM_PREPARE)
   {
     myRaytraceGeometry.ClearMaterials();
+
     myArrayToTrianglesMap.clear();
 
     myIsRaytraceDataValid = Standard_False;
@@ -64,18 +63,16 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
   // hash map of structures
   std::set<const OpenGl_Structure*> anElements;
 
-  // Set of all currently visible and "raytracable" primitive arrays.
+  // Set to store all currently visible OpenGL primitive arrays
+  // applicable for ray-tracing
   std::set<Standard_Size> anArrayIDs;
 
-  const OpenGl_LayerList& aList = myView->LayerList();
+  const OpenGl_Layer& aLayer = myZLayers.Layer (Graphic3d_ZLayerId_Default);
 
-  for (OpenGl_SequenceOfLayers::Iterator anLayerIt (aList.Layers()); anLayerIt.More(); anLayerIt.Next())
+  if (aLayer.NbStructures() != 0)
   {
-    const OpenGl_Layer& aLayer = anLayerIt.Value();
-    if (aLayer.NbStructures() == 0)
-      continue;
-
     const OpenGl_ArrayOfStructure& aStructArray = aLayer.ArrayOfStructures();
+
     for (Standard_Integer anIndex = 0; anIndex < aStructArray.Length(); ++anIndex)
     {
       for (OpenGl_SequenceOfStructure::Iterator aStructIt (aStructArray (anIndex)); aStructIt.More(); aStructIt.Next())
@@ -84,45 +81,46 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
 
         if (theMode == OpenGl_GUM_CHECK)
         {
-          if (CheckRaytraceStructure (aStructure))
+          if (toUpdateStructure (aStructure))
           {
-            return UpdateRaytraceGeometry (OpenGl_GUM_PREPARE);
+            return updateRaytraceGeometry (OpenGl_GUM_PREPARE, theViewId, theGlContext);
           }
         }
         else if (theMode == OpenGl_GUM_PREPARE)
         {
-          if (!aStructure->IsRaytracable()
-           || !aStructure->IsVisible())
+          if (!aStructure->IsRaytracable() || !aStructure->IsVisible())
           {
             continue;
           }
-          else if (!aStructure->ViewAffinity.IsNull()
-                && !aStructure->ViewAffinity->IsVisible (myViewId))
+          else if (!aStructure->ViewAffinity.IsNull() && !aStructure->ViewAffinity->IsVisible (theViewId))
           {
             continue;
           }
 
           for (OpenGl_Structure::GroupIterator aGroupIter (aStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
           {
-            // OpenGL elements from group (extract primitives arrays)
+            // Extract OpenGL elements from the group (primitives arrays)
             for (const OpenGl_ElementNode* aNode = aGroupIter.Value()->FirstNode(); aNode != NULL; aNode = aNode->next)
             {
               OpenGl_PrimitiveArray* aPrimArray = dynamic_cast<OpenGl_PrimitiveArray*> (aNode->elem);
 
               if (aPrimArray != NULL)
               {
-                // Collect all primitive arrays in scene.
                 anArrayIDs.insert (aPrimArray->GetUID());
               }
             }
           }
         }
-        else if (theMode == OpenGl_GUM_UPDATE)
+        else if (theMode == OpenGl_GUM_REBUILD)
         {
           if (!aStructure->IsRaytracable())
+          {
             continue;
-
-          AddRaytraceStructure (aStructure, anElements);
+          }
+          else if (addRaytraceStructure (aStructure, theGlContext))
+          {
+            anElements.insert (aStructure); // structure was processed
+          }
         }
       }
     }
@@ -132,19 +130,21 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
   {
     BVH_ObjectSet<Standard_ShortReal, 3>::BVH_ObjectList anUnchangedObjects;
 
-    // Leave only unchanged objects in myRaytraceGeometry so only their transforms and materials will be updated
-    // Objects which not in myArrayToTrianglesMap will be built from scratch.
-    for (Standard_Integer anObjectIdx = 0; anObjectIdx < myRaytraceGeometry.Objects().Size(); ++anObjectIdx)
+    // Filter out unchanged objects so only their transformations and materials
+    // will be updated (and newly added objects will be processed from scratch)
+    for (Standard_Integer anObjIdx = 0; anObjIdx < myRaytraceGeometry.Size(); ++anObjIdx)
     {
       OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (
-        myRaytraceGeometry.Objects().ChangeValue (anObjectIdx).operator->());
+        myRaytraceGeometry.Objects().ChangeValue (anObjIdx).operator->());
 
-      // If primitive array of object not in "anArrays" set then it was hided or deleted.
-      // If primitive array present in "anArrays" set but we don't have associated object yet, then
-      // the object is new and still has to be built.
-      if ((aTriangleSet != NULL) && ((anArrayIDs.find (aTriangleSet->AssociatedPArrayID())) != anArrayIDs.end()))
+      if (aTriangleSet == NULL)
       {
-        anUnchangedObjects.Append (myRaytraceGeometry.Objects().Value (anObjectIdx));
+        continue;
+      }
+
+      if (anArrayIDs.find (aTriangleSet->AssociatedPArrayID()) != anArrayIDs.end())
+      {
+        anUnchangedObjects.Append (myRaytraceGeometry.Objects().Value (anObjIdx));
 
         myArrayToTrianglesMap[aTriangleSet->AssociatedPArrayID()] = aTriangleSet;
       }
@@ -152,12 +152,11 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
 
     myRaytraceGeometry.Objects() = anUnchangedObjects;
 
-    return UpdateRaytraceGeometry (OpenGl_GUM_UPDATE);
+    return updateRaytraceGeometry (OpenGl_GUM_REBUILD, theViewId, theGlContext);
   }
-
-  if (theMode == OpenGl_GUM_UPDATE)
+  else if (theMode == OpenGl_GUM_REBUILD)
   {
-    // Actualize the hash map of structures -- remove out-of-date records
+    // Actualize the hash map of structures - remove out-of-date records
     std::map<const OpenGl_Structure*, Standard_Size>::iterator anIter = myStructureStates.begin();
 
     while (anIter != myStructureStates.end())
@@ -173,61 +172,58 @@ Standard_Boolean OpenGl_Workspace::UpdateRaytraceGeometry (GeomUpdateMode theMod
     }
 
     // Actualize OpenGL layer list state
-    myLayersModificationStatus = myView->LayerList().ModificationState();
+    myLayersModificationStatus = myZLayers.ModificationState();
 
-    // Rebuild bottom-level and high-level BVHs
+    // Rebuild two-level acceleration structure
     myRaytraceGeometry.ProcessAcceleration();
 
-    const Standard_ShortReal aMinRadius = Max (fabs (myRaytraceGeometry.Box().CornerMin().x()), Max (
-      fabs (myRaytraceGeometry.Box().CornerMin().y()), fabs (myRaytraceGeometry.Box().CornerMin().z())));
-    const Standard_ShortReal aMaxRadius = Max (fabs (myRaytraceGeometry.Box().CornerMax().x()), Max (
-      fabs (myRaytraceGeometry.Box().CornerMax().y()), fabs (myRaytraceGeometry.Box().CornerMax().z())));
-
-    myRaytraceSceneRadius = 2.f /* scale factor */ * Max (aMinRadius, aMaxRadius);
+    myRaytraceSceneRadius = 2.f /* scale factor */ * std::max (
+      myRaytraceGeometry.Box().CornerMin().cwiseAbs().maxComp(),
+      myRaytraceGeometry.Box().CornerMax().cwiseAbs().maxComp());
 
     const BVH_Vec3f aSize = myRaytraceGeometry.Box().Size();
 
-    myRaytraceSceneEpsilon = Max (1e-6f, 1e-4f * sqrtf (
-      aSize.x() * aSize.x() + aSize.y() * aSize.y() + aSize.z() * aSize.z()));
+    myRaytraceSceneEpsilon = Max (1.0e-6f, 1.0e-4f * aSize.Modulus());
 
-    return UploadRaytraceData();
+    return uploadRaytraceData (theGlContext);
   }
 
   return Standard_True;
 }
 
 // =======================================================================
-// function : CheckRaytraceStructure
+// function : ToUpdateStructure
 // purpose  : Checks to see if the structure is modified
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::CheckRaytraceStructure (const OpenGl_Structure* theStructure)
+Standard_Boolean OpenGl_View::toUpdateStructure (const OpenGl_Structure* theStructure)
 {
   if (!theStructure->IsRaytracable())
   {
-    // Checks to see if all ray-tracable elements were
-    // removed from the structure
     if (theStructure->ModificationState() > 0)
     {
       theStructure->ResetModificationState();
-      return Standard_True;
+
+      return Standard_True; // ray-trace element was removed - need to rebuild
     }
 
-    return Standard_False;
+    return Standard_False; // did not contain ray-trace elements
   }
 
   std::map<const OpenGl_Structure*, Standard_Size>::iterator aStructState = myStructureStates.find (theStructure);
 
   if (aStructState != myStructureStates.end())
+  {
     return aStructState->second != theStructure->ModificationState();
+  }
 
   return Standard_True;
 }
 
 // =======================================================================
-// function : BuildTexTransform
+// function : BuildTextureTransform
 // purpose  : Constructs texture transformation matrix
 // =======================================================================
-void BuildTexTransform (const Handle(Graphic3d_TextureParams)& theParams, BVH_Mat4f& theMatrix)
+void BuildTextureTransform (const Handle(Graphic3d_TextureParams)& theParams, BVH_Mat4f& theMatrix)
 {
   theMatrix.InitIdentity();
 
@@ -272,28 +268,27 @@ void BuildTexTransform (const Handle(Graphic3d_TextureParams)& theParams, BVH_Ma
 }
 
 // =======================================================================
-// function : CreateMaterial
+// function : ConvertMaterial
 // purpose  : Creates ray-tracing material properties
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::CreateMaterial (const OpenGl_AspectFace* theAspect, OpenGl_RaytraceMaterial& theMaterial)
+OpenGl_RaytraceMaterial OpenGl_View::convertMaterial (const OpenGl_AspectFace*      theAspect,
+                                                      const Handle(OpenGl_Context)& theGlContext)
 {
-  const OPENGL_SURF_PROP& aProperties = theAspect->IntFront();
-
-  const Standard_ShortReal* aSrcAmbient =
-    aProperties.isphysic ? aProperties.ambcol.rgb : aProperties.matcol.rgb;
+  OpenGl_RaytraceMaterial theMaterial;
 
-  theMaterial.Ambient = BVH_Vec4f (aSrcAmbient[0] * aProperties.amb,
-                                   aSrcAmbient[1] * aProperties.amb,
-                                   aSrcAmbient[2] * aProperties.amb,
-                                   1.f);
+  const OPENGL_SURF_PROP& aProperties = theAspect->IntFront();
 
-  const Standard_ShortReal* aSrcDiffuse =
-    aProperties.isphysic ? aProperties.difcol.rgb : aProperties.matcol.rgb;
+  theMaterial.Ambient = BVH_Vec4f (
+    (aProperties.isphysic ? aProperties.ambcol.rgb[0] : aProperties.matcol.rgb[0]) * aProperties.amb,
+    (aProperties.isphysic ? aProperties.ambcol.rgb[1] : aProperties.matcol.rgb[1]) * aProperties.amb,
+    (aProperties.isphysic ? aProperties.ambcol.rgb[2] : aProperties.matcol.rgb[2]) * aProperties.amb,
+    1.f);
 
-  theMaterial.Diffuse = BVH_Vec4f (aSrcDiffuse[0] * aProperties.diff,
-                                   aSrcDiffuse[1] * aProperties.diff,
-                                   aSrcDiffuse[2] * aProperties.diff,
-                                   -1.f /* no texture */);
+  theMaterial.Diffuse = BVH_Vec4f (
+    (aProperties.isphysic ? aProperties.difcol.rgb[0] : aProperties.matcol.rgb[0]) * aProperties.diff,
+    (aProperties.isphysic ? aProperties.difcol.rgb[1] : aProperties.matcol.rgb[1]) * aProperties.diff,
+    (aProperties.isphysic ? aProperties.difcol.rgb[2] : aProperties.matcol.rgb[2]) * aProperties.diff,
+    -1.f /* no texture */);
 
   theMaterial.Specular = BVH_Vec4f (
     (aProperties.isphysic ? aProperties.speccol.rgb[0] : 1.f) * aProperties.spec,
@@ -301,17 +296,13 @@ Standard_Boolean OpenGl_Workspace::CreateMaterial (const OpenGl_AspectFace* theA
     (aProperties.isphysic ? aProperties.speccol.rgb[2] : 1.f) * aProperties.spec,
     aProperties.shine);
 
-  const Standard_ShortReal* aSrcEmission =
-    aProperties.isphysic ? aProperties.emscol.rgb : aProperties.matcol.rgb;
-
-  theMaterial.Emission = BVH_Vec4f (aSrcEmission[0] * aProperties.emsv,
-                                    aSrcEmission[1] * aProperties.emsv,
-                                    aSrcEmission[2] * aProperties.emsv,
-                                    1.f);
+  theMaterial.Emission = BVH_Vec4f (
+    (aProperties.isphysic ? aProperties.emscol.rgb[0] : aProperties.matcol.rgb[0]) * aProperties.emsv,
+    (aProperties.isphysic ? aProperties.emscol.rgb[1] : aProperties.matcol.rgb[1]) * aProperties.emsv,
+    (aProperties.isphysic ? aProperties.emscol.rgb[2] : aProperties.matcol.rgb[2]) * aProperties.emsv,
+    1.f);
 
-  // Note: Here we use sub-linear transparency function
-  // to produce realistic-looking transparency effect
-  theMaterial.Transparency = BVH_Vec4f (powf (aProperties.trans, 0.75f),
+  theMaterial.Transparency = BVH_Vec4f (aProperties.trans,
                                         1.f - aProperties.trans,
                                         aProperties.index == 0 ? 1.f : aProperties.index,
                                         aProperties.index == 0 ? 1.f : 1.f / aProperties.index);
@@ -330,36 +321,41 @@ Standard_Boolean OpenGl_Workspace::CreateMaterial (const OpenGl_AspectFace* theA
 
   if (theAspect->DoTextureMap())
   {
-    if (myGlContext->arbTexBindless != NULL)
+    if (theGlContext->arbTexBindless != NULL)
     {
-      BuildTexTransform (theAspect->TextureParams(), theMaterial.TextureTransform);
+      BuildTextureTransform (theAspect->TextureParams(), theMaterial.TextureTransform);
+
+      // write texture ID in the w-component
       theMaterial.Diffuse.w() = static_cast<Standard_ShortReal> (
-        myRaytraceGeometry.AddTexture (theAspect->TextureRes (myGlContext)));
+        myRaytraceGeometry.AddTexture (theAspect->TextureRes (theGlContext)));
     }
     else if (!myIsRaytraceWarnTextures)
     {
-      myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-                                GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
-                                "Warning: texturing in Ray-Trace requires GL_ARB_bindless_texture extension which is missing. "
-                                "Textures will be ignored.");
+      const TCollection_ExtendedString aWarnMessage =
+        "Warning: texturing in Ray-Trace requires GL_ARB_bindless_texture extension which is missing. "
+        "Please try to update graphics card driver. At the moment textures will be ignored.";
+
+      theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+        GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, aWarnMessage);
+
       myIsRaytraceWarnTextures = Standard_True;
     }
   }
 
-  return Standard_True;
+  return theMaterial;
 }
 
 // =======================================================================
 // function : AddRaytraceStructure
 // purpose  : Adds OpenGL structure to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure* theStructure, std::set<const OpenGl_Structure*>& theElements)
+Standard_Boolean OpenGl_View::addRaytraceStructure (const OpenGl_Structure*       theStructure,
+                                                    const Handle(OpenGl_Context)& theGlContext)
 {
-  theElements.insert (theStructure);
-
   if (!theStructure->IsVisible())
   {
     myStructureStates[theStructure] = theStructure->ModificationState();
+
     return Standard_True;
   }
 
@@ -370,17 +366,15 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure*
   {
     aStructMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
 
-    OpenGl_RaytraceMaterial aStructMaterial;
-    CreateMaterial (theStructure->AspectFace(), aStructMaterial);
+    OpenGl_RaytraceMaterial aStructMaterial = convertMaterial (theStructure->AspectFace(), theGlContext);
 
     myRaytraceGeometry.Materials.push_back (aStructMaterial);
   }
 
-  Standard_ShortReal  aStructTransformArr[16];
-  Standard_ShortReal* aStructTransform = NULL;
+  Standard_ShortReal aStructTransform[16];
+
   if (theStructure->Transformation()->mat != NULL)
   {
-    aStructTransform = aStructTransformArr;
     for (Standard_Integer i = 0; i < 4; ++i)
     {
       for (Standard_Integer j = 0; j < 4; ++j)
@@ -390,26 +384,32 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure*
     }
   }
 
-  AddRaytraceGroups (theStructure, aStructMatID, aStructTransform);
+  Standard_Boolean aResult = addRaytraceGroups (theStructure, aStructMatID,
+    theStructure->Transformation()->mat ? aStructTransform : NULL, theGlContext);
 
   // Process all connected OpenGL structures
   for (OpenGl_ListOfStructure::Iterator anIts (theStructure->ConnectedStructures()); anIts.More(); anIts.Next())
   {
     if (anIts.Value()->IsRaytracable())
-      AddRaytraceGroups (anIts.Value(), aStructMatID, aStructTransform);
+    {
+      aResult &= addRaytraceGroups (anIts.Value(), aStructMatID,
+        theStructure->Transformation()->mat ? aStructTransform : NULL, theGlContext);
+    }
   }
 
   myStructureStates[theStructure] = theStructure->ModificationState();
-  return Standard_True;
+
+  return aResult;
 }
 
 // =======================================================================
 // function : AddRaytraceGroups
 // purpose  : Adds OpenGL groups to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceGroups (const OpenGl_Structure*   theStructure,
-                                                      const Standard_Integer    theStructMatId,
-                                                      const Standard_ShortReal* theTransform)
+Standard_Boolean OpenGl_View::addRaytraceGroups (const OpenGl_Structure*       theStructure,
+                                                 const Standard_Integer        theStructMat,
+                                                 const Standard_ShortReal*     theTransform,
+                                                 const Handle(OpenGl_Context)& theGlContext)
 {
   for (OpenGl_Structure::GroupIterator aGroupIter (theStructure->DrawGroups()); aGroupIter.More(); aGroupIter.Next())
   {
@@ -419,14 +419,13 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceGroups (const OpenGl_Structure*
     {
       aGroupMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
 
-      OpenGl_RaytraceMaterial aGroupMaterial;
-      CreateMaterial (aGroupIter.Value()->AspectFace(), aGroupMaterial);
+      OpenGl_RaytraceMaterial aGroupMaterial = convertMaterial (
+        aGroupIter.Value()->AspectFace(), theGlContext);
 
       myRaytraceGeometry.Materials.push_back (aGroupMaterial);
     }
 
-    Standard_Integer aMatID = aGroupMatID < 0 ? theStructMatId : aGroupMatID;
-
+    Standard_Integer aMatID = aGroupMatID < 0 ? theStructMat : aGroupMatID;
     if (aMatID < 0)
     {
       aMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
@@ -438,12 +437,12 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceGroups (const OpenGl_Structure*
     for (const OpenGl_ElementNode* aNode = aGroupIter.Value()->FirstNode(); aNode != NULL; aNode = aNode->next)
     {
       OpenGl_AspectFace* anAspect = dynamic_cast<OpenGl_AspectFace*> (aNode->elem);
+
       if (anAspect != NULL)
       {
         aMatID = static_cast<Standard_Integer> (myRaytraceGeometry.Materials.size());
 
-        OpenGl_RaytraceMaterial aMaterial;
-        CreateMaterial (anAspect, aMaterial);
+        OpenGl_RaytraceMaterial aMaterial = convertMaterial (anAspect, theGlContext);
 
         myRaytraceGeometry.Materials.push_back (aMaterial);
       }
@@ -465,7 +464,7 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceGroups (const OpenGl_Structure*
             {
               aTransform->SetTransform (*(reinterpret_cast<const BVH_Mat4f*> (theTransform)));
             }
-          
+
             aSet->SetProperties (aTransform);
 
             if (aSet->MaterialIndex() != OpenGl_TriangleSet::INVALID_MATERIAL && aSet->MaterialIndex() != aMatID)
@@ -476,7 +475,7 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceGroups (const OpenGl_Structure*
           else
           {
             NCollection_Handle<BVH_Object<Standard_ShortReal, 3> > aSet =
-              AddRaytracePrimitiveArray (aPrimArray, aMatID, 0);
+              addRaytracePrimitiveArray (aPrimArray, aMatID, 0);
 
             if (!aSet.IsNull())
             {
@@ -504,15 +503,16 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceGroups (const OpenGl_Structure*
 // function : AddRaytracePrimitiveArray
 // purpose  : Adds OpenGL primitive array to ray-traced scene geometry
 // =======================================================================
-OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_PrimitiveArray* theArray,
-                                                                 Standard_Integer             theMatID,
-                                                                 const OpenGl_Mat4*           theTransform)
+OpenGl_TriangleSet* OpenGl_View::addRaytracePrimitiveArray (const OpenGl_PrimitiveArray* theArray,
+                                                            const Standard_Integer       theMaterial,
+                                                            const OpenGl_Mat4*           theTransform)
 {
+  const Handle(Graphic3d_BoundBuffer)& aBounds   = theArray->Bounds();
   const Handle(Graphic3d_IndexBuffer)& anIndices = theArray->Indices();
   const Handle(Graphic3d_Buffer)&      anAttribs = theArray->Attributes();
-  const Handle(Graphic3d_BoundBuffer)& aBounds   = theArray->Bounds();
+
   if (theArray->DrawMode() < GL_TRIANGLES
-  #if !defined(GL_ES_VERSION_2_0)
+  #ifndef GL_ES_VERSION_2_0
    || theArray->DrawMode() > GL_POLYGON
   #else
    || theArray->DrawMode() > GL_TRIANGLE_FAN
@@ -522,20 +522,6 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
     return NULL;
   }
 
-#ifdef RAY_TRACE_PRINT_INFO
-  switch (theArray->DrawMode())
-  {
-    case GL_TRIANGLES:      std::cout << "\tAdding GL_TRIANGLES\n";      break;
-    case GL_TRIANGLE_FAN:   std::cout << "\tAdding GL_TRIANGLE_FAN\n";   break;
-    case GL_TRIANGLE_STRIP: std::cout << "\tAdding GL_TRIANGLE_STRIP\n"; break;
-  #if !defined(GL_ES_VERSION_2_0)
-    case GL_QUADS:          std::cout << "\tAdding GL_QUADS\n";          break;
-    case GL_QUAD_STRIP:     std::cout << "\tAdding GL_QUAD_STRIP\n";     break;
-    case GL_POLYGON:        std::cout << "\tAdding GL_POLYGON\n";        break;
-  #endif
-  }
-#endif
-
   OpenGl_Mat4 aNormalMatrix;
 
   if (theTransform != NULL)
@@ -549,10 +535,11 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
   OpenGl_TriangleSet* aSet = new OpenGl_TriangleSet (theArray->GetUID());
   {
     aSet->Vertices.reserve (anAttribs->NbElements);
-    aSet->Normals .reserve (anAttribs->NbElements);
-    aSet->TexCrds .reserve (anAttribs->NbElements);
+    aSet->Normals.reserve  (anAttribs->NbElements);
+    aSet->TexCrds.reserve  (anAttribs->NbElements);
 
     const size_t aVertFrom = aSet->Vertices.size();
+
     for (Standard_Integer anAttribIter = 0; anAttribIter < anAttribs->NbAttributes; ++anAttribIter)
     {
       const Graphic3d_Attribute& anAttrib = anAttribs->Attribute       (anAttribIter);
@@ -565,15 +552,17 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
           for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
           {
             aSet->Vertices.push_back (
-              *reinterpret_cast<const Graphic3d_Vec3* >(anAttribs->value (aVertIter) + anOffset));
+              *reinterpret_cast<const Graphic3d_Vec3*> (anAttribs->value (aVertIter) + anOffset));
           }
         }
         else if (anAttrib.DataType == Graphic3d_TOD_VEC2)
         {
           for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
           {
-            const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(anAttribs->value (aVertIter) + anOffset);
-            aSet->Vertices.push_back (BVH_Vec3f (aVert.x(), aVert.y(), 0.0f));
+            const Standard_ShortReal* aCoords =
+              reinterpret_cast<const Standard_ShortReal*> (anAttribs->value (aVertIter) + anOffset);
+
+            aSet->Vertices.push_back (BVH_Vec3f (aCoords[0], aCoords[1], 0.0f));
           }
         }
       }
@@ -585,7 +574,7 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
           for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
           {
             aSet->Normals.push_back (
-              *reinterpret_cast<const Graphic3d_Vec3* >(anAttribs->value (aVertIter) + anOffset));
+              *reinterpret_cast<const Graphic3d_Vec3*> (anAttribs->value (aVertIter) + anOffset));
           }
         }
       }
@@ -596,7 +585,7 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
           for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
           {
             aSet->TexCrds.push_back (
-              *reinterpret_cast<const Graphic3d_Vec2* >(anAttribs->value (aVertIter) + anOffset));
+              *reinterpret_cast<const Graphic3d_Vec2*> (anAttribs->value (aVertIter) + anOffset));
           }
         }
       }
@@ -624,8 +613,8 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
       {
         BVH_Vec3f& aVertex = aSet->Vertices[aVertIter];
 
-        BVH_Vec4f aTransVertex =
-          *theTransform * BVH_Vec4f (aVertex.x(), aVertex.y(), aVertex.z(), 1.f);
+        BVH_Vec4f aTransVertex = *theTransform *
+          BVH_Vec4f (aVertex.x(), aVertex.y(), aVertex.z(), 1.f);
 
         aVertex = BVH_Vec3f (aTransVertex.x(), aTransVertex.y(), aTransVertex.z());
       }
@@ -633,8 +622,8 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
       {
         BVH_Vec3f& aNormal = aSet->Normals[aVertIter];
 
-        BVH_Vec4f aTransNormal =
-          aNormalMatrix * BVH_Vec4f (aNormal.x(), aNormal.y(), aNormal.z(), 0.f);
+        BVH_Vec4f aTransNormal = aNormalMatrix *
+          BVH_Vec4f (aNormal.x(), aNormal.y(), aNormal.z(), 0.f);
 
         aNormal = BVH_Vec3f (aTransNormal.x(), aTransNormal.y(), aTransNormal.z());
       }
@@ -642,21 +631,11 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
 
     if (!aBounds.IsNull())
     {
-#ifdef RAY_TRACE_PRINT_INFO
-      std::cout << "\tNumber of bounds = " << aBounds->NbBounds << std::endl;
-#endif
-
-      Standard_Integer aBoundStart = 0;
-      for (Standard_Integer aBound = 0; aBound < aBounds->NbBounds; ++aBound)
+      for (Standard_Integer aBound = 0, aBoundStart = 0; aBound < aBounds->NbBounds; ++aBound)
       {
         const Standard_Integer aVertNum = aBounds->Bounds[aBound];
 
-#ifdef RAY_TRACE_PRINT_INFO
-        std::cout << "\tAdding indices from bound " << aBound << ": " <<
-                                      aBoundStart << " .. " << aVertNum << std::endl;
-#endif
-
-        if (!AddRaytraceVertexIndices (*aSet, *theArray, aBoundStart, aVertNum, theMatID))
+        if (!addRaytraceVertexIndices (*aSet, theMaterial, aVertNum, aBoundStart, *theArray))
         {
           delete aSet;
           return NULL;
@@ -669,11 +648,7 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
     {
       const Standard_Integer aVertNum = !anIndices.IsNull() ? anIndices->NbElements : anAttribs->NbElements;
 
-  #ifdef RAY_TRACE_PRINT_INFO
-        std::cout << "\tAdding indices from array: " << aVertNum << std::endl;
-  #endif
-
-      if (!AddRaytraceVertexIndices (*aSet, *theArray, 0, aVertNum, theMatID))
+      if (!addRaytraceVertexIndices (*aSet, theMaterial, aVertNum, 0, *theArray))
       {
         delete aSet;
         return NULL;
@@ -682,7 +657,9 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
   }
 
   if (aSet->Size() != 0)
+  {
     aSet->MarkDirty();
+  }
 
   return aSet;
 }
@@ -691,23 +668,24 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_Pr
 // function : AddRaytraceVertexIndices
 // purpose  : Adds vertex indices to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceVertexIndices (OpenGl_TriangleSet&          theSet,
-                                                             const OpenGl_PrimitiveArray& theArray,
-                                                             Standard_Integer             theOffset,
-                                                             Standard_Integer             theCount,
-                                                             Standard_Integer             theMatID)
+Standard_Boolean OpenGl_View::addRaytraceVertexIndices (OpenGl_TriangleSet&                  theSet,
+                                                        const Standard_Integer               theMatID,
+                                                        const Standard_Integer               theCount,
+                                                        const Standard_Integer               theOffset,
+                                                        const OpenGl_PrimitiveArray&         theArray)
 {
   switch (theArray.DrawMode())
   {
-    case GL_TRIANGLES:      return AddRaytraceTriangleArray        (theSet, theArray.Indices(), theOffset, theCount, theMatID);
-    case GL_TRIANGLE_FAN:   return AddRaytraceTriangleFanArray     (theSet, theArray.Indices(), theOffset, theCount, theMatID);
-    case GL_TRIANGLE_STRIP: return AddRaytraceTriangleStripArray   (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+    case GL_TRIANGLES:      return addRaytraceTriangleArray        (theSet, theMatID, theCount, theOffset, theArray.Indices());
+    case GL_TRIANGLE_FAN:   return addRaytraceTriangleFanArray     (theSet, theMatID, theCount, theOffset, theArray.Indices());
+    case GL_TRIANGLE_STRIP: return addRaytraceTriangleStripArray   (theSet, theMatID, theCount, theOffset, theArray.Indices());
   #if !defined(GL_ES_VERSION_2_0)
-    case GL_QUADS:          return AddRaytraceQuadrangleArray      (theSet, theArray.Indices(), theOffset, theCount, theMatID);
-    case GL_QUAD_STRIP:     return AddRaytraceQuadrangleStripArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
-    case GL_POLYGON:        return AddRaytracePolygonArray         (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+    case GL_QUAD_STRIP:     return addRaytraceQuadrangleStripArray (theSet, theMatID, theCount, theOffset, theArray.Indices());
+    case GL_QUADS:          return addRaytraceQuadrangleArray      (theSet, theMatID, theCount, theOffset, theArray.Indices());
+    case GL_POLYGON:        return addRaytracePolygonArray         (theSet, theMatID, theCount, theOffset, theArray.Indices());
   #endif
   }
+
   return Standard_False;
 }
 
@@ -715,14 +693,16 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceVertexIndices (OpenGl_TriangleSet&
 // function : AddRaytraceTriangleArray
 // purpose  : Adds OpenGL triangle array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleArray (OpenGl_TriangleSet&                  theSet,
-                                                             const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                             Standard_Integer                     theOffset,
-                                                             Standard_Integer                     theCount,
-                                                             Standard_Integer                     theMatID)
+Standard_Boolean OpenGl_View::addRaytraceTriangleArray (OpenGl_TriangleSet&                  theSet,
+                                                        const Standard_Integer               theMatID,
+                                                        const Standard_Integer               theCount,
+                                                        const Standard_Integer               theOffset,
+                                                        const Handle(Graphic3d_IndexBuffer)& theIndices)
 {
   if (theCount < 3)
+  {
     return Standard_True;
+  }
 
   theSet.Elements.reserve (theSet.Elements.size() + theCount / 3);
 
@@ -740,8 +720,7 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleArray (OpenGl_TriangleSet&
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 2; aVert += 3)
     {
-      theSet.Elements.push_back (BVH_Vec4i (aVert + 0, aVert + 1, aVert + 2,
-                                            theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (aVert + 0, aVert + 1, aVert + 2, theMatID));
     }
   }
 
@@ -752,14 +731,16 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleArray (OpenGl_TriangleSet&
 // function : AddRaytraceTriangleFanArray
 // purpose  : Adds OpenGL triangle fan array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleFanArray (OpenGl_TriangleSet&                  theSet,
-                                                                const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                                Standard_Integer                     theOffset,
-                                                                Standard_Integer                     theCount,
-                                                                Standard_Integer                     theMatID)
+Standard_Boolean OpenGl_View::addRaytraceTriangleFanArray (OpenGl_TriangleSet&                  theSet,
+                                                           const Standard_Integer               theMatID,
+                                                           const Standard_Integer               theCount,
+                                                           const Standard_Integer               theOffset,
+                                                           const Handle(Graphic3d_IndexBuffer)& theIndices)
 {
   if (theCount < 3)
+  {
     return Standard_True;
+  }
 
   theSet.Elements.reserve (theSet.Elements.size() + theCount - 2);
 
@@ -791,14 +772,16 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleFanArray (OpenGl_TriangleS
 // function : AddRaytraceTriangleStripArray
 // purpose  : Adds OpenGL triangle strip array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleStripArray (OpenGl_TriangleSet&                  theSet,
-                                                                  const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                                  Standard_Integer                     theOffset,
-                                                                  Standard_Integer                     theCount,
-                                                                  Standard_Integer                     theMatID)
+Standard_Boolean OpenGl_View::addRaytraceTriangleStripArray (OpenGl_TriangleSet&                  theSet,
+                                                             const Standard_Integer               theMatID,
+                                                             const Standard_Integer               theCount,
+                                                             const Standard_Integer               theOffset,
+                                                             const Handle(Graphic3d_IndexBuffer)& theIndices)
 {
   if (theCount < 3)
+  {
     return Standard_True;
+  }
 
   theSet.Elements.reserve (theSet.Elements.size() + theCount - 2);
 
@@ -830,14 +813,16 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleStripArray (OpenGl_Triangl
 // function : AddRaytraceQuadrangleArray
 // purpose  : Adds OpenGL quad array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleArray (OpenGl_TriangleSet&                  theSet,
-                                                               const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                               Standard_Integer                     theOffset,
-                                                               Standard_Integer                     theCount,
-                                                               Standard_Integer                     theMatID)
+Standard_Boolean OpenGl_View::addRaytraceQuadrangleArray (OpenGl_TriangleSet&                  theSet,
+                                                          const Standard_Integer               theMatID,
+                                                          const Standard_Integer               theCount,
+                                                          const Standard_Integer               theOffset,
+                                                          const Handle(Graphic3d_IndexBuffer)& theIndices)
 {
   if (theCount < 4)
+  {
     return Standard_True;
+  }
 
   theSet.Elements.reserve (theSet.Elements.size() + theCount / 2);
 
@@ -873,14 +858,16 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleArray (OpenGl_TriangleSe
 // function : AddRaytraceQuadrangleStripArray
 // purpose  : Adds OpenGL quad strip array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleStripArray (OpenGl_TriangleSet&                  theSet,
-                                                                    const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                                    Standard_Integer                     theOffset,
-                                                                    Standard_Integer                     theCount,
-                                                                    Standard_Integer                     theMatID)
+Standard_Boolean OpenGl_View::addRaytraceQuadrangleStripArray (OpenGl_TriangleSet&                  theSet,
+                                                               const Standard_Integer               theMatID,
+                                                               const Standard_Integer               theCount,
+                                                               const Standard_Integer               theOffset,
+                                                               const Handle(Graphic3d_IndexBuffer)& theIndices)
 {
   if (theCount < 4)
+  {
     return Standard_True;
+  }
 
   theSet.Elements.reserve (theSet.Elements.size() + 2 * theCount - 6);
 
@@ -922,14 +909,16 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleStripArray (OpenGl_Trian
 // function : AddRaytracePolygonArray
 // purpose  : Adds OpenGL polygon array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytracePolygonArray (OpenGl_TriangleSet&                  theSet,
-                                                            const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                            Standard_Integer                     theOffset,
-                                                            Standard_Integer                     theCount,
-                                                            Standard_Integer                     theMatID)
+Standard_Boolean OpenGl_View::addRaytracePolygonArray (OpenGl_TriangleSet&                  theSet,
+                                                       const Standard_Integer               theMatID,
+                                                       const Standard_Integer               theCount,
+                                                       const Standard_Integer               theOffset,
+                                                       const Handle(Graphic3d_IndexBuffer)& theIndices)
 {
   if (theCount < 3)
+  {
     return Standard_True;
+  }
 
   theSet.Elements.reserve (theSet.Elements.size() + theCount - 2);
 
@@ -958,129 +947,10 @@ Standard_Boolean OpenGl_Workspace::AddRaytracePolygonArray (OpenGl_TriangleSet&
 }
 
 // =======================================================================
-// function : UpdateRaytraceLightSources
-// purpose  : Updates 3D scene light sources for ray-tracing
-// =======================================================================
-Standard_Boolean OpenGl_Workspace::UpdateRaytraceLightSources (const OpenGl_Mat4& theInvModelView)
-{
-  myRaytraceGeometry.Sources.clear();
-
-  myRaytraceGeometry.Ambient = BVH_Vec4f (0.0f, 0.0f, 0.0f, 0.0f);
-
-  for (OpenGl_ListOfLight::Iterator anItl (myView->LightList()); anItl.More(); anItl.Next())
-  {
-    const OpenGl_Light& aLight = anItl.Value();
-
-    if (aLight.Type == Visual3d_TOLS_AMBIENT)
-    {
-      myRaytraceGeometry.Ambient += BVH_Vec4f (aLight.Color.r(),
-                                               aLight.Color.g(),
-                                               aLight.Color.b(),
-                                               0.0f);
-      continue;
-    }
-
-    BVH_Vec4f aDiffuse  (aLight.Color.r(),
-                         aLight.Color.g(),
-                         aLight.Color.b(),
-                         1.0f);
-
-    BVH_Vec4f aPosition (-aLight.Direction.x(),
-                         -aLight.Direction.y(),
-                         -aLight.Direction.z(),
-                         0.0f);
-
-    if (aLight.Type != Visual3d_TOLS_DIRECTIONAL)
-    {
-      aPosition = BVH_Vec4f (aLight.Position.x(),
-                             aLight.Position.y(),
-                             aLight.Position.z(),
-                             1.0f);
-    }
-
-    if (aLight.IsHeadlight)
-    {
-      aPosition = theInvModelView * aPosition;
-    }
-
-    myRaytraceGeometry.Sources.push_back (OpenGl_RaytraceLight (aDiffuse, aPosition));
-  }
-
-  if (myRaytraceLightSrcTexture.IsNull())  // create light source buffer
-  {
-    myRaytraceLightSrcTexture = new OpenGl_TextureBufferArb;
-
-    if (!myRaytraceLightSrcTexture->Create (myGlContext))
-    {
-#ifdef RAY_TRACE_PRINT_INFO
-      std::cout << "Error: Failed to create light source buffer" << std::endl;
-#endif
-      return Standard_False;
-    }
-  }
-  
-  if (myRaytraceGeometry.Sources.size() != 0)
-  {
-    const GLfloat* aDataPtr = myRaytraceGeometry.Sources.front().Packed();
-    if (!myRaytraceLightSrcTexture->Init (myGlContext, 4, GLsizei (myRaytraceGeometry.Sources.size() * 2), aDataPtr))
-    {
-#ifdef RAY_TRACE_PRINT_INFO
-      std::cout << "Error: Failed to upload light source buffer" << std::endl;
-#endif
-      return Standard_False;
-    }
-  }
-
-  return Standard_True;
-}
-
-// =======================================================================
-// function : UpdateRaytraceEnvironmentMap
-// purpose  : Updates environment map for ray-tracing
-// =======================================================================
-Standard_Boolean OpenGl_Workspace::UpdateRaytraceEnvironmentMap()
-{
-  if (myView.IsNull())
-    return Standard_False;
-
-  if (myViewModificationStatus == myView->ModificationState())
-    return Standard_True;
-
-  for (Standard_Integer anIdx = 0; anIdx < 2; ++anIdx)
-  {
-    const Handle(OpenGl_ShaderProgram)& aProgram =
-      anIdx == 0 ? myRaytraceProgram : myPostFSAAProgram;
-
-    if (!aProgram.IsNull())
-    {
-      myGlContext->BindProgram (aProgram);
-
-      if (!myView->TextureEnv().IsNull() && myView->SurfaceDetail() != Visual3d_TOD_NONE)
-      {
-        myView->TextureEnv()->Bind (
-          myGlContext, GL_TEXTURE0 + OpenGl_RT_EnvironmentMapTexture);
-
-        aProgram->SetUniform (myGlContext,
-          myUniformLocations[anIdx][OpenGl_RT_uEnvMapEnable], 1);
-      }
-      else
-      {
-        aProgram->SetUniform (myGlContext,
-          myUniformLocations[anIdx][OpenGl_RT_uEnvMapEnable], 0);
-      }
-    }
-  }
-
-  myGlContext->BindProgram (NULL);
-  myViewModificationStatus = myView->ModificationState();
-  return Standard_True;
-}
-
-// =======================================================================
 // function : Source
 // purpose  : Returns shader source combined with prefix
 // =======================================================================
-TCollection_AsciiString OpenGl_Workspace::ShaderSource::Source() const
+TCollection_AsciiString OpenGl_View::ShaderSource::Source() const
 {
   static const TCollection_AsciiString aVersion = "#version 140";
 
@@ -1096,8 +966,8 @@ TCollection_AsciiString OpenGl_Workspace::ShaderSource::Source() const
 // function : Load
 // purpose  : Loads shader source from specified files
 // =======================================================================
-void OpenGl_Workspace::ShaderSource::Load (
-  const TCollection_AsciiString* theFileNames, const Standard_Integer theCount)
+void OpenGl_View::ShaderSource::Load (const TCollection_AsciiString* theFileNames,
+                                      const Standard_Integer         theCount)
 {
   mySource.Clear();
 
@@ -1127,65 +997,110 @@ void OpenGl_Workspace::ShaderSource::Load (
 }
 
 // =======================================================================
-// function : LoadShader
+// function : GenerateShaderPrefix
+// purpose  : Generates shader prefix based on current ray-tracing options
+// =======================================================================
+TCollection_AsciiString OpenGl_View::generateShaderPrefix (const Handle(OpenGl_Context)& theGlContext) const
+{
+  TCollection_AsciiString aPrefixString =
+    TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
+    TCollection_AsciiString ("#define NB_BOUNCES ") + TCollection_AsciiString (myRaytraceParameters.NbBounces);
+
+  if (myRaytraceParameters.TransparentShadows)
+  {
+    aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
+  }
+
+  // If OpenGL driver supports bindless textures,
+  // activate texturing in ray-tracing mode
+  if (theGlContext->arbTexBindless != NULL)
+  {
+    aPrefixString += TCollection_AsciiString ("\n#define USE_TEXTURES") +
+      TCollection_AsciiString ("\n#define MAX_TEX_NUMBER ") + TCollection_AsciiString (OpenGl_RaytraceGeometry::MAX_TEX_NUMBER);
+  }
+
+  return aPrefixString;
+}
+
+// =======================================================================
+// function : SafeFailBack
+// purpose  : Performs safe exit when shaders initialization fails
+// =======================================================================
+Standard_Boolean OpenGl_View::safeFailBack (const TCollection_ExtendedString& theMessage,
+                                            const Handle(OpenGl_Context)&     theGlContext)
+{
+  theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+    GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, theMessage);
+
+  myRaytraceInitStatus = OpenGl_RT_FAIL;
+
+  releaseRaytraceResources (theGlContext);
+
+  return Standard_False;
+}
+
+// =======================================================================
+// function : InitShader
 // purpose  : Creates new shader object with specified source
 // =======================================================================
-Handle(OpenGl_ShaderObject) OpenGl_Workspace::LoadShader (const ShaderSource& theSource, GLenum theType)
+Handle(OpenGl_ShaderObject) OpenGl_View::initShader (const GLenum                  theType,
+                                                     const ShaderSource&           theSource,
+                                                     const Handle(OpenGl_Context)& theGlContext)
 {
   Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (theType);
 
-  if (!aShader->Create (myGlContext))
+  if (!aShader->Create (theGlContext))
   {
     const TCollection_ExtendedString aMessage = TCollection_ExtendedString ("Error: Failed to create ") +
       (theType == GL_VERTEX_SHADER ? "vertex" : "fragment") + " shader object";
 
-    myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+    theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
       GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, aMessage);
 
-    aShader->Release (myGlContext.operator->());
+    aShader->Release (theGlContext.operator->());
 
     return Handle(OpenGl_ShaderObject)();
   }
 
-  if (!aShader->LoadSource (myGlContext, theSource.Source()))
+  if (!aShader->LoadSource (theGlContext, theSource.Source()))
   {
     const TCollection_ExtendedString aMessage = TCollection_ExtendedString ("Error: Failed to set ") +
       (theType == GL_VERTEX_SHADER ? "vertex" : "fragment") + " shader source";
 
-    myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+    theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
       GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, aMessage);
 
-    aShader->Release (myGlContext.operator->());
+    aShader->Release (theGlContext.operator->());
 
     return Handle(OpenGl_ShaderObject)();
   }
 
   TCollection_AsciiString aBuildLog;
 
-  if (!aShader->Compile (myGlContext))
+  if (!aShader->Compile (theGlContext))
   {
-    aShader->FetchInfoLog (myGlContext, aBuildLog);
+    aShader->FetchInfoLog (theGlContext, aBuildLog);
 
     const TCollection_ExtendedString aMessage = TCollection_ExtendedString ("Error: Failed to compile ") +
       (theType == GL_VERTEX_SHADER ? "vertex" : "fragment") + " shader object:\n" + aBuildLog;
 
-    myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+    theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
       GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, aMessage);
 
-    aShader->Release (myGlContext.operator->());
+    aShader->Release (theGlContext.operator->());
 
     return Handle(OpenGl_ShaderObject)();
   }
-  else if (myGlContext->caps->glslWarnings)
+  else if (theGlContext->caps->glslWarnings)
   {
-    aShader->FetchInfoLog (myGlContext, aBuildLog);
+    aShader->FetchInfoLog (theGlContext, aBuildLog);
 
     if (!aBuildLog.IsEmpty() && !aBuildLog.IsEqual ("No errors.\n"))
     {
       const TCollection_ExtendedString aMessage = TCollection_ExtendedString (theType == GL_VERTEX_SHADER ?
         "Vertex" : "Fragment") + " shader was compiled with following warnings:\n" + aBuildLog;
 
-      myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+      theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
         GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMessage);
     }
   }
@@ -1194,71 +1109,29 @@ Handle(OpenGl_ShaderObject) OpenGl_Workspace::LoadShader (const ShaderSource& th
 }
 
 // =======================================================================
-// function : SafeFailBack
-// purpose  : Performs safe exit when shaders initialization fails
+// function : InitRaytraceResources
+// purpose  : Initializes OpenGL/GLSL shader programs
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::SafeFailBack (const TCollection_ExtendedString& theMessage)
+Standard_Boolean OpenGl_View::initRaytraceResources (const Graphic3d_CView& theCView, const Handle(OpenGl_Context)& theGlContext)
 {
-  myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-    GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, theMessage);
+  if (myRaytraceInitStatus == OpenGl_RT_FAIL)
+  {
+    return Standard_False;
+  }
 
-  myComputeInitStatus = OpenGl_RT_FAIL;
+  Standard_Boolean aToRebuildShaders = Standard_False;
 
-  ReleaseRaytraceResources();
+  if (myRaytraceInitStatus == OpenGl_RT_INIT)
+  {
+    if (!myIsRaytraceDataValid)
+      return Standard_True;
 
-  return Standard_False;
-}
+    const Standard_Integer aRequiredStackSize =
+      myRaytraceGeometry.HighLevelTreeDepth() + myRaytraceGeometry.BottomLevelTreeDepth();
 
-// =======================================================================
-// function : GenerateShaderPrefix
-// purpose  : Generates shader prefix based on current ray-tracing options
-// =======================================================================
-TCollection_AsciiString OpenGl_Workspace::GenerateShaderPrefix()
-{
-  TCollection_AsciiString aPrefixString =
-    TCollection_AsciiString ("#define STACK_SIZE ") + TCollection_AsciiString (myRaytraceParameters.StackSize) + "\n" +
-    TCollection_AsciiString ("#define NB_BOUNCES ") + TCollection_AsciiString (myRaytraceParameters.NbBounces);
-
-  if (myRaytraceParameters.TransparentShadows)
-  {
-    aPrefixString += TCollection_AsciiString ("\n#define TRANSPARENT_SHADOWS");
-  }
-
-  // If OpenGL driver supports bindless textures
-  // activate texturing in ray-tracing mode
-  if (myGlContext->arbTexBindless != NULL)
-  {
-    aPrefixString += TCollection_AsciiString ("\n#define USE_TEXTURES") +
-      TCollection_AsciiString ("\n#define MAX_TEX_NUMBER ") + TCollection_AsciiString (OpenGl_RaytraceGeometry::MAX_TEX_NUMBER);
-  }
-
-  return aPrefixString;
-}
-
-// =======================================================================
-// function : InitRaytraceResources
-// purpose  : Initializes OpenGL/GLSL shader programs
-// =======================================================================
-Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView& theCView)
-{
-  if (myComputeInitStatus == OpenGl_RT_FAIL)
-  {
-    return Standard_False;
-  }
-
-  Standard_Boolean aToRebuildShaders = Standard_False;
-
-  if (myComputeInitStatus == OpenGl_RT_INIT)
-  {
-    if (!myIsRaytraceDataValid)
-      return Standard_True;
-
-    const Standard_Integer aRequiredStackSize =
-      myRaytraceGeometry.HighLevelTreeDepth() + myRaytraceGeometry.BottomLevelTreeDepth();
-
-    if (myRaytraceParameters.StackSize < aRequiredStackSize)
-    {
-      myRaytraceParameters.StackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE);
+    if (myRaytraceParameters.StackSize < aRequiredStackSize)
+    {
+      myRaytraceParameters.StackSize = Max (aRequiredStackSize, THE_DEFAULT_STACK_SIZE);
 
       aToRebuildShaders = Standard_True;
     }
@@ -1293,9 +1166,9 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
 #endif
 
       // Change state to force update all uniforms
-      ++myViewModificationStatus;
+      myToUpdateEnvironmentMap = Standard_True;
 
-      TCollection_AsciiString aPrefixString = GenerateShaderPrefix();
+      TCollection_AsciiString aPrefixString = generateShaderPrefix (theGlContext);
 
 #ifdef RAY_TRACE_PRINT_INFO
       std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl;
@@ -1304,37 +1177,41 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
       myRaytraceShaderSource.SetPrefix (aPrefixString);
       myPostFSAAShaderSource.SetPrefix (aPrefixString);
 
-      if (!myRaytraceShader->LoadSource (myGlContext, myRaytraceShaderSource.Source())
-       || !myPostFSAAShader->LoadSource (myGlContext, myPostFSAAShaderSource.Source()))
+      if (!myRaytraceShader->LoadSource (theGlContext, myRaytraceShaderSource.Source())
+       || !myPostFSAAShader->LoadSource (theGlContext, myPostFSAAShaderSource.Source()))
       {
-        return SafeFailBack ("Failed to load source into ray-tracing fragment shaders");
+        return safeFailBack ("Failed to load source into ray-tracing fragment shaders", theGlContext);
       }
 
-      if (!myRaytraceShader->Compile (myGlContext)
-       || !myPostFSAAShader->Compile (myGlContext))
+      if (!myRaytraceShader->Compile (theGlContext)
+       || !myPostFSAAShader->Compile (theGlContext))
       {
-        return SafeFailBack ("Failed to compile ray-tracing fragment shaders");
+        return safeFailBack ("Failed to compile ray-tracing fragment shaders", theGlContext);
       }
 
-      myRaytraceProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex");
-      myPostFSAAProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex");
-      if (!myRaytraceProgram->Link (myGlContext)
-       || !myPostFSAAProgram->Link (myGlContext))
+      myRaytraceProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
+      myPostFSAAProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
+      if (!myRaytraceProgram->Link (theGlContext)
+       || !myPostFSAAProgram->Link (theGlContext))
       {
-        return SafeFailBack ("Failed to initialize vertex attributes for ray-tracing program");
+        return safeFailBack ("Failed to initialize vertex attributes for ray-tracing program", theGlContext);
       }
     }
   }
 
-  if (myComputeInitStatus == OpenGl_RT_NONE)
+  if (myRaytraceInitStatus == OpenGl_RT_NONE)
   {
-    if (!myGlContext->IsGlGreaterEqual (3, 1))
+    if (!theGlContext->IsGlGreaterEqual (3, 1))
     {
-      return SafeFailBack ("Ray-tracing requires OpenGL 3.1 and higher");
+      return safeFailBack ("Ray-tracing requires OpenGL 3.1 and higher", theGlContext);
     }
-    else if (!myGlContext->arbTboRGB32)
+    else if (!theGlContext->arbTboRGB32)
     {
-      return SafeFailBack ("Ray-tracing requires OpenGL 4.0+ or GL_ARB_texture_buffer_object_rgb32 extension");
+      return safeFailBack ("Ray-tracing requires OpenGL 4.0+ or GL_ARB_texture_buffer_object_rgb32 extension", theGlContext);
+    }
+    else if (!theGlContext->arbFBOBlit)
+    {
+      return safeFailBack ("Ray-tracing requires EXT_framebuffer_blit extension", theGlContext);
     }
 
     myRaytraceParameters.NbBounces = theCView.RenderParams.RaytracingDepth;
@@ -1343,7 +1220,7 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
 
     if (aFolder.IsEmpty())
     {
-      return SafeFailBack ("Failed to locate shaders directory");
+      return safeFailBack ("Failed to locate shaders directory", theGlContext);
     }
 
     if (myIsRaytraceDataValid)
@@ -1352,19 +1229,19 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
         myRaytraceGeometry.HighLevelTreeDepth() + myRaytraceGeometry.BottomLevelTreeDepth());
     }
 
-    TCollection_AsciiString aPrefixString  = GenerateShaderPrefix();
+    TCollection_AsciiString aPrefixString  = generateShaderPrefix (theGlContext);
 
 #ifdef RAY_TRACE_PRINT_INFO
     std::cout << "GLSL prefix string:" << std::endl << aPrefixString << std::endl;
 #endif
 
     {
-      Handle(OpenGl_ShaderObject) aBasicVertShader = LoadShader (
-        ShaderSource (aFolder + "/RaytraceBase.vs"), GL_VERTEX_SHADER);
+      Handle(OpenGl_ShaderObject) aBasicVertShader = initShader (
+        GL_VERTEX_SHADER, ShaderSource (aFolder + "/RaytraceBase.vs"), theGlContext);
 
       if (aBasicVertShader.IsNull())
       {
-        return SafeFailBack ("Failed to initialize ray-trace vertex shader");
+        return safeFailBack ("Failed to initialize ray-trace vertex shader", theGlContext);
       }
 
       TCollection_AsciiString aFiles[] = { aFolder + "/RaytraceBase.fs",
@@ -1374,65 +1251,65 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
 
       myRaytraceShaderSource.SetPrefix (aPrefixString);
 
-      myRaytraceShader = LoadShader (myRaytraceShaderSource, GL_FRAGMENT_SHADER);
+      myRaytraceShader = initShader (GL_FRAGMENT_SHADER, myRaytraceShaderSource, theGlContext);
 
       if (myRaytraceShader.IsNull())
       {
-        aBasicVertShader->Release (myGlContext.operator->());
+        aBasicVertShader->Release (theGlContext.operator->());
 
-        return SafeFailBack ("Failed to initialize ray-trace fragment shader");
+        return safeFailBack ("Failed to initialize ray-trace fragment shader", theGlContext);
       }
 
       myRaytraceProgram = new OpenGl_ShaderProgram;
 
-      if (!myRaytraceProgram->Create (myGlContext))
+      if (!myRaytraceProgram->Create (theGlContext))
       {
-        aBasicVertShader->Release (myGlContext.operator->());
+        aBasicVertShader->Release (theGlContext.operator->());
 
-        return SafeFailBack ("Failed to create ray-trace shader program");
+        return safeFailBack ("Failed to create ray-trace shader program", theGlContext);
       }
 
-      if (!myRaytraceProgram->AttachShader (myGlContext, aBasicVertShader)
-       || !myRaytraceProgram->AttachShader (myGlContext, myRaytraceShader))
+      if (!myRaytraceProgram->AttachShader (theGlContext, aBasicVertShader)
+       || !myRaytraceProgram->AttachShader (theGlContext, myRaytraceShader))
       {
-        aBasicVertShader->Release (myGlContext.operator->());
+        aBasicVertShader->Release (theGlContext.operator->());
 
-        return SafeFailBack ("Failed to attach ray-trace shader objects");
+        return safeFailBack ("Failed to attach ray-trace shader objects", theGlContext);
       }
 
-      myRaytraceProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex");
+      myRaytraceProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
 
       TCollection_AsciiString aLinkLog;
 
-      if (!myRaytraceProgram->Link (myGlContext))
+      if (!myRaytraceProgram->Link (theGlContext))
       {
-        myRaytraceProgram->FetchInfoLog (myGlContext, aLinkLog);
+        myRaytraceProgram->FetchInfoLog (theGlContext, aLinkLog);
 
-        return SafeFailBack (TCollection_ExtendedString (
-          "Failed to link ray-trace shader program:\n") + aLinkLog);
+        return safeFailBack (TCollection_ExtendedString (
+          "Failed to link ray-trace shader program:\n") + aLinkLog, theGlContext);
       }
-      else if (myGlContext->caps->glslWarnings)
+      else if (theGlContext->caps->glslWarnings)
       {
-        myRaytraceProgram->FetchInfoLog (myGlContext, aLinkLog);
+        myRaytraceProgram->FetchInfoLog (theGlContext, aLinkLog);
 
         if (!aLinkLog.IsEmpty() && !aLinkLog.IsEqual ("No errors.\n"))
         {
           const TCollection_ExtendedString aMessage = TCollection_ExtendedString (
             "Ray-trace shader program was linked with following warnings:\n") + aLinkLog;
 
-          myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+          theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
             GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMessage);
         }
       }
     }
 
     {
-      Handle(OpenGl_ShaderObject) aBasicVertShader = LoadShader (
-        ShaderSource (aFolder + "/RaytraceBase.vs"), GL_VERTEX_SHADER);
+      Handle(OpenGl_ShaderObject) aBasicVertShader = initShader (
+        GL_VERTEX_SHADER, ShaderSource (aFolder + "/RaytraceBase.vs"), theGlContext);
 
       if (aBasicVertShader.IsNull())
       {
-        return SafeFailBack ("Failed to initialize FSAA vertex shader");
+        return safeFailBack ("Failed to initialize FSAA vertex shader", theGlContext);
       }
 
       TCollection_AsciiString aFiles[] = { aFolder + "/RaytraceBase.fs",
@@ -1442,161 +1319,161 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
 
       myPostFSAAShaderSource.SetPrefix (aPrefixString);
     
-      myPostFSAAShader = LoadShader (myPostFSAAShaderSource, GL_FRAGMENT_SHADER);
+      myPostFSAAShader = initShader (GL_FRAGMENT_SHADER, myPostFSAAShaderSource, theGlContext);
 
       if (myPostFSAAShader.IsNull())
       {
-        aBasicVertShader->Release (myGlContext.operator->());
+        aBasicVertShader->Release (theGlContext.operator->());
 
-        return SafeFailBack ("Failed to initialize FSAA fragment shader");
+        return safeFailBack ("Failed to initialize FSAA fragment shader", theGlContext);
       }
 
       myPostFSAAProgram = new OpenGl_ShaderProgram;
 
-      if (!myPostFSAAProgram->Create (myGlContext))
+      if (!myPostFSAAProgram->Create (theGlContext))
       {
-        aBasicVertShader->Release (myGlContext.operator->());
+        aBasicVertShader->Release (theGlContext.operator->());
 
-        return SafeFailBack ("Failed to create FSAA shader program");
+        return safeFailBack ("Failed to create FSAA shader program", theGlContext);
       }
 
-      if (!myPostFSAAProgram->AttachShader (myGlContext, aBasicVertShader)
-       || !myPostFSAAProgram->AttachShader (myGlContext, myPostFSAAShader))
+      if (!myPostFSAAProgram->AttachShader (theGlContext, aBasicVertShader)
+       || !myPostFSAAProgram->AttachShader (theGlContext, myPostFSAAShader))
       {
-        aBasicVertShader->Release (myGlContext.operator->());
+        aBasicVertShader->Release (theGlContext.operator->());
 
-        return SafeFailBack ("Failed to attach FSAA shader objects");
+        return safeFailBack ("Failed to attach FSAA shader objects", theGlContext);
       }
 
-      myPostFSAAProgram->SetAttributeName (myGlContext, Graphic3d_TOA_POS, "occVertex");
+      myPostFSAAProgram->SetAttributeName (theGlContext, Graphic3d_TOA_POS, "occVertex");
 
       TCollection_AsciiString aLinkLog;
 
-      if (!myPostFSAAProgram->Link (myGlContext))
+      if (!myPostFSAAProgram->Link (theGlContext))
       {
-        myPostFSAAProgram->FetchInfoLog (myGlContext, aLinkLog);
+        myPostFSAAProgram->FetchInfoLog (theGlContext, aLinkLog);
       
-        return SafeFailBack (TCollection_ExtendedString (
-          "Failed to link FSAA shader program:\n") + aLinkLog);
+        return safeFailBack (TCollection_ExtendedString (
+          "Failed to link FSAA shader program:\n") + aLinkLog, theGlContext);
       }
-      else if (myGlContext->caps->glslWarnings)
+      else if (theGlContext->caps->glslWarnings)
       {
-        myPostFSAAProgram->FetchInfoLog (myGlContext, aLinkLog);
+        myPostFSAAProgram->FetchInfoLog (theGlContext, aLinkLog);
 
         if (!aLinkLog.IsEmpty() && !aLinkLog.IsEqual ("No errors.\n"))
         {
           const TCollection_ExtendedString aMessage = TCollection_ExtendedString (
             "FSAA shader program was linked with following warnings:\n") + aLinkLog;
 
-          myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+          theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
             GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMessage);
         }
       }
     }
   }
 
-  if (myComputeInitStatus == OpenGl_RT_NONE || aToRebuildShaders)
+  if (myRaytraceInitStatus == OpenGl_RT_NONE || aToRebuildShaders)
   {
     for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
     {
       Handle(OpenGl_ShaderProgram)& aShaderProgram =
         (anIndex == 0) ? myRaytraceProgram : myPostFSAAProgram;
 
-      myGlContext->BindProgram (aShaderProgram);
+      theGlContext->BindProgram (aShaderProgram);
 
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uSceneMinPointTexture", OpenGl_RT_SceneMinPointTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uSceneMaxPointTexture", OpenGl_RT_SceneMaxPointTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uSceneNodeInfoTexture", OpenGl_RT_SceneNodeInfoTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uGeometryVertexTexture", OpenGl_RT_GeometryVertexTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uGeometryNormalTexture", OpenGl_RT_GeometryNormalTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uGeometryTexCrdTexture", OpenGl_RT_GeometryTexCrdTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uGeometryTriangTexture", OpenGl_RT_GeometryTriangTexture);
-      aShaderProgram->SetSampler (myGlContext, 
+      aShaderProgram->SetSampler (theGlContext, 
         "uSceneTransformTexture", OpenGl_RT_SceneTransformTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uEnvironmentMapTexture", OpenGl_RT_EnvironmentMapTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uRaytraceMaterialTexture", OpenGl_RT_RaytraceMaterialTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uRaytraceLightSrcTexture", OpenGl_RT_RaytraceLightSrcTexture);
 
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uOpenGlColorTexture", OpenGl_RT_OpenGlColorTexture);
-      aShaderProgram->SetSampler (myGlContext,
+      aShaderProgram->SetSampler (theGlContext,
         "uOpenGlDepthTexture", OpenGl_RT_OpenGlDepthTexture);
 
       if (anIndex == 1)
       {
-        aShaderProgram->SetSampler (myGlContext,
+        aShaderProgram->SetSampler (theGlContext,
           "uFSAAInputTexture", OpenGl_RT_FSAAInputTexture);
       }
 
       myUniformLocations[anIndex][OpenGl_RT_aPosition] =
-        aShaderProgram->GetAttributeLocation (myGlContext, "occVertex");
+        aShaderProgram->GetAttributeLocation (theGlContext, "occVertex");
 
       myUniformLocations[anIndex][OpenGl_RT_uOriginLB] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uOriginLB");
+        aShaderProgram->GetUniformLocation (theGlContext, "uOriginLB");
       myUniformLocations[anIndex][OpenGl_RT_uOriginRB] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uOriginRB");
+        aShaderProgram->GetUniformLocation (theGlContext, "uOriginRB");
       myUniformLocations[anIndex][OpenGl_RT_uOriginLT] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uOriginLT");
+        aShaderProgram->GetUniformLocation (theGlContext, "uOriginLT");
       myUniformLocations[anIndex][OpenGl_RT_uOriginRT] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uOriginRT");
+        aShaderProgram->GetUniformLocation (theGlContext, "uOriginRT");
       myUniformLocations[anIndex][OpenGl_RT_uDirectLB] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uDirectLB");
+        aShaderProgram->GetUniformLocation (theGlContext, "uDirectLB");
       myUniformLocations[anIndex][OpenGl_RT_uDirectRB] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uDirectRB");
+        aShaderProgram->GetUniformLocation (theGlContext, "uDirectRB");
       myUniformLocations[anIndex][OpenGl_RT_uDirectLT] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uDirectLT");
+        aShaderProgram->GetUniformLocation (theGlContext, "uDirectLT");
       myUniformLocations[anIndex][OpenGl_RT_uDirectRT] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uDirectRT");
+        aShaderProgram->GetUniformLocation (theGlContext, "uDirectRT");
       myUniformLocations[anIndex][OpenGl_RT_uUnviewMat] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uUnviewMat");
+        aShaderProgram->GetUniformLocation (theGlContext, "uUnviewMat");
 
       myUniformLocations[anIndex][OpenGl_RT_uSceneRad] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uSceneRadius");
+        aShaderProgram->GetUniformLocation (theGlContext, "uSceneRadius");
       myUniformLocations[anIndex][OpenGl_RT_uSceneEps] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uSceneEpsilon");
+        aShaderProgram->GetUniformLocation (theGlContext, "uSceneEpsilon");
       myUniformLocations[anIndex][OpenGl_RT_uLightCount] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uLightCount");
+        aShaderProgram->GetUniformLocation (theGlContext, "uLightCount");
       myUniformLocations[anIndex][OpenGl_RT_uLightAmbnt] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uGlobalAmbient");
+        aShaderProgram->GetUniformLocation (theGlContext, "uGlobalAmbient");
 
       myUniformLocations[anIndex][OpenGl_RT_uOffsetX] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uOffsetX");
+        aShaderProgram->GetUniformLocation (theGlContext, "uOffsetX");
       myUniformLocations[anIndex][OpenGl_RT_uOffsetY] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uOffsetY");
+        aShaderProgram->GetUniformLocation (theGlContext, "uOffsetY");
       myUniformLocations[anIndex][OpenGl_RT_uSamples] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uSamples");
+        aShaderProgram->GetUniformLocation (theGlContext, "uSamples");
       myUniformLocations[anIndex][OpenGl_RT_uWinSizeX] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uWinSizeX");
+        aShaderProgram->GetUniformLocation (theGlContext, "uWinSizeX");
       myUniformLocations[anIndex][OpenGl_RT_uWinSizeY] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uWinSizeY");
+        aShaderProgram->GetUniformLocation (theGlContext, "uWinSizeY");
 
       myUniformLocations[anIndex][OpenGl_RT_uTextures] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uTextureSamplers");
+        aShaderProgram->GetUniformLocation (theGlContext, "uTextureSamplers");
 
       myUniformLocations[anIndex][OpenGl_RT_uShadEnabled] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uShadowsEnable");
+        aShaderProgram->GetUniformLocation (theGlContext, "uShadowsEnable");
       myUniformLocations[anIndex][OpenGl_RT_uReflEnabled] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uReflectionsEnable");
+        aShaderProgram->GetUniformLocation (theGlContext, "uReflectionsEnable");
       myUniformLocations[anIndex][OpenGl_RT_uEnvMapEnable] =
-        aShaderProgram->GetUniformLocation (myGlContext, "uEnvironmentEnable");
+        aShaderProgram->GetUniformLocation (theGlContext, "uEnvironmentEnable");
     }
 
-    myGlContext->BindProgram (NULL);
+    theGlContext->BindProgram (NULL);
   }
 
-  if (myComputeInitStatus != OpenGl_RT_NONE)
+  if (myRaytraceInitStatus != OpenGl_RT_NONE)
   {
-    return myComputeInitStatus == OpenGl_RT_INIT;
+    return myRaytraceInitStatus == OpenGl_RT_INIT;
   }
 
   if (myRaytraceFBO1.IsNull())
@@ -1616,9 +1493,9 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
                                  1.f, -1.f,  0.f,
                                 -1.f, -1.f,  0.f };
 
-  myRaytraceScreenQuad.Init (myGlContext, 3, 6, aVertices);
+  myRaytraceScreenQuad.Init (theGlContext, 3, 6, aVertices);
 
-  myComputeInitStatus = OpenGl_RT_INIT; // initialized in normal way
+  myRaytraceInitStatus = OpenGl_RT_INIT; // initialized in normal way
 
   return Standard_True;
 }
@@ -1627,12 +1504,12 @@ Standard_Boolean OpenGl_Workspace::InitRaytraceResources (const Graphic3d_CView&
 // function : NullifyResource
 // purpose  :
 // =======================================================================
-inline void NullifyResource (const Handle(OpenGl_Context)& theContext,
+inline void NullifyResource (const Handle(OpenGl_Context)& theGlContext,
                              Handle(OpenGl_Resource)&      theResource)
 {
   if (!theResource.IsNull())
   {
-    theResource->Release (theContext.operator->());
+    theResource->Release (theGlContext.operator->());
     theResource.Nullify();
   }
 }
@@ -1641,42 +1518,119 @@ inline void NullifyResource (const Handle(OpenGl_Context)& theContext,
 // function : ReleaseRaytraceResources
 // purpose  : Releases OpenGL/GLSL shader programs
 // =======================================================================
-void OpenGl_Workspace::ReleaseRaytraceResources()
+void OpenGl_View::releaseRaytraceResources (const Handle(OpenGl_Context)& theGlContext)
 {
-  NullifyResource (myGlContext, myOpenGlFBO);
-  NullifyResource (myGlContext, myRaytraceFBO1);
-  NullifyResource (myGlContext, myRaytraceFBO2);
+  NullifyResource (theGlContext, myOpenGlFBO);
+  NullifyResource (theGlContext, myRaytraceFBO1);
+  NullifyResource (theGlContext, myRaytraceFBO2);
 
-  NullifyResource (myGlContext, myRaytraceShader);
-  NullifyResource (myGlContext, myPostFSAAShader);
+  NullifyResource (theGlContext, myRaytraceShader);
+  NullifyResource (theGlContext, myPostFSAAShader);
 
-  NullifyResource (myGlContext, myRaytraceProgram);
-  NullifyResource (myGlContext, myPostFSAAProgram);
+  NullifyResource (theGlContext, myRaytraceProgram);
+  NullifyResource (theGlContext, myPostFSAAProgram);
 
-  NullifyResource (myGlContext, mySceneNodeInfoTexture);
-  NullifyResource (myGlContext, mySceneMinPointTexture);
-  NullifyResource (myGlContext, mySceneMaxPointTexture);
+  NullifyResource (theGlContext, mySceneNodeInfoTexture);
+  NullifyResource (theGlContext, mySceneMinPointTexture);
+  NullifyResource (theGlContext, mySceneMaxPointTexture);
 
-  NullifyResource (myGlContext, myGeometryVertexTexture);
-  NullifyResource (myGlContext, myGeometryNormalTexture);
-  NullifyResource (myGlContext, myGeometryTexCrdTexture);
-  NullifyResource (myGlContext, myGeometryTriangTexture);
-  NullifyResource (myGlContext, mySceneTransformTexture);
+  NullifyResource (theGlContext, myGeometryVertexTexture);
+  NullifyResource (theGlContext, myGeometryNormalTexture);
+  NullifyResource (theGlContext, myGeometryTexCrdTexture);
+  NullifyResource (theGlContext, myGeometryTriangTexture);
+  NullifyResource (theGlContext, mySceneTransformTexture);
 
-  NullifyResource (myGlContext, myRaytraceLightSrcTexture);
-  NullifyResource (myGlContext, myRaytraceMaterialTexture);
+  NullifyResource (theGlContext, myRaytraceLightSrcTexture);
+  NullifyResource (theGlContext, myRaytraceMaterialTexture);
 
   if (myRaytraceScreenQuad.IsValid())
-    myRaytraceScreenQuad.Release (myGlContext.operator->());
+    myRaytraceScreenQuad.Release (theGlContext.operator->());
+}
+
+// =======================================================================
+// function : ResizeRaytraceBuffers
+// purpose  : Resizes OpenGL frame buffers
+// =======================================================================
+Standard_Boolean OpenGl_View::resizeRaytraceBuffers (const Standard_Integer        theSizeX,
+                                                     const Standard_Integer        theSizeY,
+                                                     const Handle(OpenGl_Context)& theGlContext)
+{
+  if (myRaytraceFBO1->GetVPSizeX() != theSizeX
+   || myRaytraceFBO1->GetVPSizeY() != theSizeY)
+  {
+    myRaytraceFBO1->Init (theGlContext, theSizeX, theSizeY);
+    myRaytraceFBO2->Init (theGlContext, theSizeX, theSizeY);
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
+// function : UpdateCamera
+// purpose  : Generates viewing rays for corners of screen quad
+// =======================================================================
+void OpenGl_View::updateCamera (const OpenGl_Mat4& theOrientation,
+                                const OpenGl_Mat4& theViewMapping,
+                                OpenGl_Vec3*       theOrigins,
+                                OpenGl_Vec3*       theDirects,
+                                OpenGl_Mat4&       theUnview)
+{
+  // compute inverse model-view-projection matrix
+  (theViewMapping * theOrientation).Inverted (theUnview);
+
+  Standard_Integer aOriginIndex = 0;
+  Standard_Integer aDirectIndex = 0;
+
+  for (Standard_Integer aY = -1; aY <= 1; aY += 2)
+  {
+    for (Standard_Integer aX = -1; aX <= 1; aX += 2)
+    {
+      OpenGl_Vec4 aOrigin (GLfloat(aX),
+                           GLfloat(aY),
+                          -1.0f,
+                           1.0f);
+
+      aOrigin = theUnview * aOrigin;
+
+      aOrigin.x() = aOrigin.x() / aOrigin.w();
+      aOrigin.y() = aOrigin.y() / aOrigin.w();
+      aOrigin.z() = aOrigin.z() / aOrigin.w();
+
+      OpenGl_Vec4 aDirect (GLfloat(aX),
+                           GLfloat(aY),
+                           1.0f,
+                           1.0f);
+
+      aDirect = theUnview * aDirect;
+
+      aDirect.x() = aDirect.x() / aDirect.w();
+      aDirect.y() = aDirect.y() / aDirect.w();
+      aDirect.z() = aDirect.z() / aDirect.w();
+
+      aDirect = aDirect - aOrigin;
+
+      GLdouble aInvLen = 1.0 / sqrt (aDirect.x() * aDirect.x() +
+                                     aDirect.y() * aDirect.y() +
+                                     aDirect.z() * aDirect.z());
+
+      theOrigins[aOriginIndex++] = OpenGl_Vec3 (static_cast<GLfloat> (aOrigin.x()),
+                                                static_cast<GLfloat> (aOrigin.y()),
+                                                static_cast<GLfloat> (aOrigin.z()));
+
+      theDirects[aDirectIndex++] = OpenGl_Vec3 (static_cast<GLfloat> (aDirect.x() * aInvLen),
+                                                static_cast<GLfloat> (aDirect.y() * aInvLen),
+                                                static_cast<GLfloat> (aDirect.z() * aInvLen));
+    }
+  }
 }
 
 // =======================================================================
 // function : UploadRaytraceData
 // purpose  : Uploads ray-trace data to the GPU
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
+Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)& theGlContext)
 {
-  if (!myGlContext->IsGlGreaterEqual (3, 1))
+  if (!theGlContext->IsGlGreaterEqual (3, 1))
   {
 #ifdef RAY_TRACE_PRINT_INFO
     std::cout << "Error: OpenGL version is less than 3.1" << std::endl;
@@ -1687,11 +1641,11 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
   /////////////////////////////////////////////////////////////////////////////
   // Prepare OpenGL textures
 
-  if (myGlContext->arbTexBindless != NULL)
+  if (theGlContext->arbTexBindless != NULL)
   {
     // If OpenGL driver supports bindless textures we need
     // to get unique 64- bit handles for using on the GPU
-    if (!myRaytraceGeometry.UpdateTextureHandles (myGlContext))
+    if (!myRaytraceGeometry.UpdateTextureHandles (theGlContext))
     {
 #ifdef RAY_TRACE_PRINT_INFO
       std::cout << "Error: Failed to get OpenGL texture handles" << std::endl;
@@ -1710,10 +1664,10 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
     mySceneMaxPointTexture  = new OpenGl_TextureBufferArb;
     mySceneTransformTexture = new OpenGl_TextureBufferArb;
 
-    if (!mySceneNodeInfoTexture->Create  (myGlContext)
-     || !mySceneMinPointTexture->Create  (myGlContext)
-     || !mySceneMaxPointTexture->Create  (myGlContext)
-     || !mySceneTransformTexture->Create (myGlContext))
+    if (!mySceneNodeInfoTexture->Create  (theGlContext)
+     || !mySceneMinPointTexture->Create  (theGlContext)
+     || !mySceneMaxPointTexture->Create  (theGlContext)
+     || !mySceneTransformTexture->Create (theGlContext))
     {
 #ifdef RAY_TRACE_PRINT_INFO
       std::cout << "Error: Failed to create scene BVH buffers" << std::endl;
@@ -1729,10 +1683,10 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
     myGeometryTexCrdTexture = new OpenGl_TextureBufferArb;
     myGeometryTriangTexture = new OpenGl_TextureBufferArb;
 
-    if (!myGeometryVertexTexture->Create (myGlContext)
-     || !myGeometryNormalTexture->Create (myGlContext)
-     || !myGeometryTexCrdTexture->Create (myGlContext)
-     || !myGeometryTriangTexture->Create (myGlContext))
+    if (!myGeometryVertexTexture->Create (theGlContext)
+     || !myGeometryNormalTexture->Create (theGlContext)
+     || !myGeometryTexCrdTexture->Create (theGlContext)
+     || !myGeometryTriangTexture->Create (theGlContext))
     {
 #ifdef RAY_TRACE_PRINT_INFO
       std::cout << "Error: Failed to create buffers for triangulation data" << std::endl;
@@ -1745,7 +1699,7 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
   {
     myRaytraceMaterialTexture = new OpenGl_TextureBufferArb;
 
-    if (!myRaytraceMaterialTexture->Create (myGlContext))
+    if (!myRaytraceMaterialTexture->Create (theGlContext))
     {
 #ifdef RAY_TRACE_PRINT_INFO
       std::cout << "Error: Failed to create buffers for material data" << std::endl;
@@ -1775,7 +1729,7 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
     aNodeTransforms[anElemIndex] = aTransform->Inversed();
   }
 
-  aResult &= mySceneTransformTexture->Init (myGlContext, 4,
+  aResult &= mySceneTransformTexture->Init (theGlContext, 4,
     myRaytraceGeometry.Size() * 4, reinterpret_cast<const GLfloat*> (aNodeTransforms));
 
   delete [] aNodeTransforms;
@@ -1809,11 +1763,11 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
   if (aTotalBVHNodesNb != 0)
   {
     aResult &= mySceneNodeInfoTexture->Init (
-      myGlContext, 4, GLsizei (aTotalBVHNodesNb), static_cast<const GLuint*>  (NULL));
+      theGlContext, 4, GLsizei (aTotalBVHNodesNb), static_cast<const GLuint*>  (NULL));
     aResult &= mySceneMinPointTexture->Init (
-      myGlContext, 3, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
+      theGlContext, 3, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
     aResult &= mySceneMaxPointTexture->Init (
-      myGlContext, 3, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
+      theGlContext, 3, GLsizei (aTotalBVHNodesNb), static_cast<const GLfloat*> (NULL));
   }
 
   if (!aResult)
@@ -1827,17 +1781,17 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
   if (aTotalElementsNb != 0)
   {
     aResult &= myGeometryTriangTexture->Init (
-      myGlContext, 4, GLsizei (aTotalElementsNb), static_cast<const GLuint*> (NULL));
+      theGlContext, 4, GLsizei (aTotalElementsNb), static_cast<const GLuint*> (NULL));
   }
 
   if (aTotalVerticesNb != 0)
   {
     aResult &= myGeometryVertexTexture->Init (
-      myGlContext, 3, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
+      theGlContext, 3, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
     aResult &= myGeometryNormalTexture->Init (
-      myGlContext, 3, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
+      theGlContext, 3, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
     aResult &= myGeometryTexCrdTexture->Init (
-      myGlContext, 2, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
+      theGlContext, 2, GLsizei (aTotalVerticesNb), static_cast<const GLfloat*> (NULL));
   }
 
   if (!aResult)
@@ -1849,14 +1803,14 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
   }
 
   const NCollection_Handle<BVH_Tree<Standard_ShortReal, 3> >& aBVH = myRaytraceGeometry.BVH();
-  const Standard_Integer aBvhLength = aBVH->Length();
-  if (aBvhLength > 0)
+
+  if (aBVH->Length() > 0)
   {
-    aResult &= mySceneNodeInfoTexture->SubData (myGlContext, 0, aBVH->Length(),
+    aResult &= mySceneNodeInfoTexture->SubData (theGlContext, 0, aBVH->Length(),
       reinterpret_cast<const GLuint*> (&aBVH->NodeInfoBuffer().front()));
-    aResult &= mySceneMinPointTexture->SubData (myGlContext, 0, aBVH->Length(),
+    aResult &= mySceneMinPointTexture->SubData (theGlContext, 0, aBVH->Length(),
       reinterpret_cast<const GLfloat*> (&aBVH->MinPointBuffer().front()));
-    aResult &= mySceneMaxPointTexture->SubData (myGlContext, 0, aBVH->Length(),
+    aResult &= mySceneMaxPointTexture->SubData (theGlContext, 0, aBVH->Length(),
       reinterpret_cast<const GLfloat*> (&aBVH->MaxPointBuffer().front()));
   }
 
@@ -1879,12 +1833,13 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
 
     if (aBvhBuffersSize != 0)
     {
-      aResult &= mySceneNodeInfoTexture->SubData (myGlContext, aBVHOffset, aBvhBuffersSize,
-                                                   reinterpret_cast<const GLuint*> (&aTriangleSet->BVH()->NodeInfoBuffer().front()));
-      aResult &= mySceneMinPointTexture->SubData (myGlContext, aBVHOffset, aBvhBuffersSize,
-                                                   reinterpret_cast<const GLfloat*> (&aTriangleSet->BVH()->MinPointBuffer().front()));
-      aResult &= mySceneMaxPointTexture->SubData (myGlContext, aBVHOffset, aBvhBuffersSize,
-                                                   reinterpret_cast<const GLfloat*> (&aTriangleSet->BVH()->MaxPointBuffer().front()));
+      aResult &= mySceneNodeInfoTexture->SubData (theGlContext, aBVHOffset, aBvhBuffersSize,
+        reinterpret_cast<const GLuint*> (&aTriangleSet->BVH()->NodeInfoBuffer().front()));
+      aResult &= mySceneMinPointTexture->SubData (theGlContext, aBVHOffset, aBvhBuffersSize,
+        reinterpret_cast<const GLfloat*> (&aTriangleSet->BVH()->MinPointBuffer().front()));
+      aResult &= mySceneMaxPointTexture->SubData (theGlContext, aBVHOffset, aBvhBuffersSize,
+        reinterpret_cast<const GLfloat*> (&aTriangleSet->BVH()->MaxPointBuffer().front()));
+
       if (!aResult)
       {
 #ifdef RAY_TRACE_PRINT_INFO
@@ -1901,12 +1856,12 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
 
     if (!aTriangleSet->Vertices.empty())
     {
-      aResult &= myGeometryNormalTexture->SubData (myGlContext, aVerticesOffset, GLsizei (aTriangleSet->Normals.size()),
-                                                   reinterpret_cast<const GLfloat*> (&aTriangleSet->Normals.front()));
-      aResult &= myGeometryTexCrdTexture->SubData (myGlContext, aVerticesOffset, GLsizei (aTriangleSet->TexCrds.size()),
-                                                   reinterpret_cast<const GLfloat*> (&aTriangleSet->TexCrds.front()));
-      aResult &= myGeometryVertexTexture->SubData (myGlContext, aVerticesOffset, GLsizei (aTriangleSet->Vertices.size()),
-                                                   reinterpret_cast<const GLfloat*> (&aTriangleSet->Vertices.front()));
+      aResult &= myGeometryNormalTexture->SubData (theGlContext, aVerticesOffset,
+        GLsizei (aTriangleSet->Normals.size()), reinterpret_cast<const GLfloat*> (&aTriangleSet->Normals.front()));
+      aResult &= myGeometryTexCrdTexture->SubData (theGlContext, aVerticesOffset,
+        GLsizei (aTriangleSet->TexCrds.size()), reinterpret_cast<const GLfloat*> (&aTriangleSet->TexCrds.front()));
+      aResult &= myGeometryVertexTexture->SubData (theGlContext, aVerticesOffset,
+        GLsizei (aTriangleSet->Vertices.size()), reinterpret_cast<const GLfloat*> (&aTriangleSet->Vertices.front()));
     }
 
     const Standard_Integer anElementsOffset = myRaytraceGeometry.ElementsOffset (aNodeIdx);
@@ -1916,7 +1871,7 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
 
     if (!aTriangleSet->Elements.empty())
     {
-      aResult &= myGeometryTriangTexture->SubData (myGlContext, anElementsOffset, GLsizei (aTriangleSet->Elements.size()),
+      aResult &= myGeometryTriangTexture->SubData (theGlContext, anElementsOffset, GLsizei (aTriangleSet->Elements.size()),
                                                    reinterpret_cast<const GLuint*> (&aTriangleSet->Elements.front()));
     }
 
@@ -1934,7 +1889,7 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
 
   if (myRaytraceGeometry.Materials.size() != 0)
   {
-    aResult &= myRaytraceMaterialTexture->Init (myGlContext, 4,
+    aResult &= myRaytraceMaterialTexture->Init (theGlContext, 4,
       GLsizei (myRaytraceGeometry.Materials.size() * 11),  myRaytraceGeometry.Materials.front().Packed());
 
     if (!aResult)
@@ -1989,157 +1944,198 @@ Standard_Boolean OpenGl_Workspace::UploadRaytraceData()
 }
 
 // =======================================================================
-// function : ResizeRaytraceBuffers
-// purpose  : Resizes OpenGL frame buffers
+// function : UpdateRaytraceLightSources
+// purpose  : Updates 3D scene light sources for ray-tracing
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::ResizeRaytraceBuffers (const Standard_Integer theSizeX,
-                                                          const Standard_Integer theSizeY)
+Standard_Boolean OpenGl_View::updateRaytraceLightSources (const OpenGl_Mat4& theInvModelView, const Handle(OpenGl_Context)& theGlContext)
 {
-  if (myRaytraceFBO1->GetVPSizeX() != theSizeX
-   || myRaytraceFBO1->GetVPSizeY() != theSizeY)
+  myRaytraceGeometry.Sources.clear();
+
+  myRaytraceGeometry.Ambient = BVH_Vec4f (0.0f, 0.0f, 0.0f, 0.0f);
+
+  for (OpenGl_ListOfLight::Iterator anItl (LightList()); anItl.More(); anItl.Next())
+  {
+    const OpenGl_Light& aLight = anItl.Value();
+
+    if (aLight.Type == Visual3d_TOLS_AMBIENT)
+    {
+      myRaytraceGeometry.Ambient += BVH_Vec4f (aLight.Color.r(),
+                                               aLight.Color.g(),
+                                               aLight.Color.b(),
+                                               0.0f);
+      continue;
+    }
+
+    BVH_Vec4f aDiffuse  (aLight.Color.r(),
+                         aLight.Color.g(),
+                         aLight.Color.b(),
+                         1.0f);
+
+    BVH_Vec4f aPosition (-aLight.Direction.x(),
+                         -aLight.Direction.y(),
+                         -aLight.Direction.z(),
+                         0.0f);
+
+    if (aLight.Type != Visual3d_TOLS_DIRECTIONAL)
+    {
+      aPosition = BVH_Vec4f (aLight.Position.x(),
+                             aLight.Position.y(),
+                             aLight.Position.z(),
+                             1.0f);
+    }
+
+    if (aLight.IsHeadlight)
+    {
+      aPosition = theInvModelView * aPosition;
+    }
+
+    myRaytraceGeometry.Sources.push_back (OpenGl_RaytraceLight (aDiffuse, aPosition));
+  }
+
+  if (myRaytraceLightSrcTexture.IsNull())  // create light source buffer
+  {
+    myRaytraceLightSrcTexture = new OpenGl_TextureBufferArb;
+
+    if (!myRaytraceLightSrcTexture->Create (theGlContext))
+    {
+#ifdef RAY_TRACE_PRINT_INFO
+      std::cout << "Error: Failed to create light source buffer" << std::endl;
+#endif
+      return Standard_False;
+    }
+  }
+  
+  if (myRaytraceGeometry.Sources.size() != 0)
   {
-    myRaytraceFBO1->Init (myGlContext, theSizeX, theSizeY);
-    myRaytraceFBO2->Init (myGlContext, theSizeX, theSizeY);
+    const GLfloat* aDataPtr = myRaytraceGeometry.Sources.front().Packed();
+    if (!myRaytraceLightSrcTexture->Init (theGlContext, 4, GLsizei (myRaytraceGeometry.Sources.size() * 2), aDataPtr))
+    {
+#ifdef RAY_TRACE_PRINT_INFO
+      std::cout << "Error: Failed to upload light source buffer" << std::endl;
+#endif
+      return Standard_False;
+    }
   }
 
   return Standard_True;
 }
 
 // =======================================================================
-// function : UpdateCamera
-// purpose  : Generates viewing rays for corners of screen quad
+// function : UpdateRaytraceEnvironmentMap
+// purpose  : Updates environment map for ray-tracing
 // =======================================================================
-void OpenGl_Workspace::UpdateCamera (const OpenGl_Mat4& theOrientation,
-                                     const OpenGl_Mat4& theViewMapping,
-                                     OpenGl_Vec3        theOrigins[4],
-                                     OpenGl_Vec3        theDirects[4],
-                                     OpenGl_Mat4&       theInvModelProj)
+Standard_Boolean OpenGl_View::updateRaytraceEnvironmentMap (const Handle(OpenGl_Context)& theGlContext)
 {
-  // compute inverse model-view-projection matrix
-  (theViewMapping * theOrientation).Inverted (theInvModelProj);
-
-  Standard_Integer aOriginIndex = 0;
-  Standard_Integer aDirectIndex = 0;
+  Standard_Boolean aResult = Standard_True;
 
-  for (Standard_Integer aY = -1; aY <= 1; aY += 2)
+  if (!myToUpdateEnvironmentMap)
   {
-    for (Standard_Integer aX = -1; aX <= 1; aX += 2)
-    {
-      OpenGl_Vec4 aOrigin (GLfloat(aX),
-                           GLfloat(aY),
-                          -1.0f,
-                           1.0f);
-
-      aOrigin = theInvModelProj * aOrigin;
-
-      aOrigin.x() = aOrigin.x() / aOrigin.w();
-      aOrigin.y() = aOrigin.y() / aOrigin.w();
-      aOrigin.z() = aOrigin.z() / aOrigin.w();
+    return aResult;
+  }
 
-      OpenGl_Vec4 aDirect (GLfloat(aX),
-                           GLfloat(aY),
-                           1.0f,
-                           1.0f);
+  for (Standard_Integer anIdx = 0; anIdx < 2; ++anIdx)
+  {
+    const Handle(OpenGl_ShaderProgram)& aProgram =
+      anIdx == 0 ? myRaytraceProgram : myPostFSAAProgram;
 
-      aDirect = theInvModelProj * aDirect;
+    if (!aProgram.IsNull())
+    {
+      aResult &= theGlContext->BindProgram (aProgram);
 
-      aDirect.x() = aDirect.x() / aDirect.w();
-      aDirect.y() = aDirect.y() / aDirect.w();
-      aDirect.z() = aDirect.z() / aDirect.w();
+      if (!myTextureEnv.IsNull() && mySurfaceDetail != Visual3d_TOD_NONE)
+      {
+        myTextureEnv->Bind (theGlContext,
+          GL_TEXTURE0 + OpenGl_RT_EnvironmentMapTexture);
 
-      aDirect = aDirect - aOrigin;
+        aResult &= aProgram->SetUniform (theGlContext,
+          myUniformLocations[anIdx][OpenGl_RT_uEnvMapEnable], 1);
+      }
+      else
+      {
+        aResult &= aProgram->SetUniform (theGlContext,
+          myUniformLocations[anIdx][OpenGl_RT_uEnvMapEnable], 0);
+      }
+    }
+  }
 
-      GLdouble aInvLen = 1.0 / sqrt (aDirect.x() * aDirect.x() +
-                                     aDirect.y() * aDirect.y() +
-                                     aDirect.z() * aDirect.z());
+  myToUpdateEnvironmentMap = Standard_False;
 
-      theOrigins[aOriginIndex++] = OpenGl_Vec3 (static_cast<GLfloat> (aOrigin.x()),
-                                                static_cast<GLfloat> (aOrigin.y()),
-                                                static_cast<GLfloat> (aOrigin.z()));
+  theGlContext->BindProgram (NULL);
 
-      theDirects[aDirectIndex++] = OpenGl_Vec3 (static_cast<GLfloat> (aDirect.x() * aInvLen),
-                                                static_cast<GLfloat> (aDirect.y() * aInvLen),
-                                                static_cast<GLfloat> (aDirect.z() * aInvLen));
-    }
-  }
+  return aResult;
 }
 
 // =======================================================================
 // function : SetUniformState
 // purpose  : Sets uniform state for the given ray-tracing shader program
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::SetUniformState (const Graphic3d_CView&        theCView,
-                                                    const Standard_Integer        theSizeX,
-                                                    const Standard_Integer        theSizeY,
-                                                    const OpenGl_Vec3*            theOrigins,
-                                                    const OpenGl_Vec3*            theDirects,
-                                                    const OpenGl_Mat4&            theUnviewMat,
-                                                    const Standard_Integer        theProgramIndex,
-                                                    Handle(OpenGl_ShaderProgram)& theRaytraceProgram)
+Standard_Boolean OpenGl_View::setUniformState (const Graphic3d_CView&        theCView,
+                                               const OpenGl_Vec3*            theOrigins,
+                                               const OpenGl_Vec3*            theDirects,
+                                               const OpenGl_Mat4&            theUnviewMat,
+                                               const Standard_Integer        theProgramId,
+                                               const Handle(OpenGl_Context)& theGlContext)
 {
-  if (theRaytraceProgram.IsNull())
+  Handle(OpenGl_ShaderProgram)& theProgram =
+    theProgramId == 0 ? myRaytraceProgram : myPostFSAAProgram;
+
+  if (theProgram.IsNull())
   {
     return Standard_False;
   }
 
-  Standard_Integer aLightSourceBufferSize =
-    static_cast<Standard_Integer> (myRaytraceGeometry.Sources.size());
-
   Standard_Boolean aResult = Standard_True;
 
+  const Standard_Integer aLightSourceBufferSize =
+    static_cast<Standard_Integer> (myRaytraceGeometry.Sources.size());
+
   // Set camera state
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uOriginLB], theOrigins[0]);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uOriginRB], theOrigins[1]);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uOriginLT], theOrigins[2]);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uOriginRT], theOrigins[3]);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uDirectLB], theDirects[0]);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uDirectRB], theDirects[1]);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uDirectLT], theDirects[2]);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uDirectRT], theDirects[3]);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uUnviewMat], theUnviewMat);
-
-  // Set window size
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uWinSizeX], theSizeX);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uWinSizeY], theSizeY);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uOriginLB], theOrigins[0]);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uOriginRB], theOrigins[1]);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uOriginLT], theOrigins[2]);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uOriginRT], theOrigins[3]);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uDirectLB], theDirects[0]);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uDirectRB], theDirects[1]);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uDirectLT], theDirects[2]);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uDirectRT], theDirects[3]);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uUnviewMat], theUnviewMat);
 
   // Set scene parameters
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uSceneEps], myRaytraceSceneEpsilon);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uLightCount], aLightSourceBufferSize);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient);
-
-  // Set rendering options
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
-  aResult &= theRaytraceProgram->SetUniform (myGlContext,
-    myUniformLocations[theProgramIndex][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uSceneRad], myRaytraceSceneRadius);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uSceneEps], myRaytraceSceneEpsilon);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uLightCount], aLightSourceBufferSize);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uLightAmbnt], myRaytraceGeometry.Ambient);
+
+  // Set run-time rendering options
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uShadEnabled], theCView.RenderParams.IsShadowEnabled ? 1 : 0);
+  aResult &= theProgram->SetUniform (theGlContext,
+    myUniformLocations[theProgramId][OpenGl_RT_uReflEnabled], theCView.RenderParams.IsReflectionEnabled ? 1 : 0);
 
   // Set array of 64-bit texture handles
-  if (myGlContext->arbTexBindless != NULL && myRaytraceGeometry.HasTextures())
+  if (theGlContext->arbTexBindless != NULL && myRaytraceGeometry.HasTextures())
   {
-    aResult &= theRaytraceProgram->SetUniform (myGlContext, "uTextureSamplers",
-      static_cast<GLsizei> (myRaytraceGeometry.TextureHandles().size()), &myRaytraceGeometry.TextureHandles()[0]);
+    aResult &= theProgram->SetUniform (theGlContext, "uTextureSamplers", static_cast<GLsizei> (
+      myRaytraceGeometry.TextureHandles().size()), &myRaytraceGeometry.TextureHandles()[0]);
   }
 
   if (!aResult)
   {
 #ifdef RAY_TRACE_PRINT_INFO
-    std::cout << "Info: Not all uniforms were detected (for program " << theProgramIndex << ")" << std::endl;
+    std::cout << "Info: Not all uniforms were detected for program " << theProgramId << std::endl;
 #endif
   }
 
@@ -2147,319 +2143,274 @@ Standard_Boolean OpenGl_Workspace::SetUniformState (const Graphic3d_CView&
 }
 
 // =======================================================================
+// function : BindRaytraceTextures
+// purpose  : Binds ray-trace textures to corresponding texture units
+// =======================================================================
+void OpenGl_View::bindRaytraceTextures (const Handle(OpenGl_Context)& theGlContext)
+{
+  mySceneMinPointTexture->BindTexture    (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+  mySceneMaxPointTexture->BindTexture    (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+  mySceneNodeInfoTexture->BindTexture    (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+  myGeometryVertexTexture->BindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+  myGeometryNormalTexture->BindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+  myGeometryTexCrdTexture->BindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
+  myGeometryTriangTexture->BindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+  mySceneTransformTexture->BindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+  myRaytraceMaterialTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
+  myRaytraceLightSrcTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+
+  if (!myOpenGlFBO.IsNull())
+  {
+    myOpenGlFBO->ColorTexture()->Bind        (theGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+    myOpenGlFBO->DepthStencilTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+  }
+}
+
+// =======================================================================
+// function : UnbindRaytraceTextures
+// purpose  : Unbinds ray-trace textures from corresponding texture units
+// =======================================================================
+void OpenGl_View::unbindRaytraceTextures (const Handle(OpenGl_Context)& theGlContext)
+{
+  mySceneMinPointTexture->UnbindTexture    (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
+  mySceneMaxPointTexture->UnbindTexture    (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
+  mySceneNodeInfoTexture->UnbindTexture    (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
+  myGeometryVertexTexture->UnbindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
+  myGeometryNormalTexture->UnbindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
+  myGeometryTexCrdTexture->UnbindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
+  myGeometryTriangTexture->UnbindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
+  mySceneTransformTexture->UnbindTexture   (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
+  myRaytraceMaterialTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
+  myRaytraceLightSrcTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+
+  if (!myOpenGlFBO.IsNull())
+  {
+    myOpenGlFBO->ColorTexture()->Unbind        (theGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
+    myOpenGlFBO->DepthStencilTexture()->Unbind (theGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+  }
+
+  theGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
+}
+
+// =======================================================================
 // function : RunRaytraceShaders
 // purpose  : Runs ray-tracing shader programs
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& theCView,
-                                                       const Standard_Integer theSizeX,
-                                                       const Standard_Integer theSizeY,
-                                                       const OpenGl_Vec3      theOrigins[4],
-                                                       const OpenGl_Vec3      theDirects[4],
-                                                       const OpenGl_Mat4&     theUnviewMat,
-                                                       OpenGl_FrameBuffer*    theFrameBuffer)
+Standard_Boolean OpenGl_View::runRaytraceShaders (const Graphic3d_CView&        theCView,
+                                                  const Standard_Integer        theSizeX,
+                                                  const Standard_Integer        theSizeY,
+                                                  const OpenGl_Vec3*            theOrigins,
+                                                  const OpenGl_Vec3*            theDirects,
+                                                  const OpenGl_Mat4&            theUnviewMat,
+                                                  OpenGl_FrameBuffer*           theOutputFBO,
+                                                  const Handle(OpenGl_Context)& theGlContext)
 {
-  mySceneMinPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
-  mySceneMaxPointTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
-  mySceneNodeInfoTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
-  myGeometryVertexTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
-  myGeometryNormalTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
-  myGeometryTexCrdTexture->BindTexture (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
-  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);
-  
-  myOpenGlFBO->ColorTexture()->Bind        (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlColorTexture);
-  myOpenGlFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_OpenGlDepthTexture);
+  bindRaytraceTextures (theGlContext);
 
   if (theCView.RenderParams.IsAntialiasingEnabled) // render source image to FBO
   {
-    myRaytraceFBO1->BindBuffer (myGlContext);
-    
+    myRaytraceFBO1->BindBuffer (theGlContext);
+
     glDisable (GL_BLEND);
   }
 
-  myGlContext->BindProgram (myRaytraceProgram);
+  Standard_Boolean aResult = theGlContext->BindProgram (myRaytraceProgram);
 
-  SetUniformState (theCView,
-                   theSizeX,
-                   theSizeY,
-                   theOrigins,
-                   theDirects,
-                   theUnviewMat,
-                   0, // ID of RT program
-                   myRaytraceProgram);
+  aResult &= setUniformState (theCView,
+                              theOrigins,
+                              theDirects,
+                              theUnviewMat,
+                              0, // ID of RT program
+                              theGlContext);
 
-  myGlContext->core20fwd->glEnableVertexAttribArray (Graphic3d_TOA_POS);
+  myRaytraceScreenQuad.BindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
   {
-    myGlContext->core20fwd->glVertexAttribPointer (Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL);
-    myGlContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+    if (aResult)
+      theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
   }
-  myGlContext->core20fwd->glDisableVertexAttribArray (Graphic3d_TOA_POS);
+  myRaytraceScreenQuad.UnbindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
 
-  if (!theCView.RenderParams.IsAntialiasingEnabled)
+  if (!theCView.RenderParams.IsAntialiasingEnabled || !aResult)
   {
-    myGlContext->BindProgram (NULL);
+    unbindRaytraceTextures (theGlContext);
 
-    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);
-    myGeometryVertexTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
-    myGeometryNormalTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
-    myGeometryTexCrdTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
-    myGeometryTriangTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
-    mySceneTransformTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
-    myRaytraceMaterialTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
-    myRaytraceLightSrcTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+    theGlContext->BindProgram (NULL);
 
-    myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
-
-    return Standard_True;
+    return aResult;
   }
 
-  myRaytraceFBO1->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
-
-  myGlContext->BindProgram (myPostFSAAProgram);
+  myRaytraceFBO1->ColorTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
 
-  SetUniformState (theCView,
-                   theSizeX,
-                   theSizeY,
-                   theOrigins,
-                   theDirects,
-                   theUnviewMat,
-                   1, // ID of FSAA program
-                   myPostFSAAProgram);
+  aResult &= theGlContext->BindProgram (myPostFSAAProgram);
 
-  myGlContext->core20fwd->glEnableVertexAttribArray (Graphic3d_TOA_POS);
-  myGlContext->core20fwd->glVertexAttribPointer (Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL);
+  aResult &= setUniformState (theCView,
+                              theOrigins,
+                              theDirects,
+                              theUnviewMat,
+                              1, // ID of FSAA program
+                              theGlContext);
 
-  // Perform multi-pass adaptive FSAA using ping-pong technique.
-  // We use 'FLIPTRI' sampling pattern changing for every pixel
-  // (3 additional samples per pixel, the 1st sample is already
-  // available from initial ray-traced image).
-  for (Standard_Integer anIt = 1; anIt < 4; ++anIt)
+  myRaytraceScreenQuad.BindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
   {
-    GLfloat aOffsetX = 1.f / theSizeX;
-    GLfloat aOffsetY = 1.f / theSizeY;
-
-    if (anIt == 1)
-    {
-      aOffsetX *= -0.55f;
-      aOffsetY *=  0.55f;
-    }
-    else if (anIt == 2)
-    {
-      aOffsetX *=  0.00f;
-      aOffsetY *= -0.55f;
-    }
-    else if (anIt == 3)
+    // Perform multi-pass adaptive FSAA using ping-pong technique.
+    // We use 'FLIPTRI' sampling pattern changing for every pixel
+    // (3 additional samples per pixel, the 1st sample is already
+    // available from initial ray-traced image).
+    for (Standard_Integer anIt = 1; anIt < 4; ++anIt)
     {
-      aOffsetX *= 0.55f;
-      aOffsetY *= 0.00f;
-    }
+      GLfloat aOffsetX = 1.f / theSizeX;
+      GLfloat aOffsetY = 1.f / theSizeY;
 
-    myPostFSAAProgram->SetUniform (myGlContext,
-      myUniformLocations[1][OpenGl_RT_uSamples], anIt + 1);
-    myPostFSAAProgram->SetUniform (myGlContext,
-      myUniformLocations[1][OpenGl_RT_uOffsetX], aOffsetX);
-    myPostFSAAProgram->SetUniform (myGlContext,
-      myUniformLocations[1][OpenGl_RT_uOffsetY], aOffsetY);
+      if (anIt == 1)
+      {
+        aOffsetX *= -0.55f;
+        aOffsetY *=  0.55f;
+      }
+      else if (anIt == 2)
+      {
+        aOffsetX *=  0.00f;
+        aOffsetY *= -0.55f;
+      }
+      else if (anIt == 3)
+      {
+        aOffsetX *= 0.55f;
+        aOffsetY *= 0.00f;
+      }
 
-    Handle(OpenGl_FrameBuffer)& aFramebuffer = anIt % 2 ? myRaytraceFBO2 : myRaytraceFBO1;
+      aResult &= myPostFSAAProgram->SetUniform (theGlContext,
+        myUniformLocations[1][OpenGl_RT_uSamples], anIt + 1);
+      aResult &= myPostFSAAProgram->SetUniform (theGlContext,
+        myUniformLocations[1][OpenGl_RT_uOffsetX], aOffsetX);
+      aResult &= myPostFSAAProgram->SetUniform (theGlContext,
+        myUniformLocations[1][OpenGl_RT_uOffsetY], aOffsetY);
 
-    if (anIt == 3) // disable FBO on last iteration
-    {
-      glEnable (GL_BLEND);
+      Handle(OpenGl_FrameBuffer)& aFramebuffer = anIt % 2 ? myRaytraceFBO2 : myRaytraceFBO1;
 
-      if (theFrameBuffer != NULL)
-        theFrameBuffer->BindBuffer (myGlContext);
-    }
-    else
-    {
-      aFramebuffer->BindBuffer (myGlContext);
-    }
+      if (anIt == 3) // disable FBO on last iteration
+      {
+        glEnable (GL_BLEND);
+
+        if (theOutputFBO != NULL)
+          theOutputFBO->BindBuffer (theGlContext);
+      }
+      else
+      {
+        aFramebuffer->BindBuffer (theGlContext);
+      }
 
-    myGlContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
+      theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
 
-    if (anIt != 3) // set input for the next pass
-    {
-      aFramebuffer->ColorTexture()->Bind (myGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
-      aFramebuffer->UnbindBuffer (myGlContext);
+      if (anIt != 3) // set input for the next pass
+      {
+        aFramebuffer->ColorTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_FSAAInputTexture);
+      }
     }
   }
+  myRaytraceScreenQuad.UnbindVertexAttrib (theGlContext, Graphic3d_TOA_POS);
 
-  myGlContext->core20fwd->glDisableVertexAttribArray (Graphic3d_TOA_POS);
-
-  myGlContext->BindProgram (NULL);
-  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);
-  myGeometryVertexTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
-  myGeometryNormalTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
-  myGeometryTexCrdTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
-  myGeometryTriangTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
-  mySceneTransformTexture->UnbindTexture     (myGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
-  myRaytraceMaterialTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
-  myRaytraceLightSrcTexture->UnbindTexture   (myGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+  unbindRaytraceTextures (theGlContext);
 
-  myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
+  theGlContext->BindProgram (NULL);
 
-  return Standard_True;
+  return aResult;
 }
 
 // =======================================================================
 // function : Raytrace
 // purpose  : Redraws the window using OpenGL/GLSL ray-tracing
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
-                                             const Standard_Integer theSizeX,
-                                             const Standard_Integer theSizeY,
-                                             const Aspect_CLayer2d& theCOverLayer,
-                                             const Aspect_CLayer2d& theCUnderLayer,
-                                             OpenGl_FrameBuffer*    theFrameBuffer)
+Standard_Boolean OpenGl_View::raytrace (const Graphic3d_CView&        theCView,
+                                        const Standard_Integer        theSizeX,
+                                        const Standard_Integer        theSizeY,
+                                        OpenGl_FrameBuffer*           theOutputFBO,
+                                        const Handle(OpenGl_Context)& theGlContext)
 {
-  if (!ResizeRaytraceBuffers (theSizeX, theSizeY))
+  if (!initRaytraceResources (theCView, theGlContext))
+  {
     return Standard_False;
+  }
+
+  if (!resizeRaytraceBuffers (theSizeX, theSizeY, theGlContext))
+  {
+    return Standard_False;
+  }
 
-  if (!UpdateRaytraceEnvironmentMap())
+  if (!updateRaytraceEnvironmentMap (theGlContext))
+  {
     return Standard_False;
+  }
 
   // Get model-view and projection matrices
   OpenGl_Mat4 aOrientationMatrix;
   OpenGl_Mat4 aViewMappingMatrix;
+  OpenGl_Mat4 aInverOrientMatrix;
 
-  myView->GetMatrices (aOrientationMatrix,
-                       aViewMappingMatrix);
+  GetMatrices (aOrientationMatrix,
+               aViewMappingMatrix);
 
-  OpenGl_Mat4 aInvOrientationMatrix;
-  aOrientationMatrix.Inverted (aInvOrientationMatrix);
+  aOrientationMatrix.Inverted (aInverOrientMatrix);
 
-  if (!UpdateRaytraceLightSources (aInvOrientationMatrix))
+  if (!updateRaytraceLightSources (aInverOrientMatrix, theGlContext))
+  {
     return Standard_False;
+  }
 
   OpenGl_Vec3 aOrigins[4];
   OpenGl_Vec3 aDirects[4];
   OpenGl_Mat4 anUnviewMat;
 
-  UpdateCamera (aOrientationMatrix,
+  updateCamera (aOrientationMatrix,
                 aViewMappingMatrix,
                 aOrigins,
                 aDirects,
                 anUnviewMat);
 
-  Standard_Boolean wasBlendingEnabled = glIsEnabled (GL_BLEND);
-  Standard_Boolean wasDepthTestEnabled = glIsEnabled (GL_DEPTH_TEST);
-
+  glEnable (GL_BLEND);
   glDisable (GL_DEPTH_TEST);
+  glBlendFunc (GL_ONE, GL_SRC_ALPHA);
 
-  if (theFrameBuffer != NULL)
+  if (theOutputFBO != NULL)
   {
-    theFrameBuffer->BindBuffer (myGlContext);
+    theOutputFBO->BindBuffer (theGlContext);
   }
 
-  if (NamedStatus & OPENGL_NS_WHITEBACK)
-  {
-    glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
-  }
-  else
-  {
-    glClearColor (myBgColor.rgb[0],
-                  myBgColor.rgb[1],
-                  myBgColor.rgb[2],
-                  1.0f);
-  }
-
-  glClear (GL_COLOR_BUFFER_BIT);
-
-  myView->DrawBackground (this);
-
-  myView->RedrawLayer2d (myPrintContext, this, theCView, theCUnderLayer);
-
-  myGlContext->WorldViewState.Push();
-  myGlContext->ProjectionState.Push();
-
-  myGlContext->WorldViewState.SetIdentity();
-  myGlContext->ProjectionState.SetIdentity();
-
-  myGlContext->ApplyProjectionMatrix();
-  myGlContext->ApplyWorldViewMatrix();
-
-  glEnable (GL_BLEND);
-  glBlendFunc (GL_ONE, GL_SRC_ALPHA);
-
   // Generate ray-traced image
   if (myIsRaytraceDataValid)
   {
-    myRaytraceScreenQuad.Bind (myGlContext);
+    myRaytraceScreenQuad.Bind (theGlContext);
 
-    if (!myRaytraceGeometry.AcquireTextures (myGlContext))
+    if (!myRaytraceGeometry.AcquireTextures (theGlContext))
     {
-      const TCollection_ExtendedString aMessage = "Error: Failed to acquire OpenGL image textures";
-
-      myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-        GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_MEDIUM_ARB, aMessage);
+      theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_ERROR_ARB,
+        0, GL_DEBUG_SEVERITY_MEDIUM_ARB, "Error: Failed to acquire OpenGL image textures");
     }
 
-    RunRaytraceShaders (theCView,
-                        theSizeX,
-                        theSizeY,
-                        aOrigins,
-                        aDirects,
-                        anUnviewMat,
-                        theFrameBuffer);
+    Standard_Boolean aResult = runRaytraceShaders (theCView,
+                                                   theSizeX,
+                                                   theSizeY,
+                                                   aOrigins,
+                                                   aDirects,
+                                                   anUnviewMat,
+                                                   theOutputFBO,
+                                                   theGlContext);
 
-    if (!myRaytraceGeometry.ReleaseTextures (myGlContext))
+    if (!aResult)
     {
-      const TCollection_ExtendedString aMessage = "Error: Failed to release OpenGL image textures";
+      theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_ERROR_ARB,
+        0, GL_DEBUG_SEVERITY_MEDIUM_ARB, "Error: Failed to execute ray-tracing shaders");
+    }
 
-      myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
-        GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_MEDIUM_ARB, aMessage);
+    if (!myRaytraceGeometry.ReleaseTextures (theGlContext))
+    {
+      theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_ERROR_ARB,
+        0, GL_DEBUG_SEVERITY_MEDIUM_ARB, "Error: Failed to release OpenGL image textures");
     }
 
-    myRaytraceScreenQuad.Unbind (myGlContext);
+    myRaytraceScreenQuad.Unbind (theGlContext);
   }
 
-  if (!wasBlendingEnabled)
-    glDisable (GL_BLEND);
-
-  if (wasDepthTestEnabled)
-    glEnable (GL_DEPTH_TEST);
-
-  myGlContext->WorldViewState.Pop();
-  myGlContext->ProjectionState.Pop();
-
-  myGlContext->ApplyProjectionMatrix();
-
-  // Redraw trihedron
-  myView->RedrawTrihedron (this);
+  glDisable (GL_BLEND);
+  glEnable (GL_DEPTH_TEST);
 
-  // Redraw overlay
-  const int aMode = 0;
-  DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
-  myView->RedrawLayer2d (myPrintContext, this, theCView, theCOverLayer);
-  DisplayCallback (theCView, aMode);
   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);
-}
+}
\ No newline at end of file
index e608847..606d308 100644 (file)
@@ -146,15 +146,8 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDrive
   NamedStatus (0),
   HighlightColor (&THE_WHITE_COLOR),
   //
-  myComputeInitStatus (OpenGl_RT_NONE),
-  myIsRaytraceDataValid (Standard_False),
-  myIsRaytraceWarnTextures (Standard_False),
   myHasFboBlit (Standard_True),
-  myViewModificationStatus (0),
-  myLayersModificationStatus (0),
   //
-  myRaytraceFilter       (new OpenGl_RaytraceFilter()),
-  myToRedrawGL           (Standard_True),
   myViewId               (-1),
   myAntiAliasingMode     (3),
   myTransientDrawToFront (Standard_True),
@@ -252,8 +245,6 @@ OpenGl_Workspace::~OpenGl_Workspace()
   {
     myFullScreenQuad.Release (myGlContext.operator->());
   }
-
-  ReleaseRaytraceResources();
 }
 
 // =======================================================================
@@ -727,77 +718,25 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
   else
   {
     myResultFBO->Release (myGlContext.operator->());
+    myResultFBO->ChangeViewport (0, 0);
   }
 
-  myToRedrawGL = Standard_True;
-  if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
-   && myComputeInitStatus != OpenGl_RT_FAIL)
+  // draw entire frame using normal OpenGL pipeline
+  if (myResultFBO->IsValid())
   {
-    if (InitRaytraceResources (theCView) && 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);
-
-      if (myOpenGlFBO.IsNull())
-      {
-        myOpenGlFBO = new OpenGl_FrameBuffer();
-      }
-      if (myOpenGlFBO->GetVPSizeX() != aSizeX
-       || myOpenGlFBO->GetVPSizeY() != aSizeY)
-      {
-        myOpenGlFBO->Init (myGlContext, 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 (myGlContext);
-      redraw1 (theCView, anEmptyCLayer, anEmptyCLayer);
-      myOpenGlFBO->UnbindBuffer (myGlContext);
-
-      Raytrace (theCView, aSizeX, aSizeY,
-                theCOverLayer, theCUnderLayer,
-                myResultFBO->IsValid() ? myResultFBO.operator->() : aFrameBuffer);
-      myBackBufferRestored = Standard_True;
-      myIsImmediateDrawn   = Standard_False;
-      if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aFrameBuffer))
-      {
-        toSwap = false;
-      }
-
-      SetRenderFilter (aRenderFilter);
-
-      theCView.WasRedrawnGL = Standard_False;
-    }
+    myResultFBO->BindBuffer (myGlContext);
   }
-
-  if (myToRedrawGL)
+  else if (aFrameBuffer != NULL)
   {
-    // draw entire frame using normal OpenGL pipeline
-    if (myResultFBO->IsValid())
-    {
-      myResultFBO->BindBuffer (myGlContext);
-    }
-    else if (aFrameBuffer != NULL)
-    {
-      aFrameBuffer->BindBuffer (myGlContext);
-    }
-
-    redraw1 (theCView, theCUnderLayer, theCOverLayer);
-    myBackBufferRestored = Standard_True;
-    myIsImmediateDrawn   = Standard_False;
-    if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aFrameBuffer))
-    {
-      toSwap = false;
-    }
+    aFrameBuffer->BindBuffer (myGlContext);
+  }
 
-    theCView.WasRedrawnGL = Standard_True;
+  redraw1 (theCView, theCUnderLayer, theCOverLayer);
+  myBackBufferRestored = Standard_True;
+  myIsImmediateDrawn   = Standard_False;
+  if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aFrameBuffer))
+  {
+    toSwap = false;
   }
 
   if (aFrameBuffer != NULL)
@@ -885,25 +824,17 @@ void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
     glDisable (GL_DEPTH_TEST);
   }
 
-  if (!ToRedrawGL())
+  if (NamedStatus & OPENGL_NS_WHITEBACK)
   {
-    // set background to black
-    glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
-    toClear |= GL_DEPTH_BUFFER_BIT; //
+    // set background to white
+    glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
+    toClear |= GL_DEPTH_BUFFER_BIT;
   }
   else
   {
-    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);
-    }
+    glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
   }
+
   glClear (toClear);
 
   Handle(OpenGl_Workspace) aWS (this);
@@ -1211,3 +1142,21 @@ bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView,
   }
   return 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 5f74ef3..2b1ba45 100644 (file)
@@ -104,8 +104,14 @@ public:
   //! Default constructor.
   OpenGl_RaytraceFilter() {}
 
+  //! Returns the previously set filter.
+  const Handle(OpenGl_RenderFilter)& PrevRenderFilter()
+  {
+    return myPrevRenderFilter;
+  }
+
   //! Remembers the previously set filter.
-  inline void SetPrevRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter)
+  void SetPrevRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter)
   {
     myPrevRenderFilter = theFilter;
   }
@@ -259,8 +265,8 @@ 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; }
+  //! Returns framebuffer storing cached main presentation of the view.
+  const Handle(OpenGl_FrameBuffer)& ResultFBO() const { return myResultFBO; }
 
 protected:
 
@@ -292,358 +298,7 @@ protected:
   void setTextureParams (Handle(OpenGl_Texture)&                theTexture,
                          const Handle(Graphic3d_TextureParams)& theParams);
 
-protected:
-
-  //! Result of OpenGL shaders initialization.
-  enum RaytraceInitStatus
-  {
-    OpenGl_RT_NONE,
-    OpenGl_RT_INIT,
-    OpenGl_RT_FAIL
-  };
-
-  //! Describes update mode (state).
-  enum GeomUpdateMode
-  {
-    OpenGl_GUM_CHECK,   //!< check if geometry update is necessary
-    OpenGl_GUM_PREPARE, //!< collect unchanged objects
-    OpenGl_GUM_UPDATE   //!< update raytracing data, rebuild changed objects
-  };
-
-  //! Defines frequently used shader variables.
-  enum ShaderVariableIndex
-  {
-    OpenGl_RT_aPosition,
-
-    OpenGl_RT_uOriginLT,
-    OpenGl_RT_uOriginLB,
-    OpenGl_RT_uOriginRT,
-    OpenGl_RT_uOriginRB,
-    OpenGl_RT_uDirectLT,
-    OpenGl_RT_uDirectLB,
-    OpenGl_RT_uDirectRT,
-    OpenGl_RT_uDirectRB,
-    OpenGl_RT_uUnviewMat,
-
-    OpenGl_RT_uSceneRad,
-    OpenGl_RT_uSceneEps,
-    OpenGl_RT_uLightAmbnt,
-    OpenGl_RT_uLightCount,
-
-    OpenGl_RT_uShadEnabled,
-    OpenGl_RT_uReflEnabled,
-    OpenGl_RT_uEnvMapEnable,
-
-    OpenGl_RT_uOffsetX,
-    OpenGl_RT_uOffsetY,
-    OpenGl_RT_uSamples,
-    OpenGl_RT_uWinSizeX,
-    OpenGl_RT_uWinSizeY,
-
-    OpenGl_RT_uTextures,
-
-    OpenGl_RT_NbVariables // special field
-  };
-
-  //! Defines texture samplers.
-  enum ShaderSamplerNames
-  {
-    OpenGl_RT_SceneNodeInfoTexture  = 0,
-    OpenGl_RT_SceneMinPointTexture  = 1,
-    OpenGl_RT_SceneMaxPointTexture  = 2,
-    OpenGl_RT_SceneTransformTexture = 3,
-
-    OpenGl_RT_GeometryVertexTexture = 4,
-    OpenGl_RT_GeometryNormalTexture = 5,
-    OpenGl_RT_GeometryTexCrdTexture = 6,
-    OpenGl_RT_GeometryTriangTexture = 7,
-
-    OpenGl_RT_EnvironmentMapTexture = 8,
-
-    OpenGl_RT_RaytraceMaterialTexture = 9,
-    OpenGl_RT_RaytraceLightSrcTexture = 10,
-
-    OpenGl_RT_FSAAInputTexture = 11,
-
-    OpenGl_RT_OpenGlColorTexture = 12,
-    OpenGl_RT_OpenGlDepthTexture = 13
-  };
-
-  //! Tool class for management of shader sources.
-  class ShaderSource
-  {
-  public:
-
-    //! Creates new uninitialized shader source.
-    ShaderSource()
-    {
-      //
-    }
-
-    //! Creates new shader source from specified file.
-    ShaderSource (const TCollection_AsciiString& theFileName)
-    {
-      Load (&theFileName, 1);
-    }
-
-  public:
-
-    //! Returns prefix to insert before the source.
-    const TCollection_AsciiString& Prefix() const
-    {
-      return myPrefix;
-    }
-
-    //! Sets prefix to insert before the source.
-    void SetPrefix (const TCollection_AsciiString& thePrefix)
-    {
-      myPrefix = thePrefix;
-    }
-
-    //! Returns shader source combined with prefix.
-    TCollection_AsciiString Source() const;
-
-    //! Loads shader source from specified files.
-    void Load (const TCollection_AsciiString* theFileNames, const Standard_Integer theCount);
-
-  private:
-
-    TCollection_AsciiString mySource; //!< Source string of the shader object
-    TCollection_AsciiString myPrefix; //!< Prefix to insert before the source
-
-  };
-
-  //! Default ray-tracing depth.
-  static const Standard_Integer THE_DEFAULT_NB_BOUNCES = 3;
-
-  //! Default size of traversal stack.
-  static const Standard_Integer THE_DEFAULT_STACK_SIZE = 24;
-
-  //! Compile-time ray-tracing parameters.
-  struct RaytracingParams
-  {
-    //! Actual size of traversal stack in shader program.
-    Standard_Integer StackSize;
-
-    //! Actual ray-tracing depth (number of ray bounces).
-    Standard_Integer NbBounces;
-
-    //! Sets light propagation through transparent media.
-    Standard_Boolean TransparentShadows;
-
-    //! Creates default compile-time ray-tracing parameters.
-    RaytracingParams()
-    : StackSize (THE_DEFAULT_STACK_SIZE),
-      NbBounces (THE_DEFAULT_NB_BOUNCES),
-      TransparentShadows (Standard_False)
-    {
-      //
-    }
-  };
-
-protected: //! @name methods related to ray-tracing
-
-  //! Updates 3D scene geometry for ray-tracing.
-  Standard_Boolean UpdateRaytraceGeometry (GeomUpdateMode theMode);
-
-  //! Checks to see if the structure is modified.
-  Standard_Boolean CheckRaytraceStructure (const OpenGl_Structure* theStructure);
-
-  //! Creates ray-tracing material properties.
-  Standard_Boolean CreateMaterial (const OpenGl_AspectFace* theAspect, OpenGl_RaytraceMaterial& theMaterial);
-
-  //! Updates 3D scene light sources for ray-tracing.
-  Standard_Boolean UpdateRaytraceLightSources (const OpenGl_Mat4& theInvModelView);
-
-  //! Updates environment map for ray-tracing.
-  Standard_Boolean UpdateRaytraceEnvironmentMap();
-
-  //! Adds OpenGL structure to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceStructure (const OpenGl_Structure* theStructure, std::set<const OpenGl_Structure*>& theElements);
-
-  //! Adds OpenGL groups to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceGroups (const OpenGl_Structure*   theStructure,
-                                      const Standard_Integer    theStructMatId,
-                                      const Standard_ShortReal* theTransform);
-
-  //! Adds OpenGL primitive array to ray-traced scene geometry.
-  OpenGl_TriangleSet* AddRaytracePrimitiveArray (
-    const OpenGl_PrimitiveArray* theArray, int theMatID, const OpenGl_Mat4* theTrans);
-
-  //! Adds vertex indices from OpenGL primitive array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceVertexIndices (OpenGl_TriangleSet&          theSet,
-                                             const OpenGl_PrimitiveArray& theArray,
-                                             Standard_Integer             theOffset,
-                                             Standard_Integer             theCount,
-                                             Standard_Integer             theMatID);
-
-  //! Adds OpenGL triangle array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceTriangleArray (OpenGl_TriangleSet&                  theSet,
-                                             const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                             Standard_Integer                     theOffset,
-                                             Standard_Integer                     theCount,
-                                             Standard_Integer                     theMatID);
-
-  //! Adds OpenGL triangle fan array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceTriangleFanArray (OpenGl_TriangleSet&                  theSet,
-                                                const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                Standard_Integer                     theOffset,
-                                                Standard_Integer                     theCount,
-                                                Standard_Integer                     theMatID);
-
-  //! Adds OpenGL triangle strip array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceTriangleStripArray (OpenGl_TriangleSet&                  theSet,
-                                                  const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                  Standard_Integer                     theOffset,
-                                                  Standard_Integer                     theCount,
-                                                  Standard_Integer                     theMatID);
-
-  //! Adds OpenGL quadrangle array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceQuadrangleArray (OpenGl_TriangleSet&                  theSet,
-                                               const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                               Standard_Integer                     theOffset,
-                                               Standard_Integer                     theCount,
-                                               Standard_Integer                     theMatID);
-
-  //! Adds OpenGL quadrangle strip array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceQuadrangleStripArray (OpenGl_TriangleSet&                  theSet,
-                                                    const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                                    Standard_Integer                     theOffset,
-                                                    Standard_Integer                     theCount,
-                                                    Standard_Integer                     theMatID);
-
-  //! Adds OpenGL polygon array to ray-traced scene geometry.
-  Standard_Boolean AddRaytracePolygonArray (OpenGl_TriangleSet&                  theSet,
-                                            const Handle(Graphic3d_IndexBuffer)& theIndices,
-                                            Standard_Integer                     theOffset,
-                                            Standard_Integer                     theCount,
-                                            Standard_Integer                     theMatID);
-
-  //! Loads and compiles shader object from specified source.
-  Handle(OpenGl_ShaderObject) LoadShader (const ShaderSource& theSource, GLenum theType);
-
-  //! Performs safe exit when shaders initialization fails.
-  Standard_Boolean SafeFailBack (const TCollection_ExtendedString& theMessage);
-
-  //! Generates shader prefix based on current ray-tracing options.
-  TCollection_AsciiString GenerateShaderPrefix();
-
-  //! Initializes OpenGL/GLSL shader programs.
-  Standard_Boolean InitRaytraceResources (const Graphic3d_CView& theCView);
-
-  //! Releases OpenGL/GLSL shader programs.
-  void ReleaseRaytraceResources();
-
-  //! Uploads ray-trace data to the GPU.
-  Standard_Boolean UploadRaytraceData();
-
-  //! Resizes OpenGL frame buffers.
-  Standard_Boolean ResizeRaytraceBuffers (const Standard_Integer theSizeX,
-                                          const Standard_Integer theSizeY);
-
-  //! Generates viewing rays for corners of screen quad.
-  void UpdateCamera (const OpenGl_Mat4& theOrientation,
-                     const OpenGl_Mat4& theViewMapping,
-                     OpenGl_Vec3        theOrigins[4],
-                     OpenGl_Vec3        theDirects[4],
-                     OpenGl_Mat4&       theInvModelProj);
-
-  //! Sets uniform state for the given ray-tracing shader program.
-  Standard_Boolean SetUniformState (const Graphic3d_CView&        theCView,
-                                    const Standard_Integer        theSizeX,
-                                    const Standard_Integer        theSizeY,
-                                    const OpenGl_Vec3*            theOrigins,
-                                    const OpenGl_Vec3*            theDirects,
-                                    const OpenGl_Mat4&            theUnviewMat,
-                                    const Standard_Integer        theProgramIndex,
-                                    Handle(OpenGl_ShaderProgram)& theRaytraceProgram);
-
-  //! Runs ray-tracing shader programs.
-  Standard_Boolean RunRaytraceShaders (const Graphic3d_CView& theCView,
-                                       const Standard_Integer theSizeX,
-                                       const Standard_Integer theSizeY,
-                                       const OpenGl_Vec3      theOrigins[4],
-                                       const OpenGl_Vec3      theDirects[4],
-                                       const OpenGl_Mat4&     theUnviewMat,
-                                       OpenGl_FrameBuffer*    theFrameBuffer);
-
-  //! Redraws the window using OpenGL/GLSL ray-tracing.
-  Standard_Boolean Raytrace (const Graphic3d_CView& theCView,
-                             const Standard_Integer theSizeX,
-                             const Standard_Integer theSizeY,
-                             const Aspect_CLayer2d& theCOverLayer,
-                             const Aspect_CLayer2d& theCUnderLayer,
-                             OpenGl_FrameBuffer*    theFrameBuffer);
-
-protected: //! @name fields related to ray-tracing
-
-  //! Result of shaders initialization.
-  RaytraceInitStatus myComputeInitStatus;
-
-  //! Is geometry data valid?
-  Standard_Boolean myIsRaytraceDataValid;
-
-  //! Warning about missing extension GL_ARB_bindless_texture has been displayed?
-  Standard_Boolean myIsRaytraceWarnTextures;
-
-  //! 3D scene geometry data for ray-tracing.
-  OpenGl_RaytraceGeometry myRaytraceGeometry;
-
-  //! Radius of bounding sphere of the scene.
-  Standard_ShortReal myRaytraceSceneRadius;
-  //! Scene epsilon to prevent self-intersections.
-  Standard_ShortReal myRaytraceSceneEpsilon;
-
-  //! Compile-time ray-tracing parameters.
-  RaytracingParams myRaytraceParameters;
-
-  //! OpenGL/GLSL source of ray-tracing fragment shader.
-  ShaderSource myRaytraceShaderSource;
-  //! OpenGL/GLSL source of adaptive-AA fragment shader.
-  ShaderSource myPostFSAAShaderSource;
-
-  //! OpenGL/GLSL ray-tracing fragment shader.
-  Handle(OpenGl_ShaderObject) myRaytraceShader;
-  //! OpenGL/GLSL adaptive-AA fragment shader.
-  Handle(OpenGl_ShaderObject) myPostFSAAShader;
-
-  //! OpenGL/GLSL ray-tracing shader program.
-  Handle(OpenGl_ShaderProgram) myRaytraceProgram;
-  //! OpenGL/GLSL adaptive-AA shader program.
-  Handle(OpenGl_ShaderProgram) myPostFSAAProgram;
-
-  //! Texture buffer of data records of bottom-level BVH nodes.
-  Handle(OpenGl_TextureBufferArb) mySceneNodeInfoTexture;
-  //! Texture buffer of minimum points of bottom-level BVH nodes.
-  Handle(OpenGl_TextureBufferArb) mySceneMinPointTexture;
-  //! Texture buffer of maximum points of bottom-level BVH nodes.
-  Handle(OpenGl_TextureBufferArb) mySceneMaxPointTexture;
-  //! Texture buffer of transformations of high-level BVH nodes.
-  Handle(OpenGl_TextureBufferArb) mySceneTransformTexture;
-
-  //! Texture buffer of vertex coords.
-  Handle(OpenGl_TextureBufferArb) myGeometryVertexTexture;
-  //! Texture buffer of vertex normals.
-  Handle(OpenGl_TextureBufferArb) myGeometryNormalTexture;
-  //! Texture buffer of vertex UV coords.
-  Handle(OpenGl_TextureBufferArb) myGeometryTexCrdTexture;
-  //! Texture buffer of triangle indices.
-  Handle(OpenGl_TextureBufferArb) myGeometryTriangTexture;
-
-  //! Texture buffer of material properties.
-  Handle(OpenGl_TextureBufferArb) myRaytraceMaterialTexture;
-  //! Texture buffer of light source properties.
-  Handle(OpenGl_TextureBufferArb) myRaytraceLightSrcTexture;
-
-  //! Vertex buffer (VBO) for drawing dummy quad.
-  OpenGl_VertexBuffer myRaytraceScreenQuad;
-
-  //! Framebuffer (FBO) to perform adaptive FSAA.
-  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;
+protected: //! @name protected fields
 
   //! Framebuffer stores cached main presentation of the view (without presentation of immediate layers).
   Handle(OpenGl_FrameBuffer) myResultFBO;
@@ -653,28 +308,6 @@ protected: //! @name fields related to ray-tracing
   //! Vertices for full-screen quad rendering.
   OpenGl_VertexBuffer        myFullScreenQuad;
 
-  //! State of OpenGL view.
-  Standard_Size myViewModificationStatus;
-  //! State of OpenGL layer list.
-  Standard_Size myLayersModificationStatus;
-
-  //! State of OpenGL structures reflected to ray-tracing.
-  std::map<const OpenGl_Structure*, Standard_Size> myStructureStates;
-
-  //! PrimitiveArray to TriangleSet map for scene partial update.
-  std::map<Standard_Size, OpenGl_TriangleSet*> myArrayToTrianglesMap;
-
-  //! Cached locations of frequently used uniform variables.
-  Standard_Integer myUniformLocations[2][OpenGl_RT_NbVariables];
-
-  //! Graphical ray-tracing filter to filter out all raytracable structures.
-  Handle(OpenGl_RaytraceFilter) myRaytraceFilter;
-
-  //! Redraw the scene using OpenGL rasterization or ray-tracing?
-  Standard_Boolean myToRedrawGL;
-
-protected: //! @name protected fields
-
   Handle(OpenGl_PrinterContext) myPrintContext;
   Handle(OpenGl_View)           myView;
   Handle(OpenGl_LineAttributes) myLineAttribs;