0023226: Extend OpenGl_Context to store map of shared GPU resources
authorkgv <kgv@opencascade.com>
Fri, 13 Jul 2012 11:51:16 +0000 (15:51 +0400)
committerkgv <kgv@opencascade.com>
Fri, 13 Jul 2012 11:51:16 +0000 (15:51 +0400)
OpenGl_Resource was slightly corrected and OpenGl_Element was extended
with Release method to manage GPU resources.

OpenGl_PrimitiveArray now uses new OpenGl_VertexBuffer class (requires OpenGL 1.5+).
Strange workarounds for feedback mode were removed.

OpenGl_Context now provides access to shared GPU resources
and manages resources queue for delayed release
(replaces functionality of removed OpenGl_ResourceCleaner).
Loaded GL_ARB_texture_buffer_object and GL_ARB_draw_instanced extensions.

Global maps of views, workspaces and structures
were moved to OpenGl_GraphicDriver members.
UserDrawCallback() function moved to OpenGl_GraphicDriver methods.

Aspect_GraphicCallbackStruct now holds handle of OpenGl_Context
instead of system-dependent pointers to GL context definition.

New classes NCollection_Vec2, NCollection_Vec3 and NCollection_Vec4
implements interface to low-level data (points, vertices, colors) in GLSL-style.
Removed EnableVBO argument from vdrawparray Draw Harness command
Corrected compilation errors
Fixed wrong argument in Index VBO initialization
Fixed several cases of incorrect memory management in TKV3d

Visual3d_ViewManager::Remove()
Destroy structures before last view removed for correct GPU resources management.

Graphic3d_Structure::GraphicClear()
Remove groups to avoid usage of dead OpenGl_Group pointers.

V3d_View::Remove()
Fixed mistake in #0000280 patch.
Small correction
Fixed OCC280 test command

Replace removed view within created one in ViewerTest EventManager.
ViewerTest, do not create unused 3D view

In current design NIS_View always created and used for both - NIS objects and AIS objects.

74 files changed:
src/Aspect/Aspect_GraphicCallbackProc.hxx
src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx
src/Graphic3d/Graphic3d_Structure.cxx
src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx
src/NCollection/FILES
src/NCollection/NCollection_Vec2.hxx [new file with mode: 0644]
src/NCollection/NCollection_Vec3.hxx [new file with mode: 0644]
src/NCollection/NCollection_Vec4.hxx [new file with mode: 0644]
src/OpenGl/FILES
src/OpenGl/OpenGl_ArbIns.hxx [copied from src/OpenGl/OpenGl_Callback.hxx with 68% similarity]
src/OpenGl/OpenGl_ArbTBO.hxx [moved from src/OpenGl/OpenGl_Callback.hxx with 68% similarity]
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_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_Element.hxx
src/OpenGl/OpenGl_GraphicDriver.cxx
src/OpenGl/OpenGl_GraphicDriver.hxx
src/OpenGl/OpenGl_GraphicDriver_3.cxx
src/OpenGl/OpenGl_GraphicDriver_4.cxx
src/OpenGl/OpenGl_GraphicDriver_7.cxx
src/OpenGl/OpenGl_GraphicDriver_713.cxx
src/OpenGl/OpenGl_GraphicDriver_9.cxx
src/OpenGl/OpenGl_Group.cxx
src/OpenGl/OpenGl_Group.hxx
src/OpenGl/OpenGl_IndexBuffer.cxx [moved from src/OpenGl/OpenGl_ResourceVBO.cxx with 54% similarity, mode: 0644]
src/OpenGl/OpenGl_IndexBuffer.hxx [moved from src/OpenGl/OpenGl_ResourceVBO.hxx with 53% similarity, mode: 0644]
src/OpenGl/OpenGl_Marker.cxx
src/OpenGl/OpenGl_Marker.hxx
src/OpenGl/OpenGl_MarkerSet.cxx
src/OpenGl/OpenGl_MarkerSet.hxx
src/OpenGl/OpenGl_Polygon.cxx
src/OpenGl/OpenGl_Polygon.hxx
src/OpenGl/OpenGl_Polyline.cxx
src/OpenGl/OpenGl_Polyline.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_PrimitiveArray.hxx
src/OpenGl/OpenGl_Resource.cxx
src/OpenGl/OpenGl_Resource.hxx
src/OpenGl/OpenGl_ResourceCleaner.cxx [deleted file]
src/OpenGl/OpenGl_ResourceCleaner.hxx [deleted file]
src/OpenGl/OpenGl_ResourceTexture.cxx
src/OpenGl/OpenGl_ResourceTexture.hxx
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_Structure.hxx
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_Text.hxx
src/OpenGl/OpenGl_TextureBox.cxx
src/OpenGl/OpenGl_TextureBox.hxx
src/OpenGl/OpenGl_TextureBufferArb.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_TextureBufferArb.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_VertexBuffer.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_VertexBuffer.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_VertexBufferEditor.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_Window.cxx
src/OpenGl/OpenGl_Window.hxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/OpenGl/OpenGl_Workspace_2.cxx
src/OpenGl/OpenGl_Workspace_4.cxx
src/QABugs/QABugs_17.cxx
src/V3d/V3d_View.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx
src/ViewerTest/ViewerTest_OpenGlCommands.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/Visual3d/Visual3d_ViewManager.cxx
src/VoxelClient/VoxelClient_VisDrawer.cxx
src/VoxelClient/VoxelClient_VisDrawer.h

index 225c1b9..898a486 100755 (executable)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-/*============================================================================*/
-/*==== Titre: Aspect_GraphicCallbackProc.hxx                                               */
-/*==== Role : The header file of primitive type "GraphicCallbackProc" from package        */
-/*==== "V3d"                                                           */
-/*==== Implementation:  This is a primitive type implemented with typedef     */
-/*============================================================================*/
-
 #ifndef _Aspect_GraphicCallbackProc_HeaderFile
 #define _Aspect_GraphicCallbackProc_HeaderFile
+
 #include <Aspect_Display.hxx>
 #include <Aspect_Drawable.hxx>
 #include <Aspect_RenderingContext.hxx>
+#include <Handle_Standard_Transient.hxx>
 
 // The flags below provide additional information to define the moment when
 // callback was invoked in redraw procedure. These flags are bitwise OR'ed
 // mask for all additional callbacks that invoked in process of redrawing
 #define OCC_REDRAW_ADDITIONAL_CALLBACKS ( OCC_PRE_REDRAW | OCC_PRE_OVERLAY )
 
- typedef struct {
-   int reason;
-   int wsID;
-   int viewID;
-   Aspect_Display display;
-   Aspect_Drawable window;
-   Aspect_RenderingContext gcontext;
- } Aspect_GraphicCallbackStruct;
+typedef struct
+{
+  int reason;
+  int wsID;
+  int viewID;
+  Handle(Standard_Transient) glContext;
+} Aspect_GraphicCallbackStruct;
 
- typedef int (*Aspect_GraphicCallbackProc)(
-    Aspect_Drawable    /* Window ID */,
-    void*              /* user data */, 
-    Aspect_GraphicCallbackStruct*  /* call data */ 
- );
+// Prototype for callback function to perform custom drawing within the same window and GL context.
+typedef int (*Aspect_GraphicCallbackProc) (Aspect_Drawable               theWindowID,
+                                           void*                         theUserData,
+                                           Aspect_GraphicCallbackStruct* theCallData);
 
-#if defined(__cplusplus) || defined(c_plusplus)
-/*==== Definition de Type ====================================================*/
-
-#include <Standard_Macro.hxx>
 class Handle(Standard_Type);
 const Handle(Standard_Type)& STANDARD_TYPE(Aspect_GraphicCallbackProc);
 
-/*============================================================================*/
-#endif
-
 #endif /* _Aspect_GraphicCallbackProc_HeaderFile */
index acafa5f..28cb2bc 100755 (executable)
@@ -27,9 +27,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-static Standard_Integer enableArray = 1;
-static Standard_Boolean interleavedArray = Standard_False;
-
 Graphic3d_ArrayOfPrimitives :: Graphic3d_ArrayOfPrimitives (
                         const Graphic3d_TypeOfPrimitiveArray aType,
                         const Standard_Integer maxVertexs,
@@ -99,14 +96,6 @@ Graphic3d_ArrayOfPrimitives :: Graphic3d_ArrayOfPrimitives (
   myPrimitiveArray->num_bounds    = 0;
   myPrimitiveArray->num_vertexs   = 0;
   myPrimitiveArray->num_edges     = 0;
-  myPrimitiveArray->VBOEnabled    = -1;
-  myPrimitiveArray->flagBufferVBO = -1;
-  myPrimitiveArray->contextId     = 0;
-
-  for( int i =0 ; i < VBOMaxType ; i++){
-    myPrimitiveArray->bufferVBO[i] = 0;
-  }
-
 }
 
 void Graphic3d_ArrayOfPrimitives::Destroy (  ){
@@ -159,40 +148,15 @@ void Graphic3d_ArrayOfPrimitives::Destroy (  ){
 }
 
 void Graphic3d_ArrayOfPrimitives::Enable() {
-  enableArray = 1;
+  ///
 }
 
 void Graphic3d_ArrayOfPrimitives::Disable() {
-  enableArray = -1;
+  ///
 }
 
 Standard_Boolean Graphic3d_ArrayOfPrimitives::IsEnable() {
-
-  if( enableArray == 0 ) {
-    OSD_Environment csf(TCollection_AsciiString("CSF_USE_ARRAY_OF_PRIMITIVES"));
-    TCollection_AsciiString value = csf.Value();
-    enableArray = -1;
-    if( value.Length() > 0 ) {
-      if( value.IsIntegerValue() ) {
-        enableArray = value.IntegerValue();
-        if( enableArray > 1 ) {
-          enableArray = 1;
-        } else interleavedArray = Standard_False;
-      }
-    }
-#if TRACE > 0
-    if( enableArray > 0 ) {
-      if( interleavedArray ) 
-        cout << " ! ENABLE to use Interleaved arrays of primitives" << endl;
-      else
-        cout << " ! ENABLE to use Single arrays of primitives" << endl;
-    } else
-      cout << " ! DISABLE to use arrays of primitives" << endl;
-#endif
-  }
-  if( enableArray > 0 ) return Standard_True;
-
-  return Standard_False;
+  return Standard_True;
 }
 
 Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
index 615e1f1..3eb05d8 100755 (executable)
@@ -232,13 +232,6 @@ void Graphic3d_Structure::Clear (const Standard_Boolean WithDestruction)
   MyCStructure.ContainsFacet = 0;
 
   // clean groups in graphics driver at first
-  if (WithDestruction)
-  {
-    // clean and empty each group
-    Standard_Integer Length = MyGroups.Length();
-    for (Standard_Integer aGrId = 1; aGrId <= Length; ++aGrId)
-      MyGroups.ChangeValue (aGrId)->Clear();
-  }
   GraphicClear (WithDestruction);
 
   // only then remove group references
@@ -722,31 +715,31 @@ Standard_Boolean Graphic3d_Structure::IsInfinite () const {
 
 }
 
-void Graphic3d_Structure::GraphicClear (const Standard_Boolean WithDestruction) {
+void Graphic3d_Structure::GraphicClear (const Standard_Boolean WithDestruction)
+{
+  // clean and empty each group
+  Standard_Integer Length = MyGroups.Length();
+  for (Standard_Integer aGrId = 1; aGrId <= Length; ++aGrId)
+  {
+    MyGroups.ChangeValue (aGrId)->Clear();
+  }
 
   if (WithDestruction)
+  {
     /*
-    * Dans ce cas l'appelant dans faire :
     * void Prs3d_Presentation::Clear () {
     *   Graphic3d_Structure::Clear ();
     *   myCurrentGroup = new Graphic3d_Group (this);
     * }
     */
-    MyGraphicDriver->ClearStructure (MyCStructure);
-  else {
-    /*
-    * Dans ce cas l'appelant dans faire :
-    * void Prs3d_Presentation::Clear () {
-    *   Graphic3d_Structure::Clear ();
-    *   // myCurrentGroup = new Graphic3d_Group (this);
-    * }
-    */
-    Standard_Integer Length = MyGroups.Length ();
+    while (!MyGroups.IsEmpty())
+    {
+      Handle(Graphic3d_Group) aGroup = MyGroups.First();
+      aGroup->Remove();
+    }
 
-    for (Standard_Integer i=1; i<=Length; i++)
-      (MyGroups.Value (i))->Clear ();
+    MyGraphicDriver->ClearStructure (MyCStructure);
   }
-
 }
 
 void Graphic3d_Structure::GraphicConnect (const Handle(Graphic3d_Structure)& ADaughter) {
index 68bf072..e8a690a 100755 (executable)
@@ -50,16 +50,6 @@ typedef enum {
   TelTriangleFansArrayType
 } TelPrimitivesArrayType;
 
-typedef enum 
-{
-  VBOEdges, 
-  VBOVertices, 
-  VBOVcolours, 
-  VBOVnormals, 
-  VBOVtexels,
-  VBOMaxType
-} VBODataType;
-
 typedef struct {
   TelPrimitivesArrayType type;                    /* Array type */
   Tint                   format;                  /* Array datas format */
@@ -75,17 +65,6 @@ typedef struct {
   tel_texture_coord      vtexels;                 /* Texture Coordinates */
   Tchar                 *edge_vis;                /* Edge visibility flag*/
   Tchar                 *keys;                    /* Vertex keys*/
-  Tuint                  bufferVBO[VBOMaxType];   /* VBO IDs for *edges, vertices, vcolours, vnormals, vtexels.
-                                                     default = -1. VBO - Vertex Buffer Object */
-  Tint                   flagBufferVBO;           /* this flag is responded for bufferVBO load status.
-                                                     -1 - Not Initial BufferVBO. Default mean.
-                                                      0 - Error by allocated memory in Graphic Device.
-                                                      Not Initial BufferVBO.
-                                                      1 - Initial BufferVBO */
-  Tint                   VBOEnabled;              /* -1 - it is not known VBO status
-                                                      0 - draw object without VBO
-                                                      1 - draw object with VBO */
-  Standard_Address       contextId;               /* remember context for VBO */
 } CALL_DEF_PARRAY;
 
 #endif /* _InterfaceGraphic_PrimitiveArray_header_file_ */
index 2a3509b..ea23893 100755 (executable)
@@ -80,3 +80,6 @@ NCollection_Haft.h
 NCollection_DefaultHasher.hxx
 NCollection_DefineAlloc.hxx
 
+NCollection_Vec2.hxx
+NCollection_Vec3.hxx
+NCollection_Vec4.hxx
diff --git a/src/NCollection/NCollection_Vec2.hxx b/src/NCollection/NCollection_Vec2.hxx
new file mode 100644 (file)
index 0000000..36814cb
--- /dev/null
@@ -0,0 +1,230 @@
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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 _NCollection_Vec2_H__
+#define _NCollection_Vec2_H__
+
+//! Auxiliary macros to define couple of similar access components as vector methods.
+//! @return 2 components by their names in specified order
+#define NCOLLECTION_VEC_COMPONENTS_2D(theX, theY) \
+  const NCollection_Vec2<Element_t> theX##theY##() const { return NCollection_Vec2<Element_t>(theX##(), theY##()); } \
+  const NCollection_Vec2<Element_t> theY##theX##() const { return NCollection_Vec2<Element_t>(theY##(), theX##()); }
+
+//! Defines the 2D-vector template.
+//! The main target for this class - to handle raw low-level arrays (from/to graphic driver etc.).
+template<typename Element_t>
+class NCollection_Vec2
+{
+
+public:
+
+  //! Returns the number of components.
+  static int Length()
+  {
+    return 2;
+  }
+
+  //! Empty constructor. Construct the zero vector.
+  NCollection_Vec2()
+  {
+    v[0] = v[1] = Element_t(0);
+  }
+
+  //! Initialize ALL components of vector within specified value.
+  explicit NCollection_Vec2 (const Element_t theXY)
+  {
+    v[0] = v[1] = theXY;
+  }
+
+  //! Per-component constructor.
+  explicit NCollection_Vec2 (const Element_t theX,
+                             const Element_t theY)
+  {
+    v[0] = theX;
+    v[1] = theY;
+  }
+
+  //! Copy constructor.
+  NCollection_Vec2 (const NCollection_Vec2& theVec2)
+  {
+    v[0] = theVec2[0];
+    v[1] = theVec2[1];
+  }
+
+  //! Assignment operator.
+  const NCollection_Vec2& operator= (const NCollection_Vec2& theVec2)
+  {
+    v[0] = theVec2[0];
+    v[1] = theVec2[1];
+    return *this;
+  }
+
+  //! Alias to 1st component as X coordinate in XY.
+  Element_t x() const { return v[0]; }
+
+  //! Alias to 2nd component as Y coordinate in XY.
+  Element_t y() const { return v[1]; }
+
+  //! @return 2 components by their names in specified order (in GLSL-style)
+  NCOLLECTION_VEC_COMPONENTS_2D(x, y);
+
+  //! Alias to 1st component as X coordinate in XY.
+  Element_t& x() { return v[0]; }
+
+  //! Alias to 2nd component as Y coordinate in XY.
+  Element_t& y() { return v[1]; }
+
+  //! Raw access to the data (to simplify OpenGL exchange).
+  const Element_t* GetData() const { return v; }
+  operator const Element_t*() const { return v; }
+  operator Element_t*() { return v; }
+
+  //! Compute per-component summary.
+  NCollection_Vec2& operator+= (const NCollection_Vec2& theAdd)
+  {
+    v[0] += theAdd.v[0];
+    v[1] += theAdd.v[1];
+    return *this;
+  }
+
+  //! Compute per-component summary.
+  friend NCollection_Vec2 operator+ (const NCollection_Vec2& theLeft,
+                                     const NCollection_Vec2& theRight)
+  {
+    return NCollection_Vec2 (theLeft.v[0] + theRight.v[0],
+                             theLeft.v[1] + theRight.v[1]);
+  }
+
+  //! Compute per-component subtraction.
+  NCollection_Vec2& operator-= (const NCollection_Vec2& theDec)
+  {
+    v[0] -= theDec.v[0];
+    v[1] -= theDec.v[1];
+    return *this;
+  }
+
+  //! Compute per-component subtraction.
+  friend NCollection_Vec2 operator- (const NCollection_Vec2& theLeft,
+                                     const NCollection_Vec2& theRight)
+  {
+    return NCollection_Vec2 (theLeft.v[0] - theRight.v[0],
+                             theLeft.v[1] - theRight.v[1]);
+  }
+
+  //! Unary -.
+  NCollection_Vec2 operator-() const
+  {
+    return NCollection_Vec2 (-x(), -y());
+  }
+
+  //! Compute per-component multiplication.
+  NCollection_Vec2& operator*= (const NCollection_Vec2& theRight)
+  {
+    v[0] *= theRight.v[0];
+    v[1] *= theRight.v[1];
+    return *this;
+  }
+
+  //! Compute per-component multiplication.
+  friend NCollection_Vec2 operator* (const NCollection_Vec2& theLeft,
+                                     const NCollection_Vec2& theRight)
+  {
+    return NCollection_Vec2 (theLeft.v[0] * theRight.v[0],
+                             theLeft.v[1] * theRight.v[1]);
+  }
+
+  //! Compute per-component multiplication by scale factor.
+  void Multiply (const Element_t theFactor)
+  {
+    v[0] *= theFactor;
+    v[1] *= theFactor;
+  }
+
+  //! Compute per-component multiplication by scale factor.
+  NCollection_Vec2 Multiplied (const Element_t theFactor) const
+  {
+    return NCollection_Vec2 (v[0] * theFactor,
+                             v[1] * theFactor);
+  }
+
+  //! Compute per-component multiplication by scale factor.
+  NCollection_Vec2& operator*= (const Element_t theFactor)
+  {
+    Multiply (theFactor);
+    return *this;
+  }
+
+  //! Compute per-component division by scale factor.
+  NCollection_Vec2& operator/= (const Element_t theInvFactor)
+  {
+    v[0] /= theInvFactor;
+    v[1] /= theInvFactor;
+    return *this;
+  }
+
+  //! Compute per-component multiplication by scale factor.
+  NCollection_Vec2 operator* (const Element_t theFactor) const
+  {
+    return Multiplied (theFactor);
+  }
+
+  //! Compute per-component division by scale factor.
+  NCollection_Vec2 operator/ (const Element_t theInvFactor) const
+  {
+    return NCollection_Vec2(v[0] / theInvFactor,
+            v[1] / theInvFactor);
+  }
+
+  //! Computes the dot product.
+  Element_t Dot (const NCollection_Vec2& theOther) const
+  {
+    return x() * theOther.x() + y() * theOther.y();
+  }
+
+  //! Computes the vector modulus (magnitude, length).
+  Element_t Modulus() const
+  {
+    return std::sqrt (x() * x() + y() * y());
+  }
+
+  //! Computes the square of vector modulus (magnitude, length).
+  //! This method may be used for performance tricks.
+  Element_t SquareModulus() const
+  {
+    return x() * x() + y() * y();
+  }
+
+  //! Constuct DX unit vector.
+  static NCollection_Vec2 DX()
+  {
+    return NCollection_Vec2 (Element_t(1), Element_t(0));
+  }
+
+  //! Constuct DY unit vector.
+  static NCollection_Vec2 DY()
+  {
+    return NCollection_Vec2 (Element_t(0), Element_t(1));
+  }
+
+private:
+
+  Element_t v[2];
+
+};
+
+#endif // _NCollection_Vec2_H__
diff --git a/src/NCollection/NCollection_Vec3.hxx b/src/NCollection/NCollection_Vec3.hxx
new file mode 100644 (file)
index 0000000..33fbdae
--- /dev/null
@@ -0,0 +1,352 @@
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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 _NCollection_Vec3_H__
+#define _NCollection_Vec3_H__
+
+#include <cstring>
+#include <cmath>
+#include <NCollection_Vec2.hxx>
+
+//! Auxiliary macros to define couple of similar access components as vector methods
+#define NCOLLECTION_VEC_COMPONENTS_3D(theX, theY, theZ) \
+  const NCollection_Vec3<Element_t> theX##theY##theZ##() const { return NCollection_Vec3<Element_t>(theX##(), theY##(), theZ##()); } \
+  const NCollection_Vec3<Element_t> theX##theZ##theY##() const { return NCollection_Vec3<Element_t>(theX##(), theZ##(), theY##()); } \
+  const NCollection_Vec3<Element_t> theY##theX##theZ##() const { return NCollection_Vec3<Element_t>(theY##(), theX##(), theZ##()); } \
+  const NCollection_Vec3<Element_t> theY##theZ##theX##() const { return NCollection_Vec3<Element_t>(theY##(), theZ##(), theX##()); } \
+  const NCollection_Vec3<Element_t> theZ##theY##theX##() const { return NCollection_Vec3<Element_t>(theZ##(), theY##(), theX##()); } \
+  const NCollection_Vec3<Element_t> theZ##theX##theY##() const { return NCollection_Vec3<Element_t>(theZ##(), theX##(), theY##()); }
+
+//! Generic 3-components vector.
+//! To be used as RGB color pixel or XYZ 3D-point.
+//! The main target for this class - to handle raw low-level arrays (from/to graphic driver etc.).
+template<typename Element_t>
+class NCollection_Vec3
+{
+
+public:
+
+  //! Returns the number of components.
+  static int Length()
+  {
+    return 3;
+  }
+
+  //! Empty constructor. Construct the zero vector.
+  NCollection_Vec3()
+  {
+    std::memset (this, 0, sizeof(NCollection_Vec3));
+  }
+
+  //! Initialize ALL components of vector within specified value.
+  explicit NCollection_Vec3 (Element_t theValue)
+  {
+    v[0] = v[1] = v[2] = theValue;
+  }
+
+  //! Per-component constructor.
+  explicit NCollection_Vec3 (const Element_t theX,
+                             const Element_t theY,
+                             const Element_t theZ)
+  {
+    v[0] = theX;
+    v[1] = theY;
+    v[2] = theZ;
+  }
+
+  //! Constructor from 2-components vector.
+  explicit NCollection_Vec3 (const NCollection_Vec2<Element_t>& theVec2)
+  {
+    v[0] = theVec2[0];
+    v[1] = theVec2[1];
+    v[2] = Element_t(0);
+  }
+
+  //! Copy constructor.
+  NCollection_Vec3 (const NCollection_Vec3& theVec3)
+  {
+    std::memcpy (this, &theVec3, sizeof(NCollection_Vec3));
+  }
+
+  //! Assignment operator.
+  const NCollection_Vec3& operator= (const NCollection_Vec3& theVec3)
+  {
+    std::memcpy (this, &theVec3, sizeof(NCollection_Vec3));
+    return *this;
+  }
+
+  //! Alias to 1st component as X coordinate in XYZ.
+  Element_t x() const { return v[0]; }
+
+  //! Alias to 1st component as RED channel in RGB.
+  Element_t r() const { return v[0]; }
+
+  //! Alias to 2nd component as Y coordinate in XYZ.
+  Element_t y() const { return v[1]; }
+
+  //! Alias to 2nd component as GREEN channel in RGB.
+  Element_t g() const { return v[1]; }
+
+  //! Alias to 3rd component as Z coordinate in XYZ.
+  Element_t z() const { return v[2]; }
+
+  //! Alias to 3rd component as BLUE channel in RGB.
+  Element_t b() const { return v[2]; }
+
+  //! @return 2 components by their names in specified order (in GLSL-style)
+  NCOLLECTION_VEC_COMPONENTS_2D(x, y);
+  NCOLLECTION_VEC_COMPONENTS_2D(x, z);
+  NCOLLECTION_VEC_COMPONENTS_2D(y, z);
+
+  //! @return 3 components by their names in specified order (in GLSL-style)
+  NCOLLECTION_VEC_COMPONENTS_3D(x, y, z);
+
+  //! Alias to 1st component as X coordinate in XYZ.
+  Element_t& x() { return v[0]; }
+
+  //! Alias to 1st component as RED channel in RGB.
+  Element_t& r() { return v[0]; }
+
+  //! Alias to 2nd component as Y coordinate in XYZ.
+  Element_t& y() { return v[1]; }
+
+  //! Alias to 2nd component as GREEN channel in RGB.
+  Element_t& g() { return v[1]; }
+
+  //! Alias to 3rd component as Z coordinate in XYZ.
+  Element_t& z() { return v[2]; }
+
+  //! Alias to 3rd component as BLUE channel in RGB.
+  Element_t& b() { return v[2]; }
+
+  //! @return XY-components modifiable vector
+  NCollection_Vec2<Element_t>& xy()
+  {
+    return *((NCollection_Vec2<Element_t>* )&v[0]);
+  }
+
+  //! @return YZ-components modifiable vector
+  NCollection_Vec2<Element_t>& yz()
+  {
+    return *((NCollection_Vec2<Element_t>* )&v[1]);
+  }
+
+  //! Raw access to the data (for OpenGL exchange).
+  const Element_t* GetData() const { return v; }
+  operator const Element_t*() const { return v; }
+  operator Element_t*() { return v; }
+
+  //! Compute per-component summary.
+  NCollection_Vec3& operator+= (const NCollection_Vec3& theAdd)
+  {
+    v[0] += theAdd.v[0];
+    v[1] += theAdd.v[1];
+    v[2] += theAdd.v[2];
+    return *this;
+  }
+
+  //! Compute per-component summary.
+  friend NCollection_Vec3 operator+ (const NCollection_Vec3& theLeft,
+                                     const NCollection_Vec3& theRight)
+  {
+    NCollection_Vec3 aSumm = NCollection_Vec3 (theLeft);
+    return aSumm += theRight;
+  }
+
+  //! Unary -.
+  NCollection_Vec3 operator-() const
+  {
+    return NCollection_Vec3 (-x(), -y(), -z());
+  }
+
+  //! Compute per-component subtraction.
+  NCollection_Vec3& operator-= (const NCollection_Vec3& theDec)
+  {
+    v[0] -= theDec.v[0];
+    v[1] -= theDec.v[1];
+    v[2] -= theDec.v[2];
+    return *this;
+  }
+
+  //! Compute per-component subtraction.
+  friend NCollection_Vec3 operator- (const NCollection_Vec3& theLeft,
+                                     const NCollection_Vec3& theRight)
+  {
+    NCollection_Vec3 aSumm = NCollection_Vec3 (theLeft);
+    return aSumm -= theRight;
+  }
+
+  //! Compute per-component multiplication by scale factor.
+  void Multiply (const Element_t theFactor)
+  {
+    v[0] *= theFactor;
+    v[1] *= theFactor;
+    v[2] *= theFactor;
+  }
+
+  //! Compute per-component multiplication.
+  NCollection_Vec3& operator*= (const NCollection_Vec3& theRight)
+  {
+    v[0] *= theRight.v[0];
+    v[1] *= theRight.v[1];
+    v[2] *= theRight.v[2];
+    return *this;
+  }
+
+  //! Compute per-component multiplication.
+  friend NCollection_Vec3 operator* (const NCollection_Vec3& theLeft,
+                                     const NCollection_Vec3& theRight)
+  {
+    NCollection_Vec3 aResult = NCollection_Vec3 (theLeft);
+    return aResult *= theRight;
+  }
+
+  //! Compute per-component multiplication by scale factor.
+  NCollection_Vec3& operator*= (const Element_t theFactor)
+  {
+    Multiply (theFactor);
+    return *this;
+  }
+
+  //! Compute per-component multiplication by scale factor.
+  NCollection_Vec3 operator* (const Element_t theFactor) const
+  {
+    return Multiplied (theFactor);
+  }
+
+  //! Compute per-component multiplication by scale factor.
+  NCollection_Vec3 Multiplied (const Element_t theFactor) const
+  {
+    NCollection_Vec3 aCopyVec3 (*this);
+    aCopyVec3 *= theFactor;
+    return aCopyVec3;
+  }
+
+  //! Compute per-component division by scale factor.
+  NCollection_Vec3& operator/= (const Element_t theInvFactor)
+  {
+    v[0] /= theInvFactor;
+    v[1] /= theInvFactor;
+    v[2] /= theInvFactor;
+    return *this;
+  }
+
+  //! Compute per-component division by scale factor.
+  NCollection_Vec3 operator/ (const Element_t theInvFactor)
+  {
+    NCollection_Vec3 aResult (this);
+    return aResult /= theInvFactor;
+  }
+
+  //! Computes the dot product.
+  Element_t Dot (const NCollection_Vec3& theOther) const
+  {
+    return x() * theOther.x() + y() * theOther.y() + z() * theOther.z();
+  }
+
+  //! Computes the vector modulus (magnitude, length).
+  Element_t Modulus() const
+  {
+    return std::sqrt (x() * x() + y() * y() + z() * z());
+  }
+
+  //! Computes the square of vector modulus (magnitude, length).
+  //! This method may be used for performance tricks.
+  Element_t SquareModulus() const
+  {
+    return x() * x() + y() * y() + z() * z();
+  }
+
+  //! Normalize the vector.
+  void Normalize()
+  {
+    Element_t aModulus = Modulus();
+    if (aModulus != Element_t(0)) // just avoid divide by zero
+    {
+      x() = x() / aModulus;
+      y() = y() / aModulus;
+      z() = z() / aModulus;
+    }
+  }
+
+  //! Normalize the vector.
+  NCollection_Vec3 Normalized() const
+  {
+    NCollection_Vec3 aCopy (*this);
+    aCopy.Normalize();
+    return aCopy;
+  }
+
+  //! Computes the cross product.
+  static NCollection_Vec3 Cross (const NCollection_Vec3& theVec1,
+                                 const NCollection_Vec3& theVec2)
+  {
+    return NCollection_Vec3(theVec1.y() * theVec2.z() - theVec1.z() * theVec2.y(),
+            theVec1.z() * theVec2.x() - theVec1.x() * theVec2.z(),
+            theVec1.x() * theVec2.y() - theVec1.y() * theVec2.x());
+  }
+
+  //! Compute linear interpolation between to vectors.
+  //! @param theT - interpolation coefficient 0..1;
+  //! @return interpolation result.
+  static NCollection_Vec3 GetLERP (const NCollection_Vec3& theFrom,
+                                   const NCollection_Vec3& theTo,
+                                   const Element_t         theT)
+  {
+    return theFrom * (Element_t(1) - theT) + theTo * theT;
+  }
+
+  //! Constuct DX unit vector.
+  static NCollection_Vec3 DX()
+  {
+    return NCollection_Vec3 (Element_t(1), Element_t(0), Element_t(0));
+  }
+
+  //! Constuct DY unit vector.
+  static NCollection_Vec3 DY()
+  {
+    return NCollection_Vec3 (Element_t(0), Element_t(1), Element_t(0));
+  }
+
+  //! Constuct DZ unit vector.
+  static NCollection_Vec3 DZ()
+  {
+    return NCollection_Vec3 (Element_t(0), Element_t(0), Element_t(1));
+  }
+
+private:
+
+  Element_t v[3]; //!< define the vector as array to avoid structure alignment issues
+
+};
+
+//! Optimized concretization for float type.
+template<> inline NCollection_Vec3<float>& NCollection_Vec3<float>::operator/= (const float theInvFactor)
+{
+  Multiply (1.0f / theInvFactor);
+  return *this;
+}
+
+//! Optimized concretization for double type.
+template<> inline NCollection_Vec3<double>& NCollection_Vec3<double>::operator/= (const double theInvFactor)
+{
+  Multiply (1.0 / theInvFactor);
+  return *this;
+}
+
+#endif // _NCollection_Vec3_H__
diff --git a/src/NCollection/NCollection_Vec4.hxx b/src/NCollection/NCollection_Vec4.hxx
new file mode 100644 (file)
index 0000000..d72e93f
--- /dev/null
@@ -0,0 +1,321 @@
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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 _NCollection_Vec4_H__
+#define _NCollection_Vec4_H__
+
+#include <NCollection_Vec3.hxx>
+
+//! Generic 4-components vector.
+//! To be used as RGBA color vector or XYZW 3D-point with special W-component
+//! for operations with projection / model view matrices.
+//! Use this class for 3D-points carefully because declared W-component may
+//! results in incorrect results if used without matrices.
+template<typename Element_t>
+class NCollection_Vec4
+{
+
+public:
+
+  //! Returns the number of components.
+  static size_t Length()
+  {
+    return 4;
+  }
+
+  //! Empty constructor. Construct the zero vector.
+  NCollection_Vec4()
+  {
+    std::memset (this, 0, sizeof(NCollection_Vec4));
+  }
+
+  //! Initialize ALL components of vector within specified value.
+  explicit NCollection_Vec4 (const Element_t theValue)
+  {
+    v[0] = v[1] = v[2] = v[3] = theValue;
+  }
+
+  //! Per-component constructor.
+  explicit NCollection_Vec4 (const Element_t theX,
+                             const Element_t theY,
+                             const Element_t theZ,
+                             const Element_t theW)
+  {
+    v[0] = theX;
+    v[1] = theY;
+    v[2] = theZ;
+    v[3] = theW;
+  }
+
+  //! Constructor from 2-components vector.
+  explicit NCollection_Vec4 (const NCollection_Vec2<Element_t>& theVec2)
+  {
+    v[0] = theVec2[0];
+    v[1] = theVec2[1];
+    v[2] = v[3] = Element_t (0);
+  }
+
+  //! Constructor from 3-components vector.
+  explicit NCollection_Vec4(const NCollection_Vec3<Element_t>& theVec3)
+  {
+    std::memcpy (this, &theVec3, sizeof(NCollection_Vec3<Element_t>));
+    v[3] = Element_t (0);
+  }
+
+  //! Constructor from 3-components vector + alpha value.
+  explicit NCollection_Vec4(const NCollection_Vec3<Element_t>& theVec3,
+                            const Element_t                    theAlpha) {
+    std::memcpy (this, &theVec3, sizeof(NCollection_Vec3<Element_t>));
+    v[3] = theAlpha;
+  }
+
+  //! Copy constructor.
+  NCollection_Vec4 (const NCollection_Vec4& theVec4)
+  {
+    std::memcpy (this, &theVec4, sizeof(NCollection_Vec4));
+  }
+
+  //! Assignment operator.
+  const NCollection_Vec4& operator= (const NCollection_Vec4& theVec4)
+  {
+    std::memcpy (this, &theVec4, sizeof(NCollection_Vec4));
+    return *this;
+  }
+
+  //! Alias to 1st component as X coordinate in XYZW.
+  Element_t x() const { return v[0]; }
+
+  //! Alias to 1st component as RED channel in RGBA.
+  Element_t r() const { return v[0]; }
+
+  //! Alias to 2nd component as Y coordinate in XYZW.
+  Element_t y() const { return v[1]; }
+
+  //! Alias to 2nd component as GREEN channel in RGBA.
+  Element_t g() const { return v[1]; }
+
+  //! Alias to 3rd component as Z coordinate in XYZW.
+  Element_t z() const { return v[2]; }
+
+  //! Alias to 3rd component as BLUE channel in RGBA.
+  Element_t b() const { return v[2]; }
+
+  //! Alias to 4th component as W coordinate in XYZW.
+  Element_t w() const { return v[3]; }
+
+  //! Alias to 4th component as ALPHA channel in RGBA.
+  Element_t a() const { return v[3]; }
+
+  //! @return 2 of XYZW components in specified order as vector in GLSL-style
+  NCOLLECTION_VEC_COMPONENTS_2D(x, y);
+  NCOLLECTION_VEC_COMPONENTS_2D(x, z);
+  NCOLLECTION_VEC_COMPONENTS_2D(x, w);
+  NCOLLECTION_VEC_COMPONENTS_2D(y, z);
+  NCOLLECTION_VEC_COMPONENTS_2D(y, w);
+  NCOLLECTION_VEC_COMPONENTS_2D(z, w);
+
+  //! @return 3 of XYZW components in specified order as vector in GLSL-style
+  NCOLLECTION_VEC_COMPONENTS_3D(x, y, z);
+  NCOLLECTION_VEC_COMPONENTS_3D(x, y, w);
+  NCOLLECTION_VEC_COMPONENTS_3D(x, z, w);
+  NCOLLECTION_VEC_COMPONENTS_3D(y, z, w);
+
+  //! @return RGB components as vector
+  NCOLLECTION_VEC_COMPONENTS_3D(r, g, b);
+
+  //! Alias to 1st component as X coordinate in XYZW.
+  Element_t& x() { return v[0]; }
+
+  //! Alias to 1st component as RED channel in RGBA.
+  Element_t& r() { return v[0]; }
+
+  //! Alias to 2nd component as Y coordinate in XYZW.
+  Element_t& y() { return v[1]; }
+
+  //! Alias to 2nd component as GREEN channel in RGBA.
+  Element_t& g() { return v[1]; } // Green color
+
+  //! Alias to 3rd component as Z coordinate in XYZW.
+  Element_t& z() { return v[2]; }
+
+  //! Alias to 3rd component as BLUE channel in RGBA.
+  Element_t& b() { return v[2]; }
+
+  //! Alias to 4th component as W coordinate in XYZW.
+  Element_t& w() { return v[3]; }
+
+  //! Alias to 4th component as ALPHA channel in RGBA.
+  Element_t& a() { return v[3]; }
+
+  //! @return XY-components modifiable vector
+  NCollection_Vec2<Element_t>& xy()
+  {
+    return *((NCollection_Vec2<Element_t>* )&v[0]);
+  }
+
+  //! @return YZ-components modifiable vector
+  NCollection_Vec2<Element_t>& yz()
+  {
+    return *((NCollection_Vec2<Element_t>* )&v[1]);
+  }
+
+  //! @return YZ-components modifiable vector
+  NCollection_Vec2<Element_t>& zw()
+  {
+    return *((NCollection_Vec2<Element_t>* )&v[2]);
+  }
+
+  //! @return XYZ-components modifiable vector
+  NCollection_Vec3<Element_t>& xyz()
+  {
+    return *((NCollection_Vec3<Element_t>* )&v[0]);
+  }
+
+  //! @return YZW-components modifiable vector
+  NCollection_Vec3<Element_t>& yzw()
+  {
+    return *((NCollection_Vec3<Element_t>* )&v[1]);
+  }
+
+  //! Raw access to the data (for OpenGL exchange).
+  const Element_t* GetData() const { return v; }
+  operator const Element_t*() const { return v; }
+  operator Element_t*() { return v; }
+
+  //! Compute per-component summary.
+  NCollection_Vec4& operator+= (const NCollection_Vec4& theAdd)
+  {
+    v[0] += theAdd.v[0];
+    v[1] += theAdd.v[1];
+    v[2] += theAdd.v[2];
+    v[3] += theAdd.v[3];
+    return *this;
+  }
+
+  //! Compute per-component summary.
+  friend NCollection_Vec4 operator+ (const NCollection_Vec4& theLeft,
+                                     const NCollection_Vec4& theRight)
+  {
+    NCollection_Vec4 aSumm = NCollection_Vec4 (theLeft);
+    return aSumm += theRight;
+  }
+
+  //! Compute per-component subtraction.
+  NCollection_Vec4& operator-= (const NCollection_Vec4& theDec)
+  {
+    v[0] -= theDec.v[0];
+    v[1] -= theDec.v[1];
+    v[2] -= theDec.v[2];
+    v[3] -= theDec.v[3];
+    return *this;
+  }
+
+  //! Compute per-component subtraction.
+  friend NCollection_Vec4 operator- (const NCollection_Vec4& theLeft,
+                                     const NCollection_Vec4& theRight)
+  {
+    NCollection_Vec4 aSumm = NCollection_Vec4 (theLeft);
+    return aSumm -= theRight;
+  }
+
+  //! Compute per-component multiplication.
+  NCollection_Vec4& operator*= (const NCollection_Vec4& theRight)
+  {
+    v[0] *= theRight.v[0];
+    v[1] *= theRight.v[1];
+    v[2] *= theRight.v[2];
+    v[3] *= theRight.v[3];
+    return *this;
+  }
+
+  //! Compute per-component multiplication.
+  friend NCollection_Vec4 operator* (const NCollection_Vec4& theLeft,
+                                     const NCollection_Vec4& theRight)
+  {
+    NCollection_Vec4 aResult = NCollection_Vec4 (theLeft);
+    return aResult *= theRight;
+  }
+
+  //! Compute per-component multiplication.
+  void Multiply (const Element_t theFactor)
+  {
+    v[0] *= theFactor;
+    v[1] *= theFactor;
+    v[2] *= theFactor;
+    v[3] *= theFactor;
+  }
+
+  //! Compute per-component multiplication.
+  NCollection_Vec4& operator*=(const Element_t theFactor)
+  {
+    Multiply (theFactor);
+    return *this;
+  }
+
+  //! Compute per-component multiplication.
+  NCollection_Vec4 operator* (const Element_t theFactor) const
+  {
+    return Multiplied (theFactor);
+  }
+
+  //! Compute per-component multiplication.
+  NCollection_Vec4 Multiplied (const Element_t theFactor) const
+  {
+    NCollection_Vec4 aCopyVec4 (*this);
+    aCopyVec4 *= theFactor;
+    return aCopyVec4;
+  }
+
+  //! Compute per-component division by scale factor.
+  NCollection_Vec4& operator/= (const Element_t theInvFactor)
+  {
+    v[0] /= theInvFactor;
+    v[1] /= theInvFactor;
+    v[2] /= theInvFactor;
+    v[3] /= theInvFactor;
+    return *this;
+  }
+
+  //! Compute per-component division by scale factor.
+  NCollection_Vec4 operator/ (const Element_t theInvFactor)
+  {
+    NCollection_Vec4 aResult(this);
+    return aResult /= theInvFactor;
+  }
+
+private:
+
+  Element_t v[4]; //!< define the vector as array to avoid structure alignment issues
+
+};
+
+//! Optimized concretization for float type.
+template<> inline NCollection_Vec4<float>& NCollection_Vec4<float>::operator/= (const float theInvFactor)
+{
+  Multiply (1.0f / theInvFactor);
+  return *this;
+}
+
+//! Optimized concretization for double type.
+template<> inline NCollection_Vec4<double>& NCollection_Vec4<double>::operator/= (const double theInvFactor)
+{
+  Multiply (1.0 / theInvFactor);
+  return *this;
+}
+
+#endif // _NCollection_Vec4_H__
index 96ed44c..1c197cc 100755 (executable)
@@ -67,7 +67,6 @@ OpenGl_Matrix.cxx
 OpenGl_CView.hxx
 OpenGl_NamedStatus.hxx
 OpenGl_TextParam.hxx
-OpenGl_Callback.hxx
 OpenGl_PrinterContext.hxx
 OpenGl_PrinterContext.cxx
 Handle_OpenGl_Display.hxx
@@ -93,12 +92,8 @@ OpenGl_ImageBox.cxx
 OpenGl_ImageBox.hxx
 OpenGl_Resource.hxx
 OpenGl_Resource.cxx
-OpenGl_ResourceVBO.hxx
-OpenGl_ResourceVBO.cxx
 OpenGl_ResourceTexture.hxx
 OpenGl_ResourceTexture.cxx
-OpenGl_ResourceCleaner.hxx
-OpenGl_ResourceCleaner.cxx
 OpenGl_telem_util.hxx
 OpenGl_telem_util.cxx
 OpenGl_transform_persistence.hxx
@@ -108,6 +103,8 @@ OpenGl_tgl_funcs.hxx
 Handle_OpenGl_Context.hxx
 OpenGl_Context.hxx
 OpenGl_Context.cxx
+OpenGl_ArbIns.hxx
+OpenGl_ArbTBO.hxx
 OpenGl_ArbVBO.hxx
 OpenGl_ExtFBO.hxx
 glext.h
@@ -119,3 +116,10 @@ OpenGl_GlCore15.hxx
 OpenGl_GlCore20.hxx
 OpenGl_LayerList.cxx
 OpenGl_LayerList.hxx
+OpenGl_IndexBuffer.hxx
+OpenGl_IndexBuffer.cxx
+OpenGl_TextureBufferArb.hxx
+OpenGl_TextureBufferArb.cxx
+OpenGl_VertexBuffer.hxx
+OpenGl_VertexBuffer.cxx
+OpenGl_VertexBufferEditor.hxx
similarity index 68%
copy from src/OpenGl/OpenGl_Callback.hxx
copy to src/OpenGl/OpenGl_ArbIns.hxx
index a704495..9c9f141 100644 (file)
@@ -1,6 +1,6 @@
-// Created on: 2011-10-25
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Created on: 2012-04-10
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#ifndef _OpenGl_ArbIns_H__
+#define _OpenGl_ArbIns_H__
 
-#ifndef _OpenGl_Callback_HeaderFile
-#define _OpenGl_Callback_HeaderFile
+#include <OpenGl_GlCore12.hxx>
 
-#include <InterfaceGraphic_Graphic3d.hxx>
+//! TBO is available on OpenGL 3.0+ hardware
+struct OpenGl_ArbIns
+{
 
-#include <OpenGl_Element.hxx>
+  PFNGLDRAWARRAYSINSTANCEDARBPROC   glDrawArraysInstancedARB;
+  PFNGLDRAWELEMENTSINSTANCEDARBPROC glDrawElementsInstancedARB;
 
-typedef OpenGl_Element * (*OpenGl_UserDrawCallback)(const CALL_DEF_USERDRAW *);
+};
 
-Standard_EXPORT OpenGl_UserDrawCallback & UserDrawCallback ();
-
-#endif //_OpenGl_Callback_HeaderFile
+#endif // _OpenGl_ArbIns_H__
similarity index 68%
rename from src/OpenGl/OpenGl_Callback.hxx
rename to src/OpenGl/OpenGl_ArbTBO.hxx
index a704495..0f5e54e 100644 (file)
@@ -1,6 +1,6 @@
-// Created on: 2011-10-25
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Created on: 2012-04-10
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#ifndef _OpenGl_ArbTBO_H__
+#define _OpenGl_ArbTBO_H__
 
-#ifndef _OpenGl_Callback_HeaderFile
-#define _OpenGl_Callback_HeaderFile
+#include <OpenGl_GlCore12.hxx>
 
-#include <InterfaceGraphic_Graphic3d.hxx>
+//! TBO is available on OpenGL 3.0+ hardware
+struct OpenGl_ArbTBO
+{
 
-#include <OpenGl_Element.hxx>
+  PFNGLTEXBUFFERARBPROC glTexBufferARB;
 
-typedef OpenGl_Element * (*OpenGl_UserDrawCallback)(const CALL_DEF_USERDRAW *);
+};
 
-Standard_EXPORT OpenGl_UserDrawCallback & UserDrawCallback ();
-
-#endif //_OpenGl_Callback_HeaderFile
+#endif // _OpenGl_ArbTBO_H__
index 565d1b7..0718df6 100644 (file)
@@ -224,9 +224,12 @@ void OpenGl_AspectFace::SetContext (const CALL_DEF_CONTEXTFILLAREA &AContext)
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_AspectFace::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_AspectFace::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  AWorkspace->SetAspectFace(this);
+  theWorkspace->SetAspectFace (this);
 }
 
-/*----------------------------------------------------------------------*/
+void OpenGl_AspectFace::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
+}
index c6b00aa..dd9993a 100644 (file)
@@ -64,7 +64,6 @@ class OpenGl_AspectFace : public OpenGl_Element
  public:
 
   OpenGl_AspectFace ();
-  virtual ~OpenGl_AspectFace () {}
 
   void SetContext (const CALL_DEF_CONTEXTFILLAREA &AContext);
 
@@ -74,7 +73,8 @@ class OpenGl_AspectFace : public OpenGl_Element
   const TEL_CONTEXT_FACE & Context() const { return myContext; }
   const OpenGl_AspectLine * AspectEdge() const { return &myAspectEdge; }
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
  protected:
 
index 6cdf13c..6d20572 100644 (file)
@@ -52,9 +52,12 @@ void OpenGl_AspectLine::SetContext (const CALL_DEF_CONTEXTLINE &AContext)
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_AspectLine::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_AspectLine::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
 {
-  AWorkspace->SetAspectLine(this);
+  theWorkspace->SetAspectLine (this);
 }
 
-/*----------------------------------------------------------------------*/
+void OpenGl_AspectLine::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
+}
index 1216653..cf76c3f 100644 (file)
@@ -32,7 +32,6 @@ class OpenGl_AspectLine : public OpenGl_Element
 
   OpenGl_AspectLine ();
   OpenGl_AspectLine (const OpenGl_AspectLine &AnOther);
-  virtual ~OpenGl_AspectLine () {}
 
   void SetContext (const CALL_DEF_CONTEXTLINE &AContext);
 
@@ -40,7 +39,8 @@ class OpenGl_AspectLine : public OpenGl_Element
   Aspect_TypeOfLine  Type() const { return myType; }
   float              Width() const { return myWidth; }
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
  protected:
 
index a857b18..a02b397 100644 (file)
@@ -44,9 +44,12 @@ void OpenGl_AspectMarker::SetContext (const CALL_DEF_CONTEXTMARKER &AContext)
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_AspectMarker::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_AspectMarker::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  AWorkspace->SetAspectMarker(this);
+  theWorkspace->SetAspectMarker(this);
 }
 
-/*----------------------------------------------------------------------*/
+void OpenGl_AspectMarker::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
+}
index 91d9459..c03fdcb 100644 (file)
@@ -31,7 +31,6 @@ class OpenGl_AspectMarker : public OpenGl_Element
  public:
 
   OpenGl_AspectMarker ();
-  virtual ~OpenGl_AspectMarker () {}
 
   void SetContext (const CALL_DEF_CONTEXTMARKER &AContext);
 
@@ -39,7 +38,8 @@ class OpenGl_AspectMarker : public OpenGl_Element
   Aspect_TypeOfMarker Type() const { return myType; }
   float               Scale() const { return myScale; }
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
  protected:
 
index 3929d29..18eb71a 100644 (file)
@@ -72,9 +72,14 @@ void OpenGl_AspectText::SetContext (const CALL_DEF_CONTEXTTEXT &AContext)
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_AspectText::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_AspectText::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  AWorkspace->SetAspectText(this);
+  theWorkspace->SetAspectText (this);
+}
+
+void OpenGl_AspectText::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
 }
 
 /*----------------------------------------------------------------------*/
index b22cdff..8f52814 100644 (file)
 
 class OpenGl_AspectText : public OpenGl_Element
 {
- public:
 
-  OpenGl_AspectText ();
-  virtual ~OpenGl_AspectText ();
+public:
+
+  OpenGl_AspectText();
+  virtual ~OpenGl_AspectText();
 
   void SetContext (const CALL_DEF_CONTEXTTEXT &AContext);
 
@@ -46,12 +47,15 @@ class OpenGl_AspectText : public OpenGl_Element
   Aspect_TypeOfDisplayText DisplayType() const { return myDisplayType; }
   const TEL_COLOUR &       SubtitleColor() const { return mySubtitleColor; }
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
- protected:
+protected:
 
   void SetFontName (const char *AFont);
 
+protected:
+
   int                      myZoomable;
   float                    myAngle;
   OSD_FontAspect           myFontAspect;
@@ -63,8 +67,10 @@ class OpenGl_AspectText : public OpenGl_Element
   Aspect_TypeOfDisplayText myDisplayType;
   TEL_COLOUR               mySubtitleColor;
 
- public:
+public:
+
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //OpenGl_AspectText_Header
index d5c01e6..00f8c2f 100644 (file)
@@ -25,6 +25,8 @@
 #include <OpenGl_Context.hxx>
 
 #include <OpenGl_ArbVBO.hxx>
+#include <OpenGl_ArbTBO.hxx>
+#include <OpenGl_ArbIns.hxx>
 #include <OpenGl_ExtFBO.hxx>
 #include <OpenGl_GlCore20.hxx>
 
@@ -56,6 +58,11 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
 //! Make record shorter to retrieve function pointer using variable with same name
 #define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
 
+namespace
+{
+  static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
+};
+
 // =======================================================================
 // function : OpenGl_Context
 // purpose  :
@@ -67,9 +74,13 @@ OpenGl_Context::OpenGl_Context()
   core15 (NULL),
   core20 (NULL),
   arbVBO (NULL),
+  arbTBO (NULL),
+  arbIns (NULL),
   extFBO (NULL),
   atiMem (Standard_False),
   nvxMem (Standard_False),
+  mySharedResources (new OpenGl_ResourcesMap()),
+  myReleaseQueue (new OpenGl_ResourcesQueue()),
   myGlLibHandle (NULL),
   myGlCore20 (NULL),
   myGlVerMajor (0),
@@ -97,12 +108,39 @@ OpenGl_Context::OpenGl_Context()
 // =======================================================================
 OpenGl_Context::~OpenGl_Context()
 {
+  // release clean up queue
+  ReleaseDelayed();
+
+  // release shared resources if any
+  if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
+  {
+    for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
+         anIter.More(); anIter.Next())
+    {
+      anIter.Value()->Release (this);
+    }
+  }
+  mySharedResources.Nullify();
+
   delete myGlCore20;
   delete arbVBO;
   delete extFBO;
 }
 
 // =======================================================================
+// function : Share
+// purpose  :
+// =======================================================================
+void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
+{
+  if (!theShareCtx.IsNull())
+  {
+    mySharedResources = theShareCtx->mySharedResources;
+    myReleaseQueue    = theShareCtx->myReleaseQueue;
+  }
+}
+
+// =======================================================================
 // function : IsCurrent
 // purpose  :
 // =======================================================================
@@ -182,6 +220,26 @@ Standard_Boolean OpenGl_Context::MakeCurrent()
 }
 
 // =======================================================================
+// function : SwapBuffers
+// purpose  :
+// =======================================================================
+void OpenGl_Context::SwapBuffers()
+{
+#if (defined(_WIN32) || defined(__WIN32__))
+  if ((HDC )myWindowDC != NULL)
+  {
+    ::SwapBuffers ((HDC )myWindowDC);
+    glFlush();
+  }
+#else
+  if ((Display* )myDisplay != NULL)
+  {
+    glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
+  }
+#endif
+}
+
+// =======================================================================
 // function : findProc
 // purpose  :
 // =======================================================================
@@ -426,6 +484,31 @@ void OpenGl_Context::init()
     }
   }
 
+  // initialize TBO extension (ARB)
+  if (CheckExtension ("GL_ARB_texture_buffer_object"))
+  {
+    arbTBO = new OpenGl_ArbTBO();
+    memset (arbTBO, 0, sizeof(OpenGl_ArbTBO)); // nullify whole structure
+    if (!FindProcShort (arbTBO, glTexBufferARB))
+    {
+      delete arbTBO;
+      arbTBO = NULL;
+    }
+  }
+
+  // initialize hardware instancing extension (ARB)
+  if (CheckExtension ("GL_ARB_draw_instanced"))
+  {
+    arbIns = new OpenGl_ArbIns();
+    memset (arbIns, 0, sizeof(OpenGl_ArbIns)); // nullify whole structure
+    if (!FindProcShort (arbIns, glDrawArraysInstancedARB)
+     || !FindProcShort (arbIns, glDrawElementsInstancedARB))
+    {
+      delete arbIns;
+      arbIns = NULL;
+    }
+  }
+
   // initialize FBO extension (EXT)
   if (CheckExtension ("GL_EXT_framebuffer_object"))
   {
@@ -777,3 +860,70 @@ TCollection_AsciiString OpenGl_Context::MemoryInfo() const
   }
   return anInfo;
 }
+
+
+// =======================================================================
+// function : GetResource
+// purpose  :
+// =======================================================================
+const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
+{
+  return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
+}
+
+// =======================================================================
+// function : ShareResource
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
+                                                const Handle(OpenGl_Resource)& theResource)
+{
+  if (theKey.IsEmpty() || theResource.IsNull())
+  {
+    return Standard_False;
+  }
+  return mySharedResources->Bind (theKey, theResource);
+}
+
+// =======================================================================
+// function : ReleaseResource
+// purpose  :
+// =======================================================================
+void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
+{
+  if (!mySharedResources->IsBound (theKey))
+  {
+    return;
+  }
+  const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
+  if (aRes->GetRefCount() > 1)
+  {
+    return;
+  }
+
+  aRes->Release (this);
+  mySharedResources->UnBind (theKey);
+}
+
+// =======================================================================
+// function : DelayedRelease
+// purpose  :
+// =======================================================================
+void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
+{
+  myReleaseQueue->Push (theResource);
+  theResource.Nullify();
+}
+
+// =======================================================================
+// function : ReleaseDelayed
+// purpose  :
+// =======================================================================
+void OpenGl_Context::ReleaseDelayed()
+{
+  while (!myReleaseQueue->IsEmpty())
+  {
+    myReleaseQueue->Front()->Release (this);
+    myReleaseQueue->Pop();
+  }
+}
index c054baa..1d30704 100644 (file)
 #include <Aspect_Drawable.hxx>
 #include <Aspect_Display.hxx>
 #include <Aspect_RenderingContext.hxx>
+#include <Handle_OpenGl_Context.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Handle.hxx>
+#include <NCollection_Queue.hxx>
+#include <OpenGl_Resource.hxx>
 #include <Standard_Transient.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <Handle_OpenGl_Context.hxx>
@@ -36,6 +41,8 @@ struct OpenGl_GlCore14;
 struct OpenGl_GlCore15;
 struct OpenGl_GlCore20;
 struct OpenGl_ArbVBO;
+struct OpenGl_ArbTBO;
+struct OpenGl_ArbIns;
 struct OpenGl_ExtFBO;
 
 //! This class generalize access to the GL context and available extensions.
@@ -81,6 +88,10 @@ public:
   //! Destructor.
   Standard_EXPORT virtual ~OpenGl_Context();
 
+  //! Share GL context resources.
+  //! theShareCtx - handle to context to retrieve handles to shared resources.
+  Standard_EXPORT void Share (const Handle(OpenGl_Context)& theShareCtx);
+
   //! Initialize available extensions.
   //! GL context should be active!
   Standard_EXPORT Standard_Boolean Init();
@@ -130,6 +141,9 @@ public:
   //! Class should be initialized with appropriate info.
   Standard_EXPORT Standard_Boolean MakeCurrent();
 
+  //! Swap front/back buffers for this GL context (should be activated before!).
+  Standard_EXPORT void SwapBuffers();
+
   //! Return true if active mode is GL_FEEDBACK (cached state)
   Standard_EXPORT Standard_Boolean IsFeedback() const;
 
@@ -148,6 +162,53 @@ public:
   //! and contains more vendor-specific values than AvailableMemory().
   Standard_EXPORT TCollection_AsciiString MemoryInfo() const;
 
+  //! Access shared resource by its name.
+  //! @param  theKey - unique identifier;
+  //! @return handle to shared resource or NULL.
+  Standard_EXPORT const Handle(OpenGl_Resource)& GetResource (const TCollection_AsciiString& theKey) const;
+
+  //! Access shared resource by its name.
+  //! @param  theKey   - unique identifier;
+  //! @param  theValue - handle to fill;
+  //! @return true if resource was shared.
+  template<typename TheHandleType>
+  Standard_Boolean GetResource (const TCollection_AsciiString& theKey,
+                                TheHandleType&                 theValue) const
+  {
+    const Handle(OpenGl_Resource)& aResource = GetResource (theKey);
+    if (aResource.IsNull())
+    {
+      return Standard_False;
+    }
+
+    theValue = TheHandleType::DownCast (aResource);
+    return !theValue.IsNull();
+  }
+
+  //! Register shared resource.
+  //! Notice that after registration caller shouldn't release it by himself -
+  //! it will be automatically released on context destruction.
+  //! @param theKey      - unique identifier, shouldn't be empty;
+  //! @param theResource - new resource to register, shouldn't be NULL.
+  Standard_EXPORT Standard_Boolean ShareResource (const TCollection_AsciiString& theKey,
+                                                  const Handle(OpenGl_Resource)& theResource);
+
+  //! Release shared resource.
+  //! If there are more than one reference to this resource
+  //! (also used by some other existing object) then call will be ignored.
+  //! This means that current object itself should nullify handle before this call.
+  //! Notice that this is unrecommended operation at all and should be used
+  //! only in case of fat resources to release memory for other needs.
+  //! @param  theKey - unique identifier.
+  Standard_EXPORT void ReleaseResource (const TCollection_AsciiString& theKey);
+
+  //! Append resource to queue for delayed clean up.
+  //! Resources in this queue will be released at next redraw call.
+  Standard_EXPORT void DelayedRelease (Handle(OpenGl_Resource)& theResource);
+
+  //! Clean up the delayed release queue.
+  Standard_EXPORT void ReleaseDelayed();
+
 private:
 
   //! Wrapper to system function to retrieve GL function pointer by name.
@@ -170,11 +231,13 @@ public: // core profiles
 public: // extensions
 
   OpenGl_ArbVBO*   arbVBO; //!< GL_ARB_vertex_buffer_object
+  OpenGl_ArbTBO*   arbTBO; //!< GL_ARB_texture_buffer_object
+  OpenGl_ArbIns*   arbIns; //!< GL_ARB_draw_instanced
   OpenGl_ExtFBO*   extFBO; //!< GL_EXT_framebuffer_object
   Standard_Boolean atiMem; //!< GL_ATI_meminfo
   Standard_Boolean nvxMem; //!< GL_NVX_gpu_memory_info
 
-private:
+private: // system-dependent fields
 
 #if (defined(_WIN32) || defined(__WIN32__))
   Aspect_Handle           myWindow;   //!< window handle (owner of GL context) : HWND
@@ -186,6 +249,16 @@ private:
   Aspect_RenderingContext myGContext; //!< X-GLX rendering context : GLXContext
 #endif
 
+private: // context info
+
+  typedef NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)> OpenGl_ResourcesMap;
+  typedef NCollection_Handle<OpenGl_ResourcesMap> Handle(OpenGl_ResourcesMap);
+  typedef NCollection_Queue<Handle(OpenGl_Resource)> OpenGl_ResourcesQueue;
+  typedef NCollection_Handle<OpenGl_ResourcesQueue> Handle(OpenGl_ResourcesQueue);
+
+  Handle(OpenGl_ResourcesMap)   mySharedResources; //!< shared resourced with unique identification key
+  Handle(OpenGl_ResourcesQueue) myReleaseQueue;    //!< queue of resources for delayed clean up
+
   void*            myGlLibHandle;   //!< optional handle to GL library
   OpenGl_GlCore20* myGlCore20;      //!< common structure for GL core functions upto 2.0
   Standard_Integer myGlVerMajor;    //!< cached GL version major number
@@ -193,10 +266,18 @@ private:
   Standard_Boolean myIsFeedback;    //!< flag indicates GL_FEEDBACK mode
   Standard_Boolean myIsInitialized; //!< flag indicates initialization state
 
+private:
+
+  //! Copying allowed only within Handles
+  OpenGl_Context            (const OpenGl_Context& );
+  OpenGl_Context& operator= (const OpenGl_Context& );
+
 public:
 
   DEFINE_STANDARD_RTTI(OpenGl_Context) // Type definition
 
+  friend class OpenGl_Window;
+
 };
 
 #endif // _OpenGl_Context_H__
index 24219c4..e9d6773 100644 (file)
 
 class OpenGl_Element
 {
- public:
-  OpenGl_Element () {}
-  virtual ~OpenGl_Element () {}
+public:
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const = 0;
+  OpenGl_Element() {}
+
+  virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const = 0;
+
+  //! Release GPU resources.
+  virtual void Release (const Handle(OpenGl_Context)& theContext) = 0;
+
+  template <typename theResource_t>
+  static void Destroy (const Handle(OpenGl_Context)& theContext,
+                       theResource_t*&               theElement)
+  {
+    if (theElement == NULL)
+    {
+      return;
+    }
+
+    theElement->Release (theContext);
+    OpenGl_Element* anElement = theElement;
+    delete anElement;
+    theElement = NULL;
+  }
+
+protected:
+
+  virtual ~OpenGl_Element() {}
+
+public:
 
- public:
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //OpenGl_Element_Header
index 0df9140..c5d486f 100755 (executable)
@@ -29,11 +29,10 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
 
 namespace
 {
-  // Global maps - shared by whole TKOpenGl module. To be removed.
-  static NCollection_DataMap<Standard_Integer, Handle(OpenGl_View)>      TheMapOfView (1, NCollection_BaseAllocator::CommonBaseAllocator());
-  static NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)> TheMapOfWS   (1, NCollection_BaseAllocator::CommonBaseAllocator());
-  static NCollection_DataMap<Standard_Integer, OpenGl_Structure*>        TheMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator());
+  // Global switch - shared by whole TKOpenGl module. To be removed.
   static Standard_Boolean TheToUseVbo = Standard_True;
+
+  static const Handle(OpenGl_Context) TheNullGlCtx;
 };
 
 // Pour eviter de "mangler" MetaGraphicDriverFactory, le nom de la
@@ -42,16 +41,16 @@ namespace
 // classe OSD_SharedLibrary dans la methode SetGraphicDriver de la
 // classe Graphic3d_GraphicDevice
 extern "C" {
-#ifdef WNT /* disable MS VC++ warning on C-style function returning C++ object */
+#if defined(_MSC_VER) // disable MS VC++ warning on C-style function returning C++ object
   #pragma warning(push)
   #pragma warning(disable:4190)
 #endif
-  Standard_EXPORT Handle(Graphic3d_GraphicDriver) MetaGraphicDriverFactory (const Standard_CString AShrName)
+  Standard_EXPORT Handle(Graphic3d_GraphicDriver) MetaGraphicDriverFactory (const Standard_CString theShrName)
   {
-    Handle(OpenGl_GraphicDriver) aOpenDriver = new OpenGl_GraphicDriver (AShrName);
-    return aOpenDriver;
+    Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver (theShrName);
+    return aDriver;
   }
-#ifdef WNT
+#if defined(_MSC_VER)
   #pragma warning(pop)
 #endif
 }
@@ -61,45 +60,31 @@ extern "C" {
 // purpose  :
 // =======================================================================
 OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Standard_CString theShrName)
-: Graphic3d_GraphicDriver (theShrName)
+: Graphic3d_GraphicDriver (theShrName),
+  myMapOfView      (1, NCollection_BaseAllocator::CommonBaseAllocator()),
+  myMapOfWS        (1, NCollection_BaseAllocator::CommonBaseAllocator()),
+  myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()),
+  myUserDrawCallback (NULL)
 {
   //
 }
 
 // =======================================================================
-// function : DefaultTextHeight
-// purpose  :
-// =======================================================================
-Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const
-{
-  return 16.;
-}
-
-// =======================================================================
-// function : GetMapOfViews
-// purpose  :
-// =======================================================================
-NCollection_DataMap<Standard_Integer, Handle(OpenGl_View)>& OpenGl_GraphicDriver::GetMapOfViews()
-{
-  return TheMapOfView;
-}
-
-// =======================================================================
-// function : GetMapOfWorkspaces
+// function : UserDrawCallback
 // purpose  :
 // =======================================================================
-NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>& OpenGl_GraphicDriver::GetMapOfWorkspaces()
+OpenGl_GraphicDriver::OpenGl_UserDrawCallback_t& OpenGl_GraphicDriver::UserDrawCallback()
 {
-  return TheMapOfWS;
+  return myUserDrawCallback;
 }
 
 // =======================================================================
-// function : GetMapOfStructures
+// function : DefaultTextHeight
 // purpose  :
 // =======================================================================
-NCollection_DataMap<Standard_Integer, OpenGl_Structure*>& OpenGl_GraphicDriver::GetMapOfStructures()
+Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const
 {
-  return TheMapOfStructure;
+  return 16.;
 }
 
 // =======================================================================
@@ -108,7 +93,7 @@ NCollection_DataMap<Standard_Integer, OpenGl_Structure*>& OpenGl_GraphicDriver::
 // =======================================================================
 void OpenGl_GraphicDriver::InvalidateAllWorkspaces()
 {
-  for (NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator anIt (OpenGl_GraphicDriver::GetMapOfWorkspaces());
+  for (NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator anIt (myMapOfWS);
        anIt.More(); anIt.Next())
   {
     anIt.ChangeValue()->EraseAnimation();
@@ -134,6 +119,21 @@ void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn)
 }
 
 // =======================================================================
+// function : GetSharedContext
+// purpose  :
+// =======================================================================
+const Handle(OpenGl_Context)& OpenGl_GraphicDriver::GetSharedContext() const
+{
+  if (myMapOfWS.IsEmpty())
+  {
+    return TheNullGlCtx;
+  }
+
+  NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>::Iterator anIter (myMapOfWS);
+  return anIter.Value()->GetGlContext();
+}
+
+// =======================================================================
 // function : MemoryInfo
 // purpose  :
 // =======================================================================
index 4579958..01f02b9 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <Graphic3d_GraphicDriver.hxx>
 #include <Handle_OpenGl_GraphicDriver.hxx>
+#include <OpenGl_Context.hxx>
 
 #include <Standard_CString.hxx>
 
@@ -84,6 +85,7 @@ class AlienImage_AlienImage;
 class TColStd_HArray1OfReal;
 class Handle(OpenGl_View);
 class Handle(OpenGl_Workspace);
+class OpenGl_Element;
 class OpenGl_Structure;
 
 //! This class defines an OpenGl graphic driver <br>
@@ -332,23 +334,32 @@ public:
   Standard_EXPORT Standard_Boolean MemoryInfo (Standard_Size&           theFreeBytes,
                                                TCollection_AsciiString& theInfo) const;
 
-private:
+  //! UserDraw function prototype
+  typedef OpenGl_Element* (*OpenGl_UserDrawCallback_t )(const CALL_DEF_USERDRAW* );
 
-  //! Access the global map of views.
-  static NCollection_DataMap<Standard_Integer, Handle(OpenGl_View)>& GetMapOfViews();
+  //! Method to setup UserDraw callback
+  Standard_EXPORT OpenGl_UserDrawCallback_t& UserDrawCallback();
 
-  //! Access the global map of workspaces.
-  static NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)>& GetMapOfWorkspaces();
+private:
 
-  //! Access the global map of structures.
-  static NCollection_DataMap<Standard_Integer, OpenGl_Structure*>& GetMapOfStructures();
+  //! Method to retrieve valid GL context.
+  //! Could return NULL-handle if no window created by this driver.
+  Standard_EXPORT const Handle(OpenGl_Context)& GetSharedContext() const;
 
   //! Deprecated.
-  static void InvalidateAllWorkspaces();
+  void InvalidateAllWorkspaces();
 
 public:
 
   DEFINE_STANDARD_RTTI(OpenGl_GraphicDriver)
+
+private:
+
+  NCollection_DataMap<Standard_Integer, Handle(OpenGl_View)>      myMapOfView;
+  NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)> myMapOfWS;
+  NCollection_DataMap<Standard_Integer, OpenGl_Structure*>        myMapOfStructure;
+  OpenGl_UserDrawCallback_t                                       myUserDrawCallback;
+
 };
 
 #endif //_OpenGl_GraphicDriver_HeaderFile
index 72e0715..04fdd15 100755 (executable)
@@ -30,7 +30,7 @@ void OpenGl_GraphicDriver::ClearGroup (const Graphic3d_CGroup& theCGroup)
   if (theCGroup.ptrGroup == NULL)
     return;
 
-  ((OpenGl_Group* )theCGroup.ptrGroup)->Clear();
+  ((OpenGl_Group* )theCGroup.ptrGroup)->Release (GetSharedContext());
   InvalidateAllWorkspaces();
 }
 
@@ -107,7 +107,7 @@ void OpenGl_GraphicDriver::RemoveGroup (const Graphic3d_CGroup& theCGroup)
   if (aStructure == NULL)
     return;
 
-  aStructure->RemoveGroup ((const OpenGl_Group* )theCGroup.ptrGroup);
+  aStructure->RemoveGroup (GetSharedContext(), (const OpenGl_Group* )theCGroup.ptrGroup);
   InvalidateAllWorkspaces();
 }
 
index 9734c2a..1b849af 100755 (executable)
@@ -30,7 +30,7 @@ void OpenGl_GraphicDriver::ClearStructure (const Graphic3d_CStructure& theCStruc
   if (aStructure == NULL)
     return;
 
-  aStructure->Clear();
+  aStructure->Clear (GetSharedContext());
   InvalidateAllWorkspaces();
 }
 
@@ -100,12 +100,12 @@ void OpenGl_GraphicDriver::EraseStructure (const Graphic3d_CView&      theCView,
 
 void OpenGl_GraphicDriver::RemoveStructure (const Graphic3d_CStructure& theCStructure)
 {
-  if (!GetMapOfStructures().IsBound (theCStructure.Id))
+  if (!myMapOfStructure.IsBound (theCStructure.Id))
     return;
 
-  OpenGl_Structure* aStructure = OpenGl_GraphicDriver::GetMapOfStructures().Find (theCStructure.Id);
-  OpenGl_GraphicDriver::GetMapOfStructures().UnBind (theCStructure.Id);
-  delete aStructure;
+  OpenGl_Structure* aStructure = myMapOfStructure.Find (theCStructure.Id);
+  myMapOfStructure.UnBind (theCStructure.Id);
+  OpenGl_Element::Destroy (GetSharedContext(), aStructure);
   InvalidateAllWorkspaces();
 }
 
@@ -124,7 +124,7 @@ void OpenGl_GraphicDriver::Structure (Graphic3d_CStructure& theCStructure)
   aStructure->SetNamedStatus (aStatus);
 
   theCStructure.ptrStructure = aStructure;
-  OpenGl_GraphicDriver::GetMapOfStructures().Bind (theCStructure.Id, aStructure);
+  myMapOfStructure.Bind (theCStructure.Id, aStructure);
   InvalidateAllWorkspaces();
 }
 
@@ -136,11 +136,10 @@ void OpenGl_GraphicDriver::Structure (Graphic3d_CStructure& theCStructure)
 void OpenGl_GraphicDriver::ChangeZLayer (const Graphic3d_CStructure& theCStructure,
                                          const Standard_Integer theLayer)
 {
-  if (!GetMapOfStructures().IsBound (theCStructure.Id))
+  if (!myMapOfStructure.IsBound (theCStructure.Id))
     return;
 
-  OpenGl_Structure* aStructure =
-    OpenGl_GraphicDriver::GetMapOfStructures().Find (theCStructure.Id);
+  OpenGl_Structure* aStructure = myMapOfStructure.Find (theCStructure.Id);
 
   aStructure->SetZLayer (theLayer);
 }
@@ -156,11 +155,10 @@ void OpenGl_GraphicDriver::ChangeZLayer (const Graphic3d_CStructure& theCStructu
 {
   const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
 
-  if (!GetMapOfStructures().IsBound (theCStructure.Id) || !aCView)
+  if (!myMapOfStructure.IsBound (theCStructure.Id) || !aCView)
     return;
 
-  OpenGl_Structure* aStructure =
-    OpenGl_GraphicDriver::GetMapOfStructures().Find (theCStructure.Id);
+  OpenGl_Structure* aStructure = myMapOfStructure.Find (theCStructure.Id);
 
   aCView->View->ChangeZLayer (aStructure, theNewLayerId);
 }
@@ -172,11 +170,10 @@ void OpenGl_GraphicDriver::ChangeZLayer (const Graphic3d_CStructure& theCStructu
 
 Standard_Integer OpenGl_GraphicDriver::GetZLayer (const Graphic3d_CStructure& theCStructure) const
 {
-  if (!GetMapOfStructures().IsBound (theCStructure.Id))
+  if (!myMapOfStructure.IsBound (theCStructure.Id))
     return -1;
 
-  OpenGl_Structure* aStructure = 
-    OpenGl_GraphicDriver::GetMapOfStructures().Find (theCStructure.Id);
+  OpenGl_Structure* aStructure = myMapOfStructure.Find (theCStructure.Id);
 
   return aStructure->GetZLayer();
 }
@@ -188,9 +185,7 @@ Standard_Integer OpenGl_GraphicDriver::GetZLayer (const Graphic3d_CStructure& th
 
 void OpenGl_GraphicDriver::UnsetZLayer (const Standard_Integer theLayerId)
 {
-  NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator
-    aStructIt (GetMapOfStructures ());
-  
+  NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
   for( ; aStructIt.More (); aStructIt.Next ())
   {
     OpenGl_Structure* aStruct = aStructIt.ChangeValue ();
index 1b4d667..d67a84f 100755 (executable)
@@ -68,28 +68,33 @@ void OpenGl_GraphicDriver::Blink (const Graphic3d_CStructure &, const Standard_B
   // Do nothing
 }
 
-void OpenGl_GraphicDriver::BoundaryBox (const Graphic3d_CStructure& ACStructure, const Standard_Boolean Create)
+void OpenGl_GraphicDriver::BoundaryBox (const Graphic3d_CStructure& theCStructure,
+                                        const Standard_Boolean      toCreate)
 {
-  OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
-  if (!astructure)
+  OpenGl_Structure* aStructure = (OpenGl_Structure* )theCStructure.ptrStructure;
+  if (aStructure == NULL)
     return;
 
-  if ( Create )
-    astructure->SetHighlightBox(ACStructure.BoundBox);
+  if (toCreate)
+    aStructure->SetHighlightBox (GetSharedContext(), theCStructure.BoundBox);
   else
-    astructure->ClearHighlightBox();
+    aStructure->ClearHighlightBox (GetSharedContext());
 }
 
-void OpenGl_GraphicDriver::HighlightColor (const Graphic3d_CStructure& ACStructure, const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B, const Standard_Boolean Create)
+void OpenGl_GraphicDriver::HighlightColor (const Graphic3d_CStructure& theCStructure,
+                                           const Standard_ShortReal R,
+                                           const Standard_ShortReal G,
+                                           const Standard_ShortReal B,
+                                           const Standard_Boolean   toCreate)
 {
-  OpenGl_Structure *astructure = (OpenGl_Structure *)ACStructure.ptrStructure;
-  if (!astructure)
+  OpenGl_Structure* aStructure = (OpenGl_Structure* )theCStructure.ptrStructure;
+  if (aStructure == NULL)
     return;
 
-  if ( Create )
-    astructure->SetHighlightColor(R,G,B);
+  if (toCreate)
+    aStructure->SetHighlightColor (GetSharedContext(), R, G, B);
   else
-    astructure->ClearHighlightColor();
+    aStructure->ClearHighlightColor (GetSharedContext());
 }
 
 void OpenGl_GraphicDriver::NameSetStructure (const Graphic3d_CStructure& ACStructure)
@@ -379,11 +384,11 @@ Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer *theFBOPtr, Im
 
 void OpenGl_GraphicDriver::RemoveView (const Graphic3d_CView& ACView)
 {
-  if (GetMapOfViews().IsBound (ACView.ViewId))
-    GetMapOfViews().UnBind (ACView.ViewId);
+  if (myMapOfView.IsBound (ACView.ViewId))
+    myMapOfView.UnBind (ACView.ViewId);
 
-  if (GetMapOfWorkspaces().IsBound (ACView.WsId))
-    GetMapOfWorkspaces().UnBind (ACView.WsId);
+  if (myMapOfWS.IsBound (ACView.WsId))
+    myMapOfWS.UnBind (ACView.WsId);
 
   OpenGl_CView *aCView = (OpenGl_CView *)ACView.ptrView;
   delete aCView;
@@ -442,33 +447,34 @@ void OpenGl_GraphicDriver::Update (const Graphic3d_CView& ACView, const Aspect_C
     aCView->WS->Update(ACView,ACUnderLayer,ACOverLayer);
 }
 
-Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& ACView)
+Standard_Boolean OpenGl_GraphicDriver::View (Graphic3d_CView& theCView)
 {
   if (openglDisplay.IsNull())
     return Standard_False;
 
-  if (GetMapOfViews().IsBound (ACView.ViewId))
-    GetMapOfViews().UnBind (ACView.ViewId);
+  if (myMapOfView.IsBound (theCView.ViewId))
+    myMapOfView.UnBind (theCView.ViewId);
 
-  if (GetMapOfWorkspaces().IsBound (ACView.WsId))
-    GetMapOfWorkspaces().UnBind (ACView.WsId);
+  if (myMapOfWS.IsBound (theCView.WsId))
+    myMapOfWS.UnBind (theCView.WsId);
 
-  Handle(OpenGl_Workspace) aWS = Handle(OpenGl_Workspace)::DownCast(openglDisplay->GetWindow( ACView.DefWindow.XWindow ));
-  if ( aWS.IsNull() )
+  Handle(OpenGl_Workspace) aWS = Handle(OpenGl_Workspace)::DownCast(openglDisplay->GetWindow (theCView.DefWindow.XWindow));
+  if (aWS.IsNull())
   {
-    aWS = new OpenGl_Workspace( openglDisplay, ACView.DefWindow, ACView.GContext );
-    openglDisplay->SetWindow( ACView.DefWindow.XWindow, aWS );
+    Handle(OpenGl_Context) aShareCtx = GetSharedContext();
+    aWS = new OpenGl_Workspace (openglDisplay, theCView.DefWindow, theCView.GContext, aShareCtx);
+    openglDisplay->SetWindow (theCView.DefWindow.XWindow, aWS);
   }
 
-  GetMapOfWorkspaces().Bind (ACView.WsId, aWS);
+  myMapOfWS.Bind (theCView.WsId, aWS);
 
-  Handle(OpenGl_View) aView = new OpenGl_View( ACView.Context );
-  GetMapOfViews().Bind (ACView.ViewId, aView);
+  Handle(OpenGl_View) aView = new OpenGl_View (theCView.Context);
+  myMapOfView.Bind (theCView.ViewId, aView);
 
-  OpenGl_CView *aCView = new OpenGl_CView;
+  OpenGl_CView* aCView = new OpenGl_CView();
   aCView->View = aView;
   aCView->WS = aWS;
-  ACView.ptrView = aCView;
+  theCView.ptrView = aCView;
 
   return Standard_True;
 }
index 13c0384..b31fb20 100755 (executable)
@@ -20,7 +20,6 @@
 
 #include <OpenGl_GraphicDriver.hxx>
 
-#include <OpenGl_Callback.hxx>
 #include <OpenGl_Group.hxx>
 #include <OpenGl_PrimitiveArray.hxx>
 
@@ -87,30 +86,25 @@ void OpenGl_GraphicDriver::PrimitiveArray( const Graphic3d_CGroup& ACGroup,
 //           Graphic3d_Group only.
 //=======================================================================
 
-void OpenGl_GraphicDriver::RemovePrimitiveArray (const Graphic3d_CGroup&         ACGroup,
-                                                const Graphic3d_PrimitiveArray& thePArray)
+void OpenGl_GraphicDriver::RemovePrimitiveArray (const Graphic3d_CGroup&         theCGroup,
+                                                 const Graphic3d_PrimitiveArray& thePArray)
 {
-  if ( ACGroup.ptrGroup && thePArray )
+  if (theCGroup.ptrGroup && thePArray)
   {
-    ((OpenGl_Group *)ACGroup.ptrGroup)->RemovePrimitiveArray( (CALL_DEF_PARRAY *) thePArray );
+    ((OpenGl_Group* )theCGroup.ptrGroup)->RemovePrimitiveArray (GetSharedContext(), thePArray);
   }
 }
 
-static OpenGl_UserDrawCallback MyUserDrawCallback = NULL;
-
-OpenGl_UserDrawCallback& UserDrawCallback ()
+void OpenGl_GraphicDriver::UserDraw (const Graphic3d_CGroup&    theCGroup,
+                                     const Graphic3d_CUserDraw& theUserDraw)
 {
-  return MyUserDrawCallback;
-}
-
-void OpenGl_GraphicDriver::UserDraw ( const Graphic3d_CGroup& ACGroup,
-                                     const Graphic3d_CUserDraw& AUserDraw )
-{
-  if (ACGroup.ptrGroup && MyUserDrawCallback)
+  if (theCGroup.ptrGroup != NULL
+   && myUserDrawCallback != NULL)
   {
-    OpenGl_Element *auserdraw = (*MyUserDrawCallback)(&AUserDraw);
-
-    if (auserdraw != 0)
-      ((OpenGl_Group *)ACGroup.ptrGroup)->AddElement( TelUserdraw, auserdraw );
+    OpenGl_Element* aUserDraw = myUserDrawCallback(&theUserDraw);
+    if (aUserDraw != NULL)
+    {
+      ((OpenGl_Group* )theCGroup.ptrGroup)->AddElement (TelUserdraw, aUserDraw);
+    }
   }
 }
index b867ad5..edc9c58 100755 (executable)
@@ -228,7 +228,7 @@ Standard_Integer OpenGl_GraphicDriver::CreateTexture (const Graphic3d_TypeOfText
 
 void OpenGl_GraphicDriver::DestroyTexture (const Standard_Integer theTexId) const
 {
-  FreeTexture (theTexId);
+  FreeTexture (GetSharedContext(), theTexId);
 }
 
 void OpenGl_GraphicDriver::ModifyTexture (const Standard_Integer        theTexId,
index a69dc98..51a5919 100644 (file)
@@ -36,7 +36,7 @@ OpenGl_Group::OpenGl_Group ()
 
 OpenGl_Group::~OpenGl_Group()
 {
-  Clear();
+  Release (Handle(OpenGl_Context)());
 }
 
 /*----------------------------------------------------------------------*/
@@ -130,63 +130,25 @@ void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem )
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_Group::Clear ()
-{
-  if (myAspectLine)
-  {
-    // Delete line context
-    delete myAspectLine;
-    myAspectLine = NULL;
-  }
-  if (myAspectFace)
-  {
-    // Delete face context
-    delete myAspectFace;
-    myAspectFace = NULL;
-  }
-  if (myAspectMarker)
-  {
-    // Delete marker context
-    delete myAspectMarker;
-    myAspectMarker = NULL;
-  }
-  if (myAspectText)
-  {
-    // Delete text context
-    delete myAspectText;
-    myAspectText = NULL;
-  }
-  // Delete elements
-  while (myFirst)
-  {
-    OpenGl_ElementNode *next = myFirst->next;
-    delete myFirst->elem;
-    delete myFirst;
-    myFirst = next;
-  }
-  myLast = NULL;
-}
-
-/*----------------------------------------------------------------------*/
-
-void OpenGl_Group::RemovePrimitiveArray (CALL_DEF_PARRAY *APArray)
+void OpenGl_Group::RemovePrimitiveArray (const Handle(OpenGl_Context)& theGlCtx,
+                                         CALL_DEF_PARRAY*              thePArray)
 {
   OpenGl_ElementNode *prevnode = NULL, *node = myFirst;
-  while (node)
+  while (node != NULL)
   {
     if (node->type == TelParray)
     {
-      CALL_DEF_PARRAY *aCurPArray = ((const OpenGl_PrimitiveArray *)node->elem)->PArray();
+      CALL_DEF_PARRAY* aCurPArray = ((const OpenGl_PrimitiveArray* )node->elem)->PArray();
 
       // validate for correct pointer
-      if (aCurPArray->num_bounds  == APArray->num_bounds  && 
-          aCurPArray->num_edges   == APArray->num_edges   &&
-          aCurPArray->num_vertexs == APArray->num_vertexs &&
-          aCurPArray->type        == APArray->type)
+      if (aCurPArray->num_bounds  == thePArray->num_bounds  && 
+          aCurPArray->num_edges   == thePArray->num_edges   &&
+          aCurPArray->num_vertexs == thePArray->num_vertexs &&
+          aCurPArray->type        == thePArray->type)
       {
-        (prevnode? prevnode->next : myFirst) = node->next;
+        (prevnode ? prevnode->next : myFirst) = node->next;
         if (!myFirst) myLast = NULL;
-        delete node->elem;
+        OpenGl_Element::Destroy (theGlCtx, node->elem);
         delete node;
         break;
       }
@@ -294,4 +256,20 @@ void OpenGl_Group::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   AWorkspace->SetAspectText(aspect_text);
 }
 
-/*----------------------------------------------------------------------*/
+void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
+{
+  // Delete elements
+  while (myFirst != NULL)
+  {
+    OpenGl_ElementNode* aNext = myFirst->next;
+    OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
+    delete myFirst;
+    myFirst = aNext;
+  }
+  myLast = NULL;
+
+  OpenGl_Element::Destroy (theGlCtx, myAspectLine);
+  OpenGl_Element::Destroy (theGlCtx, myAspectFace);
+  OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
+  OpenGl_Element::Destroy (theGlCtx, myAspectText);
+}
index 76822b4..d2cbee1 100644 (file)
@@ -42,9 +42,10 @@ struct OpenGl_ElementNode
 
 class OpenGl_Group : public OpenGl_Element
 {
- public:
-  OpenGl_Group ();
-  virtual ~OpenGl_Group();
+
+public:
+
+  OpenGl_Group();
 
   void SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext, const Standard_Boolean IsGlobal = Standard_True);
   void SetAspectFace (const CALL_DEF_CONTEXTFILLAREA &AContext, const Standard_Boolean IsGlobal = Standard_True);
@@ -52,23 +53,31 @@ class OpenGl_Group : public OpenGl_Element
   void SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext, const Standard_Boolean IsGlobal = Standard_True);
 
   void AddElement (const TelType, OpenGl_Element * );
-  void Clear ();
 
-  void RemovePrimitiveArray (CALL_DEF_PARRAY *APArray);
+  void RemovePrimitiveArray (const Handle(OpenGl_Context)& theGlCtx,
+                             CALL_DEF_PARRAY*              thePArray);
+
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theGlCtx);
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+protected:
 
- protected:
+  virtual ~OpenGl_Group();
+
+protected:
 
-  OpenGl_AspectLine *myAspectLine;
-  OpenGl_AspectFace *myAspectFace;
-  OpenGl_AspectMarker *myAspectMarker;
-  OpenGl_AspectText *myAspectText;
+  OpenGl_AspectLine*   myAspectLine;
+  OpenGl_AspectFace*   myAspectFace;
+  OpenGl_AspectMarker* myAspectMarker;
+  OpenGl_AspectText*   myAspectText;
 
-  OpenGl_ElementNode *myFirst, *myLast;
+  OpenGl_ElementNode*  myFirst;
+  OpenGl_ElementNode*  myLast;
+
+public:
 
- public:
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //_OpenGl_Group_Header
old mode 100755 (executable)
new mode 100644 (file)
similarity index 54%
rename from src/OpenGl/OpenGl_ResourceVBO.cxx
rename to src/OpenGl/OpenGl_IndexBuffer.cxx
index f252562..a2816aa
@@ -1,6 +1,5 @@
-// Created on: 2011-03-18
-// Created by: Anton POLETAEV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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
 // 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_ResourceVBO.hxx>
 #include <OpenGl_Context.hxx>
-#include <OpenGl_ArbVBO.hxx>
+#include <Standard_Assert.hxx>
 
-IMPLEMENT_STANDARD_HANDLE (OpenGl_ResourceVBO, OpenGl_Resource)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ResourceVBO, OpenGl_Resource)
+IMPLEMENT_STANDARD_HANDLE (OpenGl_IndexBuffer, OpenGl_VertexBuffer)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_IndexBuffer, OpenGl_VertexBuffer)
 
-//=======================================================================
-//function : Clean
-//purpose  : free OpenGl memory allocated for vbo resource
-//=======================================================================
-void OpenGl_ResourceVBO::Clean (const Handle(OpenGl_Context)& theGlContext)
+// =======================================================================
+// function : OpenGl_IndexBuffer
+// purpose  :
+// =======================================================================
+OpenGl_IndexBuffer::OpenGl_IndexBuffer()
+: OpenGl_VertexBuffer() {}
+
+// =======================================================================
+// function : GetTarget
+// purpose  :
+// =======================================================================
+GLenum OpenGl_IndexBuffer::GetTarget() const
 {
-  if (theGlContext->arbVBO == NULL)
-  {
-    std::cerr << "OpenGl_ResourceVBO::Clean(), active GL context doesn't support VBO!\n";
-    return;
-  }
-  theGlContext->arbVBO->glDeleteBuffersARB (1 , &myId);
+  return GL_ELEMENT_ARRAY_BUFFER;
 }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 53%
rename from src/OpenGl/OpenGl_ResourceVBO.hxx
rename to src/OpenGl/OpenGl_IndexBuffer.hxx
index 064335b..65ced7f
@@ -1,6 +1,5 @@
-// Created on: 2011-03-18
-// Created by: Anton POLETAEV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#ifndef _OpenGl_IndexBuffer_H__
+#define _OpenGl_IndexBuffer_H__
 
-#ifndef _OPENGL_RESOURCEVBO_H
-#define _OPENGL_RESOURCEVBO_H
+#include <OpenGl_VertexBuffer.hxx>
 
-#include <OpenGl_Resource.hxx>
-#include <Standard.hxx>
-
-class OpenGl_Resource;
-
-//! OpenGl_ResourceVBO represents the Vertex Buffer
-//! Object resource (VBO) for OpenGl_ResourceCleaner
-class OpenGl_ResourceVBO : public OpenGl_Resource 
+//! Index buffer is just a VBO with special target (GL_ELEMENT_ARRAY_BUFFER).
+class OpenGl_IndexBuffer : public OpenGl_VertexBuffer
 {
-
 public:
 
-  //! Constructor
-  OpenGl_ResourceVBO(GLuint theId) : OpenGl_Resource (theId) {}
-
-  //! Destructor
-  virtual ~OpenGl_ResourceVBO() { }
-
-protected:
-
-  //! Clean procedure for VBO resource;
-  //! Should be called by the OpenGl_ResourceCleaner
-  Standard_EXPORT virtual void Clean (const Handle(OpenGl_Context)& theGlContext);
+  Standard_EXPORT OpenGl_IndexBuffer();
+  Standard_EXPORT virtual GLenum GetTarget() const;
 
 public:
 
-  DEFINE_STANDARD_RTTI(OpenGl_ResourceVBO) // Type definition
+  DEFINE_STANDARD_RTTI(OpenGl_IndexBuffer) // Type definition
 
 };
 
-DEFINE_STANDARD_HANDLE(OpenGl_ResourceVBO,OpenGl_Resource)
+DEFINE_STANDARD_HANDLE(OpenGl_IndexBuffer, OpenGl_VertexBuffer)
 
-#endif
+#endif // _OpenGl_IndexBuffer_H__
index 741d235..1f19e07 100644 (file)
 
 /*----------------------------------------------------------------------*/
 
+void OpenGl_Marker::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
+}
+
 void OpenGl_Marker::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
 {
   const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker( Standard_True );
index 87348fd..c8c0e06 100644 (file)
@@ -30,9 +30,9 @@ class OpenGl_Marker : public OpenGl_Element
  public:
 
   OpenGl_Marker (const TEL_POINT &APoint) : myPoint(APoint) {}
-  virtual ~OpenGl_Marker () {}
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
  protected:
 
index b09bffe..c2a4dd4 100644 (file)
@@ -140,4 +140,7 @@ void OpenGl_MarkerSet::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   }
 }
 
-/*----------------------------------------------------------------------*/
+void OpenGl_MarkerSet::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
+}
index 5f4d19e..4840f0c 100644 (file)
 
 class OpenGl_MarkerSet : public OpenGl_Element
 {
- public:
+
+public:
 
   OpenGl_MarkerSet (const Standard_Integer ANbPoints, const Graphic3d_Vertex *APoints);
-  virtual ~OpenGl_MarkerSet ();
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
+
+protected:
+
+  virtual ~OpenGl_MarkerSet();
 
- protected:
+protected:
 
-  Tint myNbPoints;
-  TEL_POINT *myPoints;
+  Tint       myNbPoints;
+  TEL_POINT* myPoints;
+
+public:
 
- public:
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //OpenGl_MarkerSet_Header
index 902297f..d370ef8 100644 (file)
@@ -622,4 +622,7 @@ void OpenGl_Polygon::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   glPopAttrib(); /* skt: GL_ENABLE_BIT*/
 }
 
-/*----------------------------------------------------------------------*/
+void OpenGl_Polygon::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
+}
index b6638a8..6e9d19b 100644 (file)
@@ -52,15 +52,18 @@ struct TEL_POLYGON_DATA
 
 class OpenGl_Polygon : public OpenGl_Element
 {
- public:
+
+public:
 
   OpenGl_Polygon (const Graphic3d_Array1OfVertex& AListVertex,
                  const Graphic3d_TypeOfPolygon AType);
-  virtual ~OpenGl_Polygon ();
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
+
+protected:
 
- protected:
+  virtual ~OpenGl_Polygon();
 
   void draw_polygon_concav (const Handle(OpenGl_Workspace) &AWorkspace, Tint) const;
 
@@ -72,8 +75,10 @@ class OpenGl_Polygon : public OpenGl_Element
 
   TEL_POLYGON_DATA myData;
 
- public:
+public:
+
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //OpenGl_Polygon_Header
index ef27a8b..05dd82a 100644 (file)
@@ -42,6 +42,11 @@ OpenGl_Polyline::~OpenGl_Polyline()
   delete[] myVertices;
 }
 
+void OpenGl_Polyline::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
+}
+
 /*----------------------------------------------------------------------*/
 
 void OpenGl_Polyline::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
index c3b2ccc..ac17e10 100644 (file)
 
 class OpenGl_Polyline : public OpenGl_Element
 {
- public:
+
+public:
 
   OpenGl_Polyline (const Graphic3d_Array1OfVertex& AListVertex);
-  virtual ~OpenGl_Polyline ();
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
+
+protected:
+
+  virtual ~OpenGl_Polyline();
 
- protected:
+protected:
 
   Tint       myNbVertices;    // Number of vertices in vertices array
   tel_point  myVertices;      // Vertices array of length myNbVertices
 
- public:
+public:
+
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //OpenGl_Polyline_Header
index b0dd084..63457f0 100755 (executable)
 // and conditions governing the rights and limitations under the License.
 
 
-#include <OpenGl_ArbVBO.hxx>
+#include <OpenGl_IndexBuffer.hxx>
 #include <OpenGl_Context.hxx>
 
 #include <OpenGl_PrimitiveArray.hxx>
 
 #include <OpenGl_AspectFace.hxx>
 #include <OpenGl_GraphicDriver.hxx>
-#include <OpenGl_ResourceCleaner.hxx>
-#include <OpenGl_ResourceVBO.hxx>
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_TextureBox.hxx>
 
 #include <InterfaceGraphic_PrimitiveArray.hxx>
 
-enum
-{
-  VBO_NOT_INITIALIZED = -1,
-  VBO_ERROR           =  0,
-  VBO_OK              =  1
-};
-
 namespace
 {
   static unsigned long vRand = 1L;
@@ -51,219 +42,98 @@ namespace
 // =======================================================================
 void OpenGl_PrimitiveArray::clearMemoryOwn() const
 {
-  if (myPArray->bufferVBO[VBOEdges] != 0)
-  {
-    Standard::Free ((Standard_Address& )myPArray->edges);
-    myPArray->edges = NULL;
-  }
-  if (myPArray->bufferVBO[VBOVertices] != 0)
-  {
-    Standard::Free ((Standard_Address& )myPArray->vertices);
-    myPArray->vertices = NULL;
-  }
-  if (myPArray->bufferVBO[VBOVcolours] != 0)
-  {
-    Standard::Free ((Standard_Address& )myPArray->vcolours);
-    myPArray->vcolours = NULL;
-  }
-  if (myPArray->bufferVBO[VBOVnormals] != 0)
-  {
-    Standard::Free ((Standard_Address& )myPArray->vnormals);
-    myPArray->vnormals = NULL;
-  }
-  if (myPArray->bufferVBO[VBOVtexels] != 0)
-  {
-    Standard::Free ((Standard_Address& )myPArray->vtexels);
-    myPArray->vtexels = NULL;
-  }
-  if (myPArray->edge_vis != NULL) /// ????
-  {
-    Standard::Free ((Standard_Address& )myPArray->edge_vis);
-    myPArray->edge_vis = NULL;
-  }
+  Standard::Free ((Standard_Address& )myPArray->edges);
+  Standard::Free ((Standard_Address& )myPArray->vertices);
+  Standard::Free ((Standard_Address& )myPArray->vcolours);
+  Standard::Free ((Standard_Address& )myPArray->vnormals);
+  Standard::Free ((Standard_Address& )myPArray->vtexels);
+  Standard::Free ((Standard_Address& )myPArray->edge_vis); /// ???
+
+  myPArray->edges    = NULL;
+  myPArray->vertices = NULL;
+  myPArray->vcolours = NULL;
+  myPArray->vnormals = NULL;
+  myPArray->vtexels  = NULL;
+  myPArray->edge_vis = NULL;
 }
 
 // =======================================================================
 // function : clearMemoryGL
 // purpose  :
 // =======================================================================
-void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlContext) const
+void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const
 {
-  if (myPArray->bufferVBO[VBOEdges] != 0)
+  for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
   {
-    theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);
-  }
-  if (myPArray->bufferVBO[VBOVertices] != 0)
-  {
-    theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
-  }
-  if (myPArray->bufferVBO[VBOVcolours] != 0)
-  {
-    theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
-  }
-  if (myPArray->bufferVBO[VBOVnormals] != 0)
-  {
-    theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
-  } 
-  if (myPArray->bufferVBO[VBOVtexels] != 0)
-  {
-    theGlContext->arbVBO->glDeleteBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
+    if (!myVbos[anIter].IsNull())
+    {
+      myVbos[anIter]->Release (theGlCtx.operator->());
+      myVbos[anIter].Nullify();
+    }
   }
-  theGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
-  theGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
 }
 
 // =======================================================================
-// function : checkSizeForGraphicMemory
+// function : BuildVBO
 // purpose  :
 // =======================================================================
-Standard_Boolean OpenGl_PrimitiveArray::checkSizeForGraphicMemory (const Handle(OpenGl_Context)& theGlContext) const
+Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  if (glGetError() == GL_OUT_OF_MEMORY)
+  const Handle(OpenGl_Context)& aGlCtx = theWorkspace->GetGlContext();
+  if (myPArray->vertices == NULL)
   {
-    myPArray->flagBufferVBO = VBO_ERROR;
-    clearMemoryGL (theGlContext);
+    // vertices should be always defined - others are optional
+    return Standard_False;
   }
-  else
+  myVbos[VBOVertices] = new OpenGl_VertexBuffer();
+  if (!myVbos[VBOVertices]->Init (aGlCtx, 3, myPArray->num_vertexs, &myPArray->vertices[0].xyz[0]))
   {
-    myPArray->flagBufferVBO = VBO_OK;
+    clearMemoryGL (aGlCtx);
+    return Standard_False;
   }
-  return myPArray->flagBufferVBO == VBO_OK;
-}
 
-// =======================================================================
-// function : BuildVBO
-// purpose  :
-// =======================================================================
-Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
-{
-  int size_reqd = 0;
-  const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
   if (myPArray->edges != NULL)
   {
-    size_reqd = myPArray->num_edges * sizeof(Tint);
-    aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOEdges]);   
-    aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
-    aGlContext->arbVBO->glBufferDataARB (GL_ELEMENT_ARRAY_BUFFER_ARB, size_reqd, myPArray->edges, GL_STATIC_DRAW_ARB);
-    if (!checkSizeForGraphicMemory (aGlContext))
-      return Standard_False;
-  }
-
-  if (myPArray->vertices != NULL)
-  {
-    size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
-    aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVertices]);
-    aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
-    aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vertices, GL_STATIC_DRAW_ARB);
-    if (!checkSizeForGraphicMemory (aGlContext))
+    myVbos[VBOEdges] = new OpenGl_IndexBuffer();
+    if (!myVbos[VBOEdges]->Init (aGlCtx, 1, myPArray->num_edges, (GLuint* )myPArray->edges))
+    {
+      clearMemoryGL (aGlCtx);
       return Standard_False;
+    }
   }
-
   if (myPArray->vcolours != NULL)
   {
-    size_reqd = myPArray->num_vertexs * sizeof(Tint);
-    aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVcolours]);
-    aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]); 
-    aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vcolours, GL_STATIC_DRAW_ARB);
-    if (!checkSizeForGraphicMemory (aGlContext))
+    myVbos[VBOVcolours] = new OpenGl_VertexBuffer();
+    if (!myVbos[VBOVcolours]->Init (aGlCtx, 4, myPArray->num_vertexs, (GLubyte* )myPArray->vcolours))
+    {
+      clearMemoryGL (aGlCtx);
       return Standard_False;
+    }
   }
-
   if (myPArray->vnormals != NULL)
   {
-    size_reqd = myPArray->num_vertexs * sizeof(TEL_POINT);
-    aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVnormals]);
-    aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
-    aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vnormals, GL_STATIC_DRAW_ARB);
-    if (!checkSizeForGraphicMemory (aGlContext))
+    myVbos[VBOVnormals] = new OpenGl_VertexBuffer();
+    if (!myVbos[VBOVnormals]->Init (aGlCtx, 3, myPArray->num_vertexs, &myPArray->vnormals[0].xyz[0]))
+    {
+      clearMemoryGL (aGlCtx);
       return Standard_False;
+    }
   }
-
   if (myPArray->vtexels)
   {
-    size_reqd = myPArray->num_vertexs * sizeof(TEL_TEXTURE_COORD);
-    aGlContext->arbVBO->glGenBuffersARB (1, &myPArray->bufferVBO[VBOVtexels]);
-    aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
-    aGlContext->arbVBO->glBufferDataARB (GL_ARRAY_BUFFER_ARB, size_reqd, myPArray->vtexels, GL_STATIC_DRAW_ARB);
-    if (!checkSizeForGraphicMemory (aGlContext))
+    myVbos[VBOVtexels] = new OpenGl_VertexBuffer();
+    if (!myVbos[VBOVtexels]->Init (aGlCtx, 2, myPArray->num_vertexs, &myPArray->vtexels[0].xy[0]))
+    {
+      clearMemoryGL (aGlCtx);
       return Standard_False;
+    }
   }
 
-  if (myPArray->flagBufferVBO == VBO_OK)
-    clearMemoryOwn();
-
-  // specify context for VBO resource
-  myPArray->contextId = (Standard_Address )theWorkspace->GetGContext();
+  clearMemoryOwn();
   return Standard_True;
 }
 
 // =======================================================================
-// function : DrawArrays
-// purpose  : Auxiliary method to split Feedback/Normal rendering modes
-// =======================================================================
-inline void DrawArrays (const Handle(OpenGl_Workspace)& theWorkspace,
-                        const CALL_DEF_PARRAY* thePArray,
-                        const Standard_Boolean theIsFeedback,
-                        GLenum  theMode,
-                        GLint   theFirst,
-                        GLsizei theCount)
-{
-  if (!theIsFeedback)
-  {
-    glDrawArrays (theMode, theFirst, theCount);
-    return;
-  }
-
-  glBegin (theMode);
-  for (int anIter = theFirst; anIter < (theFirst + theCount); ++anIter)
-  {
-    if (thePArray->vnormals != NULL)
-      glNormal3fv (thePArray->vnormals[anIter].xyz);
-    if (thePArray->vtexels  != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
-      glTexCoord3fv (thePArray->vtexels[anIter].xy);
-    if (thePArray->vertices != NULL)
-      glVertex3fv (thePArray->vertices[anIter].xyz);
-    if (thePArray->vcolours != NULL)
-      glColor4ubv((GLubyte* )thePArray->vcolours[anIter]);
-  }
-  glEnd();
-}
-
-// =======================================================================
-// function : DrawElements
-// purpose  : Auxiliary method to split Feedback/Normal rendering modes
-// =======================================================================
-inline void DrawElements (const Handle(OpenGl_Workspace)& theWorkspace,
-                          const CALL_DEF_PARRAY* thePArray,
-                          const Standard_Boolean theIsFeedback,
-                          GLenum  theMode,
-                          GLsizei theCount,
-                          GLenum* theIndices)
-{
-  if (!theIsFeedback)
-  {
-    glDrawElements (theMode, theCount, GL_UNSIGNED_INT, theIndices);
-    return;
-  }
-
-  GLenum anIndex;
-  glBegin (theMode);
-  for (GLsizei anIter = 0; anIter < theCount; ++anIter)
-  {
-    anIndex = theIndices[anIter];
-    if (thePArray->vnormals != NULL)
-      glNormal3fv (thePArray->vnormals[anIndex].xyz);
-    if (thePArray->vtexels != NULL && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
-      glTexCoord3fv (thePArray->vtexels[anIndex].xy);
-    if (thePArray->vertices != NULL)
-      glVertex3fv (thePArray->vertices[anIndex].xyz);
-    if (thePArray->vcolours != NULL)
-      glColor4ubv ((GLubyte* )thePArray->vcolours[anIndex]);
-  }
-  glEnd();
-}
-
-// =======================================================================
 // function : DrawArray
 // purpose  :
 // =======================================================================
@@ -348,9 +218,7 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
     else
       glEnable (GL_LIGHTING);
 
-    if (myPArray->num_vertexs > 0
-     && myPArray->flagBufferVBO != VBO_OK
-     && !aGlContext->IsFeedback())
+    if (!toDrawVbo())
     {
       if (myPArray->vertices != NULL)
       {
@@ -376,62 +244,51 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
         glEnable (GL_COLOR_MATERIAL);
       }
     }
-    else if (myPArray->num_vertexs > 0
-          && myPArray->flagBufferVBO == VBO_OK)
+    else
     {
       // Bindings concrete pointer in accordance with VBO buffer
-      if (myPArray->bufferVBO[VBOVertices] != 0)
-      {
-        aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
-        glVertexPointer (3, GL_FLOAT, 0, NULL); // array of vertices 
-        glEnableClientState (GL_VERTEX_ARRAY);
-      }
-      if (myPArray->bufferVBO[VBOVnormals] != 0)
+      myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
+      if (!myVbos[VBOVnormals].IsNull())
       {
-        aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVnormals]);
-        glNormalPointer (GL_FLOAT, 0, NULL); // array of normals  
-        glEnableClientState (GL_NORMAL_ARRAY);
+        myVbos[VBOVnormals]->BindFixed (aGlContext, GL_NORMAL_ARRAY);
       }
-      if (myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
+      if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
       {
-        aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVtexels]);
-        glTexCoordPointer (2, GL_FLOAT, 0, NULL); // array of texture coordinates
-        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+        myVbos[VBOVtexels]->BindFixed (aGlContext, GL_TEXTURE_COORD_ARRAY);
       }
-      if (myPArray->bufferVBO[VBOVcolours] != 0)
+      if (!myVbos[VBOVcolours].IsNull())
       {
-        aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVcolours]);
-        glColorPointer (4, GL_UNSIGNED_BYTE, 0, NULL); // array of colors 
-        glEnableClientState (GL_COLOR_ARRAY);
-        glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
+        myVbos[VBOVcolours]->BindFixed (aGlContext, GL_COLOR_ARRAY);
+        glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
         glEnable (GL_COLOR_MATERIAL);
       }
     }
 
-    // OCC22236 NOTE: draw for all situations:
-    // 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
-    // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
-    // 3) draw primitive by vertexes if no edges and bounds array is specified
-    if (myPArray->flagBufferVBO == VBO_OK)
+    /// OCC22236 NOTE: draw for all situations:
+    /// 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
+    /// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
+    /// 3) draw primitive by vertexes if no edges and bounds array is specified
+    if (toDrawVbo())
     {
-      if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges] != 0)
+      if (!myVbos[VBOEdges].IsNull())
       {
-        aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]); // for edge indices
+        myVbos[VBOEdges]->Bind (aGlContext);
         if (myPArray->num_bounds > 0)
         {
           // draw primitives by vertex count with the indicies
           Tint* anOffset = NULL;
           for (i = 0; i < myPArray->num_bounds; ++i)
           {
-            glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, anOffset);
+            glDrawElements (myDrawMode, myPArray->bounds[i], myVbos[VBOEdges]->GetDataType(), anOffset);
             anOffset += myPArray->bounds[i]; 
           }
         }
         else
         {
           // draw one (or sequential) primitive by the indicies
-          glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
+          glDrawElements (myDrawMode, myPArray->num_edges, myVbos[VBOEdges]->GetDataType(), NULL);
         }
+        myVbos[VBOEdges]->Unbind (aGlContext);
       }
       else if (myPArray->num_bounds > 0)
       {
@@ -443,12 +300,25 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
       }
       else
       {
-        glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
+        glDrawArrays (myDrawMode, 0, myVbos[VBOVertices]->GetElemsNb());
       }
 
       // bind with 0
-      aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0); 
-      aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+      myVbos[VBOVertices]->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
+      if (!myVbos[VBOVnormals].IsNull())
+      {
+        myVbos[VBOVnormals]->UnbindFixed (aGlContext, GL_NORMAL_ARRAY);
+      }
+      if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
+      {
+        myVbos[VBOVtexels]->UnbindFixed (aGlContext, GL_TEXTURE_COORD_ARRAY);
+      }
+      if (!myVbos[VBOVcolours].IsNull())
+      {
+        myVbos[VBOVcolours]->UnbindFixed (aGlContext, GL_COLOR_ARRAY);
+        glDisable (GL_COLOR_MATERIAL);
+        theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
+      }
     } 
     else
     {
@@ -459,8 +329,7 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
           for (i = n = 0; i < myPArray->num_bounds; ++i)
           {
             if (pfc != NULL) glColor3fv (pfc[i].rgb);
-            DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
-                          myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
+            glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
             n += myPArray->bounds[i];
           }
         }
@@ -472,38 +341,34 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
             {
               glColor3fv (pfc[i].rgb);
             }
-            DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
-                        n, myPArray->bounds[i]);
+            glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
             n += myPArray->bounds[i];
           }
         }
       }
       else if (myPArray->num_edges > 0)
       {
-        DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
-                      myPArray->num_edges, (GLenum* )myPArray->edges);
+        glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
       }
       else
       {
-        DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
-                    0, myPArray->num_vertexs);
+        glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
       }
-    }
 
-    if (myPArray->bufferVBO[VBOVcolours] != 0 || pvc != NULL)
-    {
-      glDisable (GL_COLOR_MATERIAL);
-      theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
-    }
+      if (pvc != NULL)
+      {
+        glDisable (GL_COLOR_MATERIAL);
+        theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
+      }
 
-    if (myPArray->bufferVBO[VBOVertices] != 0 || myPArray->vertices != NULL)
       glDisableClientState (GL_VERTEX_ARRAY);
-    if (myPArray->bufferVBO[VBOVcolours] != 0 || myPArray->vcolours != NULL)
-      glDisableClientState (GL_COLOR_ARRAY);
-    if (myPArray->bufferVBO[VBOVnormals] != 0 || myPArray->vnormals != NULL)
-      glDisableClientState (GL_NORMAL_ARRAY);
-    if ((myPArray->bufferVBO[VBOVtexels] != 0 && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) || myPArray->vtexels != NULL)
-      glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+      if (myPArray->vcolours != NULL)
+        glDisableClientState (GL_COLOR_ARRAY);
+      if (myPArray->vnormals != NULL)
+        glDisableClientState (GL_NORMAL_ARRAY);
+      if (myPArray->vtexels != NULL)
+        glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+    }
 
     if (theWorkspace->DegenerateModel)
     {
@@ -535,15 +400,15 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
         break;
       // DegenerateModel(as Lines, Points, BBoxs) are used only without VBO
       case 2: // XXX_TDM_WIREFRAME
-        if (myPArray->VBOEnabled == 0)
+        if (!toDrawVbo())
           DrawDegeneratesAsLines ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace);
         break;
       case 3: // XXX_TDM_MARKER
-        if (myPArray->VBOEnabled == 0)
+        if (!toDrawVbo())
           DrawDegeneratesAsPoints ((theEdgeFlag ? theEdgeColour : theInteriorColour), theWorkspace->SkipRatio);
         break;
       case 4: // XXX_TDM_BBOX
-        if (myPArray->VBOEnabled == 0)
+        if (!toDrawVbo())
           DrawDegeneratesAsBBoxs (theEdgeFlag ? theEdgeColour : theInteriorColour);
         break;
     }
@@ -575,18 +440,17 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR*               theEdgeCo
 
   Tint i, j, n;
 
-  // OCC22236 NOTE: draw edges for all situations:
-  // 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
-  // 2) draw elements from vertice array, when bounds defines count of primitive's verts.
-  // 3) draw primitive's edges by vertexes if no edges and bounds array is specified
-  if (myPArray->flagBufferVBO == VBO_OK)
+  /// OCC22236 NOTE: draw edges for all situations:
+  /// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
+  /// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
+  /// 3) draw primitive's edges by vertexes if no edges and bounds array is specified
+  if (toDrawVbo())
   { 
-    aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOVertices]);
-    glEnableClientState (GL_VERTEX_ARRAY);
+    myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
     glColor3fv (theEdgeColour->rgb);
-    if (myPArray->num_edges > 0 && myPArray->bufferVBO[VBOEdges])
+    if (!myVbos[VBOEdges].IsNull())
     {
-      aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, myPArray->bufferVBO[VBOEdges]);
+      myVbos[VBOEdges]->Bind (aGlContext);
 
       // draw primitives by vertex count with the indicies
       if (myPArray->num_bounds > 0)
@@ -594,15 +458,16 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR*               theEdgeCo
         Tint* offset = 0;
         for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
         {
-          glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, offset);
+          glDrawElements (myDrawMode, myPArray->bounds[i], myVbos[VBOEdges]->GetDataType(), offset);
           offset += myPArray->bounds[i];
         }
       }
       // draw one (or sequential) primitive by the indicies
       else
       {
-        glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, NULL);
+        glDrawElements (myDrawMode, myVbos[VBOEdges]->GetElemsNb(), myVbos[VBOEdges]->GetDataType(), NULL);
       }
+      myVbos[VBOEdges]->Unbind (aGlContext);
     }
     else if (myPArray->num_bounds > 0)
     {
@@ -618,9 +483,7 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR*               theEdgeCo
     }
 
     // unbind buffers
-    glDisableClientState (GL_VERTEX_ARRAY);
-    aGlContext->arbVBO->glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
-    aGlContext->arbVBO->glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+    myVbos[VBOVertices]->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
   }
   else
   {
@@ -646,8 +509,7 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR*               theEdgeCo
           }
           else
           {
-            DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
-                          myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
+            glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
           }
           n += myPArray->bounds[i];
         }
@@ -656,8 +518,7 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR*               theEdgeCo
       {
         for (i = n = 0 ; i < myPArray->num_bounds; ++i)
         {
-          DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
-                      n, myPArray->bounds[i]);
+          glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
           n += myPArray->bounds[i];
         }
       }
@@ -676,14 +537,12 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR*               theEdgeCo
       }
       else
       {
-        DrawElements (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
-                      myPArray->num_edges, (GLenum* )myPArray->edges);
+        glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
       }
     }
     else
     {
-      DrawArrays (theWorkspace, myPArray, aGlContext->IsFeedback(), myDrawMode,
-                  0, myPArray->num_vertexs);
+      glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
     }
   }
 
@@ -1514,7 +1373,6 @@ void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR*
   else
   {
     int i,n;
-    Standard_Boolean isFeedback = theWorkspace->GetGlContext()->IsFeedback();
     glPushAttrib (GL_POLYGON_BIT);
     glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
 
@@ -1542,8 +1400,7 @@ void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR*
       {
         for (i = n = 0; i < myPArray->num_bounds; ++i)
         {
-          DrawElements (theWorkspace, myPArray, isFeedback, myDrawMode,
-                        myPArray->bounds[i], (GLenum* )&myPArray->edges[n]);
+          glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
           n += myPArray->bounds[i];
         }
       }
@@ -1551,21 +1408,18 @@ void OpenGl_PrimitiveArray::DrawDegeneratesAsLines (const TEL_COLOUR*
       {
         for (i = n = 0; i < myPArray->num_bounds; ++i)
         {
-          DrawArrays (theWorkspace, myPArray, isFeedback, myDrawMode,
-                      n, myPArray->bounds[i]);
+          glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
           n += myPArray->bounds[i];
         }
       }
     }
     else if (myPArray->num_edges > 0)
     {
-      DrawElements (theWorkspace, myPArray, isFeedback, myDrawMode,
-                    myPArray->num_edges, (GLenum* )myPArray->edges);
+      glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
     }
     else
     {
-      DrawArrays (theWorkspace, myPArray, isFeedback, myDrawMode,
-                  0, myPArray->num_vertexs);
+      glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
     }
 
     if (!vertex_array_mode) glDisableClientState (GL_VERTEX_ARRAY);
@@ -1644,7 +1498,8 @@ void OpenGl_PrimitiveArray::DrawDegeneratesAsBBoxs (const TEL_COLOUR* theEdgeCol
 // =======================================================================
 OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
 : myPArray (thePArray),
-  myDrawMode (DRAW_MODE_NONE)
+  myDrawMode (DRAW_MODE_NONE),
+  myIsVboInit (Standard_False)
 {
   switch (myPArray->type)
   {
@@ -1682,29 +1537,24 @@ OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
 // function : ~OpenGl_PrimitiveArray
 // purpose  :
 // =======================================================================
-OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray ()
+OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray()
 {
-  if (myPArray == NULL)
-    return;
+  //
+}
 
-  if (myPArray->VBOEnabled == VBO_OK)
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_PrimitiveArray::Release (const Handle(OpenGl_Context)& theContext)
+{
+  for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
   {
-    OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
-    if (myPArray->bufferVBO[VBOEdges] != 0)
-      aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
-                                new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOEdges]));
-    if (myPArray->bufferVBO[VBOVertices] != 0)
-      aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
-                                new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVertices]));
-    if (myPArray->bufferVBO[VBOVcolours] != 0)
-      aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
-                                new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVcolours]));
-    if (myPArray->bufferVBO[VBOVnormals] != 0)
-      aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
-                                new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVnormals]));
-    if (myPArray->bufferVBO[VBOVtexels] != 0)
-      aResCleaner->AddResource ((GLCONTEXT )myPArray->contextId,
-                                new OpenGl_ResourceVBO (myPArray->bufferVBO[VBOVtexels]));
+    if (!myVbos[anIter].IsNull())
+    {
+      theContext->DelayedRelease (myVbos[anIter]);
+      myVbos[anIter].Nullify();
+    }
   }
 }
 
@@ -1714,15 +1564,14 @@ OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray ()
 // =======================================================================
 void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  if (myPArray == NULL || myDrawMode == DRAW_MODE_NONE)
+  if (myPArray == NULL || myDrawMode == DRAW_MODE_NONE || myPArray->num_vertexs <= 0)
     return;
 
   // create VBOs on first render call
-  if (myPArray->VBOEnabled == -1) // special value for uninitialized state
+  if (!myIsVboInit && OpenGl_GraphicDriver::ToUseVBO() && theWorkspace->GetGlContext()->core15 != NULL)
   {
-    myPArray->VBOEnabled = OpenGl_GraphicDriver::ToUseVBO() && (theWorkspace->GetGlContext()->arbVBO != NULL);
-    if (myPArray->VBOEnabled != 0)
-      BuildVBO (theWorkspace);
+    BuildVBO (theWorkspace);
+    myIsVboInit = Standard_True;
   }
 
   switch (myPArray->type)
index 7336404..4d4a4fd 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef OpenGl_PrimitiveArray_Header
 #define OpenGl_PrimitiveArray_Header
 
-#include <OpenGl_GlCore11.hxx>
+#include <OpenGl_VertexBuffer.hxx>
 
 #include <InterfaceGraphic_telem.hxx>
 #include <Aspect_InteriorStyle.hxx>
@@ -29,7 +29,6 @@
 #include <OpenGl_Element.hxx>
 
 struct OPENGL_SURF_PROP;
-class Handle(OpenGl_Context);
 
 class OpenGl_PrimitiveArray : public OpenGl_Element
 {
@@ -45,21 +44,24 @@ public:
   //! Default constructor
   OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray);
 
-  //! Destructor
-  virtual ~OpenGl_PrimitiveArray();
-
   //! Render primitives to the window
-  virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
   CALL_DEF_PARRAY* PArray() const { return myPArray; }
 
 private:
 
+  Standard_Boolean toDrawVbo() const
+  {
+    return !myVbos[VBOVertices].IsNull();
+  }
+
   //! VBO initialization procedures
   Standard_Boolean BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const;
   void clearMemoryOwn() const;
-  void clearMemoryGL (const Handle(OpenGl_Context)& theGlContext) const;
-  Standard_Boolean checkSizeForGraphicMemory (const Handle(OpenGl_Context)& theGlContext) const;
+  void clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const;
 
   //! Main procedure to draw array
   void DrawArray (Tint theLightingModel,
@@ -97,8 +99,25 @@ private:
 
 protected:
 
-  mutable CALL_DEF_PARRAY* myPArray;
-  GLint                    myDrawMode;
+  //! Destructor
+  virtual ~OpenGl_PrimitiveArray();
+
+protected:
+
+  typedef enum
+  {
+    VBOEdges,
+    VBOVertices,
+    VBOVcolours,
+    VBOVnormals,
+    VBOVtexels,
+    VBOMaxType
+  } VBODataType;
+
+  mutable CALL_DEF_PARRAY*            myPArray;
+  mutable Handle(OpenGl_VertexBuffer) myVbos[VBOMaxType];
+  GLint                               myDrawMode;
+  mutable Standard_Boolean            myIsVboInit;
 
 public:
 
index 030a123..5092167 100644 (file)
@@ -19,5 +19,8 @@
 
 #include <OpenGl_Resource.hxx>
 
-IMPLEMENT_STANDARD_HANDLE (OpenGl_Resource, MMgt_TShared)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Resource, MMgt_TShared)
+IMPLEMENT_STANDARD_HANDLE (OpenGl_Resource, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Resource, Standard_Transient)
+
+OpenGl_Resource::OpenGl_Resource() {}
+OpenGl_Resource::~OpenGl_Resource() {}
index c7cd264..449249b 100755 (executable)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#ifndef _OpenGl_Resource_H__
+#define _OpenGl_Resource_H__
 
-#ifndef _OPENGL_RESOURCE_H
-#define _OPENGL_RESOURCE_H
-
-#include <OpenGl_GlCore11.hxx>
-
-#include <OpenGl_ResourceCleaner.hxx>
-#include <MMgt_TShared.hxx>
-#include <Handle_MMgt_TShared.hxx>
+#include <Standard_Transient.hxx>
+#include <Handle_Standard_Transient.hxx>
 
 class Standard_Transient;
 class Handle(Standard_Type);
-class Handle(MMgt_TShared);
-class Handle(OpenGl_Context);
-class OpenGl_ResourceCleaner;
-
-//! Class represents basic OpenGl memory resource, which
-//! could be removed only if appropriate context is avaliable;
-//! The cleaning procedure is done by OpenGl_ResourceCleaner
-class OpenGl_Resource : public MMgt_TShared
+class OpenGl_Context;
+
+//! Interface for OpenGl resource with following meaning:
+//!  - object can be constructed at any time;
+//!  - should be explicitly Initialized within active OpenGL context;
+//!  - should be explicitly Released    within active OpenGL context (virtual Release() method);
+//!  - can be destroyed at any time.
+//! Destruction of object with unreleased GPU resources will cause leaks
+//! which will be ignored in release mode and will immediately stop program execution in debug mode using assert.
+class OpenGl_Resource : public Standard_Transient
 {
 
 public:
 
-  //! Constructor
-  OpenGl_Resource() : myId(0) { }
-  //! Constructor 
-  OpenGl_Resource(GLuint theId) : myId(theId) { }
-
-  //! Destructor
-  virtual ~OpenGl_Resource() {}
-
-  //! method clean() is accessible only by OpenGl_ResourceCleaner
-  friend class OpenGl_ResourceCleaner;
+  //! Empty constructor
+  Standard_EXPORT OpenGl_Resource();
 
-protected:
+  //! Destructor. Inheritors should call Clean (NULL) within it.
+  Standard_EXPORT virtual ~OpenGl_Resource();
 
-  //! Clean procedure, should be called only by OpenGl_ResourceCleaner;
-  //! Each type of resource has its own cleaning procedure
-  virtual void Clean (const Handle(OpenGl_Context)& theGlContext) = 0;
+  //! Release GPU resources.
+  //! Notice that implementation should be SAFE for several consecutive calls
+  //! (thus should invalidate internal structures / ids to avoid multiple-free errors).
+  //! @param theGlCtx - bound GL context, shouldn't be NULL.
+  Standard_EXPORT virtual void Release (const OpenGl_Context* theGlCtx) = 0;
 
-protected:
+private:
 
-  GLuint myId; // Id of OpenGl memory resource
+  //! Copy should be performed only within Handles!
+  OpenGl_Resource            (const OpenGl_Resource& );
+  OpenGl_Resource& operator= (const OpenGl_Resource& );
 
 public:
 
@@ -69,6 +63,6 @@ public:
 
 };
 
-DEFINE_STANDARD_HANDLE(OpenGl_Resource,MMgt_TShared)
+DEFINE_STANDARD_HANDLE(OpenGl_Resource, Standard_Transient)
 
-#endif
+#endif // _OpenGl_Resource_H__
diff --git a/src/OpenGl/OpenGl_ResourceCleaner.cxx b/src/OpenGl/OpenGl_ResourceCleaner.cxx
deleted file mode 100755 (executable)
index bcfec36..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-// Created on: 2011-03-18
-// Created by: Anton POLETAEV
-// Copyright (c) 2011-2012 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 <OpenGl_ResourceCleaner.hxx>
-#include <OpenGl_ResourceVBO.hxx>
-
-//=======================================================================
-//function : OpenGl_ResourceCleaner
-//purpose  : Constructor
-//=======================================================================
-
-OpenGl_ResourceCleaner::OpenGl_ResourceCleaner() 
-{
-  mySharedContexts.Clear();
-  mySharedQueue.Clear();
-  myInstanceQueue.Clear();
-}
-
-//=======================================================================
-//function : AppendContext
-//purpose  : Append given OpenGl context to the OpenGl_ResourceCleaner
-//           control list
-//=======================================================================
-
-void OpenGl_ResourceCleaner::AppendContext(GLCONTEXT theContext, Standard_Boolean isShared)
-{  
-  
-  // appending shared context
-  if (isShared) 
-  {
-    mySharedContexts.Add(theContext);
-  }
-  else
-  {
-    // if context is already in the list
-    if (myInstanceQueue.IsBound(theContext)) 
-    {
-      QueueOfResources *aQueue = &myInstanceQueue.ChangeFind(theContext);
-      aQueue->Clear();
-    }
-    else 
-    {
-      // context is not in the list - create empty queue for it and add queue to the list
-      QueueOfResources aQueue;
-      aQueue.Clear();
-      myInstanceQueue.Bind(theContext, aQueue);
-    }
-  }
-
-}
-
-//=======================================================================
-//function : AddResource
-//purpose  : Tell the OpenGl_ResourceCleaner to clean up the OpenGl 
-//           memory resource
-//=======================================================================
-
-Standard_Boolean OpenGl_ResourceCleaner::AddResource(GLCONTEXT theContext, const Handle(OpenGl_Resource)& theResource) 
-{
-  // if context found in the shared list
-  if (mySharedContexts.Contains(theContext)) 
-  {
-    mySharedQueue.Push(theResource);
-    return Standard_True;
-  }
-  // if not, then it might be found in the non-shared list
-  else if (myInstanceQueue.IsBound(theContext)) 
-  {
-    QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(theContext);
-    aQueue->Push(theResource);
-    return Standard_True;
-  }
-  
-  // context is not under OpenGl_ResourceCleaner control, do not tell to clean the resource
-  return Standard_False;
-}
-
-//=======================================================================
-//function : Clear
-//purpose  : Cancel clean procedure for all the resources added to the 
-//           OpenGl_ResourceCleaner 
-//=======================================================================
-
-void OpenGl_ResourceCleaner::Clear() 
-{
-  mySharedQueue.Clear();
-  DataMapOfContextsResources::Iterator anIter(myInstanceQueue);
-
-  // remove the resources from the list
-  for (anIter.Reset(); anIter.More(); anIter.Next()) 
-  {
-    QueueOfResources * aQueue = &anIter.ChangeValue();
-    aQueue->Clear();
-  }
-
-}
-
-//=======================================================================
-//function : Clear
-//purpose  : Cancel clean procedure for all the resources of the specific
-//           OpenGl context which were added to the OpenGl_ResourceCleaner
-//=======================================================================
-
-Standard_Boolean OpenGl_ResourceCleaner::Clear(GLCONTEXT theContext) 
-{
-  // check if the context in the the control list
-  if (myInstanceQueue.IsBound(theContext)) 
-  {
-    QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(theContext);
-    aQueue->Clear();
-    return Standard_True;
-  }
-
-  return Standard_False;
-}
-
-//=======================================================================
-//function : ClearShared
-//purpose  : Cancel clean procedure for all of the shared resources
-//=======================================================================
-
-void OpenGl_ResourceCleaner::ClearShared()
-{
-  mySharedQueue.Clear();
-}
-
-//=======================================================================
-//function : Cleanup
-//purpose  : Clear the unused resources for active OpenGl context
-//=======================================================================
-
-void OpenGl_ResourceCleaner::Cleanup (const Handle(OpenGl_Context)& theGlContext)
-{
-  GLCONTEXT aContext = GET_GL_CONTEXT();
-  if (aContext == NULL)
-    return;
-
-  // if the context is found in shared list
-  if (mySharedContexts.Contains (aContext)) 
-  {
-    while (mySharedQueue.Size() > 0) 
-    {
-      mySharedQueue.Front()->Clean (theGlContext); // delete resource memory
-      mySharedQueue.Pop();
-    }
-  }
-  // if the context is found in non-shared list
-  else if (myInstanceQueue.IsBound (aContext)) 
-  {
-    QueueOfResources* aQueue = &myInstanceQueue.ChangeFind (aContext);
-    while (aQueue->Size() > 0) 
-    {
-      aQueue->Front()->Clean (theGlContext); // delete resource memory
-      aQueue->Pop();
-    }
-  }
-}
-
-//=======================================================================
-//function : RemoveContext
-//purpose  : Remove the OpenGl context from the OpenGl_ResourceCleaner list
-//=======================================================================
-
-void OpenGl_ResourceCleaner::RemoveContext(GLCONTEXT theContext)
-{
-  // if context can be found in shared list try to remove it
-  // if it wasn't in there, try to remove it from non-shared list
-  if (!mySharedContexts.Remove(theContext))
-    myInstanceQueue.UnBind(theContext);  
-
-  // if no contexts in shared list, then there is no need to clean
-  // the resources on redraw
-  if (mySharedContexts.Size() == 0)
-    mySharedQueue.Clear();
-
-}
-
-//=======================================================================
-//function : GetSharedContext
-//purpose  : Get any of shared contexts from the OpenGl_ResourceCleaner list
-//=======================================================================
-
-GLCONTEXT OpenGl_ResourceCleaner::GetSharedContext() const
-{
-  if(mySharedContexts.Size() > 0) 
-  {
-    MapOfContexts::Iterator anIter(mySharedContexts);
-    anIter.Reset();
-    return anIter.Value();
-  }
-
-  return 0;
-}
-
-//=======================================================================
-//function : GetInstance
-//purpose  : Get the global instance of OpenGl_ResourceCleaner
-//=======================================================================
-
-OpenGl_ResourceCleaner* OpenGl_ResourceCleaner::GetInstance()
-{
-  // the static instance entity
-  static OpenGl_ResourceCleaner* anInstance = NULL;
-
-  if (anInstance == NULL)
-    anInstance = new OpenGl_ResourceCleaner;
-
-  return anInstance;
-}
diff --git a/src/OpenGl/OpenGl_ResourceCleaner.hxx b/src/OpenGl/OpenGl_ResourceCleaner.hxx
deleted file mode 100755 (executable)
index dd5a234..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// Created on: 2011-03-18
-// Created by: Anton POLETAEV
-// Copyright (c) 2011-2012 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_RESOURCECLEANER_H
-#define _OPENGL_RESOURCECLEANER_H
-
-#include <OpenGl_GlCore11.hxx>
-#include <NCollection_Queue.hxx>
-#include <NCollection_List.hxx>
-#include <NCollection_Map.hxx>
-#include <NCollection_DataMap.hxx>
-#include <OpenGl_Resource.hxx>
-
-class OpenGl_Resource;
-class Handle(OpenGl_Resource);
-class Handle(OpenGl_Context);
-
-typedef NCollection_Queue<Handle_OpenGl_Resource> QueueOfResources;
-typedef NCollection_DataMap<GLCONTEXT, QueueOfResources> DataMapOfContextsResources;
-typedef NCollection_Map<GLCONTEXT> MapOfContexts;
-
-//! OpenGl_ResourceCleaner should be used to clean OpenGl memory resources;
-//! The reason is that the resources might be shared between the contexts and
-//! should be cleaned up only while suitable context is active;
-class OpenGl_ResourceCleaner
-{
-
-public:
-       
-  //! Constructor
-  OpenGl_ResourceCleaner();
-
-  //! Destructor
-  virtual ~OpenGl_ResourceCleaner() { }
-
-  //! Append OpenGl context to the OpenGl_ResourceCleaner
-  //! control list.
-  void AppendContext(GLCONTEXT theContext, Standard_Boolean isShared); 
-  
-  //! Tell the OpenGl_ResourceCleaner to clean up the OpenGl memory resource
-  //! which has been created by the specified OpenGl context;
-  //! The context should be in the OpenGl_ResourceCleaner control list.
-  Standard_EXPORT Standard_Boolean AddResource(GLCONTEXT theContext, const Handle(OpenGl_Resource)& theResource);
-
-  //! Cancel clean procedure for all the resources added to the OpenGl_ResourceCleaner.
-  void Clear();
-
-  //! Cancel clean procedure for all the resources of the specific OpenGl context 
-  //! which were added to the OpenGl_ResourceCleaner.
-  Standard_Boolean Clear(GLCONTEXT theContext);
-
-  //! Cancel clean procedure for all of the shared resources.
-  void ClearShared();
-
-  //! Clear the unused resources for active OpenGl context;
-  //! You should add the cleaner resources by AddResources method;
-  //! It is suggested to call this method right before the OpenGl
-  //! new frame drawing procedure starts.
-  void Cleanup (const Handle(OpenGl_Context)& theGlContext);
-
-  //! Remove the OpenGl context from the OpenGl_ResourceCleaner control list.
-  void RemoveContext(GLCONTEXT theContext);
-
-  //! Get any of shared contexts from the OpenGl_ResourceCleaner list 
-  //! to share resources with a new one
-  GLCONTEXT GetSharedContext() const;
-
-  //! Get the global instance of OpenGl_ResourceCleaner
-  Standard_EXPORT static OpenGl_ResourceCleaner* GetInstance();
-
-private:
-
-  DataMapOfContextsResources myInstanceQueue;  // map for queues of non-shared context's resources
-  QueueOfResources mySharedQueue;              // queue of shared context's resources
-  MapOfContexts mySharedContexts;              // the control list of shared contexts
-
-};
-
-#endif
index c48056e..fd3eb8d 100755 (executable)
 
 
 #include <OpenGl_GlCore11.hxx>
+#include <OpenGl_Context.hxx>
 #include <OpenGl_ResourceTexture.hxx>
 
 IMPLEMENT_STANDARD_HANDLE (OpenGl_ResourceTexture, OpenGl_Resource)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ResourceTexture, OpenGl_Resource)
 
 //=======================================================================
-//function : Clean
+//function : OpenGl_ResourceTexture
+//purpose  :
+//=======================================================================
+OpenGl_ResourceTexture::OpenGl_ResourceTexture (const GLuint theId)
+: myTextureId (theId)
+{
+  //
+}
+
+//=======================================================================
+//function : ~OpenGl_ResourceTexture
+//purpose  :
+//=======================================================================
+OpenGl_ResourceTexture::~OpenGl_ResourceTexture()
+{
+  Release (NULL);
+}
+
+//=======================================================================
+//function : Release
 //purpose  : free OpenGl memory allocated for texture resource
 //=======================================================================
-void OpenGl_ResourceTexture::Clean (const Handle(OpenGl_Context)& theGlContext)
+void OpenGl_ResourceTexture::Release (const OpenGl_Context* theGlCtx)
 {
-  glDeleteTextures (1, &myId);
+  if (myTextureId != 0 && theGlCtx != NULL)
+  {
+    glDeleteTextures (1, &myTextureId);
+    myTextureId = 0;
+  }
 }
index 57c4dfd..c117ef9 100755 (executable)
@@ -34,16 +34,17 @@ class OpenGl_ResourceTexture : public OpenGl_Resource
 public:
 
   //! Constructor
-  OpenGl_ResourceTexture(GLuint theId) : OpenGl_Resource (theId) {}
+  Standard_EXPORT OpenGl_ResourceTexture (const GLuint theId);
 
   //! Destructor
-  virtual ~OpenGl_ResourceTexture() { }
+  Standard_EXPORT virtual ~OpenGl_ResourceTexture();
+
+  //! Destroy object - will release GPU memory if any.
+  Standard_EXPORT virtual void Release (const OpenGl_Context* theGlCtx);
 
 protected:
 
-  //! Clean procedure for texture resource;
-  //! Should be called by the OpenGl_ResourceCleaner
-  Standard_EXPORT virtual void Clean (const Handle(OpenGl_Context)& theGlContext);
+  GLuint myTextureId; //!< Texture name (index)
 
 public:
 
index 94b1657..8730522 100644 (file)
@@ -59,46 +59,12 @@ OpenGl_Structure::OpenGl_Structure ()
 
 /*----------------------------------------------------------------------*/
 
-OpenGl_Structure::~OpenGl_Structure ()
+OpenGl_Structure::~OpenGl_Structure()
 {
-  if (myTransformation)
-  {
-    delete myTransformation;
-    myTransformation = NULL;
-  }
-  if (myTransPers)
-  {
-    delete myTransPers;
-    myTransPers = NULL;
-  }
-  if (myDegenerateModel)
-  {
-    delete myDegenerateModel;
-    myDegenerateModel = NULL;
-  }
-  if (myAspectLine)
-  {
-    delete myAspectLine;
-    myAspectLine = NULL;
-  }
-  if (myAspectFace)
-  {
-    delete myAspectFace;
-    myAspectFace = NULL;
-  }
-  if (myAspectMarker)
-  {
-    delete myAspectMarker;
-    myAspectMarker = NULL;
-  }
-  if (myAspectText)
-  {
-    delete myAspectText;
-    myAspectText = NULL;
-  }
-  ClearHighlightColor();
-  // Delete groups
-  Clear();
+  Release (Handle(OpenGl_Context)());
+  delete myTransformation;  myTransformation  = NULL;
+  delete myTransPers;       myTransPers       = NULL;
+  delete myDegenerateModel; myDegenerateModel = NULL;
 }
 
 /*----------------------------------------------------------------------*/
@@ -106,7 +72,7 @@ OpenGl_Structure::~OpenGl_Structure ()
 void OpenGl_Structure::SetTransformation(const float *AMatrix)
 {
   if (!myTransformation)
-    myTransformation = new OpenGl_Matrix;
+    myTransformation = new OpenGl_Matrix();
 
   matcpy( myTransformation->mat, AMatrix );
 }
@@ -140,7 +106,7 @@ void OpenGl_Structure::SetDegenerateModel (const Standard_Integer AMode, const f
 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
 {
   if (!myAspectLine)
-    myAspectLine = new OpenGl_AspectLine;
+    myAspectLine = new OpenGl_AspectLine();
   myAspectLine->SetContext( AContext );
 }
 
@@ -149,7 +115,7 @@ void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA &AContext)
 {
   if (!myAspectFace)
-    myAspectFace = new OpenGl_AspectFace;
+    myAspectFace = new OpenGl_AspectFace();
   myAspectFace->SetContext( AContext );
 }
 
@@ -158,7 +124,7 @@ void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA &AContext)
 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext)
 {
   if (!myAspectMarker)
-    myAspectMarker = new OpenGl_AspectMarker;
+    myAspectMarker = new OpenGl_AspectMarker();
   myAspectMarker->SetContext( AContext );
 }
 
@@ -167,73 +133,82 @@ void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext)
 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
 {
   if (!myAspectText)
-    myAspectText = new OpenGl_AspectText;
+    myAspectText = new OpenGl_AspectText();
   myAspectText->SetContext( AContext );
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_Structure::SetHighlightBox (const CALL_DEF_BOUNDBOX &ABoundBox)
+void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
+                                        const CALL_DEF_BOUNDBOX&      theBoundBox)
 {
-  if (!myHighlightBox)
-    myHighlightBox = new OpenGl_Group;
+  if (myHighlightBox != NULL)
+  {
+    myHighlightBox->Release (theGlCtx);
+  }
   else
-    myHighlightBox->Clear();
+  {
+    myHighlightBox = new OpenGl_Group();
+  }
 
-  CALL_DEF_CONTEXTLINE context_line;
-  context_line.Color = ABoundBox.Color;
-  context_line.LineType = Aspect_TOL_SOLID;
-  context_line.Width = 1.0f;
-  myHighlightBox->SetAspectLine( context_line );
+  CALL_DEF_CONTEXTLINE aContextLine;
+  aContextLine.Color    = theBoundBox.Color;
+  aContextLine.LineType = Aspect_TOL_SOLID;
+  aContextLine.Width    = 1.0f;
+  myHighlightBox->SetAspectLine (aContextLine);
 
 #define CALL_MAX_BOUNDBOXSIZE 16
 
-  Graphic3d_Array1OfVertex points(1,CALL_MAX_BOUNDBOXSIZE);
-  const float Xm = ABoundBox.Pmin.x;
-  const float Ym = ABoundBox.Pmin.y;
-  const float Zm = ABoundBox.Pmin.z;
-  const float XM = ABoundBox.Pmax.x;
-  const float YM = ABoundBox.Pmax.y;
-  const float ZM = ABoundBox.Pmax.z;
-  points( 1).SetCoord(Xm,Ym,Zm);
-  points( 2).SetCoord(Xm,Ym,ZM);
-  points( 3).SetCoord(Xm,YM,ZM);
-  points( 4).SetCoord(Xm,YM,Zm);
-  points( 5).SetCoord(Xm,Ym,Zm);
-  points( 6).SetCoord(XM,Ym,Zm);
-  points( 7).SetCoord(XM,Ym,ZM);
-  points( 8).SetCoord(XM,YM,ZM);
-  points( 9).SetCoord(XM,YM,Zm);
-  points(10).SetCoord(XM,Ym,Zm);
-  points(11).SetCoord(XM,YM,Zm);
-  points(12).SetCoord(Xm,YM,Zm);
-  points(13).SetCoord(Xm,YM,ZM);
-  points(14).SetCoord(XM,YM,ZM);
-  points(15).SetCoord(XM,Ym,ZM);
-  points(16).SetCoord(Xm,Ym,ZM);
-
-  OpenGl_Polyline *apolyline = new OpenGl_Polyline(points);
-  myHighlightBox->AddElement( TelPolyline, apolyline );
+  Graphic3d_Array1OfVertex aPoints (1, CALL_MAX_BOUNDBOXSIZE);
+  const float Xm = theBoundBox.Pmin.x;
+  const float Ym = theBoundBox.Pmin.y;
+  const float Zm = theBoundBox.Pmin.z;
+  const float XM = theBoundBox.Pmax.x;
+  const float YM = theBoundBox.Pmax.y;
+  const float ZM = theBoundBox.Pmax.z;
+  aPoints( 1).SetCoord (Xm, Ym, Zm);
+  aPoints( 2).SetCoord (Xm, Ym, ZM);
+  aPoints( 3).SetCoord (Xm, YM, ZM);
+  aPoints( 4).SetCoord (Xm, YM, Zm);
+  aPoints( 5).SetCoord (Xm, Ym, Zm);
+  aPoints( 6).SetCoord (XM, Ym, Zm);
+  aPoints( 7).SetCoord (XM, Ym, ZM);
+  aPoints( 8).SetCoord (XM, YM, ZM);
+  aPoints( 9).SetCoord (XM, YM, Zm);
+  aPoints(10).SetCoord (XM, Ym, Zm);
+  aPoints(11).SetCoord (XM, YM, Zm);
+  aPoints(12).SetCoord (Xm, YM, Zm);
+  aPoints(13).SetCoord (Xm, YM, ZM);
+  aPoints(14).SetCoord (XM, YM, ZM);
+  aPoints(15).SetCoord (XM, Ym, ZM);
+  aPoints(16).SetCoord (Xm, Ym, ZM);
+
+  OpenGl_Polyline* aPolyline = new OpenGl_Polyline (aPoints);
+  myHighlightBox->AddElement (TelPolyline, aPolyline);
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_Structure::ClearHighlightBox ()
+void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
 {
-  if (myHighlightBox)
+  if (myHighlightBox != NULL)
   {
-    delete myHighlightBox;
-    myHighlightBox = NULL;
+    OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
   }
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_Structure::SetHighlightColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
+void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
+                                          const Standard_ShortReal R,
+                                          const Standard_ShortReal G,
+                                          const Standard_ShortReal B)
 {
-  ClearHighlightBox();
-  if (!myHighlightColor)
-    myHighlightColor = new TEL_COLOUR;
+  ClearHighlightBox (theGlCtx);
+  if (myHighlightColor == NULL)
+  {
+    myHighlightColor = new TEL_COLOUR();
+  }
 
   myHighlightColor->rgb[0] = R;
   myHighlightColor->rgb[1] = G;
@@ -243,14 +218,11 @@ void OpenGl_Structure::SetHighlightColor (const Standard_ShortReal R, const Stan
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_Structure::ClearHighlightColor ()
+void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
 {
-  ClearHighlightBox();
-  if (myHighlightColor)
-  {
-    delete myHighlightColor;
-    myHighlightColor = NULL;
-  }
+  ClearHighlightBox(theGlCtx);
+  delete myHighlightColor;
+  myHighlightColor = NULL;
 }
 
 /*----------------------------------------------------------------------*/
@@ -290,33 +262,31 @@ OpenGl_Group * OpenGl_Structure::AddGroup ()
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_Structure::RemoveGroup (const OpenGl_Group *AGroup)
+void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
+                                    const OpenGl_Group*           theGroup)
 {
-  OpenGl_ListOfGroup::Iterator itg(myGroups);
-  while (itg.More())
+  for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
   {
     // Check for the given group
-    if (itg.Value() == AGroup)
+    if (anIter.Value() == theGroup)
     {
       // Delete object
-      delete AGroup;
-      myGroups.Remove(itg);
+      OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
+      myGroups.Remove (anIter);
       return;
     }
-    itg.Next();
   }
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_Structure::Clear ()
+void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
 {
-  OpenGl_ListOfGroup::Iterator itg(myGroups);
-  while (itg.More())
+  // Release groups
+  for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
   {
     // Delete objects
-    delete itg.Value();
-    itg.Next();
+    OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
   }
   myGroups.Clear();
 }
@@ -462,6 +432,21 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   AWorkspace->NamedStatus = named_status;
 }
 
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
+{
+  // Release groups
+  Clear (theGlCtx);
+  OpenGl_Element::Destroy (theGlCtx, myAspectLine);
+  OpenGl_Element::Destroy (theGlCtx, myAspectFace);
+  OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
+  OpenGl_Element::Destroy (theGlCtx, myAspectText);
+  ClearHighlightColor (theGlCtx);
+}
+
 //=======================================================================
 //function : SetZLayer
 //purpose  : 
index a71545d..11d6985 100644 (file)
@@ -37,9 +37,10 @@ typedef NCollection_List<const OpenGl_Group *> OpenGl_ListOfGroup;
 
 class OpenGl_Structure : public OpenGl_Element
 {
- public:
-  OpenGl_Structure ();
-  virtual ~OpenGl_Structure ();
+
+public:
+
+  OpenGl_Structure();
 
   void SetTransformation (const float *AMatrix);
 
@@ -52,20 +53,27 @@ class OpenGl_Structure : public OpenGl_Element
   void SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext);
   void SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext);
 
-  void SetHighlightBox (const CALL_DEF_BOUNDBOX &ABoundBox);
-  void ClearHighlightBox ();
+  void SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
+                        const CALL_DEF_BOUNDBOX&      theBoundBox);
+
+  void ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx);
+
+  void SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
+                          const Standard_ShortReal R,
+                          const Standard_ShortReal G,
+                          const Standard_ShortReal B);
 
-  void SetHighlightColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B);
-  void ClearHighlightColor ();
+  void ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx);
 
   void SetNamedStatus (const Standard_Integer aStatus) { myNamedStatus = aStatus; }
 
   void Connect (const OpenGl_Structure *astructure);
   void Disconnect (const OpenGl_Structure *astructure);
 
-  OpenGl_Group * AddGroup ();
-  void RemoveGroup (const OpenGl_Group *);
-  void Clear ();
+  OpenGl_Group* AddGroup();
+  void RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
+                    const OpenGl_Group*           theGroup);
+  void Clear (const Handle(OpenGl_Context)& theGlCtx);
 
   //! Set z layer ID to display the structure in specified layer
   void SetZLayer (const Standard_Integer theLayerIndex);
@@ -73,32 +81,38 @@ class OpenGl_Structure : public OpenGl_Element
   //! Get z layer ID
   Standard_Integer GetZLayer () const;
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
-  
- protected:
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theGlCtx);
+
+protected:
+
+  virtual ~OpenGl_Structure();
+
+protected:
 
   //Structure_LABBegin
-  OpenGl_Matrix *myTransformation;
-  TEL_TRANSFORM_PERSISTENCE *myTransPers;
-  DEGENERATION *myDegenerateModel;
-  OpenGl_AspectLine *myAspectLine;
-  OpenGl_AspectFace *myAspectFace;
-  OpenGl_AspectMarker *myAspectMarker;
-  OpenGl_AspectText *myAspectText;
+  OpenGl_Matrix*             myTransformation;
+  TEL_TRANSFORM_PERSISTENCE* myTransPers;
+  DEGENERATION*              myDegenerateModel;
+  OpenGl_AspectLine*         myAspectLine;
+  OpenGl_AspectFace*         myAspectFace;
+  OpenGl_AspectMarker*       myAspectMarker;
+  OpenGl_AspectText*         myAspectText;
   //Structure_LABHighlight
-  OpenGl_Group *myHighlightBox;
-  TEL_COLOUR *myHighlightColor;
+  OpenGl_Group*              myHighlightBox;
+  TEL_COLOUR*                myHighlightColor;
   //Structure_LABVisibility
   //Structure_LABPick
-  int myNamedStatus; //Structure_LABNameSet
-  int myZLayer;
+  int                        myNamedStatus; //Structure_LABNameSet
+  int                        myZLayer;
 
-  OpenGl_ListOfStructure myConnected;
+  OpenGl_ListOfStructure     myConnected;
+  OpenGl_ListOfGroup         myGroups;
 
-  OpenGl_ListOfGroup myGroups;
+public:
 
- public:
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //OpenGl_Structure_Header
index 0bc7cc0..ca4b825 100644 (file)
@@ -214,4 +214,7 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
   }
 }
 
-/*----------------------------------------------------------------------*/
+void OpenGl_Text::Release (const Handle(OpenGl_Context)& theContext)
+{
+  //
+}
index cb93717..3251b43 100644 (file)
 
 class OpenGl_Text : public OpenGl_Element
 {
- public:
+
+public:
 
   OpenGl_Text (const TCollection_ExtendedString& AText,
               const Graphic3d_Vertex& APoint,
               const Standard_Real AHeight,
               const Graphic3d_HorizontalTextAlignment AHta,
               const Graphic3d_VerticalTextAlignment AVta);
-  virtual ~OpenGl_Text ();
 
-  virtual void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theContext);
+
+protected:
+
+  virtual ~OpenGl_Text();
 
- protected:
+protected:
 
   OpenGl_TextParam myParam;
   TEL_POINT       myAttachPnt;
   const wchar_t  *myString;
 
- public:
+public:
+
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //OpenGl_Text_Header
index d9ca2cf..3342ff2 100755 (executable)
@@ -74,8 +74,8 @@
 #include <OpenGl_Display.hxx>
 #include <OpenGl_TextureBox.hxx>
 #include <OpenGl_ImageBox.hxx>
-#include <OpenGl_ResourceCleaner.hxx>
 #include <OpenGl_ResourceTexture.hxx>
+#include <OpenGl_Context.hxx>
 
 #include <GL/glu.h> // gluBuild2DMipmaps()
 
@@ -105,7 +105,6 @@ struct contextData
   GLuint number;
   GLDRAWABLE drawable;
   GLCONTEXT context;
-  char use_bind_texture;
 };
 
 struct texDraw
@@ -388,7 +387,6 @@ static void MyGenTextureEXT (TextureID ID)
 
   aContextData.context = GET_GL_CONTEXT();
   aContextData.drawable = GET_GLDEV_CONTEXT();
-  aContextData.use_bind_texture = (char )GL_TRUE;
   glGenTextures (1, &aContextData.number);
   textab(ID).contextdata.Append(aContextData);
   glBindTexture (texdata(data).type, aContextData.number);
@@ -667,61 +665,28 @@ void SetCurrentTexture(TextureID ID)
 
 /*----------------------------------------------------------------------*/
 
-void FreeTexture(TextureID ID)
+void FreeTexture (const Handle(OpenGl_Context)& theContext,
+                  TextureID                     ID)
 {
-  TextureDataID data;
-  bool notResource = false; // if there old-style texture deletion
-
-  GLCONTEXT cur_context;
-  GLDRAWABLE cur_drawable;
-  int i;
-
-  if (!IsTextureValid(ID)) return;
+  if (!IsTextureValid (ID))
+  {
+    return;
+  }
 
-  data = textab(ID).data;
+  TextureDataID data = textab(ID).data;
   texdata(data).share_count--;
   if (texdata(data).share_count == 0)
-  {      
-    // liberation des datas de la textures
-   delete [] texdata(data).image;
+  {
+    // release texture data
+    delete [] texdata(data).image;
 
     // liberation de la texture dans tous les contextes
-    cur_drawable = GET_GLDEV_CONTEXT();
-    for (i = 0; i < textab(ID).contextdata.Length(); ++i)
+    for (int i = 0; i < textab(ID).contextdata.Length(); ++i)
     {
-      cur_context = 0;
-      bool isResource = false; 
-
-      if (textab(ID).contextdata(i).use_bind_texture)
-      {
-        if( !OpenGl_ResourceCleaner::GetInstance()->AddResource(textab(ID).contextdata(i).context, 
-            new OpenGl_ResourceTexture(textab(ID).contextdata(i).number)) )
-        {
-          GL_MAKE_CURRENT((openglDisplay.IsNull() ? (Display* )NULL : (Display* )openglDisplay->GetDisplay()),
-            textab(ID).contextdata(i).drawable,
-            textab(ID).contextdata(i).context);
-
-          // This check has been added to avoid exception, 
-          // which is raised when trying to delete textures when no rendering context is available
-          cur_context = GET_GL_CONTEXT();
-          if (cur_context)
-            glDeleteTextures (1, &textab(ID).contextdata(i).number);
-          notResource = true;
-        }
-        else
-        {
-          isResource = true;
-        }
-      }
-
-      if( !isResource && cur_context )
-        glFinish();
+      Handle(OpenGl_ResourceTexture) aResource = new OpenGl_ResourceTexture (textab(ID).contextdata(i).number);
+      theContext->DelayedRelease (aResource);
     }
 
-    if( notResource )
-      GL_MAKE_CURRENT((openglDisplay.IsNull() ? (Display* )NULL : (Display* )openglDisplay->GetDisplay()),
-                      cur_drawable, cur_context);
-
     texdata(data).status = TEXDATA_NONE;
 
     textab(ID).contextdata.Clear();
@@ -962,33 +927,3 @@ void TransferTexture_To_Data(TextureID ID, TextureData *TransfDt)
   memcpy(TransfDt->plane1,  textab(ID).Plane1, sizeof(SizeType));
   memcpy(TransfDt->plane2,  textab(ID).Plane2, sizeof(SizeType));                
 }
-
-/*----------------------------------------------------------------------*/
-/* Transfere de donnee de la structure TransferData aux donnees internes */
-void TransferData_To_Texture(TextureData *TransfDt, TextureID *newID)
-{                            
-  TextureID ID;
-
-  /* Affectations */
-  FreeTexture(*newID);     
-  ID = GetTexture2DMipMap(TransfDt->path);  
-
-  if(IsTextureValid(ID))
-  {
-    /* Affectation de l id courant */
-    *newID = ID;
-
-    /* Donnees concernant les caracteristiques de la texture */ 
-    strcpy(texdata(textab(ID).data).imageFileName, TransfDt->path);       
-    textab(ID).Gen    = TransfDt->gen;
-    textab(ID).Wrap   = TransfDt->wrap;
-    textab(ID).Light  = TransfDt->render;
-    textab(ID).scalex = TransfDt->scalex;
-    textab(ID).scaley = TransfDt->scaley; 
-    textab(ID).transx = TransfDt->transx;
-    textab(ID).transy = TransfDt->transy;
-    textab(ID).angle  = TransfDt->angle;
-    memcpy(textab(ID).Plane1,  TransfDt->plane1, sizeof(SizeType));
-    memcpy(textab(ID).Plane2,  TransfDt->plane2, sizeof(SizeType)); 
-  }               
-}
index bbe34d1..05d4f25 100755 (executable)
@@ -102,7 +102,9 @@ TextureID GetTextureData1D(char *FileName, const GLint width, const GLint height
 TextureID GetTextureData2D(char *FileName, const GLint width, const GLint height, const void *data);
 TextureID GetTextureData2DMipMap(char *FileName, const GLint width, const GLint height, const void *data);
 
-void FreeTexture(TextureID ID);
+class Handle(OpenGl_Context);
+void FreeTexture (const Handle(OpenGl_Context)& theContext,
+                  TextureID                     ID);
 
 void SetCurrentTexture(TextureID ID);
 GLboolean IsTextureValid(TextureID ID);
@@ -139,7 +141,6 @@ void SetTexturePosition(TextureID ID,
 void SetTextureDefaultParams(TextureID ID);
 
 void TransferTexture_To_Data(TextureID, TextureData *);
-void TransferData_To_Texture(TextureData*, TextureID*);
 
 /*----------------------------------------------------------------------*/
 
diff --git a/src/OpenGl/OpenGl_TextureBufferArb.cxx b/src/OpenGl/OpenGl_TextureBufferArb.cxx
new file mode 100644 (file)
index 0000000..405b6fd
--- /dev/null
@@ -0,0 +1,151 @@
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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 <OpenGl_TextureBufferArb.hxx>
+
+#include <OpenGl_Context.hxx>
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_TextureBufferArb, OpenGl_VertexBuffer)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureBufferArb, OpenGl_VertexBuffer)
+
+// =======================================================================
+// function : OpenGl_TextureBufferArb
+// purpose  :
+// =======================================================================
+OpenGl_TextureBufferArb::OpenGl_TextureBufferArb()
+: OpenGl_VertexBuffer(),
+  myTextureId (NO_TEXTURE),
+  myTexFormat (GL_RGBA32F)
+{
+  //
+}
+
+// =======================================================================
+// function : ~OpenGl_TextureBufferArb
+// purpose  :
+// =======================================================================
+OpenGl_TextureBufferArb::~OpenGl_TextureBufferArb()
+{
+  Release (NULL);
+}
+
+// =======================================================================
+// function : GetTarget
+// purpose  :
+// =======================================================================
+GLenum OpenGl_TextureBufferArb::GetTarget() const
+{
+  return GL_TEXTURE_BUFFER_ARB; // GL_TEXTURE_BUFFER for OpenGL 3.1+
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_TextureBufferArb::Release (const OpenGl_Context* theGlCtx)
+{
+  if (myTextureId != NO_TEXTURE)
+  {
+    // application can not handle this case by exception - this is bug in code
+    Standard_ASSERT_RETURN (theGlCtx != NULL,
+      "OpenGl_TextureBufferExt destroyed without GL context! Possible GPU memory leakage...",);
+
+    glDeleteTextures (1, &myTextureId);
+    myTextureId = NO_TEXTURE;
+  }
+  OpenGl_VertexBuffer::Release (theGlCtx);
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool OpenGl_TextureBufferArb::Create (const Handle(OpenGl_Context)& theGlCtx)
+{
+  if (!OpenGl_VertexBuffer::Create (theGlCtx))
+  {
+    return false;
+  }
+
+  if (myTextureId == NO_TEXTURE)
+  {
+    glGenTextures (1, &myTextureId);
+  }
+  return myTextureId != NO_TEXTURE;
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx,
+                                    const GLuint   theComponentsNb,
+                                    const GLsizei  theElemsNb,
+                                    const GLfloat* theData)
+{
+  if (theComponentsNb != 1
+   && theComponentsNb != 2
+   && theComponentsNb != 4)
+  {
+    // unsupported format
+    return false;
+  }
+  else if (!Create (theGlCtx)
+        || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData))
+  {
+    return false;
+  }
+
+  switch (theComponentsNb)
+  {
+    case 1: myTexFormat = GL_R32F;    break;
+    case 2: myTexFormat = GL_RG32F;   break;
+    //case 3: myTexFormat = GL_RGB32F;  break; // GL_ARB_texture_buffer_object_rgb32
+    case 4: myTexFormat = GL_RGBA32F; break;
+  }
+
+  Bind (theGlCtx);
+  BindTexture (theGlCtx);
+  theGlCtx->arbTBO->glTexBufferARB (GetTarget(), myTexFormat, myBufferId);
+  UnbindTexture (theGlCtx);
+  Unbind (theGlCtx);
+  return true;
+}
+
+// =======================================================================
+// function : BindTexture
+// purpose  :
+// =======================================================================
+void OpenGl_TextureBufferArb::BindTexture (const Handle(OpenGl_Context)& theGlCtx,
+                                           const GLenum theTextureUnit) const
+{
+  theGlCtx->core20->glActiveTexture (theTextureUnit);
+  glBindTexture (GetTarget(), myTextureId);
+}
+
+// =======================================================================
+// function : UnbindTexture
+// purpose  :
+// =======================================================================
+void OpenGl_TextureBufferArb::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
+                                             const GLenum theTextureUnit) const
+{
+  theGlCtx->core20->glActiveTexture (theTextureUnit);
+  glBindTexture (GetTarget(), NO_TEXTURE);
+}
diff --git a/src/OpenGl/OpenGl_TextureBufferArb.hxx b/src/OpenGl/OpenGl_TextureBufferArb.hxx
new file mode 100644 (file)
index 0000000..8c0ed1a
--- /dev/null
@@ -0,0 +1,97 @@
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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_TextureBufferArb_H__
+#define _OpenGl_TextureBufferArb_H__
+
+#include <OpenGl_VertexBuffer.hxx>
+#include <OpenGl_ArbTBO.hxx>
+
+//! Texture Buffer Object.
+//! This is a special 1D texture that VBO-style initialized.
+//! The main differences from general 1D texture:
+//!  - no interpolation between field;
+//!  - greater sizes;
+//!  - special sampler object in GLSL shader to access data by index.
+//!
+//! Notice that though TBO is inherited from VBO this is to unify design
+//! user shouldn't cast it to base class and all really useful methods
+//! are declared in this class.
+class OpenGl_TextureBufferArb : public OpenGl_VertexBuffer
+{
+
+public:
+
+  //! Helpful constants
+  static const GLuint NO_TEXTURE = 0;
+
+public:
+
+  //! Create uninitialized TBO.
+  Standard_EXPORT OpenGl_TextureBufferArb();
+
+  //! Destroy object, will throw exception if GPU memory not released with Release() before.
+  Standard_EXPORT virtual ~OpenGl_TextureBufferArb();
+
+  //! Override VBO target
+  Standard_EXPORT virtual GLenum GetTarget() const;
+
+  //! Returns true if TBO is valid.
+  //! Notice that no any real GL call is performed!
+  bool IsValid() const
+  {
+    return OpenGl_VertexBuffer::IsValid()
+        && myTextureId != NO_TEXTURE;
+  }
+
+  //! Destroy object - will release GPU memory if any.
+  Standard_EXPORT virtual void Release (const OpenGl_Context* theGlCtx);
+
+  //! Creates VBO and Texture names (ids) if not yet generated.
+  //! Data should be initialized by another method.
+  Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theGlCtx);
+
+  //! Perform TBO initialization with specified data.
+  //! Existing data will be deleted.
+  Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx,
+                             const GLuint   theComponentsNb,
+                             const GLsizei  theElemsNb,
+                             const GLfloat* theData);
+
+  //! Bind TBO to specified Texture Unit.
+  Standard_EXPORT void BindTexture (const Handle(OpenGl_Context)& theGlCtx,
+                                    const GLenum theTextureUnit = GL_TEXTURE0) const;
+
+  //! Unbind TBO.
+  Standard_EXPORT void UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
+                                      const GLenum theTextureUnit = GL_TEXTURE0) const;
+
+protected:
+
+  GLuint myTextureId; //!< texture id
+  GLenum myTexFormat; //!< internal texture format
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_TextureBufferArb) // Type definition
+
+};
+
+DEFINE_STANDARD_HANDLE(OpenGl_TextureBufferArb, OpenGl_VertexBuffer)
+
+#endif // _OpenGl_TextureBufferArb_H__
diff --git a/src/OpenGl/OpenGl_VertexBuffer.cxx b/src/OpenGl/OpenGl_VertexBuffer.cxx
new file mode 100644 (file)
index 0000000..436e67d
--- /dev/null
@@ -0,0 +1,290 @@
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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 <OpenGl_VertexBuffer.hxx>
+
+#include <OpenGl_Context.hxx>
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_VertexBuffer, OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_VertexBuffer, OpenGl_Resource)
+
+// =======================================================================
+// function : OpenGl_VertexBuffer
+// purpose  :
+// =======================================================================
+OpenGl_VertexBuffer::OpenGl_VertexBuffer()
+: OpenGl_Resource(),
+  myBufferId (NO_BUFFER),
+  myComponentsNb (4),
+  myElemsNb (0),
+  myDataType (GL_FLOAT)
+{
+  //
+}
+
+// =======================================================================
+// function : ~OpenGl_VertexBuffer
+// purpose  :
+// =======================================================================
+OpenGl_VertexBuffer::~OpenGl_VertexBuffer()
+{
+  Release (NULL);
+}
+
+// =======================================================================
+// function : GetTarget
+// purpose  :
+// =======================================================================
+GLenum OpenGl_VertexBuffer::GetTarget() const
+{
+  return GL_ARRAY_BUFFER;
+}
+
+// =======================================================================
+// function : Create
+// purpose  :
+// =======================================================================
+bool OpenGl_VertexBuffer::Create (const Handle(OpenGl_Context)& theGlCtx)
+{
+  if (myBufferId == NO_BUFFER)
+  {
+    theGlCtx->core15->glGenBuffers (1, &myBufferId);
+  }
+  return myBufferId != NO_BUFFER;
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::Release (const OpenGl_Context* theGlCtx)
+{
+  if (myBufferId == NO_BUFFER)
+  {
+    return;
+  }
+
+  // application can not handle this case by exception - this is bug in code
+  Standard_ASSERT_RETURN (theGlCtx != NULL,
+    "OpenGl_VertexBuffer destroyed without GL context! Possible GPU memory leakage...",);
+
+  theGlCtx->core15->glDeleteBuffers (1, &myBufferId);
+  myBufferId = NO_BUFFER;
+}
+
+// =======================================================================
+// function : Bind
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::Bind (const Handle(OpenGl_Context)& theGlCtx) const
+{
+  theGlCtx->core15->glBindBuffer (GetTarget(), myBufferId);
+}
+
+// =======================================================================
+// function : Unbind
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::Unbind (const Handle(OpenGl_Context)& theGlCtx) const
+{
+  theGlCtx->core15->glBindBuffer (GetTarget(), NO_BUFFER);
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
+                                const GLuint   theComponentsNb,
+                                const GLsizei  theElemsNb,
+                                const GLfloat* theData)
+{
+  if (!Create (theGlCtx))
+  {
+    return false;
+  }
+
+  Bind (theGlCtx);
+  myDataType     = GL_FLOAT;
+  myComponentsNb = theComponentsNb;
+  myElemsNb      = theElemsNb;
+  theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLfloat), theData, GL_STATIC_DRAW);
+  bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
+  Unbind (theGlCtx);
+  return isDone;
+}
+
+// =======================================================================
+// function : SubData
+// purpose  :
+// =======================================================================
+bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
+                                   const GLsizei  theElemFrom,
+                                   const GLsizei  theElemsNb,
+                                   const GLfloat* theData)
+{
+  if (!IsValid() || myDataType != GL_FLOAT ||
+      theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
+  {
+    return false;
+  }
+
+  Bind (theGlCtx);
+  theGlCtx->core15->glBufferSubData (GetTarget(),
+                                     GLintptr(theElemFrom)  * GLintptr(myComponentsNb)   * sizeof(GLfloat), // offset in bytes
+                                     GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLfloat), // size   in bytes
+                                     theData);
+  bool isDone = (glGetError() == GL_NO_ERROR); // some dummy error
+  Unbind (theGlCtx);
+  return isDone;
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
+                                const GLuint  theComponentsNb,
+                                const GLsizei theElemsNb,
+                                const GLuint* theData)
+{
+  if (!Create (theGlCtx))
+  {
+    return false;
+  }
+
+  Bind (theGlCtx);
+  myDataType     = GL_UNSIGNED_INT;  
+  myComponentsNb = theComponentsNb;
+  myElemsNb      = theElemsNb;
+  theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLuint), theData, GL_STATIC_DRAW);
+  bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
+  Unbind (theGlCtx);
+  return isDone;
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
+                                const GLuint   theComponentsNb,
+                                const GLsizei  theElemsNb,
+                                const GLubyte* theData)
+{
+  if (!Create (theGlCtx))
+  {
+    return false;
+  }
+
+  Bind (theGlCtx);
+  myDataType     = GL_UNSIGNED_BYTE;
+  myComponentsNb = theComponentsNb;
+  myElemsNb      = theElemsNb;
+  theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLubyte), theData, GL_STATIC_DRAW);
+  bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
+  Unbind (theGlCtx);
+  return isDone;
+}
+
+// =======================================================================
+// function : BindVertexAttrib
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
+                                            const GLuint                  theAttribLoc) const
+{
+  if (!IsValid() || theAttribLoc == GLuint (-1))
+  {
+    return;
+  }
+  Bind (theGlCtx);
+  theGlCtx->core20->glEnableVertexAttribArray (theAttribLoc);
+  theGlCtx->core20->glVertexAttribPointer (theAttribLoc, GLint (myComponentsNb), myDataType, GL_FALSE, 0, NULL);
+}
+
+// =======================================================================
+// function : UnbindVertexAttrib
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
+                                              const GLuint                  theAttribLoc) const
+{
+  if (!IsValid() || theAttribLoc == GLuint (-1))
+  {
+    return;
+  }
+  theGlCtx->core20->glDisableVertexAttribArray (theAttribLoc);
+  Unbind (theGlCtx);
+}
+
+// =======================================================================
+// function : BindFixed
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& theGlCtx,
+                                     const GLenum                  theMode) const
+{
+  if (!IsValid())
+  {
+    return;
+  }
+
+  Bind (theGlCtx);
+  glEnableClientState (theMode);
+  switch (theMode)
+  {
+    case GL_VERTEX_ARRAY:
+    {
+      glVertexPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
+      break;
+    }
+    case GL_NORMAL_ARRAY:
+    {
+      glNormalPointer (myDataType, 0, NULL);
+      break;
+    }
+    case GL_TEXTURE_COORD_ARRAY:
+    {
+      glTexCoordPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
+      break;
+    }
+    case GL_COLOR_ARRAY:
+    {
+      glColorPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
+      break;
+    }
+    default: break;
+  }
+}
+
+// =======================================================================
+// function : UnbindFixed
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& theGlCtx,
+                                       const GLenum                  theMode) const
+{
+  if (!IsValid())
+  {
+    return;
+  }
+  Unbind (theGlCtx);
+  glDisableClientState (theMode);
+}
diff --git a/src/OpenGl/OpenGl_VertexBuffer.hxx b/src/OpenGl/OpenGl_VertexBuffer.hxx
new file mode 100644 (file)
index 0000000..d691615
--- /dev/null
@@ -0,0 +1,158 @@
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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_VertexBuffer_H__
+#define _OpenGl_VertexBuffer_H__
+
+#include <OpenGl_GlCore20.hxx>
+#include <OpenGl_Resource.hxx>
+
+class Handle(OpenGl_Context);
+class OpenGl_Context;
+
+//! Vertex Buffer Object - is a general storage object for vertex attributes (position, normal, color).
+//! Notice that you should use OpenGl_IndexBuffer specialization for array of indices.
+class OpenGl_VertexBuffer : public OpenGl_Resource
+{
+
+public:
+
+  //! Helpful constants
+  static const GLuint NO_BUFFER = 0;
+
+public:
+
+  //! Create uninitialized VBO.
+  Standard_EXPORT OpenGl_VertexBuffer();
+
+  //! Destroy object.
+  Standard_EXPORT virtual ~OpenGl_VertexBuffer();
+
+  Standard_EXPORT virtual GLenum GetTarget() const;
+
+  //! @return true if current object was initialized
+  inline bool IsValid() const
+  {
+    return myBufferId != NO_BUFFER;
+  }
+
+  //! @return the number of components per generic vertex attribute.
+  inline GLuint GetComponentsNb() const
+  {
+    return myComponentsNb;
+  }
+
+  //! @return number of vertex attributes / number of vertices.
+  inline GLsizei GetElemsNb() const
+  {
+    return myElemsNb;
+  }
+
+  //! @return data type of each component in the array.
+  inline GLenum GetDataType() const
+  {
+    return myDataType;
+  }
+
+  //! Creates VBO name (id) if not yet generated.
+  //! Data should be initialized by another method.
+  Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theGlCtx);
+
+  //! Destroy object - will release GPU memory if any.
+  Standard_EXPORT virtual void Release (const OpenGl_Context* theGlCtx);
+
+  //! Bind this VBO.
+  Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theGlCtx) const;
+
+  //! Unbind this VBO.
+  Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theGlCtx) const;
+
+  //! Notice that VBO will be unbound after this call.
+  //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
+  //! @param theElemsNb      - elements count;
+  //! @param theData         - pointer to GLfloat data (vertices/normals etc.).
+  Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx,
+                             const GLuint   theComponentsNb,
+                             const GLsizei  theElemsNb,
+                             const GLfloat* theData);
+
+  //! Notice that VBO will be unbound after this call.
+  //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
+  //! @param theElemsNb      - elements count;
+  //! @param theData         - pointer to GLuint data (indices etc.).
+  Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx,
+                             const GLuint  theComponentsNb,
+                             const GLsizei theElemsNb,
+                             const GLuint* theData);
+
+  //! Notice that VBO will be unbound after this call.
+  //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
+  //! @param theElemsNb      - elements count;
+  //! @param theData         - pointer to GLubyte data (indices/colors etc.).
+  Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx,
+                             const GLuint   theComponentsNb,
+                             const GLsizei  theElemsNb,
+                             const GLubyte* theData);
+
+  //! Notice that VBO will be unbound after this call.
+  //! Function replaces portion of data within this VBO using glBufferSubData().
+  //! The VBO should be initialized before call.
+  //! @param theElemFrom - element id from which replace buffer data (>=0);
+  //! @param theElemsNb  - elements count (theElemFrom + theElemsNb < GetElemsNb());
+  //! @param theData     - pointer to GLfloat data.
+  Standard_EXPORT bool SubData (const Handle(OpenGl_Context)& theGlCtx,
+                                const GLsizei  theElemFrom,
+                                const GLsizei  theElemsNb,
+                                const GLfloat* theData);
+
+  //! Bind this VBO to active GLSL program.
+  Standard_EXPORT void BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
+                                         const GLuint                  theAttribLoc) const;
+
+  //! Unbind any VBO from active GLSL program.
+  Standard_EXPORT void UnbindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
+                                           const GLuint                  theAttribLoc) const;
+
+  //! Bind this VBO as fixed pipeline attribute.
+  //! @param theGlCtx - handle to bound GL context;
+  //! @param theMode  - array mode (GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY).
+  Standard_EXPORT void BindFixed (const Handle(OpenGl_Context)& theGlCtx,
+                                  const GLenum                  theMode) const;
+
+  //! Unbind this VBO as fixed pipeline attribute.
+  //! @param theGlCtx - handle to bound GL context;
+  //! @param theMode  - array mode.
+  Standard_EXPORT void UnbindFixed (const Handle(OpenGl_Context)& theGlCtx,
+                                    const GLenum                  theMode) const;
+
+protected:
+
+  GLuint  myBufferId;     //!< VBO name (index)
+  GLuint  myComponentsNb; //!< Number of components per generic vertex attribute, must be 1, 2, 3, or 4
+  GLsizei myElemsNb;      //!< Number of vertex attributes / number of vertices
+  GLenum  myDataType;     //!< Data type (GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.)
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_VertexBuffer) // Type definition
+
+};
+
+DEFINE_STANDARD_HANDLE(OpenGl_VertexBuffer, OpenGl_Resource)
+
+#endif // _OpenGl_VertexBuffer_H__
diff --git a/src/OpenGl/OpenGl_VertexBufferEditor.hxx b/src/OpenGl/OpenGl_VertexBufferEditor.hxx
new file mode 100644 (file)
index 0000000..b150cb8
--- /dev/null
@@ -0,0 +1,123 @@
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2012 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_VertexBufferEditor_H__
+#define _OpenGl_VertexBufferEditor_H__
+
+#include <OpenGl_VertexBuffer.hxx>
+#include <OpenGl_Context.hxx>
+
+#include <NCollection_Array1.hxx>
+
+//! Auxiliary class to iteratively modify data of existing VBO.
+//! It provides iteration interface with delayed CPU->GPU memory transfer to avoid slow per-element data transfer.
+//! User should explicitly call Flush() method to ensure that all data is transferred to VBO.
+//! Temporary buffer on CPU side can be initialized with lesser capacity than  VBO
+//! to allow re-usage of shared buffer with fixed size between VBOs.
+//!
+//! You should use NCollection_Vec2/NCollection_Vec3/NCollection_Vec4 with appropriate length
+//! to instantiate this template and access elements in VBO.
+//!
+//! Notice that this technique designed for VBO streaming scenarios (when VBO is modified from time to time).
+//! Also this class doesn't retrieve existing data from VBO - data transferred only in one direction!
+//! In case of static data this is preferred to upload it within one call during VBO initialization.
+template<typename theVec_t>
+class OpenGl_VertexBufferEditor
+{
+
+public:
+
+  //! Creates empty editor
+  //! theTmpBufferLength - temporary buffer length
+  OpenGl_VertexBufferEditor (const Standard_Integer theTmpBufferLength = 0)
+  : myElemFrom (0),
+    myElemsNb (0),
+    myTmpBuffer (0, theTmpBufferLength > 0 ? (theTmpBufferLength - 1) : 2047) {}
+
+  //! Creates empty editor
+  //! theTmpBuffer       - pointer to temporary buffer
+  //! theTmpBufferLength - temporary buffer length
+  OpenGl_VertexBufferEditor (theVec_t*              theTmpBuffer,
+                             const Standard_Integer theTmpBufferLength)
+  : myElemFrom (0),
+    myElemsNb (0),
+    myTmpBuffer (theTmpBuffer[0], 0, theTmpBufferLength - 1) {}
+
+  //! Initialize editor for specified VBO.
+  //! theGlCtx - bound OpenGL context to edit VBO
+  //! theVbo   - VBO to edit
+  Standard_Boolean Init (const Handle(OpenGl_Context)&      theGlCtx,
+                         const Handle(OpenGl_VertexBuffer)& theVbo)
+  {
+    myGlCtx = theGlCtx;
+    myVbo   = theVbo;
+    if (myGlCtx.IsNull() || myVbo.IsNull() || !myVbo->IsValid() || myVbo->GetComponentsNb() != GLuint (theVec_t::Length()))
+    {
+      return Standard_False;
+    }
+
+    myElemFrom = myElemsNb = 0;
+    return Standard_True;
+  }
+
+  //! Modify current element in VBO.
+  theVec_t& Value()
+  {
+      return myTmpBuffer.ChangeValue (myElemsNb);
+  }
+
+  //! Move to the next position in VBO.
+  Standard_Boolean Next()
+  {
+      if (++myElemsNb > myTmpBuffer.Upper())
+      {
+          return Flush();
+      }
+      return Standard_True;
+  }
+
+  //! Push current data from local buffer to VBO.
+  Standard_Boolean Flush()
+  {
+      if (myElemsNb <= 0)
+      {
+          return Standard_True;
+      }
+
+      if (!myVbo->SubData (myGlCtx, myElemFrom, myElemsNb, &myTmpBuffer.Value (0)[0]))
+      {
+          // should never happens
+          return Standard_False;
+      }
+      myElemFrom += myElemsNb;
+      myElemsNb = 0;
+
+      return Standard_True;
+  }
+
+private:
+
+  Handle(OpenGl_Context)       myGlCtx;     //!< handle to current OpenGL context
+  Handle(OpenGl_VertexBuffer)  myVbo;       //!< edited VBO
+  Standard_Integer             myElemFrom;  //!< element in VBO to upload from
+  Standard_Integer             myElemsNb;   //!< current element in temporary buffer
+  NCollection_Array1<theVec_t> myTmpBuffer; //!< temporary array
+
+};
+
+#endif // _OpenGl_VertexBufferEditor_H__
index a250766..0f4be46 100644 (file)
@@ -24,8 +24,6 @@
 
 #include <OpenGl_Context.hxx>
 #include <OpenGl_Display.hxx>
-#include <OpenGl_ResourceCleaner.hxx>
-#include <OpenGl_ResourceTexture.hxx>
 
 #include <Aspect_GraphicDeviceDefinitionError.hxx>
 #include <TCollection_AsciiString.hxx>
@@ -39,12 +37,6 @@ namespace
 {
   static const TEL_COLOUR THE_DEFAULT_BG_COLOR = { { 0.F, 0.F, 0.F, 1.F } };
 
-  static GLCONTEXT ThePreviousCtx = 0; // to share GL resources
-#if (!defined(_WIN32) && !defined(__WIN32__))
-  static GLXContext TheDeadGlxCtx; // Context to be destroyed
-  static Display*   TheDeadGlxDpy; // Display associated with TheDeadGlxCtx
-#endif
-  
 #if (defined(_WIN32) || defined(__WIN32__))
   static int find_pixel_format (HDC hDC, PIXELFORMATDESCRIPTOR* pfd, const Standard_Boolean dbuff)
   {
@@ -105,14 +97,12 @@ namespace
 // =======================================================================
 OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
                               const CALL_DEF_WINDOW&        theCWindow,
-                              Aspect_RenderingContext       theGContext)
+                              Aspect_RenderingContext       theGContext,
+                              const Handle(OpenGl_Context)& theShareCtx)
 : myDisplay (theDisplay),
-  myWindow (0),
-  myGContext ((GLCONTEXT )theGContext),
   myGlContext (new OpenGl_Context()),
   myOwnGContext (theGContext == 0),
 #if (defined(_WIN32) || defined(__WIN32__))
-  myWindowDC (0),
   mySysPalInUse (FALSE),
 #endif
   myWidth ((Standard_Integer )theCWindow.dx),
@@ -125,10 +115,77 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
   myBgColor.rgb[1] = theCWindow.Background.g;
   myBgColor.rgb[2] = theCWindow.Background.b;
 
+#if (defined(_WIN32) || defined(__WIN32__))
+  HWND  aWindow   = (HWND )theCWindow.XWindow;
+  HDC   aWindowDC = GetDC (aWindow);
+  HGLRC aGContext = (HGLRC )theGContext;
+
+  PIXELFORMATDESCRIPTOR pfd;
+  int iPixelFormat = find_pixel_format (aWindowDC, &pfd, myDisplay->DBuffer());
+  if (iPixelFormat == 0)
+  {
+    ReleaseDC (aWindow, aWindowDC);
+
+    TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: ChoosePixelFormat failed. Error code: ");
+    aMsg += (int )GetLastError();
+    Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
+    return;
+  }
+
+  if (pfd.dwFlags & PFD_NEED_PALETTE)
+  {
+    WINDOW_DATA* wd = (WINDOW_DATA* )GetWindowLongPtr (aWindow, GWLP_USERDATA);
+
+    mySysPalInUse = (pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE) ? TRUE : FALSE;
+    InterfaceGraphic_RealizePalette (aWindowDC, wd->hPal, FALSE, mySysPalInUse);
+  }
+
+  if (myDither)
+    myDither = (pfd.cColorBits <= 8);
+
+  if (myBackDither)
+    myBackDither = (pfd.cColorBits <= 8);
+
+  if (!SetPixelFormat (aWindowDC, iPixelFormat, &pfd))
+  {
+    ReleaseDC (aWindow, aWindowDC);
+
+    TCollection_AsciiString aMsg("OpenGl_Window::CreateWindow: SetPixelFormat failed. Error code: ");
+    aMsg += (int )GetLastError();
+    Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
+    return;
+  }
+
+  if (aGContext == NULL)
+  {
+    aGContext = wglCreateContext (aWindowDC);
+    if (aGContext == NULL)
+    {
+      ReleaseDC (aWindow, aWindowDC);
+
+      TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglCreateContext failed. Error code: ");
+      aMsg += (int )GetLastError();
+      Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
+      return;
+    }
+  }
+
+  // all GL context within one OpenGl_GraphicDriver should be shared!
+  if (!theShareCtx.IsNull() && wglShareLists ((HGLRC )theShareCtx->myGContext, aGContext) != TRUE)
+  {
+    TCollection_AsciiString aMsg ("OpenGl_Window::CreateWindow: wglShareLists failed. Error code: ");
+    aMsg += (int )GetLastError();
+    Aspect_GraphicDeviceDefinitionError::Raise (aMsg.ToCString());
+    return;
+  }
+
+  myGlContext->Init ((Aspect_Handle )aWindow, (Aspect_Handle )aWindowDC, (Aspect_RenderingContext )aGContext);
+#else
   WINDOW aParent = (WINDOW )theCWindow.XWindow;
+  WINDOW aWindow = 0;
   DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
+  GLXContext aGContext = (GLXContext )theGContext;
 
-#if (!defined(_WIN32) && !defined(__WIN32__))
   XWindowAttributes wattr;
   XGetWindowAttributes (aDisp, aParent, &wattr);
   const int scr = DefaultScreen (aDisp);
@@ -143,8 +200,6 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
     aVis = XGetVisualInfo (aDisp, aVisInfoMask, &aVisInfo, &aNbItems);
   }
 
-  WINDOW win;
-
   if (!myOwnGContext)
   {
     if (aVis != NULL)
@@ -153,12 +208,10 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
       return;
     }
 
-    win = aParent;
+    aWindow = aParent;
   }
   else
   {
-    GLCONTEXT ctx;
-
   #if defined(__linux) || defined(Linux)
     if (aVis != NULL)
     {
@@ -216,36 +269,22 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
       }
     }
 
-    if (TheDeadGlxCtx)
-    {
-      // recover display lists from TheDeadGlxCtx, then destroy it
-      ctx = glXCreateContext (aDisp, aVis, TheDeadGlxCtx, GL_TRUE);
-
-      OpenGl_ResourceCleaner::GetInstance()->RemoveContext (TheDeadGlxCtx);
-      glXDestroyContext (TheDeadGlxDpy, TheDeadGlxCtx);
-
-      TheDeadGlxCtx = 0;
-    }
-    else if (ThePreviousCtx == 0)
+    if (!theShareCtx.IsNull())
     {
-      ctx = glXCreateContext (aDisp, aVis, NULL, GL_TRUE);
+      // ctx est une copie du previous
+      aGContext = glXCreateContext (aDisp, aVis, (GLXContext )theShareCtx->myGContext, GL_TRUE);
     }
     else
     {
-      // ctx est une copie du previous
-      ctx = glXCreateContext (aDisp, aVis, ThePreviousCtx, GL_TRUE);
+      aGContext = glXCreateContext (aDisp, aVis, NULL, GL_TRUE);
     }
 
-    if (!ctx)
+    if (!aGContext)
     {
       Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_Window::CreateWindow: glXCreateContext failed.");
       return;
     }
 
-    OpenGl_ResourceCleaner::GetInstance()->AppendContext (ctx, true);
-
-    ThePreviousCtx = ctx;
-
     Colormap cmap = XCreateColormap (aDisp, aParent, aVis->visual, AllocNone);
 
     XColor color;
@@ -263,25 +302,23 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
 
     if (aVis->visualid == wattr.visual->visualid)
     {
-      win = aParent;
+      aWindow = aParent;
     }
     else
     {
       unsigned long mask = CWBackPixel | CWColormap | CWBorderPixel | CWEventMask;
-      win = XCreateWindow (aDisp, aParent, 0, 0, myWidth, myHeight, 0/*bw*/, aVis->depth, InputOutput, aVis->visual, mask, &cwa);
+      aWindow = XCreateWindow (aDisp, aParent, 0, 0, myWidth, myHeight, 0/*bw*/, aVis->depth, InputOutput, aVis->visual, mask, &cwa);
     }
 
-    XSetWindowBackground (aDisp, win, cwa.background_pixel);
-    XClearWindow (aDisp, win);
+    XSetWindowBackground (aDisp, aWindow, cwa.background_pixel);
+    XClearWindow (aDisp, aWindow);
 
-    if (win != aParent)
+    if (aWindow != aParent)
     {
       XEvent anEvent;
-      XMapWindow (aDisp, win);
-      XIfEvent (aDisp, &anEvent, WaitForNotify, (char* )win);
+      XMapWindow (aDisp, aWindow);
+      XIfEvent (aDisp, &anEvent, WaitForNotify, (char* )aWindow);
     }
-
-    myGContext = ctx;
   }
 
   /*
@@ -297,114 +334,21 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
   * (Carte Impact avec GLX_RED_SIZE a 5 par exemple)
   */
 
-  int value;
-  glXGetConfig (aDisp, aVis, GLX_RED_SIZE, &value);
+  int aValue;
+  glXGetConfig (aDisp, aVis, GLX_RED_SIZE, &aValue);
 
   if (myDither)
-    myDither = (value < 8);
+    myDither = (aValue < 8);
 
   if (myBackDither)
     myBackDither = (aVis->depth <= 8);
 
   XFree ((char* )aVis);
 
-  myWindow = win;
-
-#else
-
-  myWindowDC = GetDC (aParent);
-
-  PIXELFORMATDESCRIPTOR pfd;
-  int iPixelFormat = find_pixel_format (myWindowDC, &pfd, myDisplay->DBuffer());
-  if (iPixelFormat == 0)
-  {
-    ReleaseDC (aParent, myWindowDC);
-    myWindowDC = 0;
-
-    TCollection_AsciiString msg ("OpenGl_Window::CreateWindow: ChoosePixelFormat failed. Error code: ");
-    msg += (int )GetLastError();
-    Aspect_GraphicDeviceDefinitionError::Raise (msg.ToCString());
-    return;
-  }
-
-  if (pfd.dwFlags & PFD_NEED_PALETTE)
-  {
-    WINDOW_DATA* wd = (WINDOW_DATA* )GetWindowLongPtr (aParent, GWLP_USERDATA);
-
-    mySysPalInUse = (pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE) ? TRUE : FALSE;
-    InterfaceGraphic_RealizePalette (myWindowDC, wd->hPal, FALSE, mySysPalInUse);
-  }
-
-  if (myDither)
-    myDither = (pfd.cColorBits <= 8);
-
-  if (myBackDither)
-    myBackDither = (pfd.cColorBits <= 8);
-
-  if (!SetPixelFormat (myWindowDC, iPixelFormat, &pfd))
-  {
-    ReleaseDC (aParent, myWindowDC);
-    myWindowDC = NULL;
-
-    TCollection_AsciiString msg("OpenGl_Window::CreateWindow: SetPixelFormat failed. Error code: ");
-    msg += (int)GetLastError();
-    Aspect_GraphicDeviceDefinitionError::Raise (msg.ToCString());
-    return;
-  }
-
-  if (!myOwnGContext)
-  {
-    ThePreviousCtx = myGContext;
-  }
-  else
-  {
-    myGContext = wglCreateContext (myWindowDC);
-    if (myGContext == NULL)
-    {
-      ReleaseDC (aParent, myWindowDC);
-      myWindowDC = NULL;
-
-      TCollection_AsciiString msg ("OpenGl_Window::CreateWindow: wglCreateContext failed. Error code: ");
-      msg += (int )GetLastError();
-      Aspect_GraphicDeviceDefinitionError::Raise (msg.ToCString());
-      return;
-    }
-
-    Standard_Boolean isShared = Standard_True;
-    if (ThePreviousCtx == NULL)
-    {
-      ThePreviousCtx = myGContext;
-    }
-    else
-    {
-      // if we already have some shared context
-      GLCONTEXT shareCtx = OpenGl_ResourceCleaner::GetInstance()->GetSharedContext();
-      if (shareCtx != NULL)
-      {
-        // try to share context with one from resource cleaner list
-        isShared = (Standard_Boolean )wglShareLists (shareCtx, myGContext);
-      }
-      else
-      {
-        isShared = (Standard_Boolean )wglShareLists (ThePreviousCtx, myGContext);
-        // add shared ThePreviousCtx to a control list if it's not there
-        if (isShared)
-          OpenGl_ResourceCleaner::GetInstance()->AppendContext (ThePreviousCtx, isShared);
-      }
-    }
-
-    // add the context to OpenGl_ResourceCleaner control list
-    OpenGl_ResourceCleaner::GetInstance()->AppendContext (myGContext, isShared);
-  }
-
-  myWindow = aParent;
+  myGlContext->Init ((Aspect_Drawable )aWindow, (Aspect_Display )myDisplay->GetDisplay(), (Aspect_RenderingContext )aGContext);
 #endif
+  myGlContext->Share (theShareCtx);
 
-#if (defined(_WIN32) || defined(__WIN32__))
-  myGlContext->Init (myWindow, myWindowDC, myGContext);
-#else
-  myGlContext->Init (myWindow, myDisplay->GetDisplay(), myGContext);
-#endif
   Init();
 }
 
@@ -414,49 +358,31 @@ OpenGl_Window::OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
 // =======================================================================
 OpenGl_Window::~OpenGl_Window()
 {
-  DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
-  if (aDisp == NULL || !myOwnGContext)
-    return;
-
 #if (defined(_WIN32) || defined(__WIN32__))
-  OpenGl_ResourceCleaner::GetInstance()->RemoveContext (myGContext);
-
-  if (wglGetCurrentContext() != NULL)
-    wglDeleteContext (myGContext);
-  ReleaseDC (myWindow, myWindowDC);
-
-  if (myDisplay->myMapOfWindows.Size() == 0)
-    ThePreviousCtx = 0;
-#else
-  // FSXXX sync necessary if non-direct rendering
-  glXWaitGL();
+  HWND  aWindow   = (HWND  )myGlContext->myWindow;
+  HDC   aWindowDC = (HDC   )myGlContext->myWindowDC;
+  HGLRC aGContext = (HGLRC )myGlContext->myGContext;
+  myGlContext.Nullify();
 
-  if (ThePreviousCtx == myGContext)
+  if (myOwnGContext)
   {
-    ThePreviousCtx = NULL;
-    if (myDisplay->myMapOfWindows.Size() > 0)
+    if (wglGetCurrentContext() != NULL)
     {
-      NCollection_DataMap<Standard_Integer, Handle(OpenGl_Window)>::Iterator it (myDisplay->myMapOfWindows);
-      ThePreviousCtx = it.Value()->myGContext;
-    }
-
-    // if this is the last remaining context, do not destroy it yet, to avoid
-    // losing any shared display lists (fonts...)
-    if (ThePreviousCtx)
-    {
-      OpenGl_ResourceCleaner::GetInstance()->RemoveContext(myGContext);
-      glXDestroyContext(aDisp, myGContext);
-    }
-    else
-    {
-      TheDeadGlxCtx = myGContext;
-      TheDeadGlxDpy = aDisp;
+      wglDeleteContext (aGContext);
     }
+    ReleaseDC (aWindow, aWindowDC);
   }
-  else
+#else
+  GLXDrawable aWindow   = (GLXDrawable )myGlContext->myWindow;
+  Display*    aDisplay  = (Display*    )myGlContext->myDisplay;
+  GLXContext  aGContext = (GLXContext  )myGlContext->myGContext;
+  myGlContext.Nullify();
+
+  if (aDisplay != NULL && myOwnGContext)
   {
-    OpenGl_ResourceCleaner::GetInstance()->RemoveContext (myGContext);
-    glXDestroyContext (aDisp, myGContext);
+    // FSXXX sync necessary if non-direct rendering
+    glXWaitGL();
+    glXDestroyContext (aDisplay, aGContext);
   }
 #endif
 }
@@ -488,7 +414,7 @@ void OpenGl_Window::Resize (const CALL_DEF_WINDOW& theCWindow)
   myHeight = (Standard_Integer )theCWindow.dy;
 
 #if (!defined(_WIN32) && !defined(__WIN32__))
-  XResizeWindow (aDisp, myWindow, (unsigned int )myWidth, (unsigned int )myHeight);
+  XResizeWindow (aDisp, myGlContext->myWindow, (unsigned int )myWidth, (unsigned int )myHeight);
   XSync (aDisp, False);
 #endif
 
@@ -542,7 +468,7 @@ void OpenGl_Window::Init()
 
 #if (defined(_WIN32) || defined(__WIN32__))
   RECT cr;
-  GetClientRect (myWindow, &cr);
+  GetClientRect ((HWND )myGlContext->myWindow, &cr);
   myWidth  = cr.right - cr.left;
   myHeight = cr.bottom - cr.top;
 #else
@@ -552,7 +478,7 @@ void OpenGl_Window::Init()
   unsigned int aNewWidth  = 0;
   unsigned int aNewHeight = 0;
   DISPLAY* aDisp = (DISPLAY* )myDisplay->GetDisplay();
-  XGetGeometry (aDisp, myWindow, &aRootWin, &aDummy, &aDummy, &aNewWidth, &aNewHeight, &aDummyU, &aDummyU);
+  XGetGeometry (aDisp, myGlContext->myWindow, &aRootWin, &aDummy, &aDummy, &aNewWidth, &aNewHeight, &aDummyU, &aDummyU);
   myWidth  = aNewWidth;
   myHeight = aNewHeight;
 #endif
@@ -682,3 +608,12 @@ void OpenGl_Window::MakeFrontAndBackBufCurrent() const
 {
   glDrawBuffer (GL_FRONT_AND_BACK);
 }
+
+// =======================================================================
+// function : GetGContext
+// purpose  :
+// =======================================================================
+GLCONTEXT OpenGl_Window::GetGContext() const
+{
+  return (GLCONTEXT )myGlContext->myGContext;
+}
index 12babfc..783ae5c 100644 (file)
@@ -40,7 +40,8 @@ public:
   //! Main constructor - prepare GL context for specified window.
   OpenGl_Window (const Handle(OpenGl_Display)& theDisplay,
                  const CALL_DEF_WINDOW&        theCWindow,
-                 Aspect_RenderingContext       theGContext);
+                 Aspect_RenderingContext       theGContext,
+                 const Handle(OpenGl_Context)& theShareCtx);
 
   //! Destructor
   virtual ~OpenGl_Window();
@@ -70,8 +71,8 @@ public:
 
   const Handle(OpenGl_Context)& GetGlContext() const { return myGlContext; }
 
-  WINDOW    GetWindow()   const { return myWindow; }
-  GLCONTEXT GetGContext() const { return myGContext; }
+  //! This method will be removed in future version!
+  GLCONTEXT GetGContext() const;
 
 protected:
 
@@ -96,12 +97,9 @@ protected:
 protected:
 
   Handle(OpenGl_Display) myDisplay;
-  WINDOW                 myWindow;      //!< native window handle, system-specific
   Handle(OpenGl_Context) myGlContext;
-  GLCONTEXT              myGContext;    //!< native GL context bound to this window, system-specific
   Standard_Boolean       myOwnGContext; //!< set to TRUE if GL context was not created by this class
 #if (defined(_WIN32) || defined(__WIN32__))
-  HDC                    myWindowDC;
   BOOL                   mySysPalInUse;
 #endif
 
index a52fd0f..8a773bb 100644 (file)
@@ -63,8 +63,9 @@ namespace
 // =======================================================================
 OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay,
                                     const CALL_DEF_WINDOW&        theCWindow,
-                                    Aspect_RenderingContext       theGContext)
-: OpenGl_Window (theDisplay, theCWindow, theGContext),
+                                    Aspect_RenderingContext       theGContext,
+                                    const Handle(OpenGl_Context)& theShareCtx)
+: OpenGl_Window (theDisplay, theCWindow, theGContext, theShareCtx),
   myTransientList (0),
   myIsTransientOpen (Standard_False),
   myRetainMode (Standard_False),
index d689a1f..b927c46 100644 (file)
@@ -63,7 +63,8 @@ public:
   //! Main constructor - prepare GL context for specified window.
   OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay,
                     const CALL_DEF_WINDOW&        theCWindow,
-                    Aspect_RenderingContext       theGContext);
+                    Aspect_RenderingContext       theGContext,
+                    const Handle(OpenGl_Context)& theShareCtx);
 
   //! Destructor
   virtual ~OpenGl_Workspace();
index c7297e4..edd0231 100644 (file)
@@ -534,9 +534,9 @@ Standard_Boolean OpenGl_Workspace::Print
 
   // setup printing context and viewport
   GLint aViewPortBack[4]; 
-  GLint anAlignBack     = 1;
+  GLint anAlignBack = 1;
 
-  OpenGl_PrinterContext aPrinterContext (myGContext);
+  OpenGl_PrinterContext aPrinterContext (GetGContext());
   aPrinterContext.SetLayerViewport ((GLsizei)aFrameWidth,
                                     (GLsizei)aFrameHeight);
   glGetIntegerv (GL_VIEWPORT, aViewPortBack);
@@ -814,7 +814,7 @@ void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView,
       glDisable(GL_DEPTH_TEST);
 
     glClearDepth(1.0);
-       toClear |= GL_DEPTH_BUFFER_BIT;
+    toClear |= GL_DEPTH_BUFFER_BIT;
   }
   else
   {
@@ -825,7 +825,7 @@ void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView,
   {
     // Set background to white
     glClearColor (1.F, 1.F, 1.F, 1.F);
-       toClear |= GL_DEPTH_BUFFER_BIT;
+    toClear |= GL_DEPTH_BUFFER_BIT;
   }
   else
   {
@@ -839,12 +839,7 @@ void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView,
   // Swap the buffers
   if ( aswap )
   {
-#ifndef WNT
-    glXSwapBuffers ((Display*)myDisplay->GetDisplay (), myWindow );
-#else
-    SwapBuffers ( wglGetCurrentDC () );
-    glFlush();
-#endif  /* WNT */
+    GetGlContext()->SwapBuffers();
     myBackBufferRestored = Standard_False;
   }
   else
@@ -960,20 +955,20 @@ void OpenGl_Workspace::CopyBuffers (Tint vid, int FrontToBack, Tfloat xm, Tfloat
 /*----------------------------------------------------------------------*/
 
 //call_subr_displayCB
-void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& ACView, int reason)
+void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
+                                        int theReason)
 {
-  if( ACView.GDisplayCB )
+  if (theCView.GDisplayCB == NULL)
   {
-    Aspect_GraphicCallbackStruct callData;
-    callData.reason = reason;
-    callData.display = (DISPLAY*)myDisplay->GetDisplay();
-    callData.window = (WINDOW)myWindow;
-    callData.wsID = ACView.WsId;
-    callData.viewID = ACView.ViewId;
-    callData.gcontext = myGContext;
-
-    int status = (*ACView.GDisplayCB)( ACView.DefWindow.XWindow, ACView.GClientData, &callData );
+    return;
   }
+
+  Aspect_GraphicCallbackStruct aCallData;
+  aCallData.reason    = theReason;
+  aCallData.glContext = GetGlContext();
+  aCallData.wsID      = theCView.WsId;
+  aCallData.viewID    = theCView.ViewId;
+  theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData);
 }
 
 /*----------------------------------------------------------------------*/
index 3b4f0c6..0eecbcc 100644 (file)
@@ -25,7 +25,6 @@
 #endif
 
 #include <OpenGl_FrameBuffer.hxx>
-#include <OpenGl_ResourceCleaner.hxx>
 #include <InterfaceGraphic_Graphic3d.hxx>
 #include <InterfaceGraphic_Visual3d.hxx>
 
@@ -41,7 +40,7 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
 
   // release pending GL resources
   Handle(OpenGl_Context) aGlCtx = GetGlContext();
-  OpenGl_ResourceCleaner::GetInstance()->Cleanup (aGlCtx);
+  aGlCtx->ReleaseDelayed();
 
   // cache render mode state
   GLint aRendMode = GL_RENDER;
index e1648e0..79b5318 100644 (file)
@@ -32,6 +32,7 @@
 #include <DrawTrSurf.hxx>
 #include <AIS_InteractiveContext.hxx>
 #include <ViewerTest.hxx>
+#include <ViewerTest_EventManager.hxx>
 #include <AIS_Shape.hxx>
 #include <TopoDS_Shape.hxx>
 
@@ -570,26 +571,31 @@ static Standard_Integer OCC280 (Draw_Interpretor& di, Standard_Integer argc, con
     HLR = 1;
   }
 
-  Handle(V3d_View) aView = ViewerTest::CurrentView();
-
+  Handle(V3d_View) anOldView = ViewerTest::CurrentView();
   Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
-  if(atoi(argv[2])) {
-    aViewer->SetDefaultSurfaceDetail(V3d_TEX_ALL);
+  if (atoi (argv[2]))
+  {
+    aViewer->SetDefaultSurfaceDetail (V3d_TEX_ALL);
   }
-  aViewer->SetDefaultTypeOfView(V3d_PERSPECTIVE);
+  aViewer->SetDefaultTypeOfView (V3d_PERSPECTIVE);
 
-  Handle(Aspect_Window) asp = aView->Window();
-  aViewer->SetViewOff(aView);
-  aView->Remove();
+  Handle(Aspect_Window) asp = anOldView->Window();
+  aViewer->SetViewOff (anOldView);
+  anOldView->Remove();
+  anOldView.Nullify();
 
   Handle(V3d_View) aNewView = aViewer->CreateView();
-  ViewerTest::CurrentView(aNewView);
+  ViewerTest::CurrentView (aNewView);
 
-  aNewView->SetWindow(asp);
+  aNewView->SetWindow (asp);
   if (!asp->IsMapped()) asp->Map();
 
   aNewView->Update();
 
+  // replace view in event manager
+  ViewerTest::UnsetEventManager();
+  ViewerTest::SetEventManager (new ViewerTest_EventManager (aNewView, ViewerTest::GetAISContext()));
+
   if (HLR == 1) {
     di << "HLR" << "\n";
     aNewView->SetDegenerateModeOff();
@@ -2001,7 +2007,7 @@ static Standard_Integer OCC1642 (Draw_Interpretor& di, Standard_Integer argc, co
   DBRep::Set(argv[4],face);
 
   advWA->SetFace(face);
-  float precision_to_ana = 0.0001;
+  Standard_Real precision_to_ana = 0.0001;
   advWA->SetPrecision(precision_to_ana);
 
   TopTools_IndexedMapOfShape M;
index 04df995..fab3967 100755 (executable)
@@ -560,14 +560,12 @@ void V3d_View::SetWindow(const Handle(Aspect_Window)&      aWindow,
 
 /*----------------------------------------------------------------------*/
 
-void V3d_View::Remove() const  {
-
-  MyViewer->DelView(this) ;
-  MyView->Remove() ;
-#ifdef IMP260303
-  MyWindow.Nullify();
-#endif
-
+void V3d_View::Remove() const
+{
+  MyViewer->DelView (this);
+  MyView->Remove();
+  Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
+  aWin.Nullify();
 }
 
 /*----------------------------------------------------------------------*/
index 34d5cee..330d9b8 100755 (executable)
@@ -3251,10 +3251,10 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
   }
   else if (argc < 3)
   {
-    di << "Use: " << argv[0] << " Name TypeOfArray [EnableVBO={0 | 1}]"
+    di << "Use: " << argv[0] << " Name TypeOfArray"
        << " [vertex] ... [bounds] ... [edges]\n"
        << "  TypeOfArray={ points | segments | polylines | triangles |\n"
-       << "                trianglefan | trianglestrips | quads |\n"
+       << "                trianglefans | trianglestrips | quads |\n"
        << "                quadstrips | polygons }\n"
        << "  vertex={ 'v' x y z [normal={ 'n' nx ny nz }] [color={ 'c' r g b }]"
        << " [texel={ 't' tx ty }] } \n"
@@ -3264,20 +3264,16 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
   }
 
   // read the arguments
-  TCollection_AsciiString aName (argv[1]);
-  TCollection_AsciiString anArrayType (argv[2]);
-  
-  // is argument list has an vbo flag
-  Standard_Boolean hasFlagVbo = Standard_False;
-  if (isdigit (argv[3][0]) && atoi (argv[3]) >= 0 && atoi (argv[3]) <= 1)
-    hasFlagVbo = Standard_True;
+  Standard_Integer aArgIndex = 1;
+  TCollection_AsciiString aName (argv[aArgIndex++]);
+  TCollection_AsciiString anArrayType (argv[aArgIndex++]);
+  const Standard_Integer anArgsFrom = aArgIndex;
 
   // parse number of verticies, bounds, edges
   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
   Standard_Boolean hasVColors, hasBColors, hasNormals, hasInfos, hasTexels;
   hasVColors = hasNormals = hasBColors = hasInfos = hasTexels = Standard_False;
 
-  Standard_Integer aArgIndex = (hasFlagVbo) ? 4 : 3;
   TCollection_AsciiString aCommand;
   while (aArgIndex < argc)
   {
@@ -3375,7 +3371,7 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
   }
 
   // parse an array of primitives
-  aArgIndex = (hasFlagVbo) ? 4 : 3;
+  aArgIndex = anArgsFrom;
   while (aArgIndex < argc)
   {
     aCommand = argv[aArgIndex];
@@ -3438,17 +3434,6 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
       aArgIndex++;
   }
 
-  if (hasFlagVbo)
-  {
-    // enable / disable vbo
-    Handle(Graphic3d_GraphicDriver) aDriver =
-      Handle(Graphic3d_GraphicDriver)::DownCast (
-                      aContextAIS->CurrentViewer()->Device()->GraphicDriver());
-
-    if (!aDriver.IsNull())
-      aDriver->EnableVBO ((Standard_Boolean) atoi (argv[3]));
-  }
-
   // create primitives array object
   Handle (MyPArrayObject) aPObject = new MyPArrayObject (anArray);
 
@@ -4379,7 +4364,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
     __FILE__, VComputeHLR, group);
 
   theCommands.Add("vdrawparray",
-    "vdrawparray : vdrawparray Name TypeOfArray [EnableVbo=1] [vertex = { 'v' x y z [vertex_normal = { 'n' x y z }] [vertex_color = { 'c' r g b }] ] ... [bound = { 'b' vertex_count [bound_color = { 'c' r g b }] ] ... [edge = { 'e' vertex_id [edge_hidden = { 'h' }] ]",
+    "vdrawparray : vdrawparray Name TypeOfArray [vertex = { 'v' x y z [vertex_normal = { 'n' x y z }] [vertex_color = { 'c' r g b }] ] ... [bound = { 'b' vertex_count [bound_color = { 'c' r g b }] ] ... [edge = { 'e' vertex_id [edge_hidden = { 'h' }] ]",
     __FILE__,VDrawPArray,group);
 
   theCommands.Add("vconnect", 
index 2d36855..58332c6 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <ViewerTest.hxx>
 
+#include <Aspect_GraphicDevice.hxx>
+#include <AIS_InteractiveContext.hxx>
 #include <AIS_InteractiveObject.hxx>
 #include <Draw.hxx>
 #include <Draw_Interpretor.hxx>
 #include <OpenGl_AspectLine.hxx>
 #include <OpenGl_AspectMarker.hxx>
 #include <OpenGl_AspectText.hxx>
-#include <OpenGl_Callback.hxx>
 #include <OpenGl_Context.hxx>
 #include <OpenGl_Element.hxx>
 #include <OpenGl_ExtFBO.hxx>
 #include <OpenGl_GlCore20.hxx>
-#include <OpenGl_ResourceCleaner.hxx>
-#include <OpenGl_ResourceTexture.hxx>
-#include <OpenGl_ResourceVBO.hxx>
+#include <OpenGl_GraphicDriver.hxx>
 #include <OpenGl_Workspace.hxx>
 #include <Prs3d_Presentation.hxx>
 #include <Prs3d_Root.hxx>
 #include <Select3D_SensitiveCurve.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <SelectMgr_Selection.hxx>
+#include <V3d_Viewer.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <V3d_View.hxx>
 
@@ -100,6 +100,11 @@ public:
         myIObj->Render(theWorkspace);
     }
 
+    virtual void Release (const Handle(OpenGl_Context)& theGlCtx)
+    {
+      //
+    }
+
   public:
     DEFINE_STANDARD_ALLOC
   };
@@ -175,21 +180,7 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const
     *(theWorkspace->HighlightColor) : aLA->Color();
 
   // To test OpenGl_Window
-  Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
-  GLCONTEXT aGlContext = theWorkspace->GetGContext();
-
-  // To link against OpenGl_Context and extensions
-  GLuint aVboId = -1, aTexId = -1;
-  if (aCtx->arbVBO)
-    aCtx->arbVBO->glGenBuffersARB(1, &aVboId);
-  glGenTextures(1, &aTexId);
-
-  // To link against OpenGl_ResourceCleaner, OpenGl_ResourceVBO, OpenGl_ResourceTexture
-  OpenGl_ResourceCleaner* aResCleaner = OpenGl_ResourceCleaner::GetInstance();
-  if (aVboId != (GLuint)-1)
-    aResCleaner->AddResource(aGlContext, new OpenGl_ResourceVBO(aVboId));
-  if (aTexId != (GLuint)-1)
-    aResCleaner->AddResource(aGlContext, new OpenGl_ResourceTexture(aTexId));
+  //Handle(OpenGl_Context) aCtx = theWorkspace->GetGlContext();
 
   // Finally draw something to make sure UserDraw really works
   glPushAttrib(GL_ENABLE_BIT);
@@ -228,6 +219,13 @@ static Standard_Integer VUserDraw (Draw_Interpretor& di,
     return 1;
   }
 
+  Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast (aContext->CurrentViewer()->Device()->GraphicDriver());
+  if (aDriver.IsNull())
+  {
+    std::cerr << "Graphic driver not available.\n";
+    return 1;
+  }
+
   if (argc > 2)
   {
     di << argv[0] << "Wrong number of arguments, only the object name expected\n";
@@ -238,7 +236,7 @@ static Standard_Integer VUserDraw (Draw_Interpretor& di,
   VDisplayAISObject(aName, Handle(AIS_InteractiveObject)());
 
   // register the custom element factory function
-  ::UserDrawCallback() = VUserDrawCallback;
+  aDriver->UserDrawCallback() = VUserDrawCallback;
 
   Handle(VUserDrawObj) anIObj = new VUserDrawObj();
   VDisplayAISObject(aName, anIObj);
index 530979b..754411d 100755 (executable)
@@ -234,16 +234,14 @@ void ViewerTest::ViewerInit (const Standard_Integer thePxLeft,  const Standard_I
     a3DCollector = new V3d_Viewer(GetG3dDevice(), NameOfWindow.ToExtString());
     a3DViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
     a3DCollector->SetDefaultBackgroundColor(Quantity_NOC_STEELBLUE);
-    Handle(NIS_View) aView =
-      Handle(NIS_View)::DownCast(ViewerTest::CurrentView());
-    if ( aView.IsNull() ) {
-      //       Handle (V3d_View) V = a3DViewer->CreateView();
+    Handle(NIS_View) aView = Handle(NIS_View)::DownCast(ViewerTest::CurrentView());
+    if (aView.IsNull())
+    {
+      //Handle(V3d_View) a3DViewCol = a3DViewer->CreateView();
       aView = new NIS_View (a3DViewer, VT_GetWindow());
       ViewerTest::CurrentView(aView);
       TheNISContext()->AttachView (aView);
     }
-    Handle(V3d_View) a3DViewCol;
-    if ( a3DViewCol.IsNull() ) a3DViewCol    = a3DViewer->CreateView();
 
     // AIS setup
     if ( ViewerTest::GetAISContext().IsNull() ) {
index 5b0ba09..90ccd31 100755 (executable)
@@ -137,9 +137,15 @@ void Visual3d_ViewManager::Remove () {
        cout << "The Manager " << MyId << " have " << Length << " defined views\n";
        cout << flush;
 #endif
-       MyDefinedView.Clear ();
 
+  // clear all structures whilst views are alive for correct GPU memory management
+  MyDisplayedStructure.Clear();
+  MyHighlightedStructure.Clear();
+  MyVisibleStructure.Clear();
+  MyPickStructure.Clear();
+
+  // clear list of managed views
+  MyDefinedView.Clear();
 }
 
 void Visual3d_ViewManager::ChangeDisplayPriority (const Handle(Graphic3d_Structure)& AStructure, const Standard_Integer OldPriority, const Standard_Integer NewPriority) {
index e75fbc7..88497ec 100755 (executable)
@@ -27,7 +27,7 @@
 
 #include <InterfaceGraphic_telem.hxx>
 #include <OpenGl_Element.hxx>
-#include <OpenGl_Callback.hxx>
+#include <OpenGl_GraphicDriver.hxx>
 #include <OpenGl_NamedStatus.hxx>
 
 #include <GL/gl.h>
@@ -46,6 +46,11 @@ public:
 
   void Render (const Handle(OpenGl_Workspace) &theWorkspace) const;
 
+  virtual void Release (const Handle(OpenGl_Context)& theContext)
+  {
+    //
+  }
+
 private:
 
   VoxelClient_VisDrawer* myHandler;
@@ -126,16 +131,14 @@ static OpenGl_Element* VisDrawerCallBack (const Graphic3d_CUserDraw* theUserDraw
 }
 
 /**************************************************************************/
-void VoxelClient_VisDrawer::Init()
+void VoxelClient_VisDrawer::Init (Handle(OpenGl_GraphicDriver)& theDriver)
 {
     static Standard_Boolean isInitializeded(Standard_False);
 
     if (!isInitializeded)
     {
         isInitializeded = Standard_True;
-
-        OpenGl_UserDrawCallback& aCallback = UserDrawCallback ();
-        aCallback = VisDrawerCallBack;
+        theDriver->UserDrawCallback() = VisDrawerCallBack;
     }
 }
 
index cb89ac2..a36cca9 100755 (executable)
@@ -24,6 +24,8 @@
 #include "Voxel_VisData.h"
 #include <Graphic3d_CBounds.hxx>
 
+class Handle(OpenGl_GraphicDriver);
+
 class VoxelClient_VisDrawer
 {
 public:
@@ -32,7 +34,7 @@ public:
 
 public:
 
-    Standard_EXPORT static void Init();
+  Standard_EXPORT static void Init (Handle(OpenGl_GraphicDriver)& theDriver);
 
        Standard_EXPORT VoxelClient_VisDrawer(Voxel_VisData* theData);
        Standard_EXPORT virtual ~VoxelClient_VisDrawer();