0024192: Adding support for shaders to OCCT visualization toolkit
authorapl <apl@opencascade.com>
Mon, 21 Oct 2013 07:47:10 +0000 (11:47 +0400)
committerabv <abv@opencascade.com>
Thu, 24 Oct 2013 12:03:22 +0000 (16:03 +0400)
66 files changed:
src/Graphic3d/FILES
src/Graphic3d/Graphic3d.cdl
src/Graphic3d/Graphic3d_AspectFillArea3d.cdl
src/Graphic3d/Graphic3d_AspectFillArea3d.cxx
src/Graphic3d/Graphic3d_AspectLine3d.cdl
src/Graphic3d/Graphic3d_AspectLine3d.cxx
src/Graphic3d/Graphic3d_AspectMarker3d.cdl
src/Graphic3d/Graphic3d_AspectMarker3d.cxx
src/Graphic3d/Graphic3d_AspectText3d.cdl
src/Graphic3d/Graphic3d_AspectText3d.cxx
src/Graphic3d/Graphic3d_CGroup.hxx
src/Graphic3d/Graphic3d_Group_8.cxx
src/Graphic3d/Graphic3d_ShaderObject.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderObject.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderObject_Handle.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderProgram.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderProgram.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderProgram_Handle.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderVariable.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderVariable.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderVariable.lxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ShaderVariable_Handle.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_TypeOfShaderObject.hxx [new file with mode: 0644]
src/InterfaceGraphic/InterfaceGraphic_Graphic3d.hxx
src/NCollection/FILES
src/NCollection/NCollection_Mat4.hxx [new file with mode: 0644]
src/OpenGl/FILES
src/OpenGl/Handle_OpenGl_ShaderManager.hxx [new file with mode: 0644]
src/OpenGl/Handle_OpenGl_ShaderObject.hxx [new file with mode: 0644]
src/OpenGl/Handle_OpenGl_ShaderProgram.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_AspectFace.cxx
src/OpenGl/OpenGl_AspectFace.hxx
src/OpenGl/OpenGl_AspectLine.cxx
src/OpenGl/OpenGl_AspectLine.hxx
src/OpenGl/OpenGl_AspectMarker.cxx
src/OpenGl/OpenGl_AspectMarker.hxx
src/OpenGl/OpenGl_AspectText.cxx
src/OpenGl/OpenGl_AspectText.hxx
src/OpenGl/OpenGl_Clipping.cxx [moved from src/OpenGl/OpenGl_ClippingState.cxx with 88% similarity]
src/OpenGl/OpenGl_Clipping.hxx [moved from src/OpenGl/OpenGl_ClippingState.hxx with 97% similarity]
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_GraphicDriver_Layer.cxx
src/OpenGl/OpenGl_Group.cxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_ShaderManager.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_ShaderManager.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_ShaderObject.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_ShaderObject.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_ShaderProgram.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_ShaderProgram.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_ShaderStates.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_ShaderStates.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_Structure.hxx
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_TextFormatter.cxx
src/OpenGl/OpenGl_Trihedron.cxx
src/OpenGl/OpenGl_Vec.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_2.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/OpenGl/OpenGl_Workspace_5.cxx
src/Shaders/Declarations.glsl [new file with mode: 0644]
src/ViewerTest/ViewerTest.cxx

index 494616a..44b8a46 100755 (executable)
@@ -31,6 +31,17 @@ Graphic3d_Group_2.cxx
 Graphic3d_Group_8.cxx
 Graphic3d_Group_10.cxx
 Graphic3d_Structure.pxx
+Graphic3d_ShaderObject.hxx
+Graphic3d_ShaderObject.cxx
+Graphic3d_ShaderProgram.hxx
+Graphic3d_ShaderProgram.cxx
+Graphic3d_ShaderVariable.hxx
+Graphic3d_ShaderVariable.cxx
+Graphic3d_ShaderVariable.lxx
+Graphic3d_ShaderObject_Handle.hxx
+Graphic3d_ShaderProgram_Handle.hxx
+Graphic3d_ShaderVariable_Handle.hxx
+Graphic3d_TypeOfShaderObject.hxx
 Graphic3d_DataStructure.pxx
 Graphic3d_StructureManager.pxx
 Graphic3d.edl
@@ -57,4 +68,4 @@ Graphic3d_ClipPlane.hxx
 Graphic3d_ClipPlane.cxx
 Graphic3d_ClipPlane_Handle.hxx
 Graphic3d_SetOfHClipPlane.hxx
-Graphic3d_SetOfHClipPlane_Handle.hxx
\ No newline at end of file
+Graphic3d_SetOfHClipPlane_Handle.hxx
index aa39c28..e7cd632 100755 (executable)
@@ -584,6 +584,9 @@ is
     imported NListOfHAsciiString;
     ---Category: Instantiated classes
 
+    imported ShaderProgram_Handle;
+    ---Category: Instantiated classes
+
     imported SetOfHClipPlane;
     ---Category: Instantiated classes
     -- Set of handles on clip planes
index fa18c37..7aeb9d0 100755 (executable)
@@ -42,14 +42,16 @@ class AspectFillArea3d from Graphic3d inherits AspectFillArea from Aspect
 
 uses
 
-        Color           from Quantity,
-        Ratio           from Quantity,
+        Color                 from Quantity,
+        Ratio                 from Quantity,
 
-        TypeOfLine      from Aspect,    
-        InteriorStyle   from Aspect,
+        TypeOfLine            from Aspect,    
+        InteriorStyle         from Aspect,
 
-        MaterialAspect  from Graphic3d,
-        TextureMap      from Graphic3d
+        MaterialAspect        from Graphic3d,
+        TextureMap            from Graphic3d,
+
+        ShaderProgram_Handle  from Graphic3d
 
 is
 
@@ -189,6 +191,12 @@ is
         --          Consult OpenGL reference for details (glPolygonOffset function description).
         ---Category: Methods to modify the class definition
 
+        SetShaderProgram ( me  :  mutable; 
+                           theProgram  :  ShaderProgram_Handle from Graphic3d );
+        ---Level: Public
+        ---Purpose: Sets up OpenGL/GLSL shader program.
+        ---Category: Methods to modify the class definition
+
         ----------------------------
         -- Category: Inquire methods
         ----------------------------
@@ -244,9 +252,12 @@ is
                          aUnits  : out ShortReal from Standard );
         ---Level: Public
         ---Purpose: Returns current polygon offsets settings.
-        ---Category: Inquire methods    
-        
-        
+        ---Category: Inquire methods
+
+        ShaderProgram ( me )
+        returns ShaderProgram_Handle from Graphic3d;
+        ---C++: return const &
+
 --
 
 fields
@@ -290,4 +301,6 @@ fields
         MyPolygonOffsetFactor   :       ShortReal from Standard;
         MyPolygonOffsetUnits    :       ShortReal from Standard;
 
+        MyShaderProgram         :       ShaderProgram_Handle  from  Graphic3d;
+
 end AspectFillArea3d;
index b5ec053..1c9ea07 100755 (executable)
@@ -180,3 +180,13 @@ void Graphic3d_AspectFillArea3d::PolygonOffsets(Standard_Integer&    aMode,
   aFactor = MyPolygonOffsetFactor;
   aUnits  = MyPolygonOffsetUnits;
 }
+
+void Graphic3d_AspectFillArea3d::SetShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProgram)
+{
+  MyShaderProgram = theProgram;
+}
+
+const Handle(Graphic3d_ShaderProgram)& Graphic3d_AspectFillArea3d::ShaderProgram() const
+{
+  return MyShaderProgram;
+}
index a96f3e9..4f5d288 100755 (executable)
@@ -29,9 +29,9 @@ class AspectLine3d from Graphic3d inherits AspectLine from Aspect
 
 uses
 
-       Color           from Quantity,
-
-       TypeOfLine      from Aspect
+       Color                 from Quantity,
+       TypeOfLine            from Aspect,
+       ShaderProgram_Handle  from Graphic3d
 
 is
 
@@ -58,9 +58,16 @@ is
        --          factor to this nominal line width.
        --          The supported linewidths vary by 1-pixel units.
 
---\f
+  SetShaderProgram ( me  :  mutable; 
+                     theProgram  :  ShaderProgram_Handle from Graphic3d );
+  ---Level: Public
+  ---Purpose: Sets up OpenGL/GLSL shader program.
+
+  ShaderProgram ( me )
+  returns ShaderProgram_Handle from Graphic3d;
+  ---C++: return const &
 
--- fields
+fields
 
 --
 -- Class       :       Graphic3d_AspectLine3d
@@ -75,4 +82,6 @@ is
 --                     defined by AspectLine.
 --
 
+  MyShaderProgram  :  ShaderProgram_Handle  from  Graphic3d; 
+
 end AspectLine3d;
index 7628e36..b66d6fa 100755 (executable)
@@ -58,3 +58,13 @@ Graphic3d_AspectLine3d::Graphic3d_AspectLine3d () {
 // initialisation of AspectLine with AColor, AType, AWidth.
 
 Graphic3d_AspectLine3d::Graphic3d_AspectLine3d (const Quantity_Color& AColor, const Aspect_TypeOfLine AType, const Standard_Real AWidth):Aspect_AspectLine (AColor, AType, AWidth) {}
+
+void Graphic3d_AspectLine3d::SetShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProgram)
+{
+  MyShaderProgram = theProgram;
+}
+
+const Handle(Graphic3d_ShaderProgram)& Graphic3d_AspectLine3d::ShaderProgram() const
+{
+  return MyShaderProgram;
+}
index c33e785..7f53fff 100755 (executable)
@@ -32,11 +32,12 @@ class AspectMarker3d from Graphic3d inherits AspectMarker from Aspect
 
 uses
 
-  Color                from Quantity,
-  TypeOfMarker         from Aspect,
-  HArray1OfByte        from TColStd,
-  PixMap_Handle        from Image,
-  MarkerImage_Handle   from Graphic3d
+  Color                 from Quantity,
+  TypeOfMarker          from Aspect,
+  HArray1OfByte         from TColStd,
+  PixMap_Handle         from Image,
+  MarkerImage_Handle    from Graphic3d,
+  ShaderProgram_Handle  from Graphic3d
 
 is
 
@@ -89,6 +90,15 @@ is
              theHeight : Integer from Standard;
              theTexture: HArray1OfByte from TColStd ) is static;
 
+  SetShaderProgram ( me  :  mutable; 
+                     theProgram  :  ShaderProgram_Handle from Graphic3d );
+  ---Level: Public
+  ---Purpose: Sets up OpenGL/GLSL shader program.
+
+  ShaderProgram ( me )
+  returns ShaderProgram_Handle from Graphic3d;
+  ---C++: return const &
+
 fields
 
 --
@@ -105,4 +115,6 @@ fields
 
 myMarkerImage : MarkerImage_Handle from Graphic3d is protected;
 
+MyShaderProgram  :  ShaderProgram_Handle  from  Graphic3d; 
+
 end AspectMarker3d;
index fa602f5..c585043 100755 (executable)
@@ -99,3 +99,21 @@ void Graphic3d_AspectMarker3d::SetBitMap (const Standard_Integer theWidth,
   myMarkerImage.Nullify();
   myMarkerImage = new Graphic3d_MarkerImage (theTextureBitMap, theWidth, theHeight);
 }
+
+// =======================================================================
+// function : SetShaderProgram
+// purpose  :
+// =======================================================================
+void Graphic3d_AspectMarker3d::SetShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProgram)
+{
+  MyShaderProgram = theProgram;
+}
+
+// =======================================================================
+// function : ShaderProgram
+// purpose  :
+// =======================================================================
+const Handle(Graphic3d_ShaderProgram)& Graphic3d_AspectMarker3d::ShaderProgram() const
+{
+  return MyShaderProgram;
+}
index e20cb2d..758ebf2 100755 (executable)
@@ -36,11 +36,12 @@ class AspectText3d from Graphic3d inherits TShared
     
 uses
 
-    Color             from Quantity,
-    TypeOfStyleText   from Aspect,
-    TypeOfDisplayText from Aspect,
-    AsciiString       from TCollection,
-    FontAspect        from Font 
+    Color                 from Quantity,
+    TypeOfStyleText       from Aspect,
+    TypeOfDisplayText     from Aspect,
+    AsciiString           from TCollection,
+    FontAspect            from Font,
+    ShaderProgram_Handle  from Graphic3d
 
 raises
 
@@ -178,11 +179,10 @@ is
     ---Level: Public 
     ---Purpose: Returns text FontAspect
 
-
-
-
-
-
+    SetShaderProgram ( me  :  mutable; 
+                       theProgram  :  ShaderProgram_Handle from Graphic3d );
+    ---Level: Public
+    ---Purpose: Sets up OpenGL/GLSL shader program.
 
     ----------------------------
     -- Category: Inquire methods
@@ -245,7 +245,11 @@ is
     ---Purpose: Returns the current values of the group <me>.
     ---Category: Inquire methods
 
---\f
+    ShaderProgram ( me )
+    returns ShaderProgram_Handle from Graphic3d;
+    ---C++: return const &
+
+--
 
 fields
 
@@ -292,4 +296,6 @@ fields
     -- the variable turning FontAspect of the text
     MyTextFontAspect :  FontAspect from Font;
 
+    MyShaderProgram  :  ShaderProgram_Handle  from  Graphic3d; 
+
 end AspectText3d;
index 687da55..77905c1 100755 (executable)
@@ -253,5 +253,12 @@ void Graphic3d_AspectText3d::Values ( Quantity_Color& AColor,
 
 }
 
+void Graphic3d_AspectText3d::SetShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProgram)
+{
+  MyShaderProgram = theProgram;
+}
 
-
+const Handle(Graphic3d_ShaderProgram)& Graphic3d_AspectText3d::ShaderProgram() const
+{
+  return MyShaderProgram;
+}
index 2ce7a2f..c961992 100755 (executable)
@@ -23,6 +23,7 @@
 #include <InterfaceGraphic_Visual3d.hxx>
 #include <Graphic3d_CTexture.hxx>
 #include <Graphic3d_MarkerImage_Handle.hxx>
+#include <Graphic3d_ShaderProgram_Handle.hxx>
 
 class Graphic3d_CStructure;
 
@@ -80,6 +81,8 @@ public:
   float PolygonOffsetFactor;
   float PolygonOffsetUnits;
 
+  Handle(Graphic3d_ShaderProgram) ShaderProgram;
+
 };
 
 class CALL_DEF_CONTEXTMARKER
@@ -104,6 +107,7 @@ public:
   Aspect_TypeOfMarker MarkerType;
   Standard_ShortReal Scale;
   Handle(Graphic3d_MarkerImage) MarkerImage;
+  Handle(Graphic3d_ShaderProgram) ShaderProgram;
 
 };
 
index 5e93b1a..9528958 100755 (executable)
@@ -46,6 +46,7 @@
 #include <Graphic3d_Group.jxx>
 #include <Graphic3d_Group.pxx>
 #include <Graphic3d_TextureMap.hxx>
+#include <Graphic3d_ShaderProgram.hxx>
 
 //-Methods, in order
 
@@ -68,13 +69,14 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectLin
   MyCGroup.ContextLine.Width      = float (AWidth);
   MyCGroup.ContextLine.IsDef      = 1;
 
+  MyCGroup.ContextLine.ShaderProgram = CTX->ShaderProgram();
+
   int noinsert    = 1;
   MyGraphicDriver->LineContextGroup (MyCGroup, noinsert);
 
   MyCGroup.ContextLine.IsSet      = 1;
 
   Update ();
-
 }
 
 void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& CTX) {
@@ -277,13 +279,14 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
   MyCGroup.ContextFillArea.PolygonOffsetUnits  = aPolyUnits;
   // OCC4895 SAN 22/03/04 High-level interface for controlling polygon offsets
 
+  MyCGroup.ContextFillArea.ShaderProgram = CTX->ShaderProgram();
+
   int noinsert = 1;
   MyGraphicDriver->FaceContextGroup (MyCGroup, noinsert);
 
   MyCGroup.ContextFillArea.IsSet  = 1;
 
-  Update ();
-
+  Update();
 }
 
 void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theCtx)
@@ -306,6 +309,8 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectMar
   MyCGroup.ContextMarker.Scale       = Standard_ShortReal (aScale);
   MyCGroup.ContextMarker.MarkerImage = theCtx->GetMarkerImage();
 
+  MyCGroup.ContextMarker.ShaderProgram = theCtx->ShaderProgram();
+
   int noinsert = 1;
   MyGraphicDriver->MarkerContextGroup (MyCGroup, noinsert);
 
@@ -350,6 +355,8 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectTex
   MyCGroup.ContextText.TextAngle    = float (ATextAngle);
   MyCGroup.ContextText.TextFontAspect   = (int)ATextFontAspect;
 
+  MyCGroup.ContextText.ShaderProgram = CTX->ShaderProgram();
+
   MyCGroup.ContextText.IsDef      = 1;
 
   int noinsert    = 1;
@@ -358,7 +365,6 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectTex
   MyCGroup.ContextText.IsSet              = 1;
 
   Update ();
-
 }
 
 void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& CTX) {
@@ -380,13 +386,14 @@ void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)&
   MyCGroup.ContextLine.Width              = float (AWidth);
   MyCGroup.ContextLine.IsDef              = 1;
 
+  MyCGroup.ContextLine.ShaderProgram = CTX->ShaderProgram();
+
   int noinsert    = 0;
   MyGraphicDriver->LineContextGroup (MyCGroup, noinsert);
 
   MyCGroup.ContextLine.IsSet              = 1;
 
   Update ();
-
 }
 
 void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& CTX) {
@@ -584,13 +591,14 @@ void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea
   MyCGroup.ContextFillArea.PolygonOffsetUnits  = (Standard_ShortReal)aPolyUnits;
   // OCC4895 SAN 22/03/04 High-level interface for controlling polygon offsets
 
+  MyCGroup.ContextFillArea.ShaderProgram = CTX->ShaderProgram();
+
   int noinsert    = 0;
   MyGraphicDriver->FaceContextGroup (MyCGroup, noinsert);
 
   MyCGroup.ContextFillArea.IsSet  = 1;
 
   Update ();
-
 }
 
 void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& thCtx)
@@ -613,6 +621,8 @@ void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d
   MyCGroup.ContextMarker.Scale       = Standard_ShortReal (aScale);
   MyCGroup.ContextMarker.MarkerImage = thCtx->GetMarkerImage();
 
+  MyCGroup.ContextMarker.ShaderProgram = thCtx->ShaderProgram();
+
   int noinsert = 0;
   MyGraphicDriver->MarkerContextGroup (MyCGroup, noinsert);
 
@@ -658,13 +668,14 @@ void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectText3d)&
   MyCGroup.ContextText.TextFontAspect   = (int)ATextFontAspect;
   MyCGroup.ContextText.IsDef              = 1;
 
+  MyCGroup.ContextText.ShaderProgram = CTX->ShaderProgram();
+
   int noinsert    = 0;
   MyGraphicDriver->TextContextGroup (MyCGroup, noinsert);
 
   MyCGroup.ContextText.IsSet              = 1;
 
-  Update ();
-
+  Update();
 }
 
 Standard_Boolean Graphic3d_Group::IsGroupPrimitivesAspectSet (const Graphic3d_GroupAspect theAspect) const {
diff --git a/src/Graphic3d/Graphic3d_ShaderObject.cxx b/src/Graphic3d/Graphic3d_ShaderObject.cxx
new file mode 100644 (file)
index 0000000..f83ab10
--- /dev/null
@@ -0,0 +1,96 @@
+// Created on: 2013-09-20
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <OSD_File.hxx>
+#include <OSD_Protection.hxx>
+#include <Standard_Atomic.hxx>
+#include <Graphic3d_ShaderObject.hxx>
+#include <Graphic3d_GraphicDriver.hxx>
+
+namespace
+{
+  static volatile Standard_Integer THE_SHADER_OBJECT_COUNTER = 0;
+};
+
+IMPLEMENT_STANDARD_HANDLE (Graphic3d_ShaderObject, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderObject, Standard_Transient)
+
+// =======================================================================
+// function : Graphic3d_ShaderObject
+// purpose  : Creates a shader object from specified file
+// =======================================================================
+Graphic3d_ShaderObject::Graphic3d_ShaderObject (const Graphic3d_TypeOfShaderObject theType)
+: myType (theType)
+{
+  myID = TCollection_AsciiString ("Graphic3d_ShaderObject_")
+       + TCollection_AsciiString (Standard_Atomic_Increment (&THE_SHADER_OBJECT_COUNTER));
+}
+
+// =======================================================================
+// function : CreatFromFile
+// purpose  : Creates new shader object from specified file
+// =======================================================================
+Handle(Graphic3d_ShaderObject) Graphic3d_ShaderObject::CreateFromFile (const Graphic3d_TypeOfShaderObject theType,
+                                                                       const TCollection_AsciiString&     thePath)
+{
+  Handle(Graphic3d_ShaderObject) aShader = new Graphic3d_ShaderObject (theType);
+  aShader->myPath = thePath;
+
+  OSD_File aFile (thePath);
+  if (!aFile.Exists())
+  {
+    return NULL;
+  }
+
+  aFile.Open (OSD_ReadOnly, OSD_Protection());
+  aFile.Read (aShader->mySource, aFile.Size());
+  aFile.Close();
+
+  return aShader;
+}
+
+// =======================================================================
+// function : CreatFromSource
+// purpose  : Creates new shader object from specified source
+// =======================================================================
+Handle(Graphic3d_ShaderObject) Graphic3d_ShaderObject::CreateFromSource (const Graphic3d_TypeOfShaderObject theType,
+                                                                         const TCollection_AsciiString&     theSource)
+{
+  Handle(Graphic3d_ShaderObject) aShader = new Graphic3d_ShaderObject (theType);
+  aShader->mySource = theSource;
+  return aShader;
+}
+
+// =======================================================================
+// function : ~Graphic3d_ShaderObject
+// purpose  : Releases resources of shader object
+// =======================================================================
+Graphic3d_ShaderObject::~Graphic3d_ShaderObject()
+{
+  //
+}
+
+// =======================================================================
+// function : IsDone
+// purpose  : Checks if the shader object is valid or not
+// =======================================================================
+Standard_Boolean Graphic3d_ShaderObject::IsDone() const
+{
+  return !mySource.IsEmpty();
+}
diff --git a/src/Graphic3d/Graphic3d_ShaderObject.hxx b/src/Graphic3d/Graphic3d_ShaderObject.hxx
new file mode 100644 (file)
index 0000000..0f63f7f
--- /dev/null
@@ -0,0 +1,80 @@
+// Created on: 2013-09-20
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Graphic3d_ShaderObject_HeaderFile
+#define _Graphic3d_ShaderObject_HeaderFile
+
+#include <OSD_Path.hxx>
+
+#include <Graphic3d_TypeOfShaderObject.hxx>
+#include <Graphic3d_ShaderObject_Handle.hxx>
+
+//! This class is responsible for managing shader objects.
+class Graphic3d_ShaderObject : public Standard_Transient
+{
+private:
+
+  //! Creates new shader object of specified type.
+  Standard_EXPORT Graphic3d_ShaderObject (const Graphic3d_TypeOfShaderObject theType);
+
+public:
+
+  //! Releases resources of shader object. 
+  Standard_EXPORT virtual ~Graphic3d_ShaderObject();
+  
+  //! Checks if the shader object is valid or not.
+  Standard_EXPORT virtual Standard_Boolean IsDone() const;
+  
+  //! Returns the full path to the shader source.
+  const OSD_Path& Path() const { return myPath; }
+
+  //! Returns the source code of the shader object.
+  const TCollection_AsciiString& Source() const { return mySource; }
+
+  //! Returns type of the shader object.
+  Graphic3d_TypeOfShaderObject Type() const { return myType; }
+  
+  //! Returns unique ID used to manage resource in graphic driver.
+  const TCollection_AsciiString& GetId() const { return myID; }
+
+  //! Creates new shader object from specified file.
+  Standard_EXPORT static Handle(Graphic3d_ShaderObject) CreateFromFile (const Graphic3d_TypeOfShaderObject theType,
+                                                                        const TCollection_AsciiString&     thePath);
+
+  //! Creates new shader object from specified source.
+  Standard_EXPORT static Handle(Graphic3d_ShaderObject) CreateFromSource (const Graphic3d_TypeOfShaderObject theType,
+                                                                          const TCollection_AsciiString&     theSource);
+
+public:
+
+  DEFINE_STANDARD_RTTI (Graphic3d_ShaderObject)
+
+protected:
+
+  TCollection_AsciiString myID;     //!< the ID of shader object
+  TCollection_AsciiString mySource; //!< the source code of shader object
+  OSD_Path                myPath;   //!< the path to shader source (may be empty)
+
+private:
+  
+  //! The type of shader object.
+  Graphic3d_TypeOfShaderObject myType;
+};
+
+#endif
diff --git a/src/Graphic3d/Graphic3d_ShaderObject_Handle.hxx b/src/Graphic3d/Graphic3d_ShaderObject_Handle.hxx
new file mode 100644 (file)
index 0000000..1b8295e
--- /dev/null
@@ -0,0 +1,30 @@
+// Created on: 2013-09-20
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Handle_Graphic3d_ShaderObject_HeaderFile
+#define _Handle_Graphic3d_ShaderObject_HeaderFile
+
+#include <Standard_Transient.hxx>
+
+class Graphic3d_ShaderObject;
+DEFINE_STANDARD_HANDLE (Graphic3d_ShaderObject, Standard_Transient)
+
+typedef Handle(Graphic3d_ShaderObject) Graphic3d_ShaderObject_Handle;
+
+#endif
diff --git a/src/Graphic3d/Graphic3d_ShaderProgram.cxx b/src/Graphic3d/Graphic3d_ShaderProgram.cxx
new file mode 100644 (file)
index 0000000..29aa9c7
--- /dev/null
@@ -0,0 +1,132 @@
+// Created on: 2013-09-20
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <Standard_Atomic.hxx>
+#include <Standard_Assert.hxx>
+
+#include <Graphic3d_GraphicDriver.hxx>
+#include <Graphic3d_ShaderObject.hxx>
+#include <Graphic3d_ShaderProgram.hxx>
+
+namespace
+{
+  static volatile Standard_Integer THE_PROGRAM_OBJECT_COUNTER = 0;
+};
+
+IMPLEMENT_STANDARD_HANDLE (Graphic3d_ShaderProgram, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderProgram, Standard_Transient)
+
+// =======================================================================
+// function : Graphic3d_ShaderProgram
+// purpose  : Creates new empty program object
+// =======================================================================
+Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
+{
+  myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_")
+       + TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
+}
+
+// =======================================================================
+// function : ~Graphic3d_ShaderProgram
+// purpose  : Releases resources of program object
+// =======================================================================
+Graphic3d_ShaderProgram::~Graphic3d_ShaderProgram()
+{
+  Destroy();
+}
+
+// =======================================================================
+// function : Destroy
+// purpose  : Releases resources of program object
+// =======================================================================
+void Graphic3d_ShaderProgram::Destroy() const
+{ }
+
+// =======================================================================
+// function : IsDone
+// purpose  : Checks if the program object is valid or not
+// =======================================================================
+Standard_Boolean Graphic3d_ShaderProgram::IsDone() const
+{
+  if (myShaderObjects.IsEmpty())
+  {
+    return Standard_False;
+  }
+
+  for (Graphic3d_ShaderObjectList::Iterator anIt (myShaderObjects); anIt.More(); anIt.Next())
+  {
+    if (!anIt.Value()->IsDone())
+      return Standard_False;
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
+// function : AttachShader
+// purpose  : Attaches shader object to the program object
+// =======================================================================
+Standard_Boolean Graphic3d_ShaderProgram::AttachShader (const Handle(Graphic3d_ShaderObject)& theShader)
+{
+  if (theShader.IsNull())
+  {
+    return Standard_False;
+  }
+
+  for (Graphic3d_ShaderObjectList::Iterator anIt (myShaderObjects); anIt.More(); anIt.Next())
+  {
+    if (anIt.Value() == theShader)
+      return Standard_False;
+  }
+
+  myShaderObjects.Append (theShader);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : DetachShader
+// purpose  : Detaches shader object from the program object
+// =======================================================================
+Standard_Boolean Graphic3d_ShaderProgram::DetachShader (const Handle(Graphic3d_ShaderObject)& theShader)
+{
+  if (theShader.IsNull())
+  {
+    return Standard_False;
+  }
+
+  for (Graphic3d_ShaderObjectList::Iterator anIt (myShaderObjects); anIt.More(); anIt.Next())
+  {
+    if (anIt.Value() == theShader)
+    {
+      myShaderObjects.Remove (anIt);
+      return Standard_True;
+    }
+  }
+  
+  return Standard_False;
+}
+
+// =======================================================================
+// function : ClearVariables
+// purpose  : Removes all custom uniform variables from the program
+// =======================================================================
+void Graphic3d_ShaderProgram::ClearVariables()
+{
+  myVariables.Clear();
+}
diff --git a/src/Graphic3d/Graphic3d_ShaderProgram.hxx b/src/Graphic3d/Graphic3d_ShaderProgram.hxx
new file mode 100644 (file)
index 0000000..ac816f5
--- /dev/null
@@ -0,0 +1,104 @@
+// Created on: 2013-09-20
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Graphic3d_ShaderProgram_HeaderFile
+#define _Graphic3d_ShaderProgram_HeaderFile
+
+#include <Graphic3d_ShaderObject_Handle.hxx>
+#include <Graphic3d_ShaderProgram_Handle.hxx>
+#include <Graphic3d_ShaderVariable.hxx>
+#include <NCollection_Sequence.hxx>
+
+//! List of shader objects.
+typedef NCollection_Sequence<Handle(Graphic3d_ShaderObject)> Graphic3d_ShaderObjectList;
+
+//! List of custom uniform shader variables.
+typedef NCollection_Sequence<Handle(Graphic3d_ShaderVariable)> Graphic3d_ShaderVariableList;
+
+//! This class is responsible for managing shader programs.
+class Graphic3d_ShaderProgram : public Standard_Transient
+{
+public:
+
+  //! Creates new empty program object.
+  Standard_EXPORT Graphic3d_ShaderProgram();
+
+  //! Releases resources of program object.
+  Standard_EXPORT virtual ~Graphic3d_ShaderProgram();
+
+  //! Releases resources of program object.
+  Standard_EXPORT void Destroy() const;
+
+  //! Checks if the program object is valid or not.
+  Standard_EXPORT virtual Standard_Boolean IsDone() const;
+
+  //! Returns unique ID used to manage resource in graphic driver.
+  const TCollection_AsciiString& GetId() const { return myID; }
+
+  //! Attaches shader object to the program object.
+  Standard_EXPORT Standard_Boolean AttachShader (const Handle(Graphic3d_ShaderObject)& theShader);
+
+  //! Detaches shader object from the program object.
+  Standard_EXPORT Standard_Boolean DetachShader (const Handle(Graphic3d_ShaderObject)& theShader);
+
+  //! Returns list of attached shader objects.
+  const Graphic3d_ShaderObjectList& ShaderObjects() const { return myShaderObjects; }
+
+  //! Returns list of custom uniform variables.
+  const Graphic3d_ShaderVariableList& Variables() const { return myVariables; }
+
+  //! Pushes custom uniform variable to the program.
+  template<class T>
+  Standard_Boolean PushVariable (const TCollection_AsciiString& theName,
+                                 const T&                       theValue);
+
+  //! Removes all custom uniform variables from the program.
+  Standard_EXPORT void ClearVariables();
+
+public:
+
+  DEFINE_STANDARD_RTTI (Graphic3d_ShaderProgram)
+
+private:
+
+  TCollection_AsciiString      myID;            //!< The unique identifier of program object.
+  Graphic3d_ShaderObjectList   myShaderObjects; //!< the list of attached shader objects.
+  Graphic3d_ShaderVariableList myVariables;     //!< the list of custom uniform variables.
+
+};
+
+// =======================================================================
+// function : PushVariable
+// purpose  : Pushes custom uniform variable to the program
+// =======================================================================
+template<class T> inline
+Standard_Boolean Graphic3d_ShaderProgram::PushVariable (const TCollection_AsciiString& theName,
+                                                        const T& theValue)
+{
+  Handle(Graphic3d_ShaderVariable) aVariable = Graphic3d_ShaderVariable::Create (theName, theValue);
+  if (aVariable.IsNull() || !aVariable->IsDone())
+  {
+    return Standard_False;
+  }
+
+  myVariables.Append (aVariable);
+  return Standard_True;
+}
+
+#endif
diff --git a/src/Graphic3d/Graphic3d_ShaderProgram_Handle.hxx b/src/Graphic3d/Graphic3d_ShaderProgram_Handle.hxx
new file mode 100644 (file)
index 0000000..f75f8fc
--- /dev/null
@@ -0,0 +1,30 @@
+// Created on: 2013-09-20
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Handle_Graphic3d_ShaderProgram_HeaderFile
+#define _Handle_Graphic3d_ShaderProgram_HeaderFile
+
+#include <Standard_Transient.hxx>
+
+class Graphic3d_ShaderProgram;
+DEFINE_STANDARD_HANDLE (Graphic3d_ShaderProgram, Standard_Transient)
+
+typedef Handle(Graphic3d_ShaderProgram) Graphic3d_ShaderProgram_Handle;
+
+#endif
diff --git a/src/Graphic3d/Graphic3d_ShaderVariable.cxx b/src/Graphic3d/Graphic3d_ShaderVariable.cxx
new file mode 100644 (file)
index 0000000..f11661c
--- /dev/null
@@ -0,0 +1,93 @@
+// Created on: 2013-09-25
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <Standard_Atomic.hxx>
+
+#include <Graphic3d_ShaderVariable.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (Graphic3d_ShaderVariable, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ShaderVariable, Standard_Transient)
+
+//
+// Specific instantiations of struct templates to avoid compilation warnings
+//
+template struct Graphic3d_UniformValue<int>;
+template struct Graphic3d_UniformValue<float>;
+template struct Graphic3d_UniformValue<OpenGl_Vec2>;
+template struct Graphic3d_UniformValue<OpenGl_Vec3>;
+template struct Graphic3d_UniformValue<OpenGl_Vec4>;
+template struct Graphic3d_UniformValue<OpenGl_Vec2i>;
+template struct Graphic3d_UniformValue<OpenGl_Vec3i>;
+template struct Graphic3d_UniformValue<OpenGl_Vec4i>;
+
+// =======================================================================
+// function : ~Graphic3d_ValueInterface
+// purpose  : Releases memory resources of variable value
+// =======================================================================
+Graphic3d_ValueInterface::~Graphic3d_ValueInterface()
+{
+  //
+}
+
+// =======================================================================
+// function : Graphic3d_ShaderVariable
+// purpose  : Creates new abstract shader variable
+// =======================================================================
+Graphic3d_ShaderVariable::Graphic3d_ShaderVariable (const TCollection_AsciiString& theName)
+: myName (theName),
+  myValue (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Graphic3d_ShaderVariableBase
+// purpose  : Releases resources of shader variable
+// =======================================================================
+Graphic3d_ShaderVariable::~Graphic3d_ShaderVariable()
+{
+  delete myValue;
+}
+
+// =======================================================================
+// function : IsDone
+// purpose  : Checks if the shader variable is valid or not
+// =======================================================================
+Standard_Boolean Graphic3d_ShaderVariable::IsDone() const
+{
+  return !myName.IsEmpty() && (myValue != NULL);
+}
+
+// =======================================================================
+// function : Name
+// purpose  : Returns name of shader variable
+// =======================================================================
+const TCollection_AsciiString& Graphic3d_ShaderVariable::Name() const
+{
+  return myName;
+}
+
+// =======================================================================
+// function : Value
+// purpose  : Returns interface of shader variable value
+// =======================================================================
+Graphic3d_ValueInterface* Graphic3d_ShaderVariable::Value()
+{
+  return myValue;
+}
diff --git a/src/Graphic3d/Graphic3d_ShaderVariable.hxx b/src/Graphic3d/Graphic3d_ShaderVariable.hxx
new file mode 100644 (file)
index 0000000..5770c59
--- /dev/null
@@ -0,0 +1,171 @@
+// Created on: 2013-09-25
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Graphic3d_ShaderVariable_HeaderFile
+#define _Graphic3d_ShaderVariable_HeaderFile
+
+#include <OpenGl_Vec.hxx>
+#include <Standard_Transient.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <Graphic3d_ShaderVariable_Handle.hxx>
+
+//! Interface for generic variable value.
+struct Graphic3d_ValueInterface
+{
+  //! Releases memory resources of variable value.
+  Standard_EXPORT virtual ~Graphic3d_ValueInterface();
+
+  //! Returns unique identifier of value type.
+  virtual Standard_Size TypeID() const = 0;
+
+  //! Returns variable value casted to specified type.
+  template <class T> T& As();
+
+  //! Returns variable value casted to specified type.
+  template <class T> const T& As() const;
+};
+
+//! Generates unique type identifier for variable value.
+template<class T>
+struct Graphic3d_UniformValueTypeID {
+  /* Not implemented */
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<int> {
+  static const Standard_Size ID = __LINE__;
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<float> {
+  static const Standard_Size ID = __LINE__;
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<OpenGl_Vec2> {
+  static const Standard_Size ID = __LINE__;
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<OpenGl_Vec3> {
+  static const Standard_Size ID = __LINE__;
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<OpenGl_Vec4> {
+  static const Standard_Size ID = __LINE__;
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<OpenGl_Vec2i> {
+  static const Standard_Size ID = __LINE__;
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<OpenGl_Vec3i> {
+  static const Standard_Size ID = __LINE__;
+};
+
+template<>
+struct Graphic3d_UniformValueTypeID<OpenGl_Vec4i> {
+  static const Standard_Size ID = __LINE__;
+};
+
+//! Describes specific value of custom uniform variable.
+template <class T>
+struct Graphic3d_UniformValue : public Graphic3d_ValueInterface
+{
+  //! Creates new variable value.
+  Graphic3d_UniformValue (const T& theValue) : Value (theValue) { }
+
+  //! Returns unique identifier of value type.
+  virtual Standard_Size TypeID() const;
+
+  //! Value of custom uniform variable.
+  T Value;
+};
+
+//! Integer uniform value.
+typedef Graphic3d_UniformValue<int> Graphic3d_UniformInt;
+
+//! Integer uniform 2D vector.
+typedef Graphic3d_UniformValue<OpenGl_Vec2i> Graphic3d_UniformVec2i;
+
+//! Integer uniform 3D vector.
+typedef Graphic3d_UniformValue<OpenGl_Vec3i> Graphic3d_UniformVec3i;
+
+//! Integer uniform 4D vector.
+typedef Graphic3d_UniformValue<OpenGl_Vec4i> Graphic3d_UniformVec4i;
+
+//! Floating-point uniform value.
+typedef Graphic3d_UniformValue<float> Graphic3d_UniformFloat;
+
+//! Floating-point uniform 2D vector.
+typedef Graphic3d_UniformValue<OpenGl_Vec2> Graphic3d_UniformVec2;
+
+//! Floating-point uniform 3D vector.
+typedef Graphic3d_UniformValue<OpenGl_Vec3> Graphic3d_UniformVec3;
+
+//! Floating-point uniform 4D vector.
+typedef Graphic3d_UniformValue<OpenGl_Vec4> Graphic3d_UniformVec4;
+
+//! Describes custom uniform shader variable.
+class Graphic3d_ShaderVariable : public Standard_Transient
+{
+public:
+
+  //! Releases resources of shader variable.
+  Standard_EXPORT virtual ~Graphic3d_ShaderVariable();
+  
+  //! Returns name of shader variable.
+  Standard_EXPORT const TCollection_AsciiString& Name() const;
+
+  //! Checks if the shader variable is valid or not.
+  Standard_EXPORT Standard_Boolean IsDone() const;
+
+  //! Returns interface of shader variable value.
+  Standard_EXPORT Graphic3d_ValueInterface* Value();
+
+  //! Creates new initialized shader variable.
+  template<class T>
+  static Graphic3d_ShaderVariable* Create (const TCollection_AsciiString& theName,
+                                           const T&                       theValue);
+
+public:
+
+  DEFINE_STANDARD_RTTI (Graphic3d_ShaderVariable)
+
+protected:
+
+  //! Creates new uninitialized shader variable.
+  Standard_EXPORT Graphic3d_ShaderVariable (const TCollection_AsciiString& theName);
+
+protected:
+
+  //! The name of uniform shader variable.
+  TCollection_AsciiString myName;
+
+  //! The generic value of shader variable.
+  Graphic3d_ValueInterface* myValue;
+};
+
+#include <Graphic3d_ShaderVariable.lxx>
+
+#endif // _Graphic3d_ShaderVariable_HeaderFile
diff --git a/src/Graphic3d/Graphic3d_ShaderVariable.lxx b/src/Graphic3d/Graphic3d_ShaderVariable.lxx
new file mode 100644 (file)
index 0000000..1ebb059
--- /dev/null
@@ -0,0 +1,63 @@
+// Created on: 2013-09-25
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+// =======================================================================
+// function : As
+// purpose  : Returns variable value casted to specified type
+// =======================================================================
+template <class T> inline
+T& Graphic3d_ValueInterface::As()
+{
+  Graphic3d_UniformValue<T>* aPtr = dynamic_cast<Graphic3d_UniformValue<T>*> (this);
+  return aPtr->Value;
+}
+
+// =======================================================================
+// function : As
+// purpose  : Returns variable value casted to specified type
+// =======================================================================
+template <class T> inline
+const T& Graphic3d_ValueInterface::As() const
+{
+  const Graphic3d_UniformValue<T>* aPtr = dynamic_cast<const Graphic3d_UniformValue<T>*> (this);
+  return aPtr->Value;
+}
+
+// =======================================================================
+// function : TypeID
+// purpose  : Returns unique identifier of value type
+// =======================================================================
+template <class T> inline
+Standard_Size Graphic3d_UniformValue<T>::TypeID() const
+{
+  return Graphic3d_UniformValueTypeID<T>::ID;
+}
+
+// =======================================================================
+// function : Create
+// purpose  : Creates initialized shader variable
+// =======================================================================
+template<class T> inline
+Graphic3d_ShaderVariable* Graphic3d_ShaderVariable::Create (const TCollection_AsciiString& theName,
+                                                            const T&                       theValue)
+{
+  Graphic3d_ShaderVariable* theVariable = new Graphic3d_ShaderVariable (theName);
+  theVariable->myValue = new Graphic3d_UniformValue<T> (theValue);
+  return theVariable;
+}
diff --git a/src/Graphic3d/Graphic3d_ShaderVariable_Handle.hxx b/src/Graphic3d/Graphic3d_ShaderVariable_Handle.hxx
new file mode 100644 (file)
index 0000000..2961cb9
--- /dev/null
@@ -0,0 +1,28 @@
+// Created on: 2013-09-25
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Handle_Graphic3d_ShaderVariable_HeaderFile
+#define _Handle_Graphic3d_ShaderVariable_HeaderFile
+
+#include <Standard_Transient.hxx>
+
+class Graphic3d_ShaderVariable;
+DEFINE_STANDARD_HANDLE (Graphic3d_ShaderVariable, Standard_Transient)
+
+#endif
\ No newline at end of file
diff --git a/src/Graphic3d/Graphic3d_TypeOfShaderObject.hxx b/src/Graphic3d/Graphic3d_TypeOfShaderObject.hxx
new file mode 100644 (file)
index 0000000..e0ceb5e
--- /dev/null
@@ -0,0 +1,30 @@
+// Created on: 2013-09-20
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Graphic3d_TypeOfShaderObject_HeaderFile
+#define _Graphic3d_TypeOfShaderObject_HeaderFile
+
+//! Type of the shader object (may be extended).
+enum Graphic3d_TypeOfShaderObject
+{
+  Graphic3d_TOS_VERTEX,
+  Graphic3d_TOS_FRAGMENT
+};
+
+#endif
index 032468f..49b3bcd 100755 (executable)
@@ -19,6 +19,7 @@
 #ifndef InterfaceGraphic_Graphic3dHeader
 #define InterfaceGraphic_Graphic3dHeader
 
+#include <Graphic3d_ShaderProgram_Handle.hxx>
 #include <InterfaceGraphic_PrimitiveArray.hxx>
 #include <Standard_Transient.hxx>
 
@@ -326,17 +327,19 @@ typedef struct {
 
 /* CONTEXTE LIGNE */
 
-typedef struct {
-
-        int IsDef;
-
-        int IsSet;
-
-        CALL_DEF_COLOR Color;
-
-        int LineType;
-
-        float Width;
+typedef struct
+{
+  int IsDef;
+  
+  int IsSet;
+  
+  CALL_DEF_COLOR Color;
+  
+  int LineType;
+  
+  float Width;
+  
+  Handle(Graphic3d_ShaderProgram) ShaderProgram;
 
 } CALL_DEF_CONTEXTLINE;
 
@@ -373,25 +376,25 @@ typedef struct {
 
 /* CONTEXTE TEXT */
 
-typedef struct {
-
-        int IsDef;
-
-        int IsSet;
-
-        const char* Font;
-
-        float Space;
-
-        float Expan;
-
-        CALL_DEF_COLOR Color;
-
-        int Style;
-
-        int DisplayType;
-
-        CALL_DEF_COLOR ColorSubTitle;
+typedef struct
+{
+  int IsDef;
+  
+  int IsSet;
+  
+  const char* Font;
+  
+  float Space;
+  
+  float Expan;
+  
+  CALL_DEF_COLOR Color;
+  
+  int Style;
+  
+  int DisplayType;
+  
+  CALL_DEF_COLOR ColorSubTitle;
 
        int TextZoomable;
 
@@ -399,6 +402,7 @@ typedef struct {
 
        int TextFontAspect;
 
+  Handle(Graphic3d_ShaderProgram) ShaderProgram;
 
 } CALL_DEF_CONTEXTTEXT;
 
index 8011e6e..60e5de9 100755 (executable)
@@ -92,3 +92,5 @@ NCollection_DefineAlloc.hxx
 NCollection_Vec2.hxx
 NCollection_Vec3.hxx
 NCollection_Vec4.hxx
+
+NCollection_Mat4.hxx
diff --git a/src/NCollection/NCollection_Mat4.hxx b/src/NCollection/NCollection_Mat4.hxx
new file mode 100644 (file)
index 0000000..babf3e8
--- /dev/null
@@ -0,0 +1,424 @@
+// Created on: 2013-05-30
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 65 (the "License") You may not use the content of this file
+// except in compliance with the License Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file
+//
+// The Initial Developer of the Original Code is Open CASCADE SAS, having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License
+//
+// The code was inspired by "sView" project by
+// Kirill GAVRILOV: https://github.com/gkv311/sview.
+// Files: StGLMatrix.hxx, StGLMatrix.cxx.
+// Copyright (c) 2010-2013 Kirill Gavrilov <kirill@sview.ru>
+
+#ifndef _NCollection_Mat4_HeaderFile
+#define _NCollection_Mat4_HeaderFile
+
+#include <NCollection_Vec4.hxx>
+
+//! Generic matrix of 4 x 4 elements.
+//! To be used in conjunction with NCollection_Vec4 entities.
+//! Originally introduced for 3D space projection and orientation
+//! operations.
+template<typename Element_t>
+class NCollection_Mat4
+{
+
+public:
+
+  //! Get number of rows.
+  //! @return number of rows.
+  static size_t Rows()
+  {
+    return 4;
+  }
+
+  //! Get number of columns.
+  //! @retur number of columns.
+  static size_t Cols()
+  {
+    return 4;
+  }
+
+  //! Empty constructor.
+  //! Construct the zero matrix.
+  NCollection_Mat4()
+  {
+    InitIdentity();
+  }
+
+  //! Copy constructor.
+  //! @param theOther [in] the matrix to copy values from.
+  NCollection_Mat4 (const NCollection_Mat4& theOther)
+  {
+    std::memcpy (this, &theOther, sizeof (NCollection_Mat4));
+  }
+
+  //! Assignment operator.
+  //! @param theOther [in] the matrix to copy values from.
+  const NCollection_Mat4& operator= (const NCollection_Mat4& theOther)
+  {
+    std::memcpy (this, &theOther, sizeof (NCollection_Mat4));
+    return *this;
+  }
+
+  //! Get element at the specified row and column.
+  //! @param theRow [in] the row.to address.
+  //! @param theCol [in] the column to address.
+  //! @return the value of the addressed element.
+  Element_t GetValue (const size_t theRow, const size_t theCol) const
+  {
+    return myMat[theCol * 4 + theRow];
+  }
+
+  //! Access element at the specified row and column.
+  //! @param theRow [in] the row.to access.
+  //! @param theCol [in] the column to access.
+  //! @return reference on the matrix element.
+  Element_t& ChangeValue (const size_t theRow, const size_t theCol)
+  {
+    return myMat[theCol * 4 + theRow];
+  }
+
+  //! Set value for the element specified by row and columns.
+  //! @param theRow   [in] the row to change.
+  //! @param theCol   [in] the column to change.
+  //! @param theValue [in] the value to set.s
+  void SetValue (const size_t    theRow,
+                 const size_t    theCol,
+                 const Element_t theValue)
+  {
+    myMat[theCol * 4 + theRow] = theValue;
+  }
+
+  //! Get vector of elements for the specified row.
+  //! @param theRow [in] the row to access.
+  //! @return vector of elements.
+  NCollection_Vec4<Element_t> GetRow (const size_t theRow) const
+  {
+    return NCollection_Vec4<Element_t> (GetValue (theRow, 0),
+                                        GetValue (theRow, 1),
+                                        GetValue (theRow, 2),
+                                        GetValue (theRow, 3));
+  }
+
+  //! Change first 3 row values by the passed vector.
+  //! @param theRow [in] the row to change.
+  //! @param theVec [in] the vector of values.
+  void SetRow (const size_t theRow, const NCollection_Vec3<Element_t>& theVec)
+  {
+    SetValue (theRow, 0, theVec.x());
+    SetValue (theRow, 1, theVec.y());
+    SetValue (theRow, 2, theVec.z());
+  }
+
+  //! Set row values by the passed 4 element vector.
+  //! @param theRow [in] the row to change.
+  //! @param theVec [in] the vector of values.
+  void SetRow (const size_t theRow, const NCollection_Vec4<Element_t>& theVec)
+  {
+    SetValue (theRow, 0, theVec.x());
+    SetValue (theRow, 1, theVec.y());
+    SetValue (theRow, 2, theVec.z());
+    SetValue (theRow, 3, theVec.w());
+  }
+
+  //! Get vector of elements for the specified column.
+  //! @param theCol [in] the column to access.
+  //! @return vector of elements.
+  NCollection_Vec4<Element_t> GetColumn (const size_t theCol) const
+  {
+    return NCollection_Vec4<Element_t> (GetValue (0, theCol),
+                                        GetValue (1, theCol),
+                                        GetValue (2, theCol),
+                                        GetValue (3, theCol));
+  }
+
+  //! Change first 3 column values by the passed vector.
+  //! @param theCol [in] the column to change.
+  //! @param theVec [in] the vector of values.
+  void SetColumn (const size_t theCol,
+                  const NCollection_Vec3<Element_t>& theVec)
+  {
+    SetValue (0, theCol, theVec.x());
+    SetValue (1, theCol, theVec.y());
+    SetValue (2, theCol, theVec.z());
+  }
+
+  //! Set column values by the passed 4 element vector.
+  //! @param theCol [in] the column to change.
+  //! @param theVec [in] the vector of values.
+  void SetColumn (const size_t theCol,
+                  const NCollection_Vec4<Element_t>& theVec)
+  {
+    SetValue (0, theCol, theVec.x());
+    SetValue (1, theCol, theVec.y());
+    SetValue (2, theCol, theVec.z());
+    SetValue (3, theCol, theVec.w());
+  }
+
+  //! Get vector of diagonal elements.
+  //! \return vector of diagonal elements.
+  NCollection_Vec4<Element_t> GetDiagonal() const
+  {
+    return NCollection_Vec4<Element_t> (GetValue (0, 0),
+                                        GetValue (1, 1),
+                                        GetValue (2, 2),
+                                        GetValue (3, 3));
+  }
+
+  //! Change first 3 elements of the diagonal matrix.
+  //! @param theVec the vector of values.
+  void SetDiagonal (const NCollection_Vec3<Element_t>& theVec)
+  {
+    SetValue (0, 0, theVec.x());
+    SetValue (1, 1, theVec.y());
+    SetValue (2, 2, theVec.z());
+  }
+
+  //! Set diagonal elements of the matrix by the passed vector.
+  //! @param theVec [in] the vector of values.
+  void SetDiagonal (const NCollection_Vec4<Element_t>& theVec)
+  {
+    SetValue (0, 0, theVec.x());
+    SetValue (1, 1, theVec.y());
+    SetValue (2, 2, theVec.z());
+    SetValue (3, 3, theVec.w());
+  }
+
+  //! Initialize the identity matrix.
+  void InitIdentity()
+  {
+    static const Element_t anIdentity[] =
+      {1, 0, 0, 0,
+       0, 1, 0, 0,
+       0, 0, 1, 0,
+       0, 0, 0, 1};
+
+    std::memcpy (this, anIdentity, sizeof (NCollection_Mat4));
+  }
+
+  //! Raw access to the data (for OpenGL exchange).
+  const Element_t*  GetData() const { return myMat; }
+  operator const Element_t*() const { return myMat; }
+  operator       Element_t*()       { return myMat; }
+
+  //! Multiply by the vector (M * V).
+  //! @param theVec [in] the vector to multiply.
+  NCollection_Vec4<Element_t> operator* (const NCollection_Vec4<Element_t>& theVec) const
+  {
+    return NCollection_Vec4<Element_t> (
+      GetValue (0, 0) * theVec.x() + GetValue (0, 1) * theVec.y() + GetValue (0, 2) * theVec.z() + GetValue (0, 3) * theVec.w(),
+      GetValue (1, 0) * theVec.x() + GetValue (1, 1) * theVec.y() + GetValue (1, 2) * theVec.z() + GetValue (1, 3) * theVec.w(),
+      GetValue (2, 0) * theVec.x() + GetValue (2, 1) * theVec.y() + GetValue (2, 2) * theVec.z() + GetValue (2, 3) * theVec.w(),
+      GetValue (3, 0) * theVec.x() + GetValue (3, 1) * theVec.y() + GetValue (3, 2) * theVec.z() + GetValue (3, 3) * theVec.w());
+  }
+
+  //! Compute matrix multiplication product: A * B.
+  //! @param theMatA [in] the matrix "A".
+  //! @param theMatB [in] the matrix "B".
+  NCollection_Mat4 Multiply (const NCollection_Mat4& theMatA,
+                             const NCollection_Mat4& theMatB)
+  {
+    NCollection_Mat4 aMatRes;
+
+    size_t aInputElem;
+    for (size_t aResElem = 0; aResElem < 16; ++aResElem)
+    {
+      aMatRes[aResElem] = (Element_t )0;
+      for (aInputElem = 0; aInputElem < 4; ++aInputElem)
+      {
+        aMatRes[aResElem] += theMatA.GetValue(aResElem % 4, aInputElem)
+                           * theMatB.GetValue(aInputElem, aResElem / 4);
+      }
+    }
+
+    return aMatRes;
+  }
+
+  //! Compute matrix multiplication.
+  //! @param theMat [in] the matrix to multiply.
+  void Multiply (const NCollection_Mat4& theMat)
+  {
+    *this = Multiply(*this, theMat);
+  }
+
+  //! Multiply by the another matrix.
+  //! @param theMat [in] the other matrix.
+  NCollection_Mat4& operator*= (const NCollection_Mat4& theMat)
+  {
+    Multiply (theMat);
+    return *this;
+  }
+
+  //! Compute matrix multiplication product.
+  //! @param theMat [in] the other matrix.
+  //! @return result of multiplication.
+  NCollection_Mat4 operator* (const NCollection_Mat4& theMat) const
+  {
+    return Mutiplied (theMat);
+  }
+
+  //! Compute matrix multiplication product.
+  //! @param theMat [in] the other matrix.
+  //! @return result of multiplication.
+  NCollection_Mat4 Multiplied (const NCollection_Mat4& theMat) const
+  {
+    NCollection_Mat4 aTempMat (*this);
+    aTempMat *= theMat;
+    return aTempMat;
+  }
+
+  //! Compute per-component multiplication.
+  //! @param theFactor [in] the scale factor.
+  void Multiply (const Element_t theFactor)
+  {
+    for (size_t i = 0; i < 16; ++i)
+    {
+      myMat[i] *= theFactor;
+    }
+  }
+
+  //! Compute per-element multiplication.
+  //! @param theFactor [in] the scale factor.
+  NCollection_Mat4& operator*=(const Element_t theFactor)
+  {
+    Multiply (theFactor);
+    return *this;
+  }
+
+  //! Compute per-element multiplication.
+  //! @param theFactor [in] the scale factor.
+  //! @return the result of multiplicaton.
+  NCollection_Mat4 operator* (const Element_t theFactor) const
+  {
+    return Multiplied (theFactor);
+  }
+
+  //! Compute per-element multiplication.
+  //! @param theFactor [in] the scale factor.
+  //! @return the result of multiplicaton.
+  NCollection_Mat4 Multiplied (const Element_t theFactor) const
+  {
+    NCollection_Mat4 aTempMat (*this);
+    aTempMat *= theFactor;
+    return aTempMat;
+  }
+
+  //! Translate the matrix on the passed vector.
+  //! @param theVec [in] the translation vector.
+  void Translate (const NCollection_Vec3<Element_t>& theVec)
+  {
+    NCollection_Mat4 aTempMat;
+    aTempMat.SetColumn (3, theVec);
+    this->Multiply (aTempMat);
+  }
+
+  //! Compute inverted matrix.
+  //! @param theOutMx [out] the inverted matrix.
+  //! @return true if reversion success.
+  bool Inverted (NCollection_Mat4<Element_t>& theOutMx) const
+  {
+    Element_t* inv = theOutMx.myMat;
+
+    // use short-cut for better readability
+    const Element_t* m = myMat;
+
+    inv[ 0] = m[ 5] * (m[10] * m[15] - m[11] * m[14]) -
+              m[ 9] * (m[ 6] * m[15] - m[ 7] * m[14]) -
+              m[13] * (m[ 7] * m[10] - m[ 6] * m[11]);
+
+    inv[ 1] = m[ 1] * (m[11] * m[14] - m[10] * m[15]) -
+              m[ 9] * (m[ 3] * m[14] - m[ 2] * m[15]) -
+              m[13] * (m[ 2] * m[11] - m[ 3] * m[10]);
+
+    inv[ 2] = m[ 1] * (m[ 6] * m[15] - m[ 7] * m[14]) -
+              m[ 5] * (m[ 2] * m[15] - m[ 3] * m[14]) -
+              m[13] * (m[ 3] * m[ 6] - m[ 2] * m[ 7]);
+
+    inv[ 3] = m[ 1] * (m[ 7] * m[10] - m[ 6] * m[11]) -
+              m[ 5] * (m[ 3] * m[10] - m[ 2] * m[11]) -
+              m[ 9] * (m[ 2] * m[ 7] - m[ 3] * m[ 6]);
+
+    inv[ 4] = m[ 4] * (m[11] * m[14] - m[10] * m[15]) -
+              m[ 8] * (m[ 7] * m[14] - m[ 6] * m[15]) -
+              m[12] * (m[ 6] * m[11] - m[ 7] * m[10]);
+
+    inv[ 5] = m[ 0] * (m[10] * m[15] - m[11] * m[14]) -
+              m[ 8] * (m[ 2] * m[15] - m[ 3] * m[14]) -
+              m[12] * (m[ 3] * m[10] - m[ 2] * m[11]);
+
+    inv[ 6] = m[ 0] * (m[ 7] * m[14] - m[ 6] * m[15]) -
+              m[ 4] * (m[ 3] * m[14] - m[ 2] * m[15]) -
+              m[12] * (m[ 2] * m[ 7] - m[ 3] * m[ 6]);
+
+    inv[ 7] = m[ 0] * (m[ 6] * m[11] - m[ 7] * m[10]) -
+              m[ 4] * (m[ 2] * m[11] - m[ 3] * m[10]) -
+              m[ 8] * (m[ 3] * m[ 6] - m[ 2] * m[ 7]);
+
+    inv[ 8] = m[ 4] * (m[ 9] * m[15] - m[11] * m[13]) -
+              m[ 8] * (m[ 5] * m[15] - m[ 7] * m[13]) -
+              m[12] * (m[ 7] * m[ 9] - m[ 5] * m[11]);
+
+    inv[ 9] = m[ 0] * (m[11] * m[13] - m[ 9] * m[15]) -
+              m[ 8] * (m[ 3] * m[13] - m[ 1] * m[15]) -
+              m[12] * (m[ 1] * m[11] - m[ 3] * m[ 9]);
+
+    inv[10] = m[ 0] * (m[ 5] * m[15] - m[ 7] * m[13]) -
+              m[ 4] * (m[ 1] * m[15] - m[ 3] * m[13]) -
+              m[12] * (m[ 3] * m[ 5] - m[ 1] * m[ 7]);
+
+    inv[11] = m[ 0] * (m[ 7] * m[ 9] - m[ 5] * m[11]) -
+              m[ 4] * (m[ 3] * m[ 9] - m[ 1] * m[11]) -
+              m[ 8] * (m[ 1] * m[ 7] - m[ 3] * m[ 5]);
+
+    inv[12] = m[ 4] * (m[10] * m[13] - m[ 9] * m[14]) -
+              m[ 8] * (m[ 6] * m[13] - m[ 5] * m[14]) -
+              m[12] * (m[ 5] * m[10] - m[ 6] * m[ 9]);
+
+    inv[13] = m[ 0] * (m[ 9] * m[14] - m[10] * m[13]) -
+              m[ 8] * (m[ 1] * m[14] - m[ 2] * m[13]) -
+              m[12] * (m[ 2] * m[ 9] - m[ 1] * m[10]);
+
+    inv[14] = m[ 0] * (m[ 6] * m[13] - m[ 5] * m[14]) -
+              m[ 4] * (m[ 2] * m[13] - m[ 1] * m[14]) -
+              m[12] * (m[ 1] * m[ 6] - m[ 2] * m[ 5]);
+
+    inv[15] = m[ 0] * (m[ 5] * m[10] - m[ 6] * m[ 9]) -
+              m[ 4] * (m[ 1] * m[10] - m[ 2] * m[ 9]) -
+              m[ 8] * (m[ 2] * m[ 5] - m[ 1] * m[ 6]);
+
+    Element_t aDet = m[0] * inv[ 0] +
+                     m[1] * inv[ 4] +
+                     m[2] * inv[ 8] +
+                     m[3] * inv[12];
+
+    if (aDet == 0)
+      return false;
+
+    aDet = (Element_t) 1. / aDet;
+
+    for (int i = 0; i < 16; ++i)
+      inv[i] *= aDet;
+
+    return true;
+  }
+
+private:
+
+  Element_t myMat[16];
+
+};
+
+#endif // _NCollection_Matrix_H__
index 65ba3e5..57ae623 100755 (executable)
@@ -120,5 +120,16 @@ OpenGl_CappingAlgo.hxx
 OpenGl_CappingAlgo.cxx
 OpenGl_CappingPlaneResource.hxx
 OpenGl_CappingPlaneResource.cxx
-OpenGl_ClippingState.hxx
-OpenGl_ClippingState.cxx
+OpenGl_Clipping.hxx
+OpenGl_Clipping.cxx
+OpenGl_ShaderObject.hxx
+OpenGl_ShaderObject.cxx
+OpenGl_ShaderProgram.hxx
+OpenGl_ShaderProgram.cxx
+OpenGl_ShaderManager.hxx
+OpenGl_ShaderManager.cxx
+OpenGl_ShaderStates.hxx
+OpenGl_ShaderStates.cxx
+Handle_OpenGl_ShaderObject.hxx
+Handle_OpenGl_ShaderProgram.hxx
+Handle_OpenGl_ShaderManager.hxx
diff --git a/src/OpenGl/Handle_OpenGl_ShaderManager.hxx b/src/OpenGl/Handle_OpenGl_ShaderManager.hxx
new file mode 100644 (file)
index 0000000..5f5f4bd
--- /dev/null
@@ -0,0 +1,26 @@
+// Created on: 2013-09-26
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Handle_OpenGl_ShaderManager_HeaderFile
+#define _Handle_OpenGl_ShaderManager_HeaderFile
+
+class OpenGl_ShaderManager;
+DEFINE_STANDARD_HANDLE(OpenGl_ShaderManager, Standard_Transient)
+
+#endif
diff --git a/src/OpenGl/Handle_OpenGl_ShaderObject.hxx b/src/OpenGl/Handle_OpenGl_ShaderObject.hxx
new file mode 100644 (file)
index 0000000..109b02a
--- /dev/null
@@ -0,0 +1,28 @@
+// Created on: 2013-09-19
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Handle_OpenGl_ShaderObject_Header
+#define _Handle_OpenGl_ShaderObject_Header
+
+#include <OpenGl_Resource.hxx>
+
+class OpenGl_ShaderObject;
+DEFINE_STANDARD_HANDLE(OpenGl_ShaderObject, OpenGl_Resource)
+
+#endif
diff --git a/src/OpenGl/Handle_OpenGl_ShaderProgram.hxx b/src/OpenGl/Handle_OpenGl_ShaderProgram.hxx
new file mode 100644 (file)
index 0000000..a8c1d29
--- /dev/null
@@ -0,0 +1,28 @@
+// Created on: 2013-09-19
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Handle_OpenGl_ShaderProgram_Header
+#define _Handle_OpenGl_ShaderProgram_Header
+
+#include <OpenGl_Resource.hxx>
+
+class OpenGl_ShaderProgram;
+DEFINE_STANDARD_HANDLE(OpenGl_ShaderProgram, OpenGl_Resource)
+
+#endif
index 41f72e2..a9a7483 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#include <Aspect_PolygonOffsetMode.hxx>
+#include <NCollection_Vec3.hxx>
+
 #include <OpenGl_AspectFace.hxx>
+#include <OpenGl_Context.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Texture.hxx>
 #include <OpenGl_Workspace.hxx>
-#include <OpenGl_Context.hxx>
 
-#include <Aspect_PolygonOffsetMode.hxx>
 #include <Graphic3d_CGroup.hxx>
+#include <Graphic3d_ShaderProgram.hxx>
 #include <Graphic3d_TextureMap.hxx>
 #include <Graphic3d_TypeOfReflection.hxx>
 #include <Graphic3d_MaterialAspect.hxx>
 
-#include <NCollection_Vec3.hxx>
-
 namespace
 {
-
   static OPENGL_SURF_PROP THE_DEFAULT_MATERIAL =
   {
     0.2F,  0.8F, 0.1F, 0.0F, // amb, diff, spec, emsv
@@ -48,7 +50,6 @@ namespace
 
   static TEL_POFFSET_PARAM THE_DEFAULT_POFFSET = { Aspect_POM_Fill, 1.0F, 0.0F };
   static const TCollection_AsciiString THE_EMPTY_KEY;
-
 };
 
 // =======================================================================
@@ -130,11 +131,7 @@ OpenGl_AspectFace::OpenGl_AspectFace()
   myIntFront (THE_DEFAULT_MATERIAL),
   myIntBack (THE_DEFAULT_MATERIAL),
   myPolygonOffset (THE_DEFAULT_POFFSET),
-  myDoTextureMap (false),
-  myTextureMap(),
-  myIsTextureInit (Standard_False),
-  myTextureRes(),
-  myTextureId()
+  myDoTextureMap (false)
 {}
 
 // =======================================================================
@@ -208,12 +205,6 @@ void OpenGl_AspectFace::SetAspect (const CALL_DEF_CONTEXTFILLAREA& theAspect)
   myIntBack.matcol.rgb[2] = (float )theAspect.BackIntColor.b;
   myIntBack.matcol.rgb[3] = 1.0f;
 
-  myDoTextureMap  = (theAspect.Texture.doTextureMap != 0);
-  myTextureMap    = theAspect.Texture.TextureMap;
-
-  const TCollection_AsciiString& aNewKey = myTextureMap.IsNull() ? THE_EMPTY_KEY : myTextureMap->GetId();
-  myIsTextureInit = (!aNewKey.IsEmpty() && myTextureId == aNewKey);
-
   //TelPolygonOffset
   myPolygonOffset.mode   = (Aspect_PolygonOffsetMode )theAspect.PolygonOffsetMode;
   myPolygonOffset.factor = theAspect.PolygonOffsetFactor;
@@ -226,6 +217,28 @@ void OpenGl_AspectFace::SetAspect (const CALL_DEF_CONTEXTFILLAREA& theAspect)
   anEdgeAspect.LineType = (Aspect_TypeOfLine )theAspect.LineType;
   anEdgeAspect.Width    = (float )theAspect.Width;
   myAspectEdge.SetAspect (anEdgeAspect);
+
+  myDoTextureMap = (theAspect.Texture.doTextureMap != 0);
+
+  // update texture binding
+  myTexture = theAspect.Texture.TextureMap;
+
+  const TCollection_AsciiString& aTextureKey = myTexture.IsNull() ? THE_EMPTY_KEY : myTexture->GetId();
+
+  if (aTextureKey.IsEmpty() || myResources.TextureId != aTextureKey)
+  {
+    myResources.ResetTexture();
+  }
+
+  // update shader program binding
+  myShaderProgram = theAspect.ShaderProgram;
+
+  const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
+
+  if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
+  {
+    myResources.ResetShader();
+  }
 }
 
 // =======================================================================
@@ -363,6 +376,8 @@ void OpenGl_AspectFace::SetAspect (const Handle(Graphic3d_AspectFillArea3d)& the
   aFaceContext.PolygonOffsetFactor = (Standard_ShortReal)aPolyFactor;
   aFaceContext.PolygonOffsetUnits  = (Standard_ShortReal)aPolyUnits;
 
+  aFaceContext.ShaderProgram = theAspect->ShaderProgram();
+
   SetAspect (aFaceContext);
 }
 
@@ -381,66 +396,110 @@ void OpenGl_AspectFace::Render (const Handle(OpenGl_Workspace)& theWorkspace) co
 // =======================================================================
 void OpenGl_AspectFace::Release (const Handle(OpenGl_Context)& theContext)
 {
-  if (!myTextureRes.IsNull())
+  if (!myResources.Texture.IsNull())
   {
     if (!theContext.IsNull())
     {
-      if (myTextureId.IsEmpty())
+      if (myResources.TextureId.IsEmpty())
       {
-        theContext->DelayedRelease (myTextureRes);
+        theContext->DelayedRelease (myResources.Texture);
       }
       else
       {
-        myTextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
-        theContext->ReleaseResource (myTextureId);
+        myResources.Texture.Nullify(); // we need nullify all handles before ReleaseResource() call
+        theContext->ReleaseResource (myResources.TextureId);
       }
     }
-    myTextureRes.Nullify();
+    myResources.Texture.Nullify();
   }
-  myTextureId.Clear();
+  myResources.TextureId.Clear();
+  myResources.ResetTexture();
+
+  if (!myResources.ShaderProgram.IsNull() && !theContext.IsNull())
+  {
+    theContext->ShaderManager()->Unregister (myResources.ShaderProgram);
+  }
+  myResources.ShaderProgramId.Clear();
+  myResources.ResetShader();
 }
 
 // =======================================================================
-// function : buildTexure
+// function : BuildTexture
 // purpose  :
 // =======================================================================
-void OpenGl_AspectFace::buildTexture (const Handle(OpenGl_Workspace)& theWorkspace) const
+void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Workspace)& theWS,
+                                                 const Handle(Graphic3d_TextureMap)& theTexture)
 {
-  const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
 
-  const TCollection_AsciiString& aNewKey = myTextureMap.IsNull() ? THE_EMPTY_KEY : myTextureMap->GetId();
-  if (aNewKey.IsEmpty() || myTextureId != aNewKey)
+  // release old texture resource
+  if (!Texture.IsNull())
   {
-    if (!myTextureRes.IsNull())
+    if (TextureId.IsEmpty())
+    {
+      aContext->DelayedRelease (Texture);
+      Texture.Nullify();
+    }
+    else
     {
-      if (myTextureId.IsEmpty())
+      Texture.Nullify(); // we need nullify all handles before ReleaseResource() call
+      aContext->ReleaseResource (TextureId);
+    }
+  }
+
+  TextureId = theTexture.IsNull() ? THE_EMPTY_KEY : theTexture->GetId();
+
+  if (!theTexture.IsNull())
+  {
+    if (TextureId.IsEmpty() || !aContext->GetResource<Handle(OpenGl_Texture)> (TextureId, Texture))
+    {
+      Texture = new OpenGl_Texture (theTexture->GetParams());
+      Handle(Image_PixMap) anImage = theTexture->GetImage();
+      if (!anImage.IsNull())
       {
-        aContext->DelayedRelease (myTextureRes);
-        myTextureRes.Nullify();
+        Texture->Init (aContext, *anImage.operator->(), theTexture->Type());
       }
-      else
+      if (!TextureId.IsEmpty())
       {
-        myTextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
-        aContext->ReleaseResource (myTextureId);
+        aContext->ShareResource (TextureId, Texture);
       }
     }
-    myTextureId = aNewKey;
+  }
+}
 
-    if (!myTextureMap.IsNull())
+// =======================================================================
+// function : BuildShader
+// purpose  :
+// =======================================================================
+void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
+                                                const Handle(Graphic3d_ShaderProgram)& theShader)
+{
+  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
+
+  if (!aContext->IsGlGreaterEqual (2, 0))
+    return;
+
+  // release old shader program resources
+  if (!ShaderProgram.IsNull())
+  {
+    aContext->ShaderManager()->Unregister (ShaderProgram);
+  }
+
+  ShaderProgramId = theShader.IsNull() ? THE_EMPTY_KEY : theShader->GetId();
+
+  if (!theShader.IsNull())
+  {
+    if (!aContext->GetResource<Handle(OpenGl_ShaderProgram)> (ShaderProgramId, ShaderProgram))
     {
-      if (aNewKey.IsEmpty() || !aContext->GetResource<Handle(OpenGl_Texture)> (aNewKey, myTextureRes))
+      ShaderProgram = aContext->ShaderManager()->Create (theShader);
+      if (!ShaderProgramId.IsEmpty())
       {
-        myTextureRes = new OpenGl_Texture (myTextureMap->GetParams());
-        Handle(Image_PixMap) anImage = myTextureMap->GetImage();
-        if (!anImage.IsNull())
-        {
-          myTextureRes->Init (aContext, *anImage.operator->(), myTextureMap->Type());
-        }
-        if (!aNewKey.IsEmpty())
-        {
-          aContext->ShareResource (aNewKey, myTextureRes);
-        }
+        aContext->ShareResource (ShaderProgramId, ShaderProgram);
       }
     }
   }
+  else
+  {
+    ShaderProgram.Nullify();
+  }
 }
index 9174122..18b640f 100644 (file)
 #include <Aspect_InteriorStyle.hxx>
 #include <TCollection_AsciiString.hxx>
 
+#include <Handle_Graphic3d_TextureParams.hxx>
+#include <Handle_OpenGl_ShaderProgram.hxx>
+#include <Handle_OpenGl_Texture.hxx>
 #include <OpenGl_AspectLine.hxx>
 #include <OpenGl_Element.hxx>
-#include <Handle_OpenGl_Texture.hxx>
 
-#include <Graphic3d_TextureMap.hxx>
 #include <Graphic3d_AspectFillArea3d.hxx>
-#include <Handle_Graphic3d_TextureParams.hxx>
+#include <Graphic3d_ShaderProgram_Handle.hxx>
+#include <Graphic3d_TextureMap.hxx>
 
 #define OPENGL_AMBIENT_MASK  (1<<0)
 #define OPENGL_DIFFUSE_MASK  (1<<1)
@@ -180,22 +182,35 @@ public:
     return myDoTextureMap;
   }
 
+  //! @return texture mapping parameters.
+  const Handle(Graphic3d_TextureParams)& TextureParams() const
+  {
+    return myTexture->GetParams();
+  }
+
   //! @return texture map.
   const Handle(OpenGl_Texture)& TextureRes (const Handle(OpenGl_Workspace)& theWorkspace) const
   {
-    if (!myIsTextureInit)
+    if (!myResources.IsTextureReady())
     {
-      buildTexture (theWorkspace);
-      myIsTextureInit = Standard_True;
+      myResources.BuildTexture (theWorkspace, myTexture);
+      myResources.SetTextureReady();
     }
 
-    return myTextureRes;
+    return myResources.Texture;
   }
 
-  //! @return texture mapping parameters.
-  const Handle(Graphic3d_TextureParams)& TextureParams() const
+  //! Init and return OpenGl shader program resource.
+  //! @return shader program resource.
+  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Workspace)& theWorkspace) const 
   {
-    return myTextureMap->GetParams();
+    if (!myResources.IsShaderReady())
+    {
+      myResources.BuildShader (theWorkspace, myShaderProgram);
+      myResources.SetShaderReady();
+    }
+
+    return myResources.ShaderProgram;
   }
 
   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
@@ -203,7 +218,6 @@ public:
 
 protected:
 
-  void buildTexture (const Handle(OpenGl_Workspace)& theWorkspace) const;
   void convertMaterial (const CALL_DEF_MATERIAL& theMat,
                         OPENGL_SURF_PROP&        theSurf);
 
@@ -218,13 +232,40 @@ protected: //! @name ordinary aspect properties
   OPENGL_SURF_PROP                myIntBack;
   TEL_POFFSET_PARAM               myPolygonOffset;
   bool                            myDoTextureMap;
-  Handle(Graphic3d_TextureMap)    myTextureMap;
+  Handle(Graphic3d_TextureMap)    myTexture;
+  Handle(Graphic3d_ShaderProgram) myShaderProgram;
+
+protected:
+
+  //! OpenGl resources
+  mutable struct Resources
+  {
+  public:
+    Resources()
+      : myIsTextureReady (Standard_False),
+        myIsShaderReady  (Standard_False) {}
+
+    Standard_Boolean IsTextureReady() const { return myIsTextureReady; }
+    Standard_Boolean IsShaderReady () const { return myIsShaderReady;  }
+    void SetTextureReady() { myIsTextureReady = Standard_True; }
+    void SetShaderReady () { myIsShaderReady  = Standard_True; }
+    void ResetTexture() { myIsTextureReady = Standard_False; }
+    void ResetShader () { myIsShaderReady  = Standard_False; }
+
+    void BuildTexture (const Handle(OpenGl_Workspace)& theWS, const Handle(Graphic3d_TextureMap)& theTexture);
+    void BuildShader  (const Handle(OpenGl_Workspace)& theWS, const Handle(Graphic3d_ShaderProgram)& theShader);
+
+    Handle(OpenGl_Texture)  Texture;
+    TCollection_AsciiString TextureId;
+    Handle(OpenGl_ShaderProgram) ShaderProgram;
+    TCollection_AsciiString      ShaderProgramId;
+
+  private:
 
-protected: //! @name OpenGl resources
+    Standard_Boolean myIsTextureReady;
+    Standard_Boolean myIsShaderReady;
 
-  mutable Standard_Boolean        myIsTextureInit;
-  mutable Handle(OpenGl_Texture)  myTextureRes;
-  mutable TCollection_AsciiString myTextureId;
+  } myResources;
 
 protected:
 
index 189c485..a347949 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#include <Graphic3d_ShaderProgram.hxx>
+
 #include <OpenGl_AspectLine.hxx>
+#include <OpenGl_Context.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Workspace.hxx>
 
-static const TEL_COLOUR myDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
-
-/*----------------------------------------------------------------------*/
+namespace
+{
+  static const TEL_COLOUR myDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
+  static const TCollection_AsciiString THE_EMPTY_KEY;
+};
 
+// =======================================================================
+// function : OpenGl_AspectLine
+// purpose  :
+// =======================================================================
 OpenGl_AspectLine::OpenGl_AspectLine ()
  : myColor(myDefaultColor),
    myType(Aspect_TOL_SOLID),
    myWidth(1.0F)
 {}
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : OpenGl_AspectLine
+// purpose  :
+// =======================================================================
 OpenGl_AspectLine::OpenGl_AspectLine (const OpenGl_AspectLine &AnOther)
  : myColor(AnOther.myColor),
    myType(AnOther.myType),
    myWidth(AnOther.myWidth)
 {}
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspect
+// purpose  :
+// =======================================================================
 void OpenGl_AspectLine::SetAspect (const CALL_DEF_CONTEXTLINE &theAspect)
 {
   myColor.rgb[0] = (float) theAspect.Color.r;
@@ -48,16 +63,74 @@ void OpenGl_AspectLine::SetAspect (const CALL_DEF_CONTEXTLINE &theAspect)
   myColor.rgb[3] = 1.0f;
   myType = (Aspect_TypeOfLine) theAspect.LineType;
   myWidth = (float) theAspect.Width;
-}
 
-/*----------------------------------------------------------------------*/
+  // update resource bindings
+  myShaderProgram = theAspect.ShaderProgram;
+
+  const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
+
+  if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
+  {
+    myResources.ResetShader();
+  }
+}
 
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
 void OpenGl_AspectLine::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
 {
   theWorkspace->SetAspectLine (this);
 }
 
-void OpenGl_AspectLine::Release (const Handle(OpenGl_Context)&)
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_AspectLine::Release (const Handle(OpenGl_Context)& theContext)
+{
+  if (!myResources.ShaderProgram.IsNull() && !theContext.IsNull())
+  {
+    theContext->ShaderManager()->Unregister (myResources.ShaderProgram);
+  }
+  myResources.ShaderProgramId.Clear();
+  myResources.ResetShader();
+}
+
+// =======================================================================
+// function : BuildShader
+// purpose  :
+// =======================================================================
+void OpenGl_AspectLine::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
+                                                const Handle(Graphic3d_ShaderProgram)& theShader)
 {
-  //
+  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
+
+  if (!aContext->IsGlGreaterEqual (2, 0))
+    return;
+
+  // release old shader program resources
+  if (!ShaderProgram.IsNull())
+  {
+    aContext->ShaderManager()->Unregister (ShaderProgram);
+  }
+
+  ShaderProgramId = theShader.IsNull() ? THE_EMPTY_KEY : theShader->GetId();
+
+  if (!theShader.IsNull())
+  {
+    if (!aContext->GetResource<Handle(OpenGl_ShaderProgram)> (ShaderProgramId, ShaderProgram))
+    {
+      ShaderProgram = aContext->ShaderManager()->Create (theShader);
+      if (!ShaderProgramId.IsEmpty())
+      {
+        aContext->ShareResource (ShaderProgramId, ShaderProgram);
+      }
+    }
+  }
+  else
+  {
+    ShaderProgram.Nullify();
+  }
 }
index 3f2d447..c192ba7 100644 (file)
 #ifndef _OpenGl_AspectLine_Header
 #define _OpenGl_AspectLine_Header
 
+#include <TCollection_AsciiString.hxx>
+
 #include <InterfaceGraphic_Graphic3d.hxx>
 #include <Aspect_TypeOfLine.hxx>
 
+#include <Handle_OpenGl_ShaderProgram.hxx>
+
 #include <OpenGl_Element.hxx>
 
 class OpenGl_AspectLine : public OpenGl_Element
@@ -38,14 +42,51 @@ class OpenGl_AspectLine : public OpenGl_Element
   Aspect_TypeOfLine  Type() const { return myType; }
   float              Width() const { return myWidth; }
 
+  //! Init and return OpenGl shader program resource.
+  //! @return shader program resource.
+  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  {
+    if (!myResources.IsShaderReady())
+    {
+      myResources.BuildShader (theWorkspace, myShaderProgram);
+      myResources.SetShaderReady();
+    }
+
+    return myResources.ShaderProgram;
+  }
+
   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
   virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
- protected:
+protected:
+
+  TEL_COLOUR                      myColor;
+  Aspect_TypeOfLine               myType;
+  float                           myWidth;
+  Handle(Graphic3d_ShaderProgram) myShaderProgram;
+
+protected:
+
+  //! OpenGl resources
+  mutable struct Resources
+  {
+  public:
+    Resources() : myIsShaderReady (Standard_False) {}
+
+    Standard_Boolean IsShaderReady() const { return myIsShaderReady; }
+    void SetShaderReady() { myIsShaderReady = Standard_True; }
+    void ResetShader   () { myIsShaderReady = Standard_False; }
+
+    void BuildShader (const Handle(OpenGl_Workspace)& theWS, const Handle(Graphic3d_ShaderProgram)& theShader);
+
+    Handle(OpenGl_ShaderProgram) ShaderProgram;
+    TCollection_AsciiString      ShaderProgramId;
+
+  private:
+
+    Standard_Boolean myIsShaderReady;
 
-  TEL_COLOUR        myColor;
-  Aspect_TypeOfLine myType;
-  float             myWidth;
+  } myResources;
 
  public:
   DEFINE_STANDARD_ALLOC
index 2de0f83..78a077d 100644 (file)
 #include <OpenGl_Context.hxx>
 #include <OpenGl_GraphicDriver.hxx>
 #include <OpenGl_PointSprite.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Workspace.hxx>
 
 #include <Image_PixMap.hxx>
 #include <Graphic3d_MarkerImage.hxx>
+#include <Graphic3d_ShaderProgram.hxx>
 #include <NCollection_Vec4.hxx>
 #include <TColStd_HArray1OfByte.hxx>
 
-static const TEL_COLOUR myDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
+namespace
+{
+  static const TEL_COLOUR myDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
+  static const TCollection_AsciiString THE_EMPTY_KEY;
+};
 
 // Following Section relates to default markers
 
@@ -1448,11 +1455,9 @@ OpenGl_AspectMarker::OpenGl_AspectMarker()
  : myColor (myDefaultColor),
    myType  (Aspect_TOM_PLUS),
    myScale (1.0f),
-   myMarkerImage(),
    myMarkerSize (1.0f),
-   mySpriteKey  (""),
-   mySpriteAKey (""),
-   myIsSpriteInit (Standard_False)
+   myMarkerImage(),
+   myShaderProgram()
 {}
 
 // =======================================================================
@@ -1468,94 +1473,164 @@ void OpenGl_AspectMarker::SetAspect (const CALL_DEF_CONTEXTMARKER& theAspect)
   myMarkerImage  = theAspect.MarkerImage;
   myType         = theAspect.MarkerType;
   myScale = myMarkerSize = theAspect.Scale;
+  myShaderProgram = theAspect.ShaderProgram;
+
+  // update sprite resource bindings
+  TCollection_AsciiString aSpriteKey  = THE_EMPTY_KEY;
+  TCollection_AsciiString aSpriteAKey = THE_EMPTY_KEY;
+  myResources.SpriteKeys (myMarkerImage, myType, myScale, myColor, aSpriteKey, aSpriteAKey);
+
+  if (aSpriteKey.IsEmpty() || myResources.SpriteKey != aSpriteKey)
+  {
+    myResources.ResetSprite();
+  }
+  if (aSpriteAKey.IsEmpty() || myResources.SpriteAKey != aSpriteAKey)
+  {
+    myResources.ResetSprite();
+  }
+
+  // update shader program resource bindings
+  const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
+
+  if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
+  {
+    myResources.ResetShader();
+  }
+}
 
-  // check that the resources need to be renewed
-  TCollection_AsciiString aNewKey, aNewKeyA;
-  resourceKeys (myMarkerImage, myType, myScale, myColor, aNewKey, aNewKeyA);
-  myIsSpriteInit  = !aNewKey.IsEmpty()  && mySpriteKey  == aNewKey;
-  myIsSpriteInit &= !aNewKeyA.IsEmpty() && mySpriteAKey == aNewKeyA;
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
+void OpenGl_AspectMarker::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+  theWorkspace->SetAspectMarker (this);
 }
 
 // =======================================================================
-// function : buildSprites
+// function : Release
 // purpose  :
 // =======================================================================
-void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorkspace) const
+void OpenGl_AspectMarker::Release (const Handle(OpenGl_Context)& theCtx)
+{
+  if (!myResources.Sprite.IsNull())
+  {
+    if (!theCtx.IsNull())
+    {
+      if (myResources.SpriteKey.IsEmpty())
+      {
+        theCtx->DelayedRelease (myResources.Sprite);
+        theCtx->DelayedRelease (myResources.SpriteA);
+      }
+      else
+      {
+        myResources.Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
+        myResources.SpriteA.Nullify();
+        theCtx->ReleaseResource (myResources.SpriteKey,  Standard_True);
+        theCtx->ReleaseResource (myResources.SpriteAKey, Standard_True);
+      }
+    }
+    myResources.Sprite.Nullify();
+    myResources.SpriteA.Nullify();
+  }
+  myResources.SpriteKey.Clear();
+  myResources.SpriteAKey.Clear();
+  myResources.ResetSprite();
+
+  if (!myResources.ShaderProgram.IsNull() && !theCtx.IsNull())
+  {
+    theCtx->ShaderManager()->Unregister (myResources.ShaderProgram);
+  }
+  myResources.ShaderProgramId.Clear();
+  myResources.ResetShader();
+}
+
+// =======================================================================
+// function : BuildSprites
+// purpose  :
+// =======================================================================
+void OpenGl_AspectMarker::Resources::BuildSprites (const Handle(OpenGl_Workspace)& theWorkspace,
+                                                   const Handle(Graphic3d_MarkerImage)& theMarkerImage,
+                                                   const Aspect_TypeOfMarker theType,
+                                                   const Standard_ShortReal theScale,
+                                                   const TEL_COLOUR& theColor,
+                                                   Standard_ShortReal& theMarkerSize)
 {
   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
 
-  TCollection_AsciiString aNewKey, aNewKeyA;
-  resourceKeys (myMarkerImage, myType, myMarkerSize, myColor, aNewKey, aNewKeyA);
+  // generate key for shared resource
+  TCollection_AsciiString aNewKey  = THE_EMPTY_KEY;
+  TCollection_AsciiString aNewKeyA = THE_EMPTY_KEY;
+  SpriteKeys (theMarkerImage, theType, theScale, theColor, aNewKey, aNewKeyA);
 
   // release old shared resources
-  const Standard_Boolean aNewResource = aNewKey.IsEmpty() || mySpriteKey != aNewKey;
+  const Standard_Boolean aNewResource = aNewKey.IsEmpty() || SpriteKey != aNewKey;
   if (aNewResource)
   {
-    if (!mySprite.IsNull())
+    if (!Sprite.IsNull())
     {
-      if (mySpriteKey.IsEmpty())
+      if (SpriteKey.IsEmpty())
       {
-        aContext->DelayedRelease (mySprite);
-        mySprite.Nullify();
+        aContext->DelayedRelease (Sprite);
+        Sprite.Nullify();
       }
       else
       {
-        mySprite.Nullify(); // we need nullify all handles before ReleaseResource() call
-        aContext->ReleaseResource (mySpriteKey);
+        Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
+        aContext->ReleaseResource (SpriteKey);
       }
     }
-    mySpriteKey = aNewKey;
+    SpriteKey = aNewKey;
   }
-  if (aNewKeyA.IsEmpty()
-   || mySpriteAKey != aNewKeyA)
+  if (aNewKeyA.IsEmpty() || SpriteAKey != aNewKeyA)
   {
-    if (!mySpriteA.IsNull())
+    if (!SpriteA.IsNull())
     {
-      if (mySpriteAKey.IsEmpty())
+      if (SpriteAKey.IsEmpty())
       {
-        aContext->DelayedRelease (mySpriteA);
-        mySpriteA.Nullify();
+        aContext->DelayedRelease (SpriteA);
+        SpriteA.Nullify();
       }
       else
       {
-        mySpriteA.Nullify(); // we need nullify all handles before ReleaseResource() call
-        aContext->ReleaseResource (mySpriteKey);
+        SpriteA.Nullify(); // we need nullify all handles before ReleaseResource() call
+        aContext->ReleaseResource (SpriteKey);
       }
     }
-    mySpriteAKey = aNewKeyA;
+    SpriteAKey = aNewKeyA;
   }
-  if (myType == Aspect_TOM_POINT
+  if (theType == Aspect_TOM_POINT
    || !aNewResource
-   || (myType == Aspect_TOM_USERDEFINED && myMarkerImage.IsNull()))
+   || (theType == Aspect_TOM_USERDEFINED && theMarkerImage.IsNull()))
   {
     // nothing to do - just simple point
     return;
   }
 
   if (!aNewKey.IsEmpty()
-   && aContext->GetResource<Handle(OpenGl_PointSprite)> (aNewKeyA, mySpriteA) // alpha sprite could be shared
-   && aContext->GetResource<Handle(OpenGl_PointSprite)> (aNewKey,  mySprite))
+   && aContext->GetResource<Handle(OpenGl_PointSprite)> (aNewKeyA, SpriteA) // alpha sprite could be shared
+   && aContext->GetResource<Handle(OpenGl_PointSprite)> (aNewKey,  Sprite))
   {
     // reuse shared resource
-    if (!mySprite->IsDisplayList())
+    if (!Sprite->IsDisplayList())
     {
-      myMarkerSize = Standard_ShortReal (Max (mySprite->SizeX(), mySprite->SizeY()));
+      theMarkerSize = Standard_ShortReal (Max (Sprite->SizeX(), Sprite->SizeY()));
     }
     return;
   }
 
-  const bool hadAlreadyAlpha = !mySpriteA.IsNull();
+  const bool hadAlreadyAlpha = !SpriteA.IsNull();
   if (!hadAlreadyAlpha)
   {
-    mySpriteA = new OpenGl_PointSprite();
+    SpriteA = new OpenGl_PointSprite();
   }
-  mySprite  = new OpenGl_PointSprite();
+  Sprite  = new OpenGl_PointSprite();
   if (!aNewKey.IsEmpty())
   {
-    aContext->ShareResource (aNewKey,  mySprite);
+    aContext->ShareResource (aNewKey,  Sprite);
     if (!hadAlreadyAlpha)
     {
-      aContext->ShareResource (aNewKeyA, mySpriteA);
+      aContext->ShareResource (aNewKeyA, SpriteA);
     }
   }
 
@@ -1567,9 +1642,9 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
     Handle(Graphic3d_MarkerImage) aNewMarkerImage;
     Handle(Image_PixMap) anImage, anImageA;
 
-    if (myType == Aspect_TOM_USERDEFINED && !myMarkerImage.IsNull())
+    if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull())
     {
-      aNewMarkerImage = myMarkerImage;
+      aNewMarkerImage = theMarkerImage;
       anImage = aNewMarkerImage->GetImage();
     }
     else
@@ -1579,14 +1654,14 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
       Handle(Graphic3d_MarkerImage) aMarkerImage1, aMarkerImage2;
 
       const Standard_ShortReal aDelta = 0.1F;
-      Standard_ShortReal aScale = myScale;
+      Standard_ShortReal aScale = theScale;
       Standard_ShortReal aLimit = 0.0F;
 
-      switch (myType)
+      switch (theType)
       {
         case Aspect_TOM_O_POINT:
         {
-          const Standard_Integer aSize = myScale > 7 ? 7 : (Standard_Integer )(myScale + 0.5F);
+          const Standard_Integer aSize = theScale > 7 ? 7 : (Standard_Integer )(theScale + 0.5F);
           const Standard_Integer aNumOfBytes = (aSize / 8 + (aSize % 8 ? 1 : 0)) * aSize;
           aBitMap = new TColStd_HArray1OfByte (0, aNumOfBytes - 1);
           for (Standard_Integer anIter = 0; anIter < aBitMap->Length(); anIter++)
@@ -1601,10 +1676,10 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
         {
           // For this type of markers we merge two base bitmaps into one
           // For example Aspect_TOM_O_PLUS = Aspect_TOM_O + Aspect_TOM_PLUS
-          aMarkerImage1 = GetTextureImage (Aspect_TOM_O, myScale);
-          if (myType != Aspect_TOM_O_POINT)
+          aMarkerImage1 = GetTextureImage (Aspect_TOM_O, theScale);
+          if (theType != Aspect_TOM_O_POINT)
           {
-            aMarkerImage2 = GetTextureImage (Aspect_TypeOfMarker (myType - Aspect_TOM_O_POINT), myScale);
+            aMarkerImage2 = GetTextureImage (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale);
           }
           anImage = MergeImages (aMarkerImage1->GetImage(), aMarkerImage2->GetImage());
           aNewMarkerImage = new Graphic3d_MarkerImage (anImage);
@@ -1630,10 +1705,10 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
           GetMarkerBitMapParam (Aspect_TOM_O, aScale, aWidth, aHeight, anOffset, aNumOfBytes);
 
           const Standard_ShortReal aDelta = 0.1f;
-          NCollection_Vec4<Standard_Real> aColor (Standard_Real (myColor.rgb[0]),
-                                                  Standard_Real (myColor.rgb[1]),
-                                                  Standard_Real (myColor.rgb[2]),
-                                                  Standard_Real (myColor.rgb[3]));
+          NCollection_Vec4<Standard_Real> aColor (Standard_Real (theColor.rgb[0]),
+                                                  Standard_Real (theColor.rgb[1]),
+                                                  Standard_Real (theColor.rgb[2]),
+                                                  Standard_Real (theColor.rgb[3]));
 
           const Standard_Integer aSize = Max (aWidth + 2, aHeight + 2); // includes extra margin
           anImage  = new Image_PixMap();
@@ -1679,27 +1754,27 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
         }
         default:
         {
-          aNewMarkerImage = GetTextureImage (myType, myScale);
+          aNewMarkerImage = GetTextureImage (theType, theScale);
           anImage = aNewMarkerImage->GetImage();
           break;
         }
       }
     }
 
-    myMarkerSize = Max ((Standard_ShortReal )anImage->Width(),(Standard_ShortReal )anImage->Height());
+    theMarkerSize = Max ((Standard_ShortReal )anImage->Width(),(Standard_ShortReal )anImage->Height());
 
-    mySprite->Init (aContext, *anImage.operator->(), Graphic3d_TOT_2D);
+    Sprite->Init (aContext, *anImage.operator->(), Graphic3d_TOT_2D);
     if (!hadAlreadyAlpha)
     {
       if (anImageA.IsNull()
-       && mySprite->GetFormat() != GL_ALPHA8
+       && Sprite->GetFormat() != GL_ALPHA8
        && !aNewMarkerImage.IsNull())
       {
         anImageA = aNewMarkerImage->GetImageAlpha();
       }
       if (!anImageA.IsNull())
       {
-        mySpriteA->Init (aContext, *anImageA.operator->(), Graphic3d_TOT_2D);
+        SpriteA->Init (aContext, *anImageA.operator->(), Graphic3d_TOT_2D);
       }
     }
   }
@@ -1707,15 +1782,15 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
   {
     // Creating list with bitmap for using it in compatibility mode
     GLuint aBitmapList = glGenLists (1);
-    mySprite->SetDisplayList (aContext, aBitmapList);
+    Sprite->SetDisplayList (aContext, aBitmapList);
 
     Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
-    if (myType == Aspect_TOM_USERDEFINED && !myMarkerImage.IsNull())
+    if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull())
     {
       // Reading user defined marker
-      Handle(TColStd_HArray1OfByte) aBitMap = myMarkerImage->GetBitMapArray();
+      Handle(TColStd_HArray1OfByte) aBitMap = theMarkerImage->GetBitMapArray();
       Standard_Byte* aBitMapArray = new Standard_Byte[aBitMap->Length()];
-      myMarkerImage->GetTextureSize (aWidth, aHeight);
+      theMarkerImage->GetTextureSize (aWidth, aHeight);
 
       // We should pass bitmap to glBitmap with reversed line order as it draws it from
       // bottom to top
@@ -1742,11 +1817,11 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
     {
       // Creating list for default marker
       const Standard_ShortReal aDelta = 0.1f;
-      Standard_ShortReal aScale = myScale;
+      Standard_ShortReal aScale = theScale;
       Standard_ShortReal aLimit = 0.0f;
 
       glNewList (aBitmapList, GL_COMPILE);
-      switch (myType)
+      switch (theType)
       {
         case Aspect_TOM_O_PLUS:
         case Aspect_TOM_O_STAR:
@@ -1754,10 +1829,10 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
         {
           // For this type of markers we merge two base bitmaps into one
           // For example Aspect_TOM_O_PLUS = Aspect_TOM_O + Aspect_TOM_PLUS
-          GetMarkerBitMapParam (Aspect_TOM_O, myScale, aWidth, aHeight, anOffset, aNumOfBytes);
+          GetMarkerBitMapParam (Aspect_TOM_O, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
                     0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
-          GetMarkerBitMapParam (Aspect_TypeOfMarker (myType - Aspect_TOM_O_POINT), myScale, aWidth, aHeight, anOffset, aNumOfBytes);
+          GetMarkerBitMapParam (Aspect_TypeOfMarker (theType - Aspect_TOM_O_POINT), theScale, aWidth, aHeight, anOffset, aNumOfBytes);
           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, (GLfloat )(0.5f * aWidth), (GLfloat )(0.5f * aHeight),
                     0.f, 0.f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
           break;
@@ -1765,10 +1840,10 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
         case Aspect_TOM_BALL:
         {
           const Standard_ShortReal aDelta = 0.1f;
-          NCollection_Vec4<Standard_Real> aColor (Standard_Real (myColor.rgb[0]),
-                                                  Standard_Real (myColor.rgb[1]),
-                                                  Standard_Real (myColor.rgb[2]),
-                                                  Standard_Real (myColor.rgb[3]));
+          NCollection_Vec4<Standard_Real> aColor (Standard_Real (theColor.rgb[0]),
+                                                  Standard_Real (theColor.rgb[1]),
+                                                  Standard_Real (theColor.rgb[2]),
+                                                  Standard_Real (theColor.rgb[3]));
 
           // we draw a set of circles
           while (aScale >= 1.0f)
@@ -1805,7 +1880,7 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
         }
         default:
         {
-          GetMarkerBitMapParam (myType, myScale, aWidth, aHeight, anOffset, aNumOfBytes);
+          GetMarkerBitMapParam (theType, theScale, aWidth, aHeight, anOffset, aNumOfBytes);
           glBitmap ((GLsizei )aWidth, (GLsizei )aHeight, 0.5f * GLfloat(aWidth), 0.5f * GLfloat(aHeight),
                     0.0f, 0.0f, (const GLubyte* )&OpenGl_AspectMarker_myMarkerRaster[anOffset]);
           break;
@@ -1817,15 +1892,52 @@ void OpenGl_AspectMarker::buildSprites (const Handle(OpenGl_Workspace)& theWorks
 }
 
 // =======================================================================
+// function : BuildShader
+// purpose  :
+// =======================================================================
+void OpenGl_AspectMarker::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
+                                                  const Handle(Graphic3d_ShaderProgram)& theShader)
+{
+  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
+
+  if (!aContext->IsGlGreaterEqual (2, 0))
+    return;
+
+  // release old shader program resources
+  if (!ShaderProgram.IsNull())
+  {
+    aContext->ShaderManager()->Unregister (ShaderProgram);
+  }
+
+  ShaderProgramId = theShader.IsNull() ? THE_EMPTY_KEY : theShader->GetId();
+
+  if (!theShader.IsNull())
+  {
+    if (!aContext->GetResource<Handle(OpenGl_ShaderProgram)> (ShaderProgramId, ShaderProgram))
+    {
+      ShaderProgram = aContext->ShaderManager()->Create (theShader);
+      if (!ShaderProgramId.IsEmpty())
+      {
+        aContext->ShareResource (ShaderProgramId, ShaderProgram);
+      }
+    }
+  }
+  else
+  {
+    ShaderProgram.Nullify();
+  }
+}
+
+// =======================================================================
 // function : resourceKeys
 // purpose  :
 // =======================================================================
-void OpenGl_AspectMarker::resourceKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
-                                        const Aspect_TypeOfMarker theType,
-                                        const Standard_ShortReal theScale,
-                                        const TEL_COLOUR& theColor,
-                                        TCollection_AsciiString& theKey,
-                                        TCollection_AsciiString& theKeyA) const
+void OpenGl_AspectMarker::Resources::SpriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
+                                                 const Aspect_TypeOfMarker theType,
+                                                 const Standard_ShortReal theScale,
+                                                 const TEL_COLOUR& theColor,
+                                                 TCollection_AsciiString& theKey,
+                                                 TCollection_AsciiString& theKeyA)
 {
   // generate key for shared resource
   if (theType == Aspect_TOM_USERDEFINED)
@@ -1856,42 +1968,3 @@ void OpenGl_AspectMarker::resourceKeys (const Handle(Graphic3d_MarkerImage)& the
     }
   }
 }
-
-// =======================================================================
-// function : Render
-// purpose  :
-// =======================================================================
-void OpenGl_AspectMarker::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
-{
-  theWorkspace->SetAspectMarker (this);
-}
-
-// =======================================================================
-// function : Release
-// purpose  :
-// =======================================================================
-void OpenGl_AspectMarker::Release (const Handle(OpenGl_Context)& theCtx)
-{
-  if (!mySprite.IsNull())
-  {
-    if (!theCtx.IsNull())
-    {
-      if (mySpriteKey.IsEmpty())
-      {
-        theCtx->DelayedRelease (mySprite);
-        theCtx->DelayedRelease (mySpriteA);
-      }
-      else
-      {
-        mySprite.Nullify(); // we need nullify all handles before ReleaseResource() call
-        mySpriteA.Nullify();
-        theCtx->ReleaseResource (mySpriteKey,  Standard_True);
-        theCtx->ReleaseResource (mySpriteAKey, Standard_True);
-      }
-    }
-    mySprite.Nullify();
-    mySpriteA.Nullify();
-  }
-  mySpriteKey.Clear();
-  mySpriteAKey.Clear();
-}
index 0a3eb8b..7477e04 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <OpenGl_Element.hxx>
 #include <Handle_OpenGl_PointSprite.hxx>
+#include <Handle_OpenGl_ShaderProgram.hxx>
 
 #include <Image_PixMap_Handle.hxx>
 
@@ -65,58 +66,106 @@ public:
 
   //! Init and return OpenGl point sprite resource.
   //! @return point sprite texture.
-  const Handle(OpenGl_PointSprite)& Sprite (const Handle(OpenGl_Workspace)& theWorkspace) const
+  const Handle(OpenGl_PointSprite)& SpriteRes (const Handle(OpenGl_Workspace)& theWorkspace) const
   {
-    if (!myIsSpriteInit)
+    if (!myResources.IsSpriteReady())
     {
-      buildSprites (theWorkspace);
-      myIsSpriteInit = Standard_True;
+      myResources.BuildSprites (theWorkspace, myMarkerImage, myType, myScale, myColor, myMarkerSize);
+      myResources.SetSpriteReady();
     }
 
-    return mySprite;
+    return myResources.Sprite;
   }
 
   //! Init and return OpenGl highlight point sprite resource.
   //! @return point sprite texture for highlight.
-  const Handle(OpenGl_PointSprite)& SpriteHighlight (const Handle(OpenGl_Workspace)& theWorkspace) const
+  const Handle(OpenGl_PointSprite)& SpriteHighlightRes (const Handle(OpenGl_Workspace)& theWorkspace) const
   {
-    if (!myIsSpriteInit)
+    if (!myResources.IsSpriteReady())
     {
-      buildSprites (theWorkspace);
-      myIsSpriteInit = Standard_True;
+      myResources.BuildSprites (theWorkspace, myMarkerImage, myType, myScale, myColor, myMarkerSize);
+      myResources.SetSpriteReady();
     }
 
-    return mySpriteA;
+    return myResources.SpriteA;
+  }
+
+  //! Init and return OpenGl shader program resource.
+  //! @return shader program resource.
+  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  {
+    if (!myResources.IsShaderReady())
+    {
+      myResources.BuildShader (theWorkspace, myShaderProgram);
+      myResources.SetShaderReady();
+    }
+
+    return myResources.ShaderProgram;
   }
 
   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
   virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
-protected:
+protected: //! @name ordinary aspect properties
+
+  TEL_COLOUR                      myColor;
+  Aspect_TypeOfMarker             myType;
+  Standard_ShortReal              myScale;
+  mutable Standard_ShortReal      myMarkerSize;
+  Handle(Graphic3d_MarkerImage)   myMarkerImage;
+  Handle(Graphic3d_ShaderProgram) myShaderProgram;
 
-  void buildSprites (const Handle(OpenGl_Workspace)& theWorkspace) const;
-  void resourceKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
+protected: //! @name OpenGl resources
+
+  //! OpenGl resources
+  mutable struct Resources
+  {
+  public:
+
+    Resources() :
+        SpriteKey (""),
+        SpriteAKey (""),
+        myIsSpriteReady (Standard_False),
+        myIsShaderReady (Standard_False) {}
+
+    Standard_Boolean IsSpriteReady() const { return myIsSpriteReady; }
+    Standard_Boolean IsShaderReady() const { return myIsShaderReady; }
+    void SetSpriteReady() { myIsSpriteReady = Standard_True; }
+    void SetShaderReady() { myIsShaderReady = Standard_True; }
+    void ResetSprite   () { myIsSpriteReady = Standard_False; }
+    void ResetShader   () { myIsShaderReady = Standard_False; }
+
+    void BuildSprites (const Handle(OpenGl_Workspace)& theWS,
+                       const Handle(Graphic3d_MarkerImage)& theMarkerImage,
+                       const Aspect_TypeOfMarker theType,
+                       const Standard_ShortReal theScale,
+                       const TEL_COLOUR& theColor,
+                       Standard_ShortReal& theMarkerSize);
+
+    void BuildShader (const Handle(OpenGl_Workspace)& theWS, const Handle(Graphic3d_ShaderProgram)& theShader);
+
+    void SpriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
                      const Aspect_TypeOfMarker theType,
                      const Standard_ShortReal theScale,
                      const TEL_COLOUR& theColor,
                      TCollection_AsciiString& theKey,
-                     TCollection_AsciiString& theKeyA) const;
+                     TCollection_AsciiString& theKeyA);
 
-protected: //! @name ordinary aspect properties
+    Handle(OpenGl_PointSprite)   Sprite;
+    TCollection_AsciiString      SpriteKey;
 
-  TEL_COLOUR                    myColor;
-  Aspect_TypeOfMarker           myType;
-  Standard_ShortReal            myScale;
-  Handle(Graphic3d_MarkerImage) myMarkerImage;
+    Handle(OpenGl_PointSprite)   SpriteA;
+    TCollection_AsciiString      SpriteAKey;
 
-protected: //! @name OpenGl resources
+    Handle(OpenGl_ShaderProgram) ShaderProgram;
+    TCollection_AsciiString      ShaderProgramId;
+
+  private:
+
+    Standard_Boolean myIsSpriteReady;
+    Standard_Boolean myIsShaderReady;
 
-  mutable Standard_ShortReal         myMarkerSize;
-  mutable TCollection_AsciiString    mySpriteKey;
-  mutable TCollection_AsciiString    mySpriteAKey;
-  mutable Standard_Boolean           myIsSpriteInit;
-  mutable Handle(OpenGl_PointSprite) mySprite;       //!< normal sprite
-  mutable Handle(OpenGl_PointSprite) mySpriteA;      //!< extra alpha-only sprite for RGB sprites
+  } myResources;
 
 public:
 
index 8cf3e6c..482a374 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#include <Graphic3d_ShaderProgram.hxx>
+
 #include <OpenGl_AspectText.hxx>
+#include <OpenGl_Context.hxx>
 #include <OpenGl_Workspace.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
 
 namespace
 {
   static const TEL_COLOUR TheDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
+  static const TCollection_AsciiString THE_EMPTY_KEY;
 };
 
 // =======================================================================
@@ -37,7 +43,8 @@ OpenGl_AspectText::OpenGl_AspectText()
   myStyleType   (Aspect_TOST_NORMAL),
   myDisplayType (Aspect_TODT_NORMAL),
   myFontAspect  (Font_FA_Regular),
-  myZoomable (false)
+  myZoomable (false),
+  myShaderProgram()
 {
   //
 }
@@ -58,6 +65,7 @@ OpenGl_AspectText::~OpenGl_AspectText()
 void OpenGl_AspectText::SetAspect (const CALL_DEF_CONTEXTTEXT& theAspect)
 {
   myFont = theAspect.Font;
+
   myColor.rgb[0] = (float )theAspect.Color.r;
   myColor.rgb[1] = (float )theAspect.Color.g;
   myColor.rgb[2] = (float )theAspect.Color.b;
@@ -66,11 +74,22 @@ void OpenGl_AspectText::SetAspect (const CALL_DEF_CONTEXTTEXT& theAspect)
   mySubtitleColor.rgb[1] = (float )theAspect.ColorSubTitle.g;
   mySubtitleColor.rgb[2] = (float )theAspect.ColorSubTitle.b;
   mySubtitleColor.rgb[3] = 1.0f;
+
   myAngle       = (float )theAspect.TextAngle;
   myStyleType   = (Aspect_TypeOfStyleText   )theAspect.Style;
   myDisplayType = (Aspect_TypeOfDisplayText )theAspect.DisplayType;
   myFontAspect  = (Font_FontAspect )theAspect.TextFontAspect;
   myZoomable    = (theAspect.TextZoomable != 0);
+
+  // update resource bindings
+  myShaderProgram = theAspect.ShaderProgram;
+
+  const TCollection_AsciiString& aShaderKey = myShaderProgram.IsNull() ? THE_EMPTY_KEY : myShaderProgram->GetId();
+
+  if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
+  {
+    myResources.ResetShader();
+  }
 }
 
 // =======================================================================
@@ -86,7 +105,49 @@ void OpenGl_AspectText::Render (const Handle(OpenGl_Workspace)& theWorkspace) co
 // function : Release
 // purpose  :
 // =======================================================================
-void OpenGl_AspectText::Release (const Handle(OpenGl_Context)&)
+void OpenGl_AspectText::Release (const Handle(OpenGl_Context)& theContext)
 {
-  //
+  if (!myResources.ShaderProgram.IsNull() && !theContext.IsNull())
+  {
+    theContext->ShaderManager()->Unregister (myResources.ShaderProgram);
+  }
+  myResources.ShaderProgramId.Clear();
+  myResources.ResetShader();
+}
+
+// =======================================================================
+// function : BuildShader
+// purpose  :
+// =======================================================================
+void OpenGl_AspectText::Resources::BuildShader (const Handle(OpenGl_Workspace)& theWS,
+                                                const Handle(Graphic3d_ShaderProgram)& theShader)
+{
+  const Handle(OpenGl_Context)& aContext = theWS->GetGlContext();
+
+  if (!aContext->IsGlGreaterEqual (2, 0))
+    return;
+
+  // release old shader program resources
+  if (!ShaderProgram.IsNull())
+  {
+    aContext->ShaderManager()->Unregister (ShaderProgram);
+  }
+
+  ShaderProgramId = theShader.IsNull() ? THE_EMPTY_KEY : theShader->GetId();
+
+  if (!theShader.IsNull())
+  {
+    if (!aContext->GetResource<Handle(OpenGl_ShaderProgram)> (ShaderProgramId, ShaderProgram))
+    {
+      ShaderProgram = aContext->ShaderManager()->Create (theShader);
+      if (!ShaderProgramId.IsEmpty())
+      {
+        aContext->ShareResource (ShaderProgramId, ShaderProgram);
+      }
+    }
+  }
+  else
+  {
+    ShaderProgram.Nullify();
+  }
 }
index b0f3a7d..e426ae6 100644 (file)
@@ -28,6 +28,7 @@
 #include <TCollection_AsciiString.hxx>
 
 #include <OpenGl_Element.hxx>
+#include <Handle_OpenGl_ShaderProgram.hxx>
 
 //! Text representation parameters
 class OpenGl_AspectText : public OpenGl_Element
@@ -118,19 +119,56 @@ public:
     return mySubtitleColor;
   }
 
+  //! Init and return OpenGl shader program resource.
+  //! @return shader program resource.
+  const Handle(OpenGl_ShaderProgram)& ShaderProgramRes (const Handle(OpenGl_Workspace)& theWorkspace) const
+  {
+    if (!myResources.IsShaderReady())
+    {
+      myResources.BuildShader (theWorkspace, myShaderProgram);
+      myResources.SetShaderReady();
+    }
+
+    return myResources.ShaderProgram;
+  }
+
   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
   virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
 protected:
 
-  TCollection_AsciiString  myFont;
-  TEL_COLOUR               myColor;
-  TEL_COLOUR               mySubtitleColor;
-  float                    myAngle;
-  Aspect_TypeOfStyleText   myStyleType;
-  Aspect_TypeOfDisplayText myDisplayType;
-  Font_FontAspect          myFontAspect;
-  bool                     myZoomable;
+  TCollection_AsciiString         myFont;
+  TEL_COLOUR                      myColor;
+  TEL_COLOUR                      mySubtitleColor;
+  float                           myAngle;
+  Aspect_TypeOfStyleText          myStyleType;
+  Aspect_TypeOfDisplayText        myDisplayType;
+  Font_FontAspect                 myFontAspect;
+  bool                            myZoomable;
+  Handle(Graphic3d_ShaderProgram) myShaderProgram;
+
+protected:
+
+  //! OpenGl resources
+  mutable struct Resources
+  {
+  public:
+    Resources() : myIsShaderReady (Standard_False) {}
+
+    Standard_Boolean IsShaderReady() const { return myIsShaderReady; }
+    void SetShaderReady() { myIsShaderReady = Standard_True; }
+    void ResetShader   () { myIsShaderReady = Standard_False; }
+
+    void BuildShader (const Handle(OpenGl_Workspace)& theWS, const Handle(Graphic3d_ShaderProgram)& theShader);
+
+    Handle(OpenGl_ShaderProgram) ShaderProgram;
+    TCollection_AsciiString      ShaderProgramId;
+
+  private:
+
+    Standard_Boolean myIsShaderReady;
+
+  } myResources;
 
 public:
 
similarity index 88%
rename from src/OpenGl/OpenGl_ClippingState.cxx
rename to src/OpenGl/OpenGl_Clipping.cxx
index 25c7b0f..c8e7e6b 100644 (file)
@@ -17,7 +17,7 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-#include <OpenGl_ClippingState.hxx>
+#include <OpenGl_Clipping.hxx>
 #include <OpenGl_GlCore11.hxx>
 #include <OpenGl_Workspace.hxx>
 
@@ -30,7 +30,7 @@ namespace
 // function : OpenGl_ClippingState
 // purpose  :
 // =======================================================================
-OpenGl_ClippingState::OpenGl_ClippingState ()
+OpenGl_Clipping::OpenGl_Clipping ()
 : myPlanes(),
   myPlaneStates(),
   myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE5))
@@ -40,7 +40,7 @@ OpenGl_ClippingState::OpenGl_ClippingState ()
 // function : Init
 // purpose  :
 // =======================================================================
-void OpenGl_ClippingState::Init (const Standard_Integer theMaxPlanes)
+void OpenGl_Clipping::Init (const Standard_Integer theMaxPlanes)
 {
   myPlanes.Clear();
   myPlaneStates.Clear();
@@ -53,9 +53,9 @@ void OpenGl_ClippingState::Init (const Standard_Integer theMaxPlanes)
 // function : Add
 // purpose  :
 // =======================================================================
-void OpenGl_ClippingState::Add (Graphic3d_SetOfHClipPlane& thePlanes,
-                                const EquationCoords& theCoordSpace,
-                                const Handle(OpenGl_Workspace)& theWS)
+void OpenGl_Clipping::Add (Graphic3d_SetOfHClipPlane& thePlanes,
+                           const EquationCoords& theCoordSpace,
+                           const Handle(OpenGl_Workspace)& theWS)
 {
   GLint aMatrixMode;
   glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
@@ -90,7 +90,7 @@ void OpenGl_ClippingState::Add (Graphic3d_SetOfHClipPlane& thePlanes,
 // function : Add
 // purpose  :
 // =======================================================================
-void OpenGl_ClippingState::Add (Graphic3d_SetOfHClipPlane& thePlanes, const EquationCoords& theCoordSpace)
+void OpenGl_Clipping::Add (Graphic3d_SetOfHClipPlane& thePlanes, const EquationCoords& theCoordSpace)
 {
   Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
   while (aPlaneIt.More() && myEmptyPlaneIds->Available() > 0)
@@ -121,7 +121,7 @@ void OpenGl_ClippingState::Add (Graphic3d_SetOfHClipPlane& thePlanes, const Equa
 // function : Remove
 // purpose  :
 // =======================================================================
-void OpenGl_ClippingState::Remove (const Graphic3d_SetOfHClipPlane& thePlanes)
+void OpenGl_Clipping::Remove (const Graphic3d_SetOfHClipPlane& thePlanes)
 {
   Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
   for (; aPlaneIt.More(); aPlaneIt.Next())
@@ -159,7 +159,7 @@ void OpenGl_ClippingState::Remove (const Graphic3d_SetOfHClipPlane& thePlanes)
 // function : SetEnabled
 // purpose  :
 // =======================================================================
-void OpenGl_ClippingState::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
+void OpenGl_Clipping::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
                                        const Standard_Boolean theIsEnabled)
 {
   if (!Contains (thePlane))
similarity index 97%
rename from src/OpenGl/OpenGl_ClippingState.hxx
rename to src/OpenGl/OpenGl_Clipping.hxx
index 5b087c1..e84be9d 100644 (file)
@@ -17,8 +17,8 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-#ifndef _OpenGl_ClippingState_H__
-#define _OpenGl_ClippingState_H__
+#ifndef _OpenGl_Clipping_H__
+#define _OpenGl_Clipping_H__
 
 #include <Aspect_GenId.hxx>
 #include <Graphic3d_ClipPlane.hxx>
@@ -34,7 +34,7 @@
 //! clipping planes and provides method to change clippings in context. The methods
 //! should be executed within OpenGl context associated with instance of this
 //! class.
-class OpenGl_ClippingState
+class OpenGl_Clipping
 {
 public:
 
@@ -48,7 +48,7 @@ public:
 public: //! @name general methods
 
   //! Default constructor.
-  Standard_EXPORT OpenGl_ClippingState();
+  Standard_EXPORT OpenGl_Clipping();
 
   //! Initialize.
   //! @param theMaxPlanes [in] number of clipping planes supported by OpenGl context.
@@ -209,8 +209,8 @@ private:
 private:
 
   //! Copying allowed only within Handles
-  OpenGl_ClippingState            (const OpenGl_ClippingState& );
-  OpenGl_ClippingState& operator= (const OpenGl_ClippingState& );
+  OpenGl_Clipping            (const OpenGl_Clipping& );
+  OpenGl_Clipping& operator= (const OpenGl_Clipping& );
 };
 
 #endif
index 4862cf3..85f7481 100644 (file)
 #include <OpenGl_ExtFBO.hxx>
 #include <OpenGl_ExtGS.hxx>
 #include <OpenGl_GlCore20.hxx>
+#include <OpenGl_ShaderManager.hxx>
 
 #include <Message_Messenger.hxx>
+
 #include <NCollection_Vector.hxx>
 
 #include <Standard_ProgramError.hxx>
@@ -88,7 +90,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   extGS  (NULL),
   extBgra(Standard_False),
   extAnis(Standard_False),
-  extPDS(Standard_False),
+  extPDS (Standard_False),
   atiMem (Standard_False),
   nvxMem (Standard_False),
   mySharedResources (new OpenGl_ResourcesMap()),
@@ -117,6 +119,8 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   // (depends on renderer).
   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
 #endif
+
+  myShaderManager = new OpenGl_ShaderManager (this);
 }
 
 // =======================================================================
@@ -487,7 +491,7 @@ void OpenGl_Context::readGlVersion()
   GLint aMajor = 0, aMinor = 0;
   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
-  // glGetError() sometimes does not report an error here even if 
+  // glGetError() sometimes does not report an error here even if
   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
   // This happens on some rendereres like e.g. Cygwin MESA.
   // Thus checking additionally if GL has put anything to
@@ -816,7 +820,7 @@ void OpenGl_Context::init()
     && FindProcShort (myGlCore20, glLoadTransposeMatrixd)
     && FindProcShort (myGlCore20, glMultTransposeMatrixf)
     && FindProcShort (myGlCore20, glMultTransposeMatrixd);
-  
+
   // Check if OpenGL 1.4 core functionality is actually present
   Standard_Boolean hasGlCore14 = IsGlGreaterEqual (1, 4)
     && FindProcShort (myGlCore20, glBlendFuncSeparate)
index 4ecd928..d69c472 100644 (file)
@@ -25,6 +25,7 @@
 #include <Aspect_Display.hxx>
 #include <Aspect_RenderingContext.hxx>
 #include <Handle_OpenGl_Context.hxx>
+#include <Handle_OpenGl_ShaderManager.hxx>
 #include <NCollection_DataMap.hxx>
 #include <NCollection_Map.hxx>
 #include <NCollection_Handle.hxx>
@@ -35,7 +36,7 @@
 #include <Standard_Transient.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <Handle_OpenGl_Context.hxx>
-#include <OpenGl_ClippingState.hxx>
+#include <OpenGl_Clipping.hxx>
 
 //! Forward declarations
 struct OpenGl_GlCore12;
@@ -248,10 +249,13 @@ public:
   Standard_EXPORT void ReleaseDelayed();
 
   //! @return tool for management of clippings within this context.
-  inline OpenGl_ClippingState& ChangeClipping() { return myClippingState; }
+  inline OpenGl_Clipping& ChangeClipping() { return myClippingState; }
 
   //! @return tool for management of clippings within this context.
-  inline const OpenGl_ClippingState& Clipping() const { return myClippingState; }
+  inline const OpenGl_Clipping& Clipping() const { return myClippingState; }
+
+  //! @return tool for management of shader programs within this context.
+  inline const Handle(OpenGl_ShaderManager)& ShaderManager() const { return myShaderManager; }
 
 public:
 
@@ -350,7 +354,7 @@ private: // context info
   Handle(OpenGl_DelayReleaseMap) myDelayed;         //!< shared resources for delayed release
   Handle(OpenGl_ResourcesQueue)  myReleaseQueue;    //!< queue of resources for delayed clean up
 
-  OpenGl_ClippingState myClippingState; //!< state of clip planes
+  OpenGl_Clipping myClippingState; //!< state of clip planes
 
   void*            myGlLibHandle;   //!< optional handle to GL library
   OpenGl_GlCore20* myGlCore20;      //!< common structure for GL core functions upto 2.0
@@ -362,6 +366,8 @@ private: // context info
   Standard_Boolean myIsFeedback;    //!< flag indicates GL_FEEDBACK mode
   Standard_Boolean myIsInitialized; //!< flag indicates initialization state
 
+  Handle(OpenGl_ShaderManager) myShaderManager; //! support object for managing shader programs
+
 private:
 
   //! Copying allowed only within Handles
index 33b977e..fcadda9 100755 (executable)
@@ -38,7 +38,6 @@ struct OpenGl_LAYER_PROP
   int        NbPoints;
   int        LineType;
   float      LineWidth;
-
   OpenGl_AspectText AspectText;
   OpenGl_TextParam TextParam;
 };
@@ -67,11 +66,11 @@ static OpenGl_LAYER_PROP TheLayerProp;
 
 /*----------------------------------------------------------------------*/
 
-void InitLayerProp (const int AListId)
+void InitLayerProp (const int theListId)
 {
-  TheLayerProp.ListId = AListId;
+  TheLayerProp.ListId = theListId;
 
-  if (AListId)
+  if (theListId)
   {
     TheLayerProp.Color = myDefaultColor;
     TheLayerProp.NbPoints = 0;
@@ -115,7 +114,7 @@ void OpenGl_GraphicDriver::BeginLayer (const Aspect_CLayer2d& ACLayer)
   call_def_ptrLayer ptrLayer = (call_def_ptrLayer) ACLayer.ptrLayer;
   if (!ptrLayer) return;
 
-  InitLayerProp(ptrLayer->listIndex);
+  InitLayerProp (ptrLayer->listIndex);
   if (!TheLayerProp.ListId) return;
 
   glNewList (TheLayerProp.ListId, GL_COMPILE);
@@ -140,7 +139,7 @@ void OpenGl_GraphicDriver::ClearLayer (const Aspect_CLayer2d& ACLayer)
 {
   if (!ACLayer.ptrLayer) return;
 
-  InitLayerProp(ACLayer.ptrLayer->listIndex);
+  InitLayerProp (ACLayer.ptrLayer->listIndex);
   if (!TheLayerProp.ListId) return;
 
   glNewList (TheLayerProp.ListId, GL_COMPILE);
index 38d2d83..5c6a63c 100644 (file)
 // purpose  :
 // =======================================================================
 OpenGl_Group::OpenGl_Group ()
-: myAspectLine(NULL),
-  myAspectFace(NULL),
-  myAspectMarker(NULL),
-  myAspectText(NULL),
-  myFirst(NULL), myLast(NULL)
+: myAspectLine (NULL),
+  myAspectFace (NULL),
+  myAspectMarker (NULL),
+  myAspectText (NULL),
+  myFirst (NULL),
+  myLast (NULL)
 {
 }
 
index f806cc7..ceda9b7 100755 (executable)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-#include <OpenGl_IndexBuffer.hxx>
-#include <OpenGl_Context.hxx>
-
-#include <OpenGl_PrimitiveArray.hxx>
-
 #include <OpenGl_AspectFace.hxx>
+#include <OpenGl_Context.hxx>
 #include <OpenGl_GraphicDriver.hxx>
+#include <OpenGl_IndexBuffer.hxx>
 #include <OpenGl_PointSprite.hxx>
+#include <OpenGl_PrimitiveArray.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_Workspace.hxx>
 
 #include <InterfaceGraphic_PrimitiveArray.hxx>
 
+namespace
+{
+  template<class T>
+  void BindProgramWithMaterial (const Handle(OpenGl_Workspace)& theWS,
+                                const T*                      theAspect)
+  {
+    const Handle(OpenGl_Context)& aCtx = theWS->GetGlContext();
+    const Handle(OpenGl_ShaderProgram)& aProgram = theAspect->ShaderProgramRes (theWS);
+    if (aProgram.IsNull())
+    {
+      OpenGl_ShaderProgram::Unbind (aCtx);
+      return;
+    }
+    aProgram->BindWithVariables (aCtx);
+
+    const OpenGl_MaterialState* aMaterialState = aCtx->ShaderManager()->MaterialState (aProgram);
+    if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
+    {
+      aCtx->ShaderManager()->UpdateMaterialStateTo (aProgram, theAspect);
+    }
+
+    aCtx->ShaderManager()->PushState (aProgram);
+  }
+}
+
 // =======================================================================
 // function : clearMemoryOwn
 // purpose  :
@@ -409,10 +434,15 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR*               theEdgeCo
   if (myDrawMode > GL_LINE_STRIP)
   {
     anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace (Standard_True)->AspectEdge());
-    theWorkspace->AspectLine (Standard_True);
+    const OpenGl_AspectLine* anAspect = theWorkspace->AspectLine (Standard_True);
 
     glPushAttrib (GL_POLYGON_BIT);
     glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
+
+    if (aGlContext->IsGlGreaterEqual (2, 0))
+    {
+      BindProgramWithMaterial (theWorkspace, anAspect);
+    }
   }
 
   Tint i, j, n;
@@ -539,7 +569,7 @@ void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWork
 {
   const OpenGl_AspectMarker* anAspectMarker     = theWorkspace->AspectMarker (Standard_True);
   const Handle(OpenGl_Context)&     aCtx        = theWorkspace->GetGlContext();
-  const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->Sprite(theWorkspace);
+  const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (theWorkspace);
   const Standard_Boolean            isHilight   = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT);
   if (aCtx->IsGlGreaterEqual (2, 0)
    && !aSpriteNorm.IsNull() && !aSpriteNorm->IsDisplayList())
@@ -550,8 +580,8 @@ void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWork
     Handle(OpenGl_Texture) aTextureBack;
     if (anAspectMarker->Type() != Aspect_TOM_POINT)
     {
-      const Handle(OpenGl_PointSprite)& aSprite = (isHilight && anAspectMarker->SpriteHighlight(theWorkspace)->IsValid())
-                                                ? anAspectMarker->SpriteHighlight(theWorkspace)
+      const Handle(OpenGl_PointSprite)& aSprite = (isHilight && anAspectMarker->SpriteHighlightRes (theWorkspace)->IsValid())
+                                                ? anAspectMarker->SpriteHighlightRes (theWorkspace)
                                                 : aSpriteNorm;
       aTextureBack = theWorkspace->EnableTexture (aSprite);
 
@@ -704,7 +734,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
   if (!myIsVboInit
    && !aCtx->caps->vboDisable
    && aCtx->core15 != NULL
-   && (myDrawMode != GL_POINTS || anAspectMarker->Sprite(theWorkspace).IsNull() || !anAspectMarker->Sprite(theWorkspace)->IsDisplayList()))
+   && (myDrawMode != GL_POINTS || anAspectMarker->SpriteRes (theWorkspace).IsNull() || !anAspectMarker->SpriteRes (theWorkspace)->IsDisplayList()))
   {
     if (!BuildVBO (theWorkspace))
     {
@@ -742,6 +772,29 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
     aFrontLightingModel = 0;
   }
 
+  if (aCtx->IsGlGreaterEqual (2, 0))
+  {
+    switch (myPArray->type)
+    {
+      case TelPointsArrayType:
+      {
+        BindProgramWithMaterial (theWorkspace, anAspectMarker);
+        break;
+      }
+      case TelSegmentsArrayType:
+      case TelPolylinesArrayType:
+      {
+        BindProgramWithMaterial (theWorkspace, anAspectLine);
+        break;
+      }
+      default: // polygonal array
+      {
+        BindProgramWithMaterial (theWorkspace, anAspectFace);
+        break;
+      }
+    }
+  }
+
   DrawArray (aFrontLightingModel,
              anAspectFace->InteriorStyle(),
              anAspectFace->Edge(),
diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx
new file mode 100644 (file)
index 0000000..97b0fbb
--- /dev/null
@@ -0,0 +1,759 @@
+// Created on: 2013-09-26
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <typeinfo>
+
+#include <OpenGl_AspectFace.hxx>
+#include <OpenGl_AspectLine.hxx>
+#include <OpenGl_AspectMarker.hxx>
+#include <OpenGl_AspectText.hxx>
+#include <OpenGl_Clipping.hxx>
+#include <OpenGl_Context.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
+
+// =======================================================================
+// function : OpenGl_ShaderManager
+// purpose  : Creates new empty shader manager
+// =======================================================================
+OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
+: myContext (theContext),
+  myIsPP    (Standard_False)
+{
+  //
+}
+
+// =======================================================================
+// function : ~OpenGl_ShaderManager
+// purpose  : Releases resources of shader manager
+// =======================================================================
+OpenGl_ShaderManager::~OpenGl_ShaderManager()
+{
+  myProgramList.Clear();
+}
+
+// =======================================================================
+// function : Create
+// purpose  : Creates new shader program
+// =======================================================================
+Handle(OpenGl_ShaderProgram) OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxyProgram)
+{
+  if (theProxyProgram.IsNull())
+  {
+    return NULL;
+  }
+  
+  Handle(OpenGl_ShaderProgram) aProgram = new OpenGl_ShaderProgram (theProxyProgram);
+  if (!aProgram->Initialize (myContext, theProxyProgram->ShaderObjects()))
+  {
+    return NULL;
+  }
+  
+  myProgramList.Append (aProgram);
+
+  return aProgram;
+}
+
+// =======================================================================
+// function : Unregister
+// purpose  : Removes specified shader program from the manager
+// =======================================================================
+void OpenGl_ShaderManager::Unregister (Handle(OpenGl_ShaderProgram)& theProgram)
+{
+  for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
+  {
+    if (anIt.Value() == theProgram)
+    {
+      myProgramList.Remove (anIt);
+      break;
+    }
+  }
+
+  const TCollection_AsciiString anID = theProgram->myProxy->GetId();
+  if (anID.IsEmpty())
+  {
+    myContext->DelayedRelease (theProgram);
+    theProgram.Nullify();
+  }
+  else
+  {
+    theProgram.Nullify();
+    myContext->ReleaseResource (anID);
+  }
+}
+
+// =======================================================================
+// function : ShaderPrograms
+// purpose  : Returns list of registered shader programs
+// =======================================================================
+const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
+{
+  return myProgramList;
+}
+
+// =======================================================================
+// function : Empty
+// purpose  : Returns true if no program objects are attached
+// =======================================================================
+Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
+{
+  return myProgramList.IsEmpty();
+}
+
+// =======================================================================
+// function : UpdateLightSourceStateTo
+// purpose  : Updates state of OCCT light sources
+// =======================================================================
+void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
+{
+  myLightSourceState.Set (theLights);
+  myLightSourceState.Update();
+}
+
+// =======================================================================
+// function : SetProjectionState
+// purpose  : Sets new state of OCCT projection transform
+// =======================================================================
+void OpenGl_ShaderManager::UpdateProjectionStateTo (const Tmatrix3& theProjectionMatrix)
+{
+  myProjectionState.Set (theProjectionMatrix);
+  myProjectionState.Update();
+}
+
+// =======================================================================
+// function : SetModelWorldState
+// purpose  : Sets new state of OCCT model-world transform
+// =======================================================================
+void OpenGl_ShaderManager::UpdateModelWorldStateTo (const Tmatrix3& theModelWorldMatrix)
+{
+  myModelWorldState.Set (theModelWorldMatrix);
+  myModelWorldState.Update();
+}
+
+// =======================================================================
+// function : SetWorldViewState
+// purpose  : Sets new state of OCCT world-view transform
+// =======================================================================
+void OpenGl_ShaderManager::UpdateWorldViewStateTo (const Tmatrix3& theWorldViewMatrix)
+{
+  myWorldViewState.Set (theWorldViewMatrix);
+  myWorldViewState.Update();
+}
+
+// =======================================================================
+// function : RevertProjectionStateTo
+// purpose  : Reverts state of OCCT projection transform
+// =======================================================================
+void OpenGl_ShaderManager::RevertProjectionStateTo (const Tmatrix3& theProjectionMatrix)
+{
+  myProjectionState.Set (theProjectionMatrix);
+  myProjectionState.Revert();
+}
+
+// =======================================================================
+// function : RevertModelWorldStateTo
+// purpose  : Reverts state of OCCT model-world transform
+// =======================================================================
+void OpenGl_ShaderManager::RevertModelWorldStateTo (const Tmatrix3& theModelWorldMatrix)
+{
+  myModelWorldState.Set (theModelWorldMatrix);
+  myModelWorldState.Revert();
+}
+
+// =======================================================================
+// function : RevertWorldViewStateTo
+// purpose  : Reverts state of OCCT world-view transform
+// =======================================================================
+void OpenGl_ShaderManager::RevertWorldViewStateTo (const Tmatrix3& theWorldViewMatrix)
+{
+  myWorldViewState.Set (theWorldViewMatrix);
+  myWorldViewState.Revert();
+}
+
+// =======================================================================
+// function : LightSourceState
+// purpose  : Returns current state of OCCT light sources
+// =======================================================================
+const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const
+{
+  return myLightSourceState;
+}
+
+// =======================================================================
+// function : ProjectionState
+// purpose  : Returns current state of OCCT projection transform
+// =======================================================================
+const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const
+{
+  return myProjectionState;
+}
+
+// =======================================================================
+// function : ModelWorldState
+// purpose  : Returns current state of OCCT model-world transform
+// =======================================================================
+const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const
+{
+  return myModelWorldState;
+}
+
+// =======================================================================
+// function : WorldViewState
+// purpose  : Returns current state of OCCT world-view transform
+// =======================================================================
+const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
+{
+  return myWorldViewState;
+}
+
+// =======================================================================
+// function : PushLightSourceState
+// purpose  : Pushes state of OCCT light sources to the program
+// =======================================================================
+void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+{
+  if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE))
+  {
+    return;
+  }
+  
+  theProgram->SetUniform (myContext, theProgram->GetStateLocation (
+    OpenGl_OCC_LIGHT_SOURCE_COUNT), myLightSourceState.LightSources()->Size());
+
+  OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources());
+  for (unsigned int anIndex = 0; anIter.More(); anIter.Next())
+  {
+    if (anIndex >= OpenGLMaxLights)
+    {
+      break;
+    }
+
+    const OpenGl_Light& aLight = anIter.Value();
+    if (aLight.type == TLightAmbient)
+    {
+      OpenGl_Vec3 anAmbient (aLight.col.rgb[0],
+                             aLight.col.rgb[1],
+                             aLight.col.rgb[2]);
+
+      theProgram->SetUniform (myContext,
+        theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT + anIndex), anAmbient);
+
+      anIter.Next();
+      if (!anIter.More())
+      {
+        theProgram->SetUniform (myContext,
+          theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type));
+        break;
+      }
+    }
+
+    OpenGl_Vec3 aDiffuse (aLight.col.rgb[0],
+                          aLight.col.rgb[1],
+                          aLight.col.rgb[2]);
+
+    OpenGl_Vec3 aPosition (aLight.type == TLightDirectional ? -aLight.dir[0] : aLight.pos[0],
+                           aLight.type == TLightDirectional ? -aLight.dir[1] : aLight.pos[1],
+                           aLight.type == TLightDirectional ? -aLight.dir[2] : aLight.pos[2]);
+
+    theProgram->SetUniform (myContext,
+      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_TYPE + anIndex), int (aLight.type));
+
+    theProgram->SetUniform (myContext,
+      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_HEAD + anIndex), aLight.HeadLight);
+
+    theProgram->SetUniform (myContext,
+      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE + anIndex), aDiffuse);
+
+    theProgram->SetUniform (myContext,
+      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR + anIndex), aDiffuse);
+
+    theProgram->SetUniform (myContext,
+      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_POSITION + anIndex), aPosition);
+
+    theProgram->SetUniform (myContext,
+      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION + anIndex), aLight.atten[0]);
+
+    theProgram->SetUniform (myContext,
+      theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION + anIndex), aLight.atten[1]);
+
+    if (aLight.type == TLightSpot)
+    {
+      OpenGl_Vec3 aDirection (aLight.dir[0],
+                              aLight.dir[1],
+                              aLight.dir[2]);
+
+      theProgram->SetUniform (myContext,
+        theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF + anIndex), aLight.angle);
+
+      theProgram->SetUniform (myContext,
+        theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT + anIndex), aLight.shine);
+
+      theProgram->SetUniform (myContext,
+        theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION + anIndex), aDirection);
+    }
+
+    ++anIndex;
+  }
+
+  theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
+}
+
+// =======================================================================
+// function : PushProjectionState
+// purpose  : Pushes state of OCCT projection transform to the program
+// =======================================================================
+void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+{
+  if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
+  {
+    return;
+  }
+
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
+                          myProjectionState.ProjectionMatrix());
+
+  GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
+  if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+  {
+    theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
+  }
+
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
+                          myProjectionState.ProjectionMatrix(), true);
+
+  aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
+  if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+  {
+    theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
+  }
+
+  theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
+}
+
+// =======================================================================
+// function : PushModelWorldState
+// purpose  : Pushes state of OCCT model-world transform to the program
+// =======================================================================
+void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+{
+  if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
+  {
+    return;
+  }
+
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
+                          myModelWorldState.ModelWorldMatrix());
+
+  GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
+  if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+  {
+    theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
+  }
+
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
+                          myModelWorldState.ModelWorldMatrix(), true);
+
+  aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
+  if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+  {
+    theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
+  }
+
+  theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
+}
+
+// =======================================================================
+// function : PushWorldViewState
+// purpose  : Pushes state of OCCT world-view transform to the program
+// =======================================================================
+void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+{
+  if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
+  {
+    return;
+  }
+
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
+                          myWorldViewState.WorldViewMatrix());
+
+  GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
+  if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+  {
+    theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
+  }
+
+  theProgram->SetUniform (myContext,
+                          theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
+                          myWorldViewState.WorldViewMatrix(), true);
+
+  aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
+  if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+  {
+    theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
+  }
+
+  theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
+}
+
+// =======================================================================
+// function : UpdateClippingState
+// purpose  : Updates state of OCCT clipping planes
+// =======================================================================
+void OpenGl_ShaderManager::UpdateClippingState()
+{
+  myClippingState.Update();
+}
+
+// =======================================================================
+// function : RevertClippingState
+// purpose  : Reverts state of OCCT clipping planes
+// =======================================================================
+void OpenGl_ShaderManager::RevertClippingState()
+{
+  myClippingState.Revert();
+}
+
+// =======================================================================
+// function : PushClippingState
+// purpose  : Pushes state of OCCT clipping planes to the program
+// =======================================================================
+void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+{
+  if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
+  {
+    return;
+  }
+
+  Graphic3d_SetOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
+  for (GLuint anIndex = 0; anIter.More(); anIter.Next())
+  {
+    const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
+    if (!myContext->Clipping().IsEnabled (aPlane))
+    {
+      continue;
+    }
+
+    GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_EQUATION + anIndex);
+    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+    {
+      const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
+      theProgram->SetUniform (myContext, aLocation, OpenGl_Vec4 ((float) anEquation.x(),
+                                                                 (float) anEquation.y(),
+                                                                 (float) anEquation.z(),
+                                                                 (float) anEquation.w()));
+    }
+
+    theProgram->SetUniform (myContext,
+                            theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_0_SPACE + anIndex),
+                            myContext->Clipping().GetEquationSpace (aPlane));
+    ++anIndex;
+  }
+
+  theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
+}
+
+// =======================================================================
+// function : UpdateMaterialStateTo
+// purpose  : Updates state of OCCT material for specified program
+// =======================================================================
+void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
+                                                  const OpenGl_Element*               theAspect)
+{
+  if (myMaterialStates.IsBound (theProgram))
+  {
+    myMaterialStates.ChangeFind (theProgram).Set (theAspect);
+  }
+  else
+  {
+    myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
+  }
+
+  myMaterialStates.ChangeFind (theProgram).Update();
+}
+
+// =======================================================================
+// function : ResetMaterialStates
+// purpose  : Resets state of OCCT material for all programs
+// =======================================================================
+void OpenGl_ShaderManager::ResetMaterialStates()
+{
+  for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
+  {
+    anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
+  }
+}
+
+// =======================================================================
+// function : MaterialState
+// purpose  : Returns state of OCCT material for specified program
+// =======================================================================
+const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+{
+  if (!myMaterialStates.IsBound (theProgram))
+    return NULL;
+
+  return &myMaterialStates.Find (theProgram);
+}
+
+namespace
+{
+
+static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
+
+// =======================================================================
+// function : PushAspectFace
+// purpose  :
+// =======================================================================
+static void PushAspectFace (const Handle(OpenGl_Context)&       theCtx,
+                            const Handle(OpenGl_ShaderProgram)& theProgram,
+                            const OpenGl_AspectFace*            theAspect)
+{
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
+                          theAspect->DoTextureMap());
+
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
+                          0 /* GL_TEXTURE0 */);
+
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
+                          theAspect->DistinguishingMode());
+
+  for (int anIndex = 0; anIndex < 2; ++anIndex)
+  {
+    const OPENGL_SURF_PROP& aProperties = (anIndex == 0) ? theAspect->IntFront() : theAspect->IntBack();
+    GLint aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT + anIndex);
+    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+    {
+      OpenGl_Vec4 anAmbient (aProperties.ambcol.rgb[0] * aProperties.amb,
+                             aProperties.ambcol.rgb[1] * aProperties.amb,
+                             aProperties.ambcol.rgb[2] * aProperties.amb,
+                             aProperties.ambcol.rgb[3] * aProperties.amb);
+      theProgram->SetUniform (theCtx, aLocation, anAmbient);
+    }
+
+    aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE + anIndex);
+    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+    {
+      OpenGl_Vec4 aDiffuse (aProperties.difcol.rgb[0] * aProperties.diff,
+                            aProperties.difcol.rgb[1] * aProperties.diff,
+                            aProperties.difcol.rgb[2] * aProperties.diff,
+                            aProperties.difcol.rgb[3] * aProperties.diff);
+      theProgram->SetUniform (theCtx, aLocation, aDiffuse);
+    }
+
+    aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR + anIndex);
+    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+    {
+      OpenGl_Vec4 aSpecular (aProperties.speccol.rgb[0] * aProperties.spec,
+                             aProperties.speccol.rgb[1] * aProperties.spec,
+                             aProperties.speccol.rgb[2] * aProperties.spec,
+                             aProperties.speccol.rgb[3] * aProperties.spec);
+      theProgram->SetUniform (theCtx, aLocation, aSpecular);
+    }
+
+    aLocation = theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION + anIndex);
+    if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
+    {
+      OpenGl_Vec4 anEmission (aProperties.emscol.rgb[0] * aProperties.emsv,
+                              aProperties.emscol.rgb[1] * aProperties.emsv,
+                              aProperties.emscol.rgb[2] * aProperties.emsv,
+                              aProperties.emscol.rgb[3] * aProperties.emsv);
+      theProgram->SetUniform (theCtx, aLocation, anEmission);
+    }
+    
+    theProgram->SetUniform (theCtx,
+                            theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SHININESS + anIndex),
+                            aProperties.shine);
+
+    theProgram->SetUniform (theCtx,
+                            theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY + anIndex),
+                            aProperties.trans);
+  }
+}
+
+// =======================================================================
+// function : PushAspectLine
+// purpose  :
+// =======================================================================
+static void PushAspectLine (const Handle(OpenGl_Context)&       theCtx,
+                            const Handle(OpenGl_ShaderProgram)& theProgram,
+                            const OpenGl_AspectLine*            theAspect)
+{
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),   TOff);
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
+
+  const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
+                              theAspect->Color().rgb[1],
+                              theAspect->Color().rgb[2],
+                              theAspect->Color().rgb[3]);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
+                          aDiffuse);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
+                          0.0f);
+}
+
+// =======================================================================
+// function : PushAspectText
+// purpose  :
+// =======================================================================
+static void PushAspectText (const Handle(OpenGl_Context)&       theCtx,
+                            const Handle(OpenGl_ShaderProgram)& theProgram,
+                            const OpenGl_AspectText*            theAspect)
+{
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),   TOn);
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),   0 /* GL_TEXTURE0 */);
+
+  OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
+                        theAspect->Color().rgb[1],
+                        theAspect->Color().rgb[2],
+                        theAspect->Color().rgb[3]);
+  if (theAspect->DisplayType() == Aspect_TODT_DEKALE
+   || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
+  {
+    aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
+                            theAspect->SubtitleColor().rgb[1],
+                            theAspect->SubtitleColor().rgb[2],
+                            theAspect->SubtitleColor().rgb[3]);
+  }
+
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
+                          aDiffuse);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
+                          0.0f);
+}
+
+// =======================================================================
+// function : PushAspectMarker
+// purpose  :
+// =======================================================================
+static void PushAspectMarker (const Handle(OpenGl_Context)&       theCtx,
+                              const Handle(OpenGl_ShaderProgram)& theProgram,
+                              const OpenGl_AspectMarker*          theAspect)
+{
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),   TOn);
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
+  theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),   0 /* GL_TEXTURE0 */);
+
+  const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
+                              theAspect->Color().rgb[1],
+                              theAspect->Color().rgb[2],
+                              theAspect->Color().rgb[3]);
+
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_AMBIENT),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE),
+                          aDiffuse);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_SPECULAR),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_EMISSION),
+                          THE_COLOR_BLACK_VEC4);
+  theProgram->SetUniform (theCtx,
+                          theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY),
+                          0.0f);
+}
+
+}; // nameless namespace
+
+// =======================================================================
+// function : PushMaterialState
+// purpose  : Pushes current state of OCCT material to the program
+// =======================================================================
+void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+{
+  if (!myMaterialStates.IsBound (theProgram))
+  {
+    return;
+  }
+
+  const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
+  if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
+  {
+    return;
+  }
+
+  if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
+  {
+    PushAspectFace   (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
+  }
+  else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
+  {
+    PushAspectLine   (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
+  }
+  else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
+  {
+    PushAspectText   (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
+  }
+  else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
+  {
+    PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
+  }
+
+  theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
+}
+
+// =======================================================================
+// function : PushWorldViewState
+// purpose  : Pushes state of OCCT graphics parameters to the program
+// =======================================================================
+void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
+{
+  PushClippingState    (theProgram);
+  PushMaterialState    (theProgram);
+  PushWorldViewState   (theProgram);
+  PushModelWorldState  (theProgram);
+  PushProjectionState  (theProgram);  
+  PushLightSourceState (theProgram);
+}
\ No newline at end of file
diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx
new file mode 100644 (file)
index 0000000..b3ddf22
--- /dev/null
@@ -0,0 +1,169 @@
+// Created on: 2013-09-26
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_ShaderManager_HeaderFile
+#define _OpenGl_ShaderManager_HeaderFile
+
+#include <Graphic3d_ShaderProgram_Handle.hxx>
+
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Sequence.hxx>
+
+#include <Handle_OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
+#include <OpenGl_ShaderStates.hxx>
+
+//! List of shader programs.
+typedef NCollection_Sequence<Handle(OpenGl_ShaderProgram)> OpenGl_ShaderProgramList;
+
+//! Map to declare per-program states of OCCT materials.
+typedef NCollection_DataMap<Handle(OpenGl_ShaderProgram), OpenGl_MaterialState> OpenGl_MaterialStates;
+
+//! This class is responsible for managing shader programs.
+class OpenGl_ShaderManager : public Standard_Transient
+{
+  friend class OpenGl_ShaderProgram;
+
+public:
+
+  //! Creates new empty shader manager.
+  Standard_EXPORT OpenGl_ShaderManager (OpenGl_Context* theContext);
+
+  //! Releases resources of shader manager.
+  Standard_EXPORT virtual ~OpenGl_ShaderManager();
+
+  //! Creates new shader program.
+  Standard_EXPORT Handle(OpenGl_ShaderProgram) Create (const Handle(Graphic3d_ShaderProgram)& theProxyProgram = NULL);
+
+  //! Unregisters specified shader program.
+  Standard_EXPORT void Unregister (Handle(OpenGl_ShaderProgram)& theProgram);
+
+  //! Returns list of registered shader programs.
+  Standard_EXPORT const OpenGl_ShaderProgramList& ShaderPrograms() const;
+
+  //! Returns true if no program objects are registered in the manager.
+  Standard_EXPORT Standard_Boolean IsEmpty() const;
+
+  DEFINE_STANDARD_RTTI (OpenGl_ShaderManager)
+
+protected:
+
+  OpenGl_MaterialStates   myMaterialStates;   //!< Per-program state of OCCT material
+  OpenGl_ProjectionState  myProjectionState;  //!< State of OCCT projection transformation
+  OpenGl_ModelWorldState  myModelWorldState;  //!< State of OCCT model-world transformation
+  OpenGl_WorldViewState   myWorldViewState;   //!< State of OCCT world-view transformation
+  OpenGl_LightSourceState myClippingState;    //!< State of OCCT clipping planes
+  OpenGl_LightSourceState myLightSourceState; //!< State of OCCT light sources
+
+public:
+
+  //! Returns current state of OCCT light sources.
+  Standard_EXPORT const OpenGl_LightSourceState& LightSourceState() const;
+
+  //! Updates state of OCCT light sources.
+  Standard_EXPORT void UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights);
+
+  //! Pushes current state of OCCT light sources to specified program.
+  Standard_EXPORT void PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+
+public:
+
+  //! Returns current state of OCCT projection transform.
+  Standard_EXPORT const OpenGl_ProjectionState& ProjectionState() const;
+
+  //! Updates state of OCCT projection transform.
+  Standard_EXPORT void UpdateProjectionStateTo (const Tmatrix3& theProjectionMatrix);
+
+  //! Reverts state of OCCT projection transform.
+  Standard_EXPORT void RevertProjectionStateTo (const Tmatrix3& theProjectionMatrix);
+
+  //! Pushes current state of OCCT projection transform to specified program.
+  Standard_EXPORT void PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+
+public:
+
+  //! Returns current state of OCCT model-world transform.
+  Standard_EXPORT const OpenGl_ModelWorldState& ModelWorldState() const;
+
+  //! Updates state of OCCT model-world transform.
+  Standard_EXPORT void UpdateModelWorldStateTo (const Tmatrix3& theModelWorldMatrix);
+
+  //! Reverts state of OCCT model-world transform.
+  Standard_EXPORT void RevertModelWorldStateTo (const Tmatrix3& theModelWorldMatrix);
+
+  //! Pushes current state of OCCT model-world transform to specified program.
+  Standard_EXPORT void PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+
+public:
+
+  //! Returns current state of OCCT world-view transform.
+  Standard_EXPORT const OpenGl_WorldViewState& WorldViewState() const;
+
+  //! Updates state of OCCT world-view transform.
+  Standard_EXPORT void UpdateWorldViewStateTo (const Tmatrix3& theWorldViewMatrix);
+
+  //! Reverts state of OCCT world-view transform.
+  Standard_EXPORT void RevertWorldViewStateTo (const Tmatrix3& theWorldViewMatrix);
+
+  //! Pushes current state of OCCT world-view transform to specified program.
+  Standard_EXPORT void PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+
+public:
+
+  //! Updates state of OCCT clipping planes.
+  Standard_EXPORT void UpdateClippingState();
+
+  //! Reverts state of OCCT clipping planes.
+  Standard_EXPORT void RevertClippingState();
+
+  //! Pushes current state of OCCT clipping planes to specified program.
+  Standard_EXPORT void PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+
+public:
+
+  //! Resets state of OCCT material for all programs.
+  Standard_EXPORT void ResetMaterialStates();
+
+  //! Updates state of OCCT material for specified program.
+  Standard_EXPORT void UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
+                                              const OpenGl_Element*               theAspect);
+
+  //! Pushes current state of OCCT material to specified program.
+  Standard_EXPORT void PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+
+  //! Returns current state of OCCT material for specified program.
+  Standard_EXPORT const OpenGl_MaterialState* MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+
+public:
+  
+  //! Pushes current state of OCCT graphics parameters to specified program.
+  Standard_EXPORT void PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const;
+
+protected:
+
+  OpenGl_ShaderProgramList myProgramList;  //!< The list of shader programs
+  OpenGl_Context*          myContext;      //!< The OpenGL context
+
+private:
+
+  Standard_Boolean         myIsPP;         //!< Is any program object bound (programmable pipeline)?
+
+};
+
+#endif // _OpenGl_ShaderManager_HeaderFile
diff --git a/src/OpenGl/OpenGl_ShaderObject.cxx b/src/OpenGl/OpenGl_ShaderObject.cxx
new file mode 100644 (file)
index 0000000..9537ccd
--- /dev/null
@@ -0,0 +1,147 @@
+// Created on: 2013-09-19
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <Graphic3d_ShaderObject.hxx>
+#include <OpenGl_Context.hxx>
+#include <OpenGl_ShaderObject.hxx>
+#include <OSD_Path.hxx>
+#include <Standard_Assert.hxx>
+#include <TCollection_AsciiString.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderObject, OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderObject, OpenGl_Resource)
+
+// =======================================================================
+// function : OpenGl_ShaderObject
+// purpose  : Creates uninitialized shader object
+// =======================================================================
+OpenGl_ShaderObject::OpenGl_ShaderObject (GLenum theType)
+: myType     (theType),
+  myShaderID (NO_SHADER)
+{
+  //
+}
+
+// =======================================================================
+// function : ~OpenGl_ShaderObject
+// purpose  : Releases resources of shader object
+// =======================================================================
+OpenGl_ShaderObject::~OpenGl_ShaderObject()
+{
+  Release (NULL);
+}
+
+// =======================================================================
+// function : LoadSource
+// purpose  : Loads shader source code
+// =======================================================================
+Standard_Boolean OpenGl_ShaderObject::LoadSource (const Handle(OpenGl_Context)&  theCtx,
+                                                  const TCollection_AsciiString& theSource)
+{
+  if (myShaderID == NO_SHADER)
+  {
+    return Standard_False;
+  }
+
+  const GLchar* aLines = theSource.ToCString();
+  theCtx->core20->glShaderSource (myShaderID, 1, &aLines, NULL);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : Compile
+// purpose  : Compiles the shader object
+// =======================================================================
+Standard_Boolean OpenGl_ShaderObject::Compile (const Handle(OpenGl_Context)& theCtx)
+{
+  if (myShaderID == NO_SHADER)
+  {
+    return Standard_False;
+  }
+
+  // Try to compile shader
+  theCtx->core20->glCompileShader (myShaderID);
+
+  // Check compile status
+  GLint aStatus = GL_FALSE;
+  theCtx->core20->glGetShaderiv (myShaderID, GL_COMPILE_STATUS, &aStatus);
+  return aStatus != GL_FALSE;
+}
+
+// =======================================================================
+// function : FetchInfoLog
+// purpose  : Fetches information log of the last compile operation
+// =======================================================================
+Standard_Boolean OpenGl_ShaderObject::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
+                                                    TCollection_AsciiString&      theLog)
+{
+  if (myShaderID == NO_SHADER)
+  {
+    return Standard_False;
+  }
+
+  // Load information log of the compiler
+  GLint aLength = 0;
+  theCtx->core20->glGetShaderiv (myShaderID, GL_INFO_LOG_LENGTH, &aLength);
+  if (aLength > 0)
+  {
+    GLchar* aLog = (GLchar*) alloca (aLength);
+    memset (aLog, 0, aLength);
+    theCtx->core20->glGetShaderInfoLog (myShaderID, aLength, NULL, aLog);
+    theLog = aLog;
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
+// function : Create
+// purpose  : Creates new empty shader object of specified type
+// =======================================================================
+Standard_Boolean OpenGl_ShaderObject::Create (const Handle(OpenGl_Context)& theCtx)
+{
+  if (myShaderID == NO_SHADER
+   && theCtx->core20 != NULL)
+  {
+    myShaderID = theCtx->core20->glCreateShader (myType);
+  }
+
+  return myShaderID != NO_SHADER;
+}
+
+// =======================================================================
+// function : Release
+// purpose  : Destroys shader object
+// =======================================================================
+void OpenGl_ShaderObject::Release (const OpenGl_Context* theCtx)
+{
+  if (myShaderID == NO_SHADER)
+  {
+    return;
+  }
+
+  Standard_ASSERT_RETURN (theCtx != NULL,
+    "OpenGl_ShaderObject destroyed without GL context! Possible GPU memory leakage...",);
+
+  if (theCtx->core20 != NULL)
+  {
+    theCtx->core20->glDeleteShader (myShaderID);
+  }
+  myShaderID = NO_SHADER;
+}
diff --git a/src/OpenGl/OpenGl_ShaderObject.hxx b/src/OpenGl/OpenGl_ShaderObject.hxx
new file mode 100644 (file)
index 0000000..8f72b4b
--- /dev/null
@@ -0,0 +1,81 @@
+// Created on: 2013-09-19
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_ShaderObject_Header
+#define _OpenGl_ShaderObject_Header
+
+#include <Handle_OpenGl_ShaderObject.hxx>
+#include <Graphic3d_ShaderObject.hxx>
+#include <OpenGl_GlCore20.hxx>
+#include <OpenGl_Resource.hxx>
+
+//! Wrapper for OpenGL shader object.
+class OpenGl_ShaderObject : public OpenGl_Resource
+{
+
+public:
+
+  //! Non-valid shader name.
+  static const GLuint NO_SHADER = 0;
+
+public:
+
+  //! Creates uninitialized shader object.
+  Standard_EXPORT OpenGl_ShaderObject (GLenum theType);
+
+  //! Releases resources of shader object.
+  Standard_EXPORT virtual ~OpenGl_ShaderObject();
+
+  //! Loads shader source code.
+  Standard_EXPORT Standard_Boolean LoadSource (const Handle(OpenGl_Context)&  theCtx,
+                                               const TCollection_AsciiString& theSource);
+
+  //! Compiles the shader object.
+  Standard_EXPORT Standard_Boolean Compile (const Handle(OpenGl_Context)& theCtx);
+
+  //! Initializes (loads and compiles) shader object with the specified description.
+  Standard_EXPORT Standard_Boolean Initialize (const Handle(OpenGl_Context)&         theCtx,
+                                               const Handle(Graphic3d_ShaderObject)& theShader);
+
+  //! Fetches information log of the last compile operation.
+  Standard_EXPORT Standard_Boolean FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
+                                                 TCollection_AsciiString&      theLog);
+
+  //! Creates new empty shader object of specified type.
+  Standard_EXPORT Standard_Boolean Create (const Handle(OpenGl_Context)& theCtx);
+
+  //! Destroys shader object.
+  Standard_EXPORT virtual void Release (const OpenGl_Context* theCtx);
+
+  //! Returns type of shader object.
+  GLenum Type() const { return myType; }
+  
+protected:
+
+  GLenum myType;     //!< Type of OpenGL shader object
+  GLuint myShaderID; //!< Handle of OpenGL shader object
+
+public:
+
+  DEFINE_STANDARD_RTTI (OpenGl_ShaderObject)
+  friend class OpenGl_ShaderProgram;
+
+};
+
+#endif // _OpenGl_ShaderObject_Header
diff --git a/src/OpenGl/OpenGl_ShaderProgram.cxx b/src/OpenGl/OpenGl_ShaderProgram.cxx
new file mode 100644 (file)
index 0000000..8aee2a7
--- /dev/null
@@ -0,0 +1,1129 @@
+// Created on: 2013-09-19
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <OSD_File.hxx>
+#include <OSD_Protection.hxx>
+
+#include <Standard_Assert.hxx>
+#include <Standard_Atomic.hxx>
+#include <TCollection_ExtendedString.hxx>
+
+#include <OpenGl_Context.hxx>
+#include <OpenGl_ShaderProgram.hxx>
+#include <OpenGl_ShaderManager.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
+
+OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
+
+// Declare OCCT-specific OpenGL/GLSL shader variables
+Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
+{
+  /* OpenGl_OCC_MODEL_WORLD_MATRIX */ "occModelWorldMatrix",
+  /* OpenGl_OCC_WORLD_VIEW_MATRIX */ "occWorldViewMatrix",
+  /* OpenGl_OCC_PROJECTION_MATRIX */ "occProjectionMatrix",
+  /* OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE */ "occModelWorldMatrixInverse",
+  /* OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE */ "occWorldViewMatrixInverse",
+  /* OpenGl_OCC_PROJECTION_MATRIX_INVERSE */ "occProjectionMatrixInverse",
+  /* OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE */ "occModelWorldMatrixTranspose",
+  /* OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE */ "occWorldViewMatrixTranspose",
+  /* OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE */ "occProjectionMatrixTranspose",
+  /* OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE */ "occModelWorldMatrixInverseTranspose",
+  /* OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE */ "occWorldViewMatrixInverseTranspose",
+  /* OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE */ "occProjectionMatrixInverseTranspose",
+
+  /* OpenGl_OCC_CLIP_PLANE_0_EQUATION */ "occClipPlanes[0].Equation",
+  /* OpenGl_OCC_CLIP_PLANE_1_EQUATION */ "occClipPlanes[1].Equation",
+  /* OpenGl_OCC_CLIP_PLANE_2_EQUATION */ "occClipPlanes[2].Equation",
+  /* OpenGl_OCC_CLIP_PLANE_3_EQUATION */ "occClipPlanes[3].Equation",
+  /* OpenGl_OCC_CLIP_PLANE_4_EQUATION */ "occClipPlanes[4].Equation",
+  /* OpenGl_OCC_CLIP_PLANE_5_EQUATION */ "occClipPlanes[5].Equation",
+  /* OpenGl_OCC_CLIP_PLANE_6_EQUATION */ "occClipPlanes[6].Equation",
+  /* OpenGl_OCC_CLIP_PLANE_7_EQUATION */ "occClipPlanes[7].Equation",
+
+  /* OpenGl_OCC_CLIP_PLANE_0_SPACE */ "occClipPlanes[0].Space",
+  /* OpenGl_OCC_CLIP_PLANE_1_SPACE */ "occClipPlanes[1].Space",
+  /* OpenGl_OCC_CLIP_PLANE_2_SPACE */ "occClipPlanes[2].Space",
+  /* OpenGl_OCC_CLIP_PLANE_3_SPACE */ "occClipPlanes[3].Space",
+  /* OpenGl_OCC_CLIP_PLANE_4_SPACE */ "occClipPlanes[4].Space",
+  /* OpenGl_OCC_CLIP_PLANE_5_SPACE */ "occClipPlanes[5].Space",
+  /* OpenGl_OCC_CLIP_PLANE_6_SPACE */ "occClipPlanes[6].Space",
+  /* OpenGl_OCC_CLIP_PLANE_7_SPACE */ "occClipPlanes[7].Space",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_COUNT */ "occLightSourcesCount",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_TYPE */ "occLightSources[0].Type",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_TYPE */ "occLightSources[1].Type",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_TYPE */ "occLightSources[2].Type",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_TYPE */ "occLightSources[3].Type",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_TYPE */ "occLightSources[4].Type",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_TYPE */ "occLightSources[5].Type",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_TYPE */ "occLightSources[6].Type",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_TYPE */ "occLightSources[7].Type",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_HEAD */ "occLightSources[0].Head",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_HEAD */ "occLightSources[1].Head",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_HEAD */ "occLightSources[2].Head",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_HEAD */ "occLightSources[3].Head",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_HEAD */ "occLightSources[4].Head",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_HEAD */ "occLightSources[5].Head",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_HEAD */ "occLightSources[6].Head",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_HEAD */ "occLightSources[7].Head",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT */ "occLightSources[0].Ambient",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_AMBIENT */ "occLightSources[1].Ambient",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_AMBIENT */ "occLightSources[2].Ambient",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_AMBIENT */ "occLightSources[3].Ambient",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_AMBIENT */ "occLightSources[4].Ambient",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_AMBIENT */ "occLightSources[5].Ambient",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_AMBIENT */ "occLightSources[6].Ambient",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_AMBIENT */ "occLightSources[7].Ambient",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE */ "occLightSources[0].Diffuse",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_DIFFUSE */ "occLightSources[1].Diffuse",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_DIFFUSE */ "occLightSources[2].Diffuse",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_DIFFUSE */ "occLightSources[3].Diffuse",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_DIFFUSE */ "occLightSources[4].Diffuse",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_DIFFUSE */ "occLightSources[5].Diffuse",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_DIFFUSE */ "occLightSources[6].Diffuse",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_DIFFUSE */ "occLightSources[7].Diffuse",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR */ "occLightSources[0].Specular",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_SPECULAR */ "occLightSources[1].Specular",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_SPECULAR */ "occLightSources[2].Specular",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_SPECULAR */ "occLightSources[3].Specular",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_SPECULAR */ "occLightSources[4].Specular",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_SPECULAR */ "occLightSources[5].Specular",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_SPECULAR */ "occLightSources[6].Specular",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_SPECULAR */ "occLightSources[7].Specular",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_POSITION */ "occLightSources[0].Position",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_POSITION */ "occLightSources[1].Position",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_POSITION */ "occLightSources[2].Position",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_POSITION */ "occLightSources[3].Position",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_POSITION */ "occLightSources[4].Position",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_POSITION */ "occLightSources[5].Position",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_POSITION */ "occLightSources[6].Position",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_POSITION */ "occLightSources[7].Position",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF */ "occLightSources[0].SpotCutoff",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_CUTOFF */ "occLightSources[1].SpotCutoff",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_CUTOFF */ "occLightSources[2].SpotCutoff",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_CUTOFF */ "occLightSources[3].SpotCutoff",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_CUTOFF */ "occLightSources[4].SpotCutoff",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_CUTOFF */ "occLightSources[5].SpotCutoff",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_CUTOFF */ "occLightSources[6].SpotCutoff",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_CUTOFF */ "occLightSources[7].SpotCutoff",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT */ "occLightSources[0].SpotExponent",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_EXPONENT */ "occLightSources[1].SpotExponent",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_EXPONENT */ "occLightSources[2].SpotExponent",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_EXPONENT */ "occLightSources[3].SpotExponent",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_EXPONENT */ "occLightSources[4].SpotExponent",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_EXPONENT */ "occLightSources[5].SpotExponent",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_EXPONENT */ "occLightSources[6].SpotExponent",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_EXPONENT */ "occLightSources[7].SpotExponent",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION */ "occLightSources[0].SpotDirection",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_DIRECTION */ "occLightSources[1].SpotDirection",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_DIRECTION */ "occLightSources[2].SpotDirection",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_DIRECTION */ "occLightSources[3].SpotDirection",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_DIRECTION */ "occLightSources[4].SpotDirection",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_DIRECTION */ "occLightSources[5].SpotDirection",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_DIRECTION */ "occLightSources[6].SpotDirection",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_DIRECTION */ "occLightSources[7].SpotDirection",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION */ "occLightSources[0].ConstAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_CONST_ATTENUATION */ "occLightSources[1].ConstAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_CONST_ATTENUATION */ "occLightSources[2].ConstAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_CONST_ATTENUATION */ "occLightSources[3].ConstAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_CONST_ATTENUATION */ "occLightSources[4].ConstAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_CONST_ATTENUATION */ "occLightSources[5].ConstAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_CONST_ATTENUATION */ "occLightSources[6].ConstAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_CONST_ATTENUATION */ "occLightSources[7].ConstAttenuation",
+
+  /* OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION */ "occLightSources[0].LinearAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_1_LINEAR_ATTENUATION */ "occLightSources[1].LinearAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_2_LINEAR_ATTENUATION */ "occLightSources[2].LinearAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_3_LINEAR_ATTENUATION */ "occLightSources[3].LinearAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_4_LINEAR_ATTENUATION */ "occLightSources[4].LinearAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_5_LINEAR_ATTENUATION */ "occLightSources[5].LinearAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_6_LINEAR_ATTENUATION */ "occLightSources[6].LinearAttenuation",
+  /* OpenGl_OCC_LIGHT_SOURCE_7_LINEAR_ATTENUATION */ "occLightSources[7].LinearAttenuation",
+
+  /* OpenGl_OCCT_ACTIVE_SAMPLER */ "occActiveSampler",
+  /* OpenGl_OCCT_TEXTURE_ENABLE */ "occTextureEnable",
+  /* OpenGl_OCCT_DISTINGUISH_MODE */ "occDistinguishingMode",
+  /* OpenGl_OCCT_FRONT_MATERIAL_AMBIENT */ "occFrontMaterial.Ambient",
+  /* OpenGl_OCCT_BACK_MATERIAL_AMBIENT */ "occBackMaterial.Ambient",
+  /* OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE */ "occFrontMaterial.Diffuse",
+  /* OpenGl_OCCT_BACK_MATERIAL_DIFFUSE */ "occBackMaterial.Diffuse",
+  /* OpenGl_OCCT_FRONT_MATERIAL_SPECULAR */ "occFrontMaterial.Specular",
+  /* OpenGl_OCCT_BACK_MATERIAL_SPECULAR */ "occBackMaterial.Specular",
+  /* OpenGl_OCCT_FRONT_MATERIAL_EMISSION */ "occFrontMaterial.Emission",
+  /* OpenGl_OCCT_BACK_MATERIAL_EMISSION */ "occBackMaterial.Emission",
+  /* OpenGl_OCCT_FRONT_MATERIAL_SHININESS */ "occFrontMaterial.Shininess",
+  /* OpenGl_OCCT_BACK_MATERIAL_SHININESS */ "occBackMaterial.Shininess",
+  /* OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY */ "occFrontMaterial.Transparency",
+  /* OpenGl_OCCT_BACK_MATERIAL_TRANSPARENCY */ "occBackMaterial.Transparency"
+
+};
+
+// =======================================================================
+// function : OpenGl_VariableSetterSelector
+// purpose  : Creates new variable setter selector
+// =======================================================================
+OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
+{
+  // Note: Add new variable setters here
+  mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
+    (Graphic3d_UniformValueTypeID<int>::ID,          new OpenGl_VariableSetter<int>())
+    (Graphic3d_UniformValueTypeID<float>::ID,        new OpenGl_VariableSetter<float>())
+    (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID,  new OpenGl_VariableSetter<OpenGl_Vec2>())
+    (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID,  new OpenGl_VariableSetter<OpenGl_Vec3>())
+    (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID,  new OpenGl_VariableSetter<OpenGl_Vec4>())
+    (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
+    (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
+    (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
+}
+
+// =======================================================================
+// function : ~OpenGl_VariableSetterSelector
+// purpose  : Releases memory resources of variable setter selector
+// =======================================================================
+OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
+{
+  for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
+  {
+    delete anIt.Value();
+  }
+
+  mySetterList.Clear();
+}
+
+// =======================================================================
+// function : Set
+// purpose  : Sets generic variable to specified shader program
+// =======================================================================
+void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)&           theCtx,
+                                         const Handle(Graphic3d_ShaderVariable)& theVariable,
+                                         OpenGl_ShaderProgram*                   theProgram) const
+{
+  Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
+    "The type of user-defined uniform variable is not supported...", );
+
+  mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
+}
+
+// =======================================================================
+// function : OpenGl_ShaderProgram
+// purpose  : Creates uninitialized shader program
+// =======================================================================
+OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
+: myProgramID (NO_PROGRAM),
+  myProxy     (theProxy)
+{
+  memset (myCurrentState, 0, sizeof (myCurrentState));
+  for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
+  {
+    myStateLocations[aVar] = INVALID_LOCATION;
+  }
+}
+
+// =======================================================================
+// function : Initialize
+// purpose  : Initializes program object with the list of shader objects
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&     theCtx,
+                                                   const Graphic3d_ShaderObjectList& theShaders)
+{
+  if (theCtx.IsNull() || !Create (theCtx))
+  {
+    return Standard_False;
+  }
+
+  GLchar *aShaderDir = getenv ("CSF_ShadersDirectory");
+  if (aShaderDir == NULL)
+  {
+    TCollection_ExtendedString aMsg = "Error! Failed to get OCCT shaders directory";
+
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                         GL_DEBUG_TYPE_ERROR_ARB,
+                         0,
+                         GL_DEBUG_SEVERITY_HIGH_ARB,
+                         aMsg);
+
+    return Standard_False;
+  }
+
+  OSD_File aDeclFile (TCollection_AsciiString (aShaderDir) + "/Declarations.glsl");
+  if (!aDeclFile.Exists())
+  {
+    TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
+
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                         GL_DEBUG_TYPE_ERROR_ARB,
+                         0,
+                         GL_DEBUG_SEVERITY_HIGH_ARB,
+                         aMsg);
+
+    return Standard_False;
+  }
+
+  TCollection_AsciiString aDeclarations;
+
+  aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
+  aDeclFile.Read (aDeclarations, aDeclFile.Size());
+  aDeclFile.Close();
+
+  for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
+       anIter.More(); anIter.Next())
+  {
+    if (!anIter.Value()->IsDone())
+    {
+      TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
+
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                           GL_DEBUG_TYPE_ERROR_ARB,
+                           0,
+                           GL_DEBUG_SEVERITY_HIGH_ARB,
+                           aMsg);
+
+      return Standard_False;
+    }
+
+    Handle(OpenGl_ShaderObject) aShader;
+
+    // Note: Add support of other shader types here
+    switch (anIter.Value()->Type())
+    {
+      case Graphic3d_TOS_VERTEX:
+        aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
+        break;
+      case Graphic3d_TOS_FRAGMENT:
+        aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
+        break;
+    }
+
+    // Is unsupported shader type?
+    if (aShader.IsNull())
+    {
+      TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
+
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                           GL_DEBUG_TYPE_ERROR_ARB,
+                           0,
+                           GL_DEBUG_SEVERITY_HIGH_ARB,
+                           aMsg);
+
+      return Standard_False;
+    }
+
+    if (!aShader->Create (theCtx))
+    {
+      return Standard_False;
+    }
+
+    TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
+    
+    if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
+    {
+      aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
+    }
+
+    if (!aShader->LoadSource (theCtx, aSource))
+    {
+      TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
+
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                           GL_DEBUG_TYPE_ERROR_ARB,
+                           0,
+                           GL_DEBUG_SEVERITY_HIGH_ARB,
+                           aMsg);
+
+      return Standard_False;
+    }
+
+    if (!aShader->Compile (theCtx))
+    {
+      TCollection_ExtendedString aMsg = "Error! Failed to compile shader object";
+
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                           GL_DEBUG_TYPE_ERROR_ARB,
+                           0,
+                           GL_DEBUG_SEVERITY_HIGH_ARB,
+                           aMsg);
+
+      if (theCtx->caps->contextDebug)
+      {
+        TCollection_AsciiString aLog;
+        aShader->FetchInfoLog (theCtx, aLog);
+        if (!aLog.IsEmpty())
+        {
+          std::cout << aLog.ToCString() << std::endl << std::flush;
+        }
+        else
+        {
+          std::cout << "Information log is empty" << std::endl;
+        }
+      }
+
+      return Standard_False;
+    }
+
+    if (!AttachShader (theCtx, aShader))
+    {
+      return Standard_False;
+    }
+  }
+
+  if (!Link (theCtx))
+  {
+    TCollection_ExtendedString aMsg = "Error! Failed to link program object";
+
+    theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                         GL_DEBUG_TYPE_ERROR_ARB,
+                         0,
+                         GL_DEBUG_SEVERITY_HIGH_ARB,
+                         aMsg);
+
+    if (theCtx->caps->contextDebug)
+    {
+      TCollection_AsciiString aLog;
+      FetchInfoLog (theCtx, aLog);
+      if (!aLog.IsEmpty())
+      {
+        std::cout << aLog.ToCString() << std::endl;
+      }
+      else
+      {
+        std::cout << "Information log is empty" << std::endl;
+      }
+    }
+
+    return Standard_False;
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
+// function : ~OpenGl_ShaderProgram
+// purpose  : Releases resources of shader program
+// =======================================================================
+OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
+{
+  Release (NULL);
+}
+
+// =======================================================================
+// function : AttachShader
+// purpose  : Attaches shader object to the program object
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)&      theCtx,
+                                                     const Handle(OpenGl_ShaderObject)& theShader)
+{
+  if (myProgramID == NO_PROGRAM || theShader.IsNull())
+  {
+    return Standard_False;
+  }
+
+  for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
+  {
+    if (theShader == anIter.Value())
+    {
+      return Standard_False;
+    }
+  }
+
+  myShaderObjects.Append (theShader);
+  theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : DetachShader
+// purpose  : Detaches shader object to the program object
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)&      theCtx,
+                                                     const Handle(OpenGl_ShaderObject)& theShader)
+{
+  if (myProgramID == NO_PROGRAM
+   || theShader.IsNull())
+  {
+    return Standard_False;
+  }
+
+  OpenGl_ShaderList::Iterator anIter (myShaderObjects);
+  while (anIter.More())
+  {
+    if (theShader == anIter.Value())
+    {
+      myShaderObjects.Remove (anIter);
+      break;
+    }
+
+    anIter.Next();
+  }
+
+  if (!anIter.More())
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : Link
+// purpose  : Links the program object
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
+{
+  if (myProgramID == NO_PROGRAM)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glLinkProgram (myProgramID);
+
+  GLint aStatus = GL_FALSE;
+  theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
+
+  for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
+  {
+    myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
+  }
+
+  return aStatus != GL_FALSE;
+}
+
+// =======================================================================
+// function : FetchInfoLog
+// purpose  : Fetches information log of the last link operation
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
+                                                     TCollection_AsciiString&      theOutput)
+{
+  if (myProgramID == NO_PROGRAM)
+  {
+    return Standard_False;
+  }
+
+  GLint aLength = 0;
+  theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
+  if (aLength > 0)
+  {
+    GLchar* aLog = (GLchar*) alloca (aLength);
+    memset (aLog, 0, aLength);
+    theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
+    theOutput = aLog;
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : Bind
+// purpose  : Sets the program object as part of current rendering state
+// =======================================================================
+void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const
+{
+  if (myProgramID == NO_PROGRAM)
+  {
+    return;
+  }
+
+  theCtx->core20->glUseProgram (myProgramID);
+  theCtx->ShaderManager()->myIsPP = Standard_True;
+}
+
+// =======================================================================
+// function : ApplyVariables
+// purpose  : Fetches uniform variables from proxy shader program
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
+{
+  if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
+  {
+    return Standard_False;
+  }
+
+  for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
+  {
+    mySetterSelector.Set (theCtx, anIter.Value(), this);
+  }
+
+  myProxy->ClearVariables();
+  return Standard_True;
+}
+
+// =======================================================================
+// function : BindWithVariables
+// purpose  : Binds the program object and applies variables
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx)
+{
+  Bind (theCtx);
+  return ApplyVariables (theCtx);
+}
+
+// =======================================================================
+// function : Unbind
+// purpose  : Reverts to fixed-function graphics pipeline (FFP)
+// =======================================================================
+void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx)
+{
+  if (theCtx->ShaderManager()->myIsPP)
+  {
+    theCtx->core20->glUseProgram (NO_PROGRAM);
+    theCtx->ShaderManager()->myIsPP = Standard_False;
+  }
+}
+
+// =======================================================================
+// function : ActiveState
+// purpose  : Returns index of last modification for specified state type
+// =======================================================================
+Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
+{
+  if (theType < MaxStateTypes)
+  {
+    return myCurrentState[theType];
+  }
+  return 0;
+}
+
+// =======================================================================
+// function : UpdateState
+// purpose  : Updates index of last modification for specified state type
+// =======================================================================
+void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
+                                        const Standard_Size           theIndex)
+{
+  if (theType < MaxStateTypes)
+  {
+    myCurrentState[theType] = theIndex;
+  }
+}
+
+// =======================================================================
+// function : GetUniformLocation
+// purpose  : Returns location (index) of the specific uniform variable
+// =======================================================================
+GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
+                                                const GLchar*                 theName) const
+{
+  return myProgramID != NO_PROGRAM
+       ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
+       : INVALID_LOCATION;
+}
+
+// =======================================================================
+// function : GetAttributeLocation
+// purpose  : Returns location (index) of the generic vertex attribute
+// =======================================================================
+GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
+                                                  const GLchar*                 theName) const
+{
+  return myProgramID != NO_PROGRAM
+       ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
+       : INVALID_LOCATION;
+}
+
+// =======================================================================
+// function : GetStateLocation
+// purpose  : Returns location of the OCCT state uniform variable
+// =======================================================================
+GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
+{
+  if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
+  {
+    return myStateLocations[theVariable];
+  }
+  return INVALID_LOCATION;
+}
+
+// =======================================================================
+// function : GetUniform
+// purpose  : Returns the value of the integer uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   OpenGl_Vec4i&                 theValue) const
+{
+  return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : GetUniform
+// purpose  : Returns the value of the integer uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   OpenGl_Vec4i&                 theValue) const
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : GetUniform
+// purpose  : Returns the value of the floating-point uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   OpenGl_Vec4&                  theValue) const
+{
+  return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : GetUniform
+// purpose  : Returns the value of the floating-point uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   OpenGl_Vec4&                  theValue) const
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : GetAttribute
+// purpose  : Returns the integer vertex attribute
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
+                                                     const GLchar*                 theName,
+                                                     OpenGl_Vec4i&                 theValue) const
+{
+  return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : GetAttribute
+// purpose  : Returns the integer vertex attribute
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
+                                                     GLint                         theIndex,
+                                                     OpenGl_Vec4i&                 theValue) const
+{
+  if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : GetAttribute
+// purpose  : Returns the floating-point vertex attribute
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
+                                                     const GLchar*                 theName,
+                                                     OpenGl_Vec4&                  theValue) const
+{
+  return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : GetAttribute
+// purpose  : Returns the floating-point vertex attribute
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
+                                                     GLint                         theIndex,
+                                                     OpenGl_Vec4&                  theValue) const
+{
+  if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the integer uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   GLint                         theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the integer uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   GLint                         theValue)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform1i (theLocation, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   GLfloat                       theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   GLfloat                       theValue)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform1f (theLocation, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the integer uniform 2D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const OpenGl_Vec2i&           theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the integer uniform 2D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const OpenGl_Vec2i&           theValue)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform2iv (theLocation, 1, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the integer uniform 3D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const OpenGl_Vec3i&           theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the integer uniform 3D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const OpenGl_Vec3i&           theValue)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform3iv (theLocation, 1, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the integer uniform 4D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const OpenGl_Vec4i&           theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the integer uniform 4D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const OpenGl_Vec4i&           theValue)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform4iv (theLocation, 1, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 2D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const OpenGl_Vec2&            theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 2D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const OpenGl_Vec2&            theValue)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform2fv (theLocation, 1, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 3D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const OpenGl_Vec3&            theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 3D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const OpenGl_Vec3&            theValue)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform3fv (theLocation, 1, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 4D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const OpenGl_Vec4&            theValue)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 4D vector
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const OpenGl_Vec4&            theValue)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform4fv (theLocation, 1, theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 4x4 matrix
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const OpenGl_Matrix&          theValue,
+                                                   GLboolean                     theTranspose)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 4x4 matrix
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const OpenGl_Matrix&          theValue,
+                                                   GLboolean                     theTranspose)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 4x4 matrix
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const Tmatrix3&               theValue,
+                                                   GLboolean                     theTranspose)
+{
+  return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
+}
+
+// =======================================================================
+// function : SetUniform
+// purpose  : Specifies the value of the floating-point uniform 4x4 matrix
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const Tmatrix3&               theValue,
+                                                   GLboolean                     theTranspose)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : SetSampler
+// purpose  : Specifies the value of the sampler uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
+                                                   const GLchar*                 theName,
+                                                   const GLenum                  theTextureUnit)
+{
+  return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
+}
+
+// =======================================================================
+// function : SetSampler
+// purpose  : Specifies the value of the sampler uniform variable
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
+                                                   GLint                         theLocation,
+                                                   const GLenum                  theTextureUnit)
+{
+  if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
+  {
+    return Standard_False;
+  }
+
+  theCtx->core20->glUniform1i (theLocation, theTextureUnit);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : Create
+// purpose  : Creates new empty shader program of specified type
+// =======================================================================
+Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
+{
+  if (myProgramID == NO_PROGRAM
+   && theCtx->core20 != NULL)
+  {
+    myProgramID = theCtx->core20->glCreateProgram();
+  }
+
+  return myProgramID != NO_PROGRAM;
+}
+
+// =======================================================================
+// function : Release
+// purpose  : Destroys shader program
+// =======================================================================
+void OpenGl_ShaderProgram::Release (const OpenGl_Context* theCtx)
+{
+  if (myProgramID == NO_PROGRAM)
+  {
+    return;
+  }
+
+  Standard_ASSERT_RETURN (theCtx != NULL,
+    "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
+
+  for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
+  {
+    anIter.ChangeValue()->Release (theCtx);
+    anIter.ChangeValue().Nullify();
+  }
+
+  if (theCtx->core20 != NULL)
+  {
+    theCtx->core20->glDeleteProgram (myProgramID);
+  }
+
+  myProgramID = NO_PROGRAM;
+}
diff --git a/src/OpenGl/OpenGl_ShaderProgram.hxx b/src/OpenGl/OpenGl_ShaderProgram.hxx
new file mode 100644 (file)
index 0000000..a38f845
--- /dev/null
@@ -0,0 +1,557 @@
+// Created on: 2013-09-19
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_ShaderProgram_Header
+#define _OpenGl_ShaderProgram_Header
+
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Sequence.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <Graphic3d_ShaderObject.hxx>
+#include <Graphic3d_ShaderProgram.hxx>
+
+#include <InterfaceGraphic_tgl_all.hxx>
+
+#include <OpenGl_Vec.hxx>
+#include <OpenGl_Matrix.hxx>
+#include <OpenGl_ShaderObject.hxx>
+#include <Handle_OpenGl_ShaderProgram.hxx>
+
+//! The enumeration of OCCT-specific OpenGL/GLSL variables.
+enum OpenGl_StateVariable
+{
+  // OpenGL matrix state
+  OpenGl_OCC_MODEL_WORLD_MATRIX,
+  OpenGl_OCC_WORLD_VIEW_MATRIX,
+  OpenGl_OCC_PROJECTION_MATRIX,
+  OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE,
+  OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE,
+  OpenGl_OCC_PROJECTION_MATRIX_INVERSE,
+  OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE,
+  OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE,
+  OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE,
+  OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE,
+  OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE,
+  OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE,
+
+  // OpenGL clip planes state
+  OpenGl_OCC_CLIP_PLANE_0_EQUATION,
+  OpenGl_OCC_CLIP_PLANE_1_EQUATION,
+  OpenGl_OCC_CLIP_PLANE_2_EQUATION,
+  OpenGl_OCC_CLIP_PLANE_3_EQUATION,
+  OpenGl_OCC_CLIP_PLANE_4_EQUATION,
+  OpenGl_OCC_CLIP_PLANE_5_EQUATION,
+  OpenGl_OCC_CLIP_PLANE_6_EQUATION,
+  OpenGl_OCC_CLIP_PLANE_7_EQUATION,
+  OpenGl_OCC_CLIP_PLANE_0_SPACE,
+  OpenGl_OCC_CLIP_PLANE_1_SPACE,
+  OpenGl_OCC_CLIP_PLANE_2_SPACE,
+  OpenGl_OCC_CLIP_PLANE_3_SPACE,
+  OpenGl_OCC_CLIP_PLANE_4_SPACE,
+  OpenGl_OCC_CLIP_PLANE_5_SPACE,
+  OpenGl_OCC_CLIP_PLANE_6_SPACE,
+  OpenGl_OCC_CLIP_PLANE_7_SPACE,
+
+  OpenGl_OCC_LIGHT_SOURCE_COUNT,
+
+  // OpenGL light state
+  OpenGl_OCC_LIGHT_SOURCE_0_TYPE,
+  OpenGl_OCC_LIGHT_SOURCE_1_TYPE,
+  OpenGl_OCC_LIGHT_SOURCE_2_TYPE,
+  OpenGl_OCC_LIGHT_SOURCE_3_TYPE,
+  OpenGl_OCC_LIGHT_SOURCE_4_TYPE,
+  OpenGl_OCC_LIGHT_SOURCE_5_TYPE,
+  OpenGl_OCC_LIGHT_SOURCE_6_TYPE,
+  OpenGl_OCC_LIGHT_SOURCE_7_TYPE,
+  OpenGl_OCC_LIGHT_SOURCE_0_HEAD,
+  OpenGl_OCC_LIGHT_SOURCE_1_HEAD,
+  OpenGl_OCC_LIGHT_SOURCE_2_HEAD,
+  OpenGl_OCC_LIGHT_SOURCE_3_HEAD,
+  OpenGl_OCC_LIGHT_SOURCE_4_HEAD,
+  OpenGl_OCC_LIGHT_SOURCE_5_HEAD,
+  OpenGl_OCC_LIGHT_SOURCE_6_HEAD,
+  OpenGl_OCC_LIGHT_SOURCE_7_HEAD,
+  OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT,
+  OpenGl_OCC_LIGHT_SOURCE_1_AMBIENT,
+  OpenGl_OCC_LIGHT_SOURCE_2_AMBIENT,
+  OpenGl_OCC_LIGHT_SOURCE_3_AMBIENT,
+  OpenGl_OCC_LIGHT_SOURCE_4_AMBIENT,
+  OpenGl_OCC_LIGHT_SOURCE_5_AMBIENT,
+  OpenGl_OCC_LIGHT_SOURCE_6_AMBIENT,
+  OpenGl_OCC_LIGHT_SOURCE_7_AMBIENT,
+  OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE,
+  OpenGl_OCC_LIGHT_SOURCE_1_DIFFUSE,
+  OpenGl_OCC_LIGHT_SOURCE_2_DIFFUSE,
+  OpenGl_OCC_LIGHT_SOURCE_3_DIFFUSE,
+  OpenGl_OCC_LIGHT_SOURCE_4_DIFFUSE,
+  OpenGl_OCC_LIGHT_SOURCE_5_DIFFUSE,
+  OpenGl_OCC_LIGHT_SOURCE_6_DIFFUSE,
+  OpenGl_OCC_LIGHT_SOURCE_7_DIFFUSE,
+  OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR,
+  OpenGl_OCC_LIGHT_SOURCE_1_SPECULAR,
+  OpenGl_OCC_LIGHT_SOURCE_2_SPECULAR,
+  OpenGl_OCC_LIGHT_SOURCE_3_SPECULAR,
+  OpenGl_OCC_LIGHT_SOURCE_4_SPECULAR,
+  OpenGl_OCC_LIGHT_SOURCE_5_SPECULAR,
+  OpenGl_OCC_LIGHT_SOURCE_6_SPECULAR,
+  OpenGl_OCC_LIGHT_SOURCE_7_SPECULAR,
+  OpenGl_OCC_LIGHT_SOURCE_0_POSITION,
+  OpenGl_OCC_LIGHT_SOURCE_1_POSITION,
+  OpenGl_OCC_LIGHT_SOURCE_2_POSITION,
+  OpenGl_OCC_LIGHT_SOURCE_3_POSITION,
+  OpenGl_OCC_LIGHT_SOURCE_4_POSITION,
+  OpenGl_OCC_LIGHT_SOURCE_5_POSITION,
+  OpenGl_OCC_LIGHT_SOURCE_6_POSITION,
+  OpenGl_OCC_LIGHT_SOURCE_7_POSITION,
+  OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF,
+  OpenGl_OCC_LIGHT_SOURCE_1_SPOT_CUTOFF,
+  OpenGl_OCC_LIGHT_SOURCE_2_SPOT_CUTOFF,
+  OpenGl_OCC_LIGHT_SOURCE_3_SPOT_CUTOFF,
+  OpenGl_OCC_LIGHT_SOURCE_4_SPOT_CUTOFF,
+  OpenGl_OCC_LIGHT_SOURCE_5_SPOT_CUTOFF,
+  OpenGl_OCC_LIGHT_SOURCE_6_SPOT_CUTOFF,
+  OpenGl_OCC_LIGHT_SOURCE_7_SPOT_CUTOFF,
+  OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT,
+  OpenGl_OCC_LIGHT_SOURCE_1_SPOT_EXPONENT,
+  OpenGl_OCC_LIGHT_SOURCE_2_SPOT_EXPONENT,
+  OpenGl_OCC_LIGHT_SOURCE_3_SPOT_EXPONENT,
+  OpenGl_OCC_LIGHT_SOURCE_4_SPOT_EXPONENT,
+  OpenGl_OCC_LIGHT_SOURCE_5_SPOT_EXPONENT,
+  OpenGl_OCC_LIGHT_SOURCE_6_SPOT_EXPONENT,
+  OpenGl_OCC_LIGHT_SOURCE_7_SPOT_EXPONENT,
+  OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION,
+  OpenGl_OCC_LIGHT_SOURCE_1_SPOT_DIRECTION,
+  OpenGl_OCC_LIGHT_SOURCE_2_SPOT_DIRECTION,
+  OpenGl_OCC_LIGHT_SOURCE_3_SPOT_DIRECTION,
+  OpenGl_OCC_LIGHT_SOURCE_4_SPOT_DIRECTION,
+  OpenGl_OCC_LIGHT_SOURCE_5_SPOT_DIRECTION,
+  OpenGl_OCC_LIGHT_SOURCE_6_SPOT_DIRECTION,
+  OpenGl_OCC_LIGHT_SOURCE_7_SPOT_DIRECTION,
+  OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_1_CONST_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_2_CONST_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_3_CONST_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_4_CONST_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_5_CONST_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_6_CONST_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_7_CONST_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_1_LINEAR_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_2_LINEAR_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_3_LINEAR_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_4_LINEAR_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_5_LINEAR_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_6_LINEAR_ATTENUATION,
+  OpenGl_OCC_LIGHT_SOURCE_7_LINEAR_ATTENUATION,
+
+  // Material state
+  OpenGl_OCCT_ACTIVE_SAMPLER,
+  OpenGl_OCCT_TEXTURE_ENABLE,
+  OpenGl_OCCT_DISTINGUISH_MODE,
+  OpenGl_OCCT_FRONT_MATERIAL_AMBIENT,
+  OpenGl_OCCT_BACK_MATERIAL_AMBIENT,
+  OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE,
+  OpenGl_OCCT_BACK_MATERIAL_DIFFUSE,
+  OpenGl_OCCT_FRONT_MATERIAL_SPECULAR,
+  OpenGl_OCCT_BACK_MATERIAL_SPECULAR,
+  OpenGl_OCCT_FRONT_MATERIAL_EMISSION,
+  OpenGl_OCCT_BACK_MATERIAL_EMISSION,
+  OpenGl_OCCT_FRONT_MATERIAL_SHININESS,
+  OpenGl_OCCT_BACK_MATERIAL_SHININESS,
+  OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY,
+  OpenGl_OCCT_BACK_MATERIAL_TRANSPARENCY,
+
+  // DON'T MODIFY THIS ITEM (insert new items before it)
+  OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
+};
+
+class OpenGl_ShaderProgram;
+
+//! Interface for generic setter of user-defined uniform variables.
+struct OpenGl_SetterInterface
+{
+  //! Sets user-defined uniform variable to specified program.
+  virtual void Set (const Handle(OpenGl_Context)&           theCtx,
+                    const Handle(Graphic3d_ShaderVariable)& theVariable,
+                    OpenGl_ShaderProgram*                   theProgram) = 0;
+
+  //! Destructor
+  virtual ~OpenGl_SetterInterface() {}
+};
+
+//! List of OpenGL shader objects.
+typedef NCollection_Sequence<Handle(OpenGl_ShaderObject)>    OpenGl_ShaderList;
+
+//! List of shader variable setters.
+typedef NCollection_DataMap<size_t, OpenGl_SetterInterface*> OpenGl_SetterList;
+
+//! Support tool for setting user-defined uniform variables.
+class OpenGl_VariableSetterSelector
+{
+public:
+
+  //! Creates new setter selector.
+  OpenGl_VariableSetterSelector();
+
+  //! Releases memory resources of setter selector.
+  ~OpenGl_VariableSetterSelector();
+
+  //! Sets user-defined uniform variable to specified program.
+  void Set (const Handle(OpenGl_Context)&           theCtx,
+            const Handle(Graphic3d_ShaderVariable)& theVariable,
+            OpenGl_ShaderProgram*                   theProgram) const;
+
+private:
+
+  //! List of variable setters.
+  OpenGl_SetterList mySetterList;
+};
+
+//! Defines types of uniform state variables.
+enum OpenGl_UniformStateType
+{
+  OpenGl_LIGHT_SOURCES_STATE,
+  OpenGl_CLIP_PLANES_STATE,
+  OpenGl_MODEL_WORLD_STATE,
+  OpenGl_WORLD_VIEW_STATE,
+  OpenGl_PROJECTION_STATE,
+  OpenGl_MATERIALS_STATE
+};
+
+//! Total number of state types.
+const int MaxStateTypes = 6;
+
+//! Wrapper for OpenGL program object.
+class OpenGl_ShaderProgram : public OpenGl_Resource
+{
+
+public:
+
+  //! Non-valid shader name.
+  static const GLuint NO_PROGRAM = 0;
+
+  //! Invalid location of uniform/attribute variable.
+  static const GLint INVALID_LOCATION = -1;
+
+  //! List of pre-defined OCCT state uniform variables.
+  static Standard_CString PredefinedKeywords[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
+
+protected:
+
+  //! Creates uninitialized shader program.
+  Standard_EXPORT OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy = NULL);
+
+  static OpenGl_VariableSetterSelector mySetterSelector;
+
+public:
+
+  //! Releases resources of shader program.
+  Standard_EXPORT virtual ~OpenGl_ShaderProgram();
+
+  //! Creates new empty shader program of specified type.
+  Standard_EXPORT Standard_Boolean Create (const Handle(OpenGl_Context)& theCtx);
+
+  //! Destroys shader program.
+  Standard_EXPORT virtual void Release (const OpenGl_Context* theCtx);
+
+  //! Attaches shader object to the program object.
+  Standard_EXPORT Standard_Boolean AttachShader (const Handle(OpenGl_Context)&      theCtx,
+                                                 const Handle(OpenGl_ShaderObject)& theShader);
+
+  //! Detaches shader object to the program object.
+  Standard_EXPORT Standard_Boolean DetachShader (const Handle(OpenGl_Context)&      theCtx,
+                                                 const Handle(OpenGl_ShaderObject)& theShader);
+
+  //! Initializes program object with the list of shader objects.
+  Standard_EXPORT Standard_Boolean Initialize (const Handle(OpenGl_Context)&     theCtx,
+                                               const Graphic3d_ShaderObjectList& theShaders);
+
+  //! Links the program object.
+  Standard_EXPORT Standard_Boolean Link (const Handle(OpenGl_Context)& theCtx);
+
+  //! Fetches information log of the last link operation.
+  Standard_EXPORT Standard_Boolean FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
+                                                 TCollection_AsciiString&      theLog);
+
+  //! Fetches uniform variables from proxy shader program.
+  Standard_EXPORT Standard_Boolean ApplyVariables (const Handle(OpenGl_Context)& theCtx);
+
+  //! Sets the program object as part of current rendering state.
+  Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx) const;
+
+  //! Binds the program object and applies variables from proxy shader program.
+  Standard_EXPORT Standard_Boolean BindWithVariables (const Handle(OpenGl_Context)& theCtx);
+
+  //! Reverts to fixed-function graphics pipeline (FFP).
+  Standard_EXPORT static void Unbind (const Handle(OpenGl_Context)& theCtx);
+
+private:
+
+  //! Returns index of last modification of variables of specified state type.
+  Standard_EXPORT Standard_Size ActiveState (const OpenGl_UniformStateType theType) const;
+
+  //! Updates index of last modification of variables of specified state type.
+  Standard_EXPORT void UpdateState (const OpenGl_UniformStateType theType,
+                                    const Standard_Size           theIndex);
+
+public:
+
+  //! Returns location of the specific uniform variable.
+  Standard_EXPORT GLint GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
+                                            const GLchar*                 theName) const;
+
+  //! Returns index of the generic vertex attribute by variable name.
+  Standard_EXPORT GLint GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
+                                              const GLchar*                 theName) const;
+
+  //! Returns location of the OCCT state uniform variable.
+  Standard_EXPORT GLint GetStateLocation (const GLuint theVariable) const;
+
+public:
+
+  //! Returns the value of the integer uniform variable.
+  Standard_EXPORT Standard_Boolean GetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               OpenGl_Vec4i&                 theValue) const;
+
+  Standard_EXPORT Standard_Boolean GetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               OpenGl_Vec4i&                 theValue) const;
+
+  //! Returns the value of the float uniform variable.
+  Standard_EXPORT Standard_Boolean GetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               OpenGl_Vec4&                  theValue) const;
+
+  //! Returns the value of the float uniform variable.
+  Standard_EXPORT Standard_Boolean GetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               OpenGl_Vec4&                  theValue) const;
+
+public:
+
+  //! Returns the integer vertex attribute.
+  Standard_EXPORT Standard_Boolean GetAttribute (const Handle(OpenGl_Context)& theCtx,
+                                                 const GLchar*                 theName,
+                                                 OpenGl_Vec4i&                 theValue) const;
+
+  //! Returns the integer vertex attribute.
+  Standard_EXPORT Standard_Boolean GetAttribute (const Handle(OpenGl_Context)& theCtx,
+                                                 GLint                         theIndex,
+                                                 OpenGl_Vec4i&                 theValue) const;
+
+  //! Returns the float vertex attribute.
+  Standard_EXPORT Standard_Boolean GetAttribute (const Handle(OpenGl_Context)& theCtx,
+                                                 const GLchar*                 theName,
+                                                 OpenGl_Vec4&                  theValue) const;
+
+  //! Returns the float vertex attribute.
+  Standard_EXPORT Standard_Boolean GetAttribute (const Handle(OpenGl_Context)& theCtx,
+                                                 GLint                         theIndex,
+                                                 OpenGl_Vec4&                  theValue) const;
+
+public:
+
+  //! Specifies the value of the integer uniform variable.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               GLint                         theValue);
+
+  //! Specifies the value of the integer uniform variable.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               GLint                         theValue);
+
+  //! Specifies the value of the integer uniform 2D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const OpenGl_Vec2i&           theValue);
+
+  //! Specifies the value of the integer uniform 2D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const OpenGl_Vec2i&           theValue);
+
+  //! Specifies the value of the integer uniform 3D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const OpenGl_Vec3i&           theValue);
+
+  //! Specifies the value of the integer uniform 3D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const OpenGl_Vec3i&           theValue);
+
+  //! Specifies the value of the integer uniform 4D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const OpenGl_Vec4i&           theValue);
+
+  //! Specifies the value of the integer uniform 4D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const OpenGl_Vec4i&           theValue);
+
+public:
+
+  //! Specifies the value of the float uniform variable.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               GLfloat                       theValue);
+
+  //! Specifies the value of the float uniform variable.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               GLfloat                       theValue);
+
+  //! Specifies the value of the float uniform 2D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const OpenGl_Vec2&            theValue);
+
+  //! Specifies the value of the float uniform 2D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const OpenGl_Vec2&            theValue);
+
+  //! Specifies the value of the float uniform 3D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const OpenGl_Vec3&            theValue);
+
+  //! Specifies the value of the float uniform 3D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const OpenGl_Vec3&            theValue);
+
+  //! Specifies the value of the float uniform 4D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const OpenGl_Vec4&            theValue);
+
+  //! Specifies the value of the float uniform 4D vector.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const OpenGl_Vec4&            theValue);
+
+public:
+
+  //! Specifies the value of the float uniform 4x4 matrix.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const OpenGl_Matrix&          theValue,
+                                               GLboolean                     theTranspose = GL_FALSE);
+
+  //! Specifies the value of the float uniform 4x4 matrix.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const OpenGl_Matrix&          theValue,
+                                               GLboolean                     theTranspose = GL_FALSE);
+
+  //! Specifies the value of the float uniform 4x4 matrix.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const Tmatrix3&               theValue,
+                                               GLboolean                     theTranspose = GL_FALSE);
+
+  //! Specifies the value of the float uniform 4x4 matrix.
+  Standard_EXPORT Standard_Boolean SetUniform (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const Tmatrix3&               theValue,
+                                               GLboolean                     theTranspose = GL_FALSE);
+
+public:
+
+  //! Specifies the value of the sampler uniform variable.
+  Standard_EXPORT Standard_Boolean SetSampler (const Handle(OpenGl_Context)& theCtx,
+                                               const GLchar*                 theName,
+                                               const GLenum                  theTextureUnit);
+
+  //! Specifies the value of the sampler uniform variable.
+  Standard_EXPORT Standard_Boolean SetSampler (const Handle(OpenGl_Context)& theCtx,
+                                               GLint                         theLocation,
+                                               const GLenum                  theTextureUnit);
+
+protected:
+
+  GLuint                          myProgramID;     //! Handle of OpenGL shader program
+  OpenGl_ShaderList               myShaderObjects; //! List of attached shader objects
+  Handle(Graphic3d_ShaderProgram) myProxy;         //! Proxy shader program (from application layer)
+
+protected:
+
+  //! Defines last modification for variables of each state type.
+  Standard_Size myCurrentState[MaxStateTypes];
+
+  //! Stores locations of OCCT state uniform variables.
+  GLint myStateLocations[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
+
+public:
+
+  DEFINE_STANDARD_RTTI (OpenGl_ShaderProgram)
+  friend class OpenGl_ShaderManager;
+
+};
+
+template<class T>
+struct OpenGl_VariableSetter : public OpenGl_SetterInterface
+{
+  virtual void Set (const Handle(OpenGl_Context)&           theCtx,
+                    const Handle(Graphic3d_ShaderVariable)& theVariable,
+                    OpenGl_ShaderProgram*                   theProgram)
+  {
+    theProgram->SetUniform (theCtx,
+                            theVariable->Name().ToCString(),
+                            theVariable->Value()->As<T>());
+  }
+};
+
+namespace OpenGl_HashMapInitializer
+{
+  template<class K, class V>
+  struct MapListOfType
+  {
+    NCollection_DataMap<K, V> myDictionary;
+
+    MapListOfType (K theKey, V theValue)
+    {
+      myDictionary.Bind (theKey, theValue);
+    }
+
+    MapListOfType& operator() (K theKey, V theValue)
+    {
+      myDictionary.Bind (theKey, theValue);
+      return *this;
+    }
+
+    operator const NCollection_DataMap<K, V>& () const
+    {
+      return myDictionary;
+    }
+  };
+
+  template<class K, class V>
+  MapListOfType<K, V> CreateListOf (K theKey, V theValue)
+  {
+    return MapListOfType<K, V> (theKey, theValue);
+  }
+}
+
+#endif // _OpenGl_ShaderProgram_Header
diff --git a/src/OpenGl/OpenGl_ShaderStates.cxx b/src/OpenGl/OpenGl_ShaderStates.cxx
new file mode 100644 (file)
index 0000000..d02a80a
--- /dev/null
@@ -0,0 +1,262 @@
+// Created on: 2013-10-02
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <NCollection_Mat4.hxx>
+
+#include <OpenGl_ShaderStates.hxx>
+
+// =======================================================================
+// function : OpenGl_StateInterface
+// purpose  : Creates new OCCT state
+// =======================================================================
+OpenGl_StateInterface::OpenGl_StateInterface()
+: myIndex (0)
+{
+  //
+}
+
+// =======================================================================
+// function : Index
+// purpose  : Returns current state index
+// =======================================================================
+Standard_Size OpenGl_StateInterface::Index() const
+{
+  return myIndex;
+}
+
+// =======================================================================
+// function : Update
+// purpose  : Updates current state
+// =======================================================================
+void OpenGl_StateInterface::Update()
+{
+  ++myIndex;
+}
+
+// =======================================================================
+// function : Revert
+// purpose  : Reverts current state
+// =======================================================================
+void OpenGl_StateInterface::Revert()
+{
+  if (myIndex > 0)
+  {
+    --myIndex;
+  }
+}
+
+// =======================================================================
+// function : OpenGl_ProjectionState
+// purpose  : Creates uninitialized projection state
+// =======================================================================
+OpenGl_ProjectionState::OpenGl_ProjectionState()
+: myInverseNeedUpdate (false)
+{
+  //
+}
+
+// =======================================================================
+// function : Set
+// purpose  : Sets new OCCT projection state
+// =======================================================================
+void OpenGl_ProjectionState::Set (const Tmatrix3& theProjectionMatrix)
+{
+  memcpy (myProjectionMatrix, theProjectionMatrix, sizeof (Tmatrix3));
+  myInverseNeedUpdate = true;
+}
+
+// =======================================================================
+// function : ProjectionMatrix
+// purpose  : Returns current projection matrix
+// =======================================================================
+const Tmatrix3& OpenGl_ProjectionState::ProjectionMatrix() const
+{
+  return myProjectionMatrix;
+}
+
+// =======================================================================
+// function : ProjectionMatrixInverse
+// purpose  : Returns inverse of current projection matrix
+// =======================================================================
+const Tmatrix3& OpenGl_ProjectionState::ProjectionMatrixInverse() const
+{
+  if (!myInverseNeedUpdate)
+  {
+    return myProjectionMatrixInverse;
+  }
+
+  reinterpret_cast<const NCollection_Mat4<float>*> (*myProjectionMatrix)->Inverted (
+                *(reinterpret_cast<NCollection_Mat4<float>*> (*myProjectionMatrixInverse)));
+  return myProjectionMatrixInverse;
+}
+
+// =======================================================================
+// function : OpenGl_ModelWorldState
+// purpose  : Creates uninitialized model-world state
+// =======================================================================
+OpenGl_ModelWorldState::OpenGl_ModelWorldState()
+: myInverseNeedUpdate (false)
+{
+  //
+}
+
+// =======================================================================
+// function : Set
+// purpose  : Sets new model-world matrix
+// =======================================================================
+void OpenGl_ModelWorldState::Set (const Tmatrix3& theModelWorldMatrix)
+{
+  memcpy (myModelWorldMatrix, theModelWorldMatrix, sizeof (Tmatrix3));
+  myInverseNeedUpdate = true;
+}
+
+// =======================================================================
+// function : ModelWorldMatrix
+// purpose  : Returns current model-world matrix
+// =======================================================================
+const Tmatrix3& OpenGl_ModelWorldState::ModelWorldMatrix() const
+{
+  return myModelWorldMatrix;
+}
+
+// =======================================================================
+// function : ModelWorldMatrixInverse
+// purpose  : Returns inverse of current model-world matrix
+// =======================================================================
+const Tmatrix3& OpenGl_ModelWorldState::ModelWorldMatrixInverse() const
+{
+  if (!myInverseNeedUpdate)
+  {
+    return myModelWorldMatrix;
+  }
+
+  reinterpret_cast<const NCollection_Mat4<float>*> (*myModelWorldMatrix)->Inverted (
+                *(reinterpret_cast<NCollection_Mat4<float>*> (*myModelWorldMatrixInverse)));
+  return myModelWorldMatrixInverse;
+}
+
+// =======================================================================
+// function : OpenGl_WorldViewState
+// purpose  : Creates uninitialized world-view state
+// =======================================================================
+OpenGl_WorldViewState::OpenGl_WorldViewState()
+: myInverseNeedUpdate (false)
+{
+  //
+}
+
+// =======================================================================
+// function : Set
+// purpose  : Sets new world-view matrix
+// =======================================================================
+void OpenGl_WorldViewState::Set (const Tmatrix3& theWorldViewMatrix)
+{
+  memcpy (myWorldViewMatrix, theWorldViewMatrix, sizeof (Tmatrix3));
+  myInverseNeedUpdate = true;
+}
+
+// =======================================================================
+// function : WorldViewMatrix
+// purpose  : Returns current world-view matrix
+// =======================================================================
+const Tmatrix3& OpenGl_WorldViewState::WorldViewMatrix() const
+{
+  return myWorldViewMatrix;
+}
+
+// =======================================================================
+// function : WorldViewMatrixInverse
+// purpose  : Returns inverse of current world-view matrix
+// =======================================================================
+const Tmatrix3& OpenGl_WorldViewState::WorldViewMatrixInverse() const
+{
+  if (!myInverseNeedUpdate)
+  {
+    return myWorldViewMatrix;
+  }
+
+  reinterpret_cast<const NCollection_Mat4<float>*> (*myWorldViewMatrix)->Inverted (
+                *(reinterpret_cast<NCollection_Mat4<float>*> (*myWorldViewMatrixInverse)));
+  return myWorldViewMatrixInverse;
+}
+
+// =======================================================================
+// function : OpenGl_LightSourceState
+// purpose  : Creates uninitialized state of light sources
+// =======================================================================
+OpenGl_LightSourceState::OpenGl_LightSourceState()
+: myLightSources (NULL)
+{
+  //
+}
+
+// =======================================================================
+// function : Set
+// purpose  : Sets new light sources
+// =======================================================================
+void OpenGl_LightSourceState::Set (const OpenGl_ListOfLight* theLightSources)
+{
+  myLightSources = theLightSources;
+}
+
+// =======================================================================
+// function : LightSources
+// purpose  : Returns current list of light sources
+// =======================================================================
+const OpenGl_ListOfLight* OpenGl_LightSourceState::LightSources() const
+{
+  return myLightSources;
+}
+
+// =======================================================================
+// function : OpenGl_MaterialState
+// purpose  : Creates uninitialized material state
+// =======================================================================
+OpenGl_MaterialState::OpenGl_MaterialState (const OpenGl_Element* theAspect)
+: myAspect (theAspect)
+{
+  //
+}
+
+// =======================================================================
+// function : Set
+// purpose  : Sets new material aspect
+// =======================================================================
+void OpenGl_MaterialState::Set (const OpenGl_Element* theAspect)
+{
+  myAspect = theAspect;
+}
+
+// =======================================================================
+// function : Aspect
+// purpose  : Returns material aspect
+// =======================================================================
+const OpenGl_Element* OpenGl_MaterialState::Aspect() const
+{
+  return myAspect;
+}
+
+// =======================================================================
+// function : OpenGl_ClippingState
+// purpose  : Creates new clipping state
+// =======================================================================
+OpenGl_ClippingState::OpenGl_ClippingState()
+{
+  //
+}
diff --git a/src/OpenGl/OpenGl_ShaderStates.hxx b/src/OpenGl/OpenGl_ShaderStates.hxx
new file mode 100644 (file)
index 0000000..60731ff
--- /dev/null
@@ -0,0 +1,178 @@
+// Created on: 2013-10-02
+// Created by: Denis BOGOLEPOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_State_HeaderFile
+#define _OpenGl_State_HeaderFile
+
+#include <Graphic3d_SetOfHClipPlane.hxx>
+
+#include <InterfaceGraphic_tgl_all.hxx>
+
+#include <OpenGl_Element.hxx>
+#include <OpenGl_Light.hxx>
+
+//! Defines interface for OpenGL state.
+class OpenGl_StateInterface
+{
+public:
+
+  //! Creates new OCCT state.
+  OpenGl_StateInterface();
+
+  //! Returns current state index.
+  Standard_Size Index() const;
+
+  //! Updates current state.
+  void Update();
+
+  //! Reverts current state.
+  void Revert();
+
+protected:
+
+  Standard_Size myIndex; //!< Current state index
+
+};
+
+//! Defines state of OCCT projection transformation.
+class OpenGl_ProjectionState : public OpenGl_StateInterface
+{
+public:
+
+  //! Creates uninitialized projection state.
+  OpenGl_ProjectionState();
+
+  //! Sets new projection matrix.
+  void Set (const Tmatrix3& theProjectionMatrix);
+
+  //! Returns current projection matrix.
+  const Tmatrix3& ProjectionMatrix() const;
+
+  //! Returns inverse of current projection matrix.
+  const Tmatrix3& ProjectionMatrixInverse() const;
+
+private:
+
+  Tmatrix3         myProjectionMatrix;        //!< OCCT projection matrix
+  mutable Tmatrix3 myProjectionMatrixInverse; //!< Inverse of OCCT projection matrix
+  bool             myInverseNeedUpdate;       //!< Is inversed matrix outdated?
+
+};
+
+//! Defines state of OCCT model-world transformation.
+class OpenGl_ModelWorldState : public OpenGl_StateInterface
+{
+public:
+
+  //! Creates uninitialized model-world state.
+  OpenGl_ModelWorldState();
+
+  //! Sets new model-world matrix.
+  void Set (const Tmatrix3& theModelWorldMatrix);
+
+  //! Returns current model-world matrix.
+  const Tmatrix3& ModelWorldMatrix() const;
+
+  //! Returns inverse of current model-world matrix.
+  const Tmatrix3& ModelWorldMatrixInverse() const;
+
+private:
+
+  Tmatrix3         myModelWorldMatrix;        //!< OCCT model-world matrix
+  mutable Tmatrix3 myModelWorldMatrixInverse; //!< Inverse of OCCT model-world matrix
+  bool             myInverseNeedUpdate;       //!< Is inversed matrix outdated?
+  
+};
+
+//! Defines state of OCCT world-view transformation.
+class OpenGl_WorldViewState : public OpenGl_StateInterface
+{
+public:
+
+  //! Creates uninitialized world-view state.
+  OpenGl_WorldViewState();
+  
+  //! Sets new world-view matrix.
+  void Set (const Tmatrix3& theWorldViewMatrix);
+
+  //! Returns current world-view matrix.
+  const Tmatrix3& WorldViewMatrix() const;
+
+  //! Returns inverse of current world-view matrix.
+  const Tmatrix3& WorldViewMatrixInverse() const;
+
+private:
+
+  Tmatrix3         myWorldViewMatrix;        //!< OCCT world-view matrix
+  mutable Tmatrix3 myWorldViewMatrixInverse; //!< Inverse of OCCT world-view matrix
+  bool             myInverseNeedUpdate;      //!< Is inversed matrix outdated?
+
+};
+
+//! Defines state of OCCT light sources.
+class OpenGl_LightSourceState : public OpenGl_StateInterface
+{
+public:
+
+  //! Creates uninitialized state of light sources.
+  OpenGl_LightSourceState();
+
+  //! Sets new light sources.
+  void Set (const OpenGl_ListOfLight* theLightSources);
+
+  //! Returns current list of light sources.
+  const OpenGl_ListOfLight* LightSources() const;
+
+private:
+
+  const OpenGl_ListOfLight* myLightSources; //!< List of OCCT light sources
+
+};
+
+//! Defines generic state of OCCT material properties.
+class OpenGl_MaterialState : public OpenGl_StateInterface
+{
+public:
+
+  //! Creates new material state.
+  OpenGl_MaterialState (const OpenGl_Element* theAspect = NULL);
+  
+  //! Sets new material aspect.
+  void Set (const OpenGl_Element* theAspect);
+
+  //! Returns material aspect.
+  const OpenGl_Element* Aspect() const;
+
+private:
+
+  const OpenGl_Element* myAspect; //!< OCCT material aspect
+
+};
+
+//! Defines generic state of OCCT clipping state.
+class OpenGl_ClippingState : public OpenGl_StateInterface
+{
+public:
+
+  //! Creates new clipping state.
+  OpenGl_ClippingState();
+
+};
+
+#endif // _OpenGl_State_HeaderFile
index 6bcd5bb..5f9c9d7 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-#include <OpenGl_GlCore11.hxx>
-
-#include <OpenGl_Structure.hxx>
 
-#include <OpenGl_Workspace.hxx>
-#include <OpenGl_Vec.hxx>
-#include <OpenGl_View.hxx>
 #include <OpenGl_CappingAlgo.hxx>
 #include <OpenGl_Context.hxx>
+#include <OpenGl_GlCore11.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
+#include <OpenGl_Structure.hxx>
 #include <OpenGl_telem_util.hxx>
+#include <OpenGl_Vec.hxx>
+#include <OpenGl_View.hxx>
+#include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_SetOfHClipPlane_Handle.hxx>
 
@@ -398,6 +399,8 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   // Is rendering in ADD or IMMEDIATE mode?
   const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
 
+  const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
+
   // Apply local transformation
   GLint matrix_mode = 0;
   const OpenGl_Matrix *local_trsf = NULL;
@@ -405,20 +408,34 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   {
     if (isImmediate)
     {
-      float mat16[16];
-      call_util_transpose_mat (mat16, myTransformation->mat);
+      Tmatrix3 aModelWorld;
+      call_util_transpose_mat (*aModelWorld, myTransformation->mat);
       glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
+
+      if (!aCtx->ShaderManager()->IsEmpty())
+      {
+        Tmatrix3 aWorldView;
+        glGetFloatv (GL_MODELVIEW_MATRIX, *aWorldView);
+
+        Tmatrix3 aProjection;
+        glGetFloatv (GL_PROJECTION_MATRIX, *aProjection);
+
+        aCtx->ShaderManager()->UpdateModelWorldStateTo (aModelWorld);
+        aCtx->ShaderManager()->UpdateWorldViewStateTo (aWorldView);
+        aCtx->ShaderManager()->UpdateProjectionStateTo (aProjection);
+      }
+
       glMatrixMode (GL_MODELVIEW);
       glPushMatrix ();
       glScalef (1.F, 1.F, 1.F);
-      glMultMatrixf (mat16);
+      glMultMatrixf (*aModelWorld);
     }
     else
     {
       glMatrixMode (GL_MODELVIEW);
       glPushMatrix();
 
-      local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
+      local_trsf = AWorkspace->SetStructureMatrix (myTransformation);
     }
   }
 
@@ -426,7 +443,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
   if ( myTransPers && myTransPers->mode != 0 )
   {
-    trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
+    trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers);
   }
 
   // Apply aspects
@@ -491,6 +508,12 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   {
     // add planes at loaded view matrix state
     aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
+
+    // Set OCCT state uniform variables
+    if (!aContext->ShaderManager()->IsEmpty())
+    {
+      aContext->ShaderManager()->UpdateClippingState();
+    }
   }
 
   // Render groups
@@ -511,6 +534,12 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
   {
     aContext->ChangeClipping().Remove (*aUserPlanes);
+
+    // Set OCCT state uniform variables
+    if (!aContext->ShaderManager()->IsEmpty())
+    {
+      aContext->ShaderManager()->RevertClippingState();
+    }
   }
 
   // Restore highlight color
@@ -525,7 +554,7 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   // Restore transform persistence
   if ( myTransPers && myTransPers->mode != 0 )
   {
-    AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
+    AWorkspace->ActiveView()->BeginTransformPersistence (aContext, trans_pers);
   }
 
   // Restore local transformation
@@ -535,10 +564,17 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
     {
       glPopMatrix ();
       glMatrixMode (matrix_mode);
+
+      Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
+                                    { 0.f, 1.f, 0.f, 0.f },
+                                    { 0.f, 0.f, 1.f, 0.f },
+                                    { 0.f, 0.f, 0.f, 1.f } };
+
+      aContext->ShaderManager()->RevertModelWorldStateTo (aModelWorldState);
     }
     else
     {
-      AWorkspace->SetStructureMatrix(local_trsf);
+      AWorkspace->SetStructureMatrix (local_trsf, true);
 
       glMatrixMode (GL_MODELVIEW);
       glPopMatrix();
index 47862bb..8d49896 100644 (file)
@@ -54,7 +54,7 @@ public:
   void SetAspectText   (const CALL_DEF_CONTEXTTEXT &theAspect);
 
   void SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
-                        const CALL_DEF_BOUNDBOX&      theBoundBox);
+                        const CALL_DEF_BOUNDBOX& theBoundBox);
 
   void ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx);
 
index 3520479..5d78def 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-#include <OpenGl_GlCore11.hxx>
-#include <OpenGl_Text.hxx>
-
 #include <OpenGl_AspectText.hxx>
+#include <OpenGl_GlCore11.hxx>
 #include <OpenGl_GraphicDriver.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
+#include <OpenGl_ShaderStates.hxx>
+#include <OpenGl_Text.hxx>
 #include <OpenGl_Workspace.hxx>
 
 #include <Font_FontMgr.hxx>
@@ -385,11 +387,34 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
   const OpenGl_AspectText* aTextAspect = theWorkspace->AspectText (Standard_True);
   const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
 
+  const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+
+  if (aCtx->IsGlGreaterEqual (2, 0))
+  {
+    Handle(OpenGl_ShaderProgram) aProgram = aTextAspect->ShaderProgramRes (theWorkspace);
+
+    if (!aProgram.IsNull())
+    {
+      aProgram->BindWithVariables (aCtx);
+
+      const OpenGl_MaterialState* aMaterialState = aCtx->ShaderManager()->MaterialState (aProgram);
+      
+      if (aMaterialState == NULL || aMaterialState->Aspect() != aTextAspect)
+        aCtx->ShaderManager()->UpdateMaterialStateTo (aProgram, aTextAspect);
+      
+      aCtx->ShaderManager()->PushState (aProgram);
+    }
+    else
+    {
+      OpenGl_ShaderProgram::Unbind (aCtx);
+    }
+  }
+
   // use highlight color or colors from aspect
   if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
   {
     render (theWorkspace->PrinterContext(),
-            theWorkspace->GetGlContext(),
+            aCtx,
             *aTextAspect,
             *theWorkspace->HighlightColor,
             *theWorkspace->HighlightColor);
@@ -397,7 +422,7 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
   else
   {
     render (theWorkspace->PrinterContext(),
-            theWorkspace->GetGlContext(),
+            aCtx,
             *aTextAspect,
             aTextAspect->Color(),
             aTextAspect->SubtitleColor());
index 36ca3bb..82a295b 100644 (file)
@@ -50,7 +50,7 @@ namespace
   }
 
   //! Auxiliary function to translate rectangles in horizontal direction.
-  inline void moveX (NCollection_Vector<OpenGl_Font::Tile>& theRects,
+  /*inline void moveX (NCollection_Vector<OpenGl_Font::Tile>& theRects,
                      const Standard_ShortReal               theMoveVec,
                      Standard_Integer                       theCharLower,
                      const Standard_Integer                 theCharUpper)
@@ -61,7 +61,7 @@ namespace
       aRect.Left  += theMoveVec;
       aRect.Right += theMoveVec;
     }
-  }
+  }*/
 
   //! Auxiliary function to translate rectangles in vertical direction.
   inline void moveY (NCollection_Vector<OpenGl_Font::Tile>& theRects,
index e3498f9..de86dea 100644 (file)
@@ -617,6 +617,8 @@ void OpenGl_Trihedron::Release (const Handle(OpenGl_Context)& theCtx)
   myLabelX.Release (theCtx);
   myLabelY.Release (theCtx);
   myLabelZ.Release (theCtx);
+  myAspectLine.Release (theCtx);
+  myAspectText.Release (theCtx);
 }
 
 /*----------------------------------------------------------------------*/
@@ -648,7 +650,7 @@ void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) con
   const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
 
   /* affichage du Triedre Non Zoomable */
-  theWorkspace->ActiveView()->EndTransformPersistence();
+  theWorkspace->ActiveView()->EndTransformPersistence (theWorkspace->GetGlContext());
 
   if (myIsWireframe)
   {
index d659fe3..9eeb62d 100644 (file)
 
 #include <NCollection_Vec4.hxx>
 
+typedef NCollection_Vec2<int> OpenGl_Vec2i;
+typedef NCollection_Vec3<int> OpenGl_Vec3i;
+typedef NCollection_Vec4<int> OpenGl_Vec4i;
+
+typedef NCollection_Vec2<char> OpenGl_Vec2b;
+typedef NCollection_Vec3<char> OpenGl_Vec3b;
+typedef NCollection_Vec4<char> OpenGl_Vec4b;
+
+typedef NCollection_Vec2<unsigned int> OpenGl_Vec2u;
+typedef NCollection_Vec3<unsigned int> OpenGl_Vec3u;
+typedef NCollection_Vec4<unsigned int> OpenGl_Vec4u;
+
+typedef NCollection_Vec2<unsigned char> OpenGl_Vec2ub;
+typedef NCollection_Vec3<unsigned char> OpenGl_Vec3ub;
+typedef NCollection_Vec4<unsigned char> OpenGl_Vec4ub;
+
 typedef NCollection_Vec2<float> OpenGl_Vec2;
 typedef NCollection_Vec3<float> OpenGl_Vec3;
 typedef NCollection_Vec4<float> OpenGl_Vec4;
 
+typedef NCollection_Vec2<double> OpenGl_Vec2d;
+typedef NCollection_Vec3<double> OpenGl_Vec3d;
+typedef NCollection_Vec4<double> OpenGl_Vec4d;
+
 #endif // _OpenGl_Vec_H__
index cb53c90..32e4b2d 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-#include <OpenGl_GlCore11.hxx>
+#include <NCollection_Mat4.hxx>
 
-#include <OpenGl_View.hxx>
 #include <OpenGl_Context.hxx>
-#include <OpenGl_Workspace.hxx>
 #include <OpenGl_Display.hxx>
-
+#include <OpenGl_GlCore11.hxx>
+#include <OpenGl_GraduatedTrihedron.hxx>
+#include <OpenGl_ShaderManager.hxx>
 #include <OpenGl_Texture.hxx>
 #include <OpenGl_Trihedron.hxx>
-#include <OpenGl_GraduatedTrihedron.hxx>
-
 #include <OpenGl_transform_persistence.hxx>
+#include <OpenGl_View.hxx>
+#include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_TextureEnv.hxx>
 
@@ -103,7 +103,10 @@ OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
   myIntShadingMethod(TEL_SM_GOURAUD),
   myAntiAliasing(Standard_False),
   myTransPers(&myDefaultTransPers),
-  myIsTransPers(Standard_False)  
+  myIsTransPers(Standard_False),
+  myOrientationChanged (Standard_True),
+  myViewMappingChanged (Standard_True),
+  myLightSourcesChanged (Standard_True)
 {
   // Initialize matrices
   memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
@@ -133,7 +136,7 @@ void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
 {
   OpenGl_Element::Destroy (theCtx, myTrihedron);
   OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
-   
+
   if (!myTextureEnv.IsNull())
   {
     theCtx->DelayedRelease (myTextureEnv);
@@ -242,6 +245,8 @@ void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
 
     myLights.Append(rep);
   }
+
+  myLightSourcesChanged = Standard_True;
 }
 
 /*----------------------------------------------------------------------*/
@@ -353,6 +358,8 @@ void OpenGl_View::SetMapping (const Handle(OpenGl_Display)& theGlDisplay,
 
   if (!err_ind)
     myExtra.map = Map;
+
+  myViewMappingChanged = Standard_True;
 }
 
 /*----------------------------------------------------------------------*/
@@ -414,6 +421,8 @@ void OpenGl_View::SetOrientation (const Graphic3d_CView& theCView)
     myExtra.scaleFactors[1] = ScaleFactors[1],
     myExtra.scaleFactors[2] = ScaleFactors[2];
   }
+
+  myOrientationChanged = Standard_True;
 }
 
 /*----------------------------------------------------------------------*/
@@ -498,7 +507,7 @@ void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
 /*----------------------------------------------------------------------*/
 
 //transform_persistence_end
-void OpenGl_View::EndTransformPersistence()
+void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
 {
   if (myIsTransPers)
   {
@@ -508,19 +517,33 @@ void OpenGl_View::EndTransformPersistence()
     glMatrixMode (GL_MODELVIEW);
     glPopMatrix();
     myIsTransPers = Standard_False;
+
+    // Note: the approach of accessing OpenGl matrices is used now since the matrix
+    // manipulation are made with help of OpenGl methods. This might be replaced by
+    // direct computation of matrices by OCC subroutines.
+    Tmatrix3 aResultWorldView;
+    glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
+
+    Tmatrix3 aResultProjection;
+    glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
+
+    // Set OCCT state uniform variables
+    theCtx->ShaderManager()->RevertWorldViewStateTo (aResultWorldView);
+    theCtx->ShaderManager()->RevertProjectionStateTo (aResultProjection);
   }
 }
 
 /*----------------------------------------------------------------------*/
 
 //transform_persistence_begin
-const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const TEL_TRANSFORM_PERSISTENCE* theTransPers)
+const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
+                                                                         const TEL_TRANSFORM_PERSISTENCE* theTransPers)
 {
   const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
   myTransPers = theTransPers;
   if (theTransPers->mode == 0)
   {
-    EndTransformPersistence();
+    EndTransformPersistence (theCtx);
     return aTransPersPrev;
   }
 
@@ -659,5 +682,18 @@ const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const T
     glTranslated (aMoveX, aMoveY, aMoveZ);
   }
 
+  // Note: the approach of accessing OpenGl matrices is used now since the matrix
+  // manipulation are made with help of OpenGl methods. This might be replaced by
+  // direct computation of matrices by OCC subroutines.
+  Tmatrix3 aResultWorldView;
+  glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
+
+  Tmatrix3 aResultProjection;
+  glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
+
+  // Set OCCT state uniform variables
+  theCtx->ShaderManager()->UpdateWorldViewStateTo (aResultWorldView);
+  theCtx->ShaderManager()->UpdateProjectionStateTo (aResultProjection);
+
   return aTransPersPrev;
 }
index 43d3a6b..fb1636d 100644 (file)
@@ -152,8 +152,9 @@ class OpenGl_View : public MMgt_TShared
 
   Standard_Integer Backfacing () const { return myBackfacing; }
 
-  const TEL_TRANSFORM_PERSISTENCE * BeginTransformPersistence ( const TEL_TRANSFORM_PERSISTENCE *ATransPers );
-  void EndTransformPersistence ();
+  const TEL_TRANSFORM_PERSISTENCE * BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
+                                                               const TEL_TRANSFORM_PERSISTENCE *theTransPers);
+  void EndTransformPersistence (const Handle(OpenGl_Context)& theCtx);
 
   //! Add structure to display list with specified priority.
   //! The structure will be added to associated with it z layer.
@@ -196,7 +197,6 @@ public:
 
   void RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace);
   void RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
-                      const Handle(OpenGl_Workspace)&      theWorkspace,
                       const Graphic3d_CView&               theCView,
                       const Aspect_CLayer2d&               theCLayer);
 
@@ -245,6 +245,11 @@ public:
   const TEL_TRANSFORM_PERSISTENCE *myTransPers;
   Standard_Boolean myIsTransPers;
 
+  //! Modification flags.
+  Standard_Boolean myOrientationChanged;
+  Standard_Boolean myViewMappingChanged;
+  Standard_Boolean myLightSourcesChanged;
+
  public:
   DEFINE_STANDARD_ALLOC
 };
index 363b225..7200c3a 100644 (file)
 #include <Image_AlienPixMap.hxx>
 #include <Visual3d_Layer.hxx>
 
+#include <NCollection_Mat4.hxx>
+
 #include <OpenGl_AspectLine.hxx>
+#include <OpenGl_Context.hxx>
 #include <OpenGl_Display.hxx>
+#include <OpenGl_Matrix.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_View.hxx>
 #include <OpenGl_Trihedron.hxx>
 #include <OpenGl_GraduatedTrihedron.hxx>
 #include <OpenGl_PrinterContext.hxx>
+#include <OpenGl_ShaderManager.hxx>
+#include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_Structure.hxx>
 
 #define EPSI 0.0001
@@ -42,7 +48,7 @@ static const GLfloat default_sptdir[3] = { 0.F, 0.F, -1.F };
 static const GLfloat default_sptexpo = 0.F;
 static const GLfloat default_sptcutoff = 180.F;
 
-extern void InitLayerProp (const int AListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
+extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
 
 /*----------------------------------------------------------------------*/
 
@@ -658,6 +664,39 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
     }
   }
 
+  // Set OCCT state uniform variables
+
+  if (!aContext->ShaderManager()->IsEmpty())
+  {
+    if (myLightSourcesChanged)
+    {
+      aContext->ShaderManager()->UpdateLightSourceStateTo (&myLights);
+      myLightSourcesChanged = Standard_False;
+    }
+
+    if (myViewMappingChanged)
+    {
+      aContext->ShaderManager()->UpdateProjectionStateTo (myMappingMatrix);
+      myViewMappingChanged = Standard_False;
+    }
+
+    if (myOrientationChanged)
+    {
+      aContext->ShaderManager()->UpdateWorldViewStateTo (myOrientationMatrix);
+      myOrientationChanged = Standard_False;
+    }
+
+    if (aContext->ShaderManager()->ModelWorldState().Index() == 0)
+    {
+      Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
+                                    { 0.f, 1.f, 0.f, 0.f },
+                                    { 0.f, 0.f, 1.f, 0.f },
+                                    { 0.f, 0.f, 0.f, 1.f } };
+
+      aContext->ShaderManager()->UpdateModelWorldStateTo (aModelWorldState);
+    }
+  }
+
   /////////////////////////////////////////////////////////////////////////////
   // Step 1: Prepare for redraw
 
@@ -858,7 +897,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
 
   /////////////////////////////////////////////////////////////////////////////
   // Step 2: Draw underlayer
-  RedrawLayer2d (thePrintContext, AWorkspace, ACView, ACUnderLayer);
+  RedrawLayer2d (thePrintContext, ACView, ACUnderLayer);
 
   /////////////////////////////////////////////////////////////////////////////
   // Step 3: Redraw main plane
@@ -1051,6 +1090,11 @@ D = -[Px,Py,Pz] dot |Nx|
         aContext->ChangeClipping().AddWorld (aUserPlanes);
       }
     }
+    
+    if (!aContext->ShaderManager()->IsEmpty())
+    {
+      aContext->ShaderManager()->UpdateClippingState();
+    }
   }
 
   // Apply AntiAliasing
@@ -1138,6 +1182,12 @@ D = -[Px,Py,Pz] dot |Nx|
 
   aContext->ChangeClipping().RemoveAll();
 
+  if (!aContext->ShaderManager()->IsEmpty())
+  {
+    aContext->ShaderManager()->ResetMaterialStates();
+    aContext->ShaderManager()->RevertClippingState();
+  }
+
   // display global trihedron
   if (myTrihedron != NULL)
   {
@@ -1165,7 +1215,7 @@ D = -[Px,Py,Pz] dot |Nx|
   const int aMode = 0;
   AWorkspace->DisplayCallback (ACView, (aMode | OCC_PRE_OVERLAY));
 
-  RedrawLayer2d (thePrintContext, AWorkspace, ACView, ACOverLayer);
+  RedrawLayer2d (thePrintContext, ACView, ACOverLayer);
 
   AWorkspace->DisplayCallback (ACView, aMode);
 
@@ -1225,7 +1275,6 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
 
 //call_togl_redraw_layer2d
 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
-                                 const Handle(OpenGl_Workspace)&      /*AWorkspace*/,
                                  const Graphic3d_CView&               ACView,
                                  const Aspect_CLayer2d&               ACLayer)
 {
@@ -1336,9 +1385,9 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
   //calling dynamic render of LayerItems
   if ( ACLayer.ptrLayer->layerData )
   {
-    InitLayerProp(ACLayer.ptrLayer->listIndex);
+    InitLayerProp (ACLayer.ptrLayer->listIndex);
     ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
-    InitLayerProp(0);
+    InitLayerProp (0);
   }
 
   glPopAttrib ();
index 5caff56..c17a006 100644 (file)
@@ -143,7 +143,7 @@ public:
   const TEL_COLOUR* HighlightColor;
 
   const OpenGl_Matrix* SetViewMatrix (const OpenGl_Matrix* );
-  const OpenGl_Matrix* SetStructureMatrix (const OpenGl_Matrix* );
+  const OpenGl_Matrix* SetStructureMatrix (const OpenGl_Matrix*, bool aRevert = false);
 
   const OpenGl_AspectLine*   SetAspectLine   (const OpenGl_AspectLine*   theAspect);
   const OpenGl_AspectFace*   SetAspectFace   (const OpenGl_AspectFace*   theAspect);
index c537078..df02474 100644 (file)
@@ -26,6 +26,8 @@
 #include <OpenGl_AspectFace.hxx>
 #include <OpenGl_AspectMarker.hxx>
 #include <OpenGl_AspectText.hxx>
+#include <OpenGl_Context.hxx>
+#include <OpenGl_ShaderManager.hxx>
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -441,7 +443,7 @@ const OpenGl_Matrix * OpenGl_Workspace::SetViewMatrix(const OpenGl_Matrix *AMatr
 
 /*----------------------------------------------------------------------*/
 
-const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix(const OpenGl_Matrix *AMatrix)
+const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix (const OpenGl_Matrix *AMatrix, bool aRevert)
 {
   const OpenGl_Matrix *StructureMatrix_old = StructureMatrix_applied;
   StructureMatrix_applied = AMatrix;
@@ -454,6 +456,14 @@ const OpenGl_Matrix * OpenGl_Workspace::SetStructureMatrix(const OpenGl_Matrix *
   OpenGl_Multiplymat3 (&rmat, &lmat, ViewMatrix_applied);
   glLoadMatrixf ((const GLfloat* )rmat.mat);
 
+  if (!myGlContext->ShaderManager()->IsEmpty())
+  {
+    if (aRevert)
+      myGlContext->ShaderManager()->UpdateModelWorldStateTo (lmat.mat);
+    else
+      myGlContext->ShaderManager()->RevertModelWorldStateTo (lmat.mat);
+  }
+
   return StructureMatrix_old;
 }
 
diff --git a/src/Shaders/Declarations.glsl b/src/Shaders/Declarations.glsl
new file mode 100644 (file)
index 0000000..88046a8
--- /dev/null
@@ -0,0 +1,192 @@
+#define _OCC_MAX_LIGHTS_ 8
+
+#define _OCC_MAX_CLIP_PLANES_ 8
+
+
+//! OCCT ambient light source.
+const int occAmbientLight = 0;
+
+//! OCCT directional light source.
+const int occDirectLight = 1;
+
+//! OCCT isotropic point light source.
+const int occPointLight = 2;
+
+//! OCCT spot light source.
+const int occSpotLight = 3;
+
+
+//! Parameters of OCCT light source.
+struct occLightSource
+{
+  //! Type of light source.
+  int Type;
+  
+  //! Is light a headlight?
+  int Head;
+  
+  //! Ambient intensity.
+  vec3 Ambient;
+  
+  //! Diffuse intensity.
+  vec3 Diffuse;
+  
+  //! Specular intensity.
+  vec3 Specular;
+  
+  //! Position of light source.
+  vec3 Position;
+  
+  //! Direction of the spot light.
+  vec3 SpotDirection;
+    
+  //! Maximum spread angle of the spot light (in radians).
+  float SpotCutoff;
+  
+  //! Attenuation of the spot light intensity (from 0 to 1).
+  float SpotExponent;
+
+  //! Const attenuation factor of positional light source.
+  float ConstAttenuation;
+  
+  //! Linear attenuation factor of positional light source.
+  float LinearAttenuation;
+};
+
+//! Parameters of OCCT material.
+struct occMaterialParams
+{
+  //! Emission color.
+  vec4 Emission;
+  
+  //! Ambient reflection.
+  vec4 Ambient;
+  
+  //! Diffuse reflection.
+  vec4 Diffuse;
+  
+  //! Specular reflection.
+  vec4 Specular;
+  
+  //! Specular exponent.
+  float Shininess;
+  
+  //! Transparency coefficient.
+  float Transparency;
+};
+
+//! OCCT view-space clipping plane.
+const int occEquationCoordsView = 0;
+
+//! OCCT world-space clipping plane.
+const int occEquationCoordsWorld = 1;
+
+//! Parameters of OCCT clipping plane.
+struct occClipPlane
+{
+  //! Plane equation.
+  vec4 Equation;
+
+  //! Equation space.
+  int Space;
+};
+
+#ifdef VERTEX_SHADER
+
+/////////////////////////////////////////////////////////////////////
+// OCCT vertex attributes
+
+// Note: At the moment, we just 'rename' the default OpenGL
+// vertex attributes from compatibility profile. In the next
+// release old functionality will be removed from shader API.
+
+//! Vertex color.
+#define occColor gl_Color
+
+//! Normal coordinates.
+#define occNormal gl_Normal
+
+//! Vertex coordinates.
+#define occVertex gl_Vertex
+
+//! Texture coordinates.
+#define occTexCoord gl_MultiTexCoord0
+
+#endif
+
+/////////////////////////////////////////////////////////////////////
+// OCCT matrix state
+
+//! World-view matrix.
+uniform mat4 occWorldViewMatrix;
+
+//! Projection matrix.
+uniform mat4 occProjectionMatrix;
+
+//! Model-world matrix.
+uniform mat4 occModelWorldMatrix;
+
+//-------------------------------------------------------
+
+//! Inverse of the world-view matrix.
+uniform mat4 occWorldViewMatrixInverse;
+
+//! Inverse of the projection matrix.
+uniform mat4 occProjectionMatrixInverse;
+
+//! Inverse of the model-world matrix.
+uniform mat4 occModelWorldMatrixInverse;
+
+//-------------------------------------------------------
+
+//! Transpose of the world-view matrix.
+uniform mat4 occWorldViewMatrixTranspose;
+
+//! Transpose of the projection matrix.
+uniform mat4 occProjectionMatrixTranspose;
+
+//! Transpose of the model-world matrix.
+uniform mat4 occModelWorldMatrixTranspose;
+
+//-------------------------------------------------------
+
+//! Transpose of the inverse of the world-view matrix.
+uniform mat4 occWorldViewMatrixInverseTranspose;
+
+//! Transpose of the inverse of the projection matrix.
+uniform mat4 occProjectionMatrixInverseTranspose;
+
+//! Transpose of the inverse of the model-world matrix.
+uniform mat4 occModelWorldMatrixInverseTranspose;
+
+/////////////////////////////////////////////////////////////////////
+// OCCT light source state
+
+//! Array of OCCT light sources.
+uniform occLightSource occLightSources[_OCC_MAX_LIGHTS_];
+
+//! Total number of OCCT light sources.
+uniform int occLightSourcesCount;
+
+/////////////////////////////////////////////////////////////////////
+// OCCT material state
+
+//! Parameters of OCCT back material.
+uniform occMaterialParams occBackMaterial;
+
+//! Parameters of OCCT front material.
+uniform occMaterialParams occFrontMaterial;
+
+//! Are front and back faces distinguished?
+uniform int occDistinguishingMode;
+
+//! Is texture enabled?
+uniform int occTextureEnable;
+
+//! Current active sampler.
+uniform sampler2D occActiveSampler;
+
+/////////////////////////////////////////////////////////////////////
+// OCCT clipping planes state
+
+uniform occClipPlane occClipPlanes[_OCC_MAX_CLIP_PLANES_];
index ac8fda7..065fd97 100755 (executable)
@@ -56,6 +56,8 @@
 #include <Graphic3d_AspectFillArea3d.hxx>
 #include <Graphic3d_TextureRoot.hxx>
 #include <Graphic3d_AspectLine3d.hxx>
+#include <Graphic3d_ShaderObject.hxx>
+#include <Graphic3d_ShaderProgram.hxx>
 #include <Image_AlienPixMap.hxx>
 #include <Prs3d_ShadingAspect.hxx>
 #include <Prs3d_IsoAspect.hxx>
@@ -1898,6 +1900,64 @@ Standard_Integer VTexture (Draw_Interpretor& di,Standard_Integer argc, const cha
 }
 
 //==============================================================================
+//function : VShaderProg
+//purpose  : Sets the pair of vertex and fragment shaders for the object
+//==============================================================================
+static Standard_Integer VShaderProg (Draw_Interpretor& /*theDI*/,
+                                     Standard_Integer  theArgNb,
+                                     const char**      theArgVec)
+{
+  Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
+  if (anAISContext.IsNull())
+  {
+    std::cerr << "Use 'vinit' command before " << theArgVec[0] << "\n";
+    return 1;
+  }
+
+  if (theArgNb < 3)
+  {
+    std::cerr << theArgVec[0] <<" syntax error: lack of arguments - Type 'help vshaderprog\n";
+    return 1;
+  }
+
+  const TCollection_AsciiString aShapeName = theArgVec[1];
+  if (!GetMapOfAIS().IsBound2 (aShapeName))
+  {
+    std::cerr << theArgVec[0] << ": Use 'vdisplay' before\n";
+    return 1;
+  }
+
+  Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aShapeName));
+  if (anIO.IsNull())
+  {
+    std::cerr << "Shape " << aShapeName.ToCString() << " does not exist\n";
+    return 1;
+  }
+
+  Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
+  const TCollection_AsciiString aVertexSource (theArgVec[2]);
+  if (!aVertexSource.IsEmpty() && !OSD_File(aVertexSource).Exists())
+  {
+    std::cerr << "Non-existing vertex shader source\n";
+    return 1;
+  }
+
+  TCollection_AsciiString aFragmentSource (theArgVec[3]);
+  if (!aFragmentSource.IsEmpty() && !OSD_File(aFragmentSource).Exists())
+  {
+    std::cerr << "Non-existing fragment shader source\n";
+    return 1;
+  }
+
+  aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX,   aVertexSource));
+  aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aFragmentSource));
+  anIO->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
+
+  anAISContext->Redisplay (anIO);
+  return 0;
+}
+
+//==============================================================================
 //function : VDisplay2
 //author   : ege
 //purpose  : Display an object from its name
@@ -3281,6 +3341,10 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
                   or 'vtexture NameOfShape IdOfTexture' (0<=IdOfTexture<=20)' to use predefined  textures\n ",
                  __FILE__,VTexture,group);
 
+  theCommands.Add("vshaderprog",
+                 "'vshaderprog NameOfShape VertexShaderFile FragmentShaderFile'",
+      __FILE__,VShaderProg,group);
+
   theCommands.Add("vtexscale",
                  "'vtexscale  NameOfShape ScaleU ScaleV' \n \
                    or 'vtexscale NameOfShape ScaleUV' \n \