From 5e27df788d564fdcae7d51d0a98e32779c5da2d6 Mon Sep 17 00:00:00 2001 From: kgv Date: Fri, 13 Jul 2012 15:51:16 +0400 Subject: [PATCH] 0023226: Extend OpenGl_Context to store map of shared GPU resources 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. --- src/Aspect/Aspect_GraphicCallbackProc.hxx | 40 +- src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx | 42 +- src/Graphic3d/Graphic3d_Structure.cxx | 37 +- .../InterfaceGraphic_PrimitiveArray.hxx | 21 - src/NCollection/FILES | 3 + src/NCollection/NCollection_Vec2.hxx | 230 +++++++++ src/NCollection/NCollection_Vec3.hxx | 352 ++++++++++++++ src/NCollection/NCollection_Vec4.hxx | 321 +++++++++++++ src/OpenGl/FILES | 14 +- ...{OpenGl_Callback.hxx => OpenGl_ArbIns.hxx} | 24 +- src/OpenGl/OpenGl_ArbTBO.hxx | 33 ++ src/OpenGl/OpenGl_AspectFace.cxx | 9 +- src/OpenGl/OpenGl_AspectFace.hxx | 4 +- src/OpenGl/OpenGl_AspectLine.cxx | 9 +- src/OpenGl/OpenGl_AspectLine.hxx | 4 +- src/OpenGl/OpenGl_AspectMarker.cxx | 9 +- src/OpenGl/OpenGl_AspectMarker.hxx | 4 +- src/OpenGl/OpenGl_AspectText.cxx | 9 +- src/OpenGl/OpenGl_AspectText.hxx | 18 +- src/OpenGl/OpenGl_Context.cxx | 150 ++++++ src/OpenGl/OpenGl_Context.hxx | 83 +++- src/OpenGl/OpenGl_Element.hxx | 34 +- src/OpenGl/OpenGl_GraphicDriver.cxx | 70 +-- src/OpenGl/OpenGl_GraphicDriver.hxx | 27 +- src/OpenGl/OpenGl_GraphicDriver_3.cxx | 4 +- src/OpenGl/OpenGl_GraphicDriver_4.cxx | 31 +- src/OpenGl/OpenGl_GraphicDriver_7.cxx | 66 +-- src/OpenGl/OpenGl_GraphicDriver_713.cxx | 32 +- src/OpenGl/OpenGl_GraphicDriver_9.cxx | 2 +- src/OpenGl/OpenGl_Group.cxx | 78 ++- src/OpenGl/OpenGl_Group.hxx | 35 +- ...ResourceVBO.cxx => OpenGl_IndexBuffer.cxx} | 37 +- ...ResourceVBO.hxx => OpenGl_IndexBuffer.hxx} | 40 +- src/OpenGl/OpenGl_Marker.cxx | 5 + src/OpenGl/OpenGl_Marker.hxx | 4 +- src/OpenGl/OpenGl_MarkerSet.cxx | 5 +- src/OpenGl/OpenGl_MarkerSet.hxx | 21 +- src/OpenGl/OpenGl_Polygon.cxx | 5 +- src/OpenGl/OpenGl_Polygon.hxx | 15 +- src/OpenGl/OpenGl_Polyline.cxx | 5 + src/OpenGl/OpenGl_Polyline.hxx | 17 +- src/OpenGl/OpenGl_PrimitiveArray.cxx | 447 ++++++------------ src/OpenGl/OpenGl_PrimitiveArray.hxx | 39 +- src/OpenGl/OpenGl_Resource.cxx | 7 +- src/OpenGl/OpenGl_Resource.hxx | 64 ++- src/OpenGl/OpenGl_ResourceCleaner.cxx | 226 --------- src/OpenGl/OpenGl_ResourceCleaner.hxx | 96 ---- src/OpenGl/OpenGl_ResourceTexture.cxx | 30 +- src/OpenGl/OpenGl_ResourceTexture.hxx | 11 +- src/OpenGl/OpenGl_Structure.cxx | 197 ++++---- src/OpenGl/OpenGl_Structure.hxx | 68 +-- src/OpenGl/OpenGl_Text.cxx | 5 +- src/OpenGl/OpenGl_Text.hxx | 17 +- src/OpenGl/OpenGl_TextureBox.cxx | 93 +--- src/OpenGl/OpenGl_TextureBox.hxx | 5 +- src/OpenGl/OpenGl_TextureBufferArb.cxx | 151 ++++++ src/OpenGl/OpenGl_TextureBufferArb.hxx | 97 ++++ src/OpenGl/OpenGl_VertexBuffer.cxx | 290 ++++++++++++ src/OpenGl/OpenGl_VertexBuffer.hxx | 158 +++++++ src/OpenGl/OpenGl_VertexBufferEditor.hxx | 123 +++++ src/OpenGl/OpenGl_Window.cxx | 301 +++++------- src/OpenGl/OpenGl_Window.hxx | 10 +- src/OpenGl/OpenGl_Workspace.cxx | 5 +- src/OpenGl/OpenGl_Workspace.hxx | 3 +- src/OpenGl/OpenGl_Workspace_2.cxx | 37 +- src/OpenGl/OpenGl_Workspace_4.cxx | 3 +- src/QABugs/QABugs_17.cxx | 28 +- src/V3d/V3d_View.cxx | 14 +- src/ViewerTest/ViewerTest_ObjectCommands.cxx | 31 +- src/ViewerTest/ViewerTest_OpenGlCommands.cxx | 38 +- src/ViewerTest/ViewerTest_ViewerCommands.cxx | 10 +- src/Visual3d/Visual3d_ViewManager.cxx | 10 +- src/VoxelClient/VoxelClient_VisDrawer.cxx | 13 +- src/VoxelClient/VoxelClient_VisDrawer.h | 4 +- 74 files changed, 2996 insertions(+), 1584 deletions(-) create mode 100644 src/NCollection/NCollection_Vec2.hxx create mode 100644 src/NCollection/NCollection_Vec3.hxx create mode 100644 src/NCollection/NCollection_Vec4.hxx rename src/OpenGl/{OpenGl_Callback.hxx => OpenGl_ArbIns.hxx} (68%) create mode 100644 src/OpenGl/OpenGl_ArbTBO.hxx rename src/OpenGl/{OpenGl_ResourceVBO.cxx => OpenGl_IndexBuffer.cxx} (54%) mode change 100755 => 100644 rename src/OpenGl/{OpenGl_ResourceVBO.hxx => OpenGl_IndexBuffer.hxx} (53%) mode change 100755 => 100644 delete mode 100755 src/OpenGl/OpenGl_ResourceCleaner.cxx delete mode 100755 src/OpenGl/OpenGl_ResourceCleaner.hxx create mode 100644 src/OpenGl/OpenGl_TextureBufferArb.cxx create mode 100644 src/OpenGl/OpenGl_TextureBufferArb.hxx create mode 100644 src/OpenGl/OpenGl_VertexBuffer.cxx create mode 100644 src/OpenGl/OpenGl_VertexBuffer.hxx create mode 100644 src/OpenGl/OpenGl_VertexBufferEditor.hxx diff --git a/src/Aspect/Aspect_GraphicCallbackProc.hxx b/src/Aspect/Aspect_GraphicCallbackProc.hxx index 225c1b9bcc..898a4865f9 100755 --- a/src/Aspect/Aspect_GraphicCallbackProc.hxx +++ b/src/Aspect/Aspect_GraphicCallbackProc.hxx @@ -15,18 +15,13 @@ // 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 #include #include +#include // The flags below provide additional information to define the moment when // callback was invoked in redraw procedure. These flags are bitwise OR'ed @@ -42,29 +37,20 @@ // 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 class Handle(Standard_Type); const Handle(Standard_Type)& STANDARD_TYPE(Aspect_GraphicCallbackProc); -/*============================================================================*/ -#endif - #endif /* _Aspect_GraphicCallbackProc_HeaderFile */ diff --git a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx index acafa5fc8f..28cb2bce0e 100755 --- a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx @@ -27,9 +27,6 @@ #include #include -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( diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx index 615e1f1800..3eb05d8673 100755 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -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) { diff --git a/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx b/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx index 68bf072b60..e8a690a0a4 100755 --- a/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx +++ b/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx @@ -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_ */ diff --git a/src/NCollection/FILES b/src/NCollection/FILES index 2a3509bcdd..ea23893cde 100755 --- a/src/NCollection/FILES +++ b/src/NCollection/FILES @@ -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 index 0000000000..36814cb22d --- /dev/null +++ b/src/NCollection/NCollection_Vec2.hxx @@ -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 theX##theY##() const { return NCollection_Vec2(theX##(), theY##()); } \ + const NCollection_Vec2 theY##theX##() const { return NCollection_Vec2(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 +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 index 0000000000..33fbdaedc4 --- /dev/null +++ b/src/NCollection/NCollection_Vec3.hxx @@ -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 +#include +#include + +//! Auxiliary macros to define couple of similar access components as vector methods +#define NCOLLECTION_VEC_COMPONENTS_3D(theX, theY, theZ) \ + const NCollection_Vec3 theX##theY##theZ##() const { return NCollection_Vec3(theX##(), theY##(), theZ##()); } \ + const NCollection_Vec3 theX##theZ##theY##() const { return NCollection_Vec3(theX##(), theZ##(), theY##()); } \ + const NCollection_Vec3 theY##theX##theZ##() const { return NCollection_Vec3(theY##(), theX##(), theZ##()); } \ + const NCollection_Vec3 theY##theZ##theX##() const { return NCollection_Vec3(theY##(), theZ##(), theX##()); } \ + const NCollection_Vec3 theZ##theY##theX##() const { return NCollection_Vec3(theZ##(), theY##(), theX##()); } \ + const NCollection_Vec3 theZ##theX##theY##() const { return NCollection_Vec3(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 +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& 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& xy() + { + return *((NCollection_Vec2* )&v[0]); + } + + //! @return YZ-components modifiable vector + NCollection_Vec2& yz() + { + return *((NCollection_Vec2* )&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& NCollection_Vec3::operator/= (const float theInvFactor) +{ + Multiply (1.0f / theInvFactor); + return *this; +} + +//! Optimized concretization for double type. +template<> inline NCollection_Vec3& NCollection_Vec3::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 index 0000000000..d72e93f937 --- /dev/null +++ b/src/NCollection/NCollection_Vec4.hxx @@ -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 + +//! 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 +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& 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& theVec3) + { + std::memcpy (this, &theVec3, sizeof(NCollection_Vec3)); + v[3] = Element_t (0); + } + + //! Constructor from 3-components vector + alpha value. + explicit NCollection_Vec4(const NCollection_Vec3& theVec3, + const Element_t theAlpha) { + std::memcpy (this, &theVec3, sizeof(NCollection_Vec3)); + 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& xy() + { + return *((NCollection_Vec2* )&v[0]); + } + + //! @return YZ-components modifiable vector + NCollection_Vec2& yz() + { + return *((NCollection_Vec2* )&v[1]); + } + + //! @return YZ-components modifiable vector + NCollection_Vec2& zw() + { + return *((NCollection_Vec2* )&v[2]); + } + + //! @return XYZ-components modifiable vector + NCollection_Vec3& xyz() + { + return *((NCollection_Vec3* )&v[0]); + } + + //! @return YZW-components modifiable vector + NCollection_Vec3& yzw() + { + return *((NCollection_Vec3* )&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& NCollection_Vec4::operator/= (const float theInvFactor) +{ + Multiply (1.0f / theInvFactor); + return *this; +} + +//! Optimized concretization for double type. +template<> inline NCollection_Vec4& NCollection_Vec4::operator/= (const double theInvFactor) +{ + Multiply (1.0 / theInvFactor); + return *this; +} + +#endif // _NCollection_Vec4_H__ diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index 96ed44c1e5..1c197ccc15 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -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 diff --git a/src/OpenGl/OpenGl_Callback.hxx b/src/OpenGl/OpenGl_ArbIns.hxx similarity index 68% rename from src/OpenGl/OpenGl_Callback.hxx rename to src/OpenGl/OpenGl_ArbIns.hxx index a704495ada..9c9f141cd8 100644 --- a/src/OpenGl/OpenGl_Callback.hxx +++ b/src/OpenGl/OpenGl_ArbIns.hxx @@ -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 @@ -17,16 +17,18 @@ // 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 -#include +//! TBO is available on OpenGL 3.0+ hardware +struct OpenGl_ArbIns +{ -#include + 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__ diff --git a/src/OpenGl/OpenGl_ArbTBO.hxx b/src/OpenGl/OpenGl_ArbTBO.hxx new file mode 100644 index 0000000000..0f5e54e07b --- /dev/null +++ b/src/OpenGl/OpenGl_ArbTBO.hxx @@ -0,0 +1,33 @@ +// 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 +// 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_ArbTBO_H__ +#define _OpenGl_ArbTBO_H__ + +#include + +//! TBO is available on OpenGL 3.0+ hardware +struct OpenGl_ArbTBO +{ + + PFNGLTEXBUFFERARBPROC glTexBufferARB; + +}; + +#endif // _OpenGl_ArbTBO_H__ diff --git a/src/OpenGl/OpenGl_AspectFace.cxx b/src/OpenGl/OpenGl_AspectFace.cxx index 565d1b77b7..0718df62fd 100644 --- a/src/OpenGl/OpenGl_AspectFace.cxx +++ b/src/OpenGl/OpenGl_AspectFace.cxx @@ -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) +{ + // +} diff --git a/src/OpenGl/OpenGl_AspectFace.hxx b/src/OpenGl/OpenGl_AspectFace.hxx index c6b00aad8c..dd9993ab4f 100644 --- a/src/OpenGl/OpenGl_AspectFace.hxx +++ b/src/OpenGl/OpenGl_AspectFace.hxx @@ -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: diff --git a/src/OpenGl/OpenGl_AspectLine.cxx b/src/OpenGl/OpenGl_AspectLine.cxx index 6cdf13c5af..6d20572a26 100644 --- a/src/OpenGl/OpenGl_AspectLine.cxx +++ b/src/OpenGl/OpenGl_AspectLine.cxx @@ -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) +{ + // +} diff --git a/src/OpenGl/OpenGl_AspectLine.hxx b/src/OpenGl/OpenGl_AspectLine.hxx index 12166539bf..cf76c3f9d9 100644 --- a/src/OpenGl/OpenGl_AspectLine.hxx +++ b/src/OpenGl/OpenGl_AspectLine.hxx @@ -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: diff --git a/src/OpenGl/OpenGl_AspectMarker.cxx b/src/OpenGl/OpenGl_AspectMarker.cxx index a857b18f9e..a02b397a38 100644 --- a/src/OpenGl/OpenGl_AspectMarker.cxx +++ b/src/OpenGl/OpenGl_AspectMarker.cxx @@ -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) +{ + // +} diff --git a/src/OpenGl/OpenGl_AspectMarker.hxx b/src/OpenGl/OpenGl_AspectMarker.hxx index 91d9459f30..c03fdcbce2 100644 --- a/src/OpenGl/OpenGl_AspectMarker.hxx +++ b/src/OpenGl/OpenGl_AspectMarker.hxx @@ -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: diff --git a/src/OpenGl/OpenGl_AspectText.cxx b/src/OpenGl/OpenGl_AspectText.cxx index 3929d29c40..18eb71a05c 100644 --- a/src/OpenGl/OpenGl_AspectText.cxx +++ b/src/OpenGl/OpenGl_AspectText.cxx @@ -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) +{ + // } /*----------------------------------------------------------------------*/ diff --git a/src/OpenGl/OpenGl_AspectText.hxx b/src/OpenGl/OpenGl_AspectText.hxx index b22cdff6fc..8f52814a0f 100644 --- a/src/OpenGl/OpenGl_AspectText.hxx +++ b/src/OpenGl/OpenGl_AspectText.hxx @@ -30,10 +30,11 @@ 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 diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index d5c01e6263..00f8c2f0f9 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -25,6 +25,8 @@ #include #include +#include +#include #include #include @@ -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,11 +108,38 @@ 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::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 : @@ -181,6 +219,26 @@ Standard_Boolean OpenGl_Context::MakeCurrent() return Standard_True; } +// ======================================================================= +// 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(); + } +} diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index c054baa426..1d30704018 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -25,6 +25,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -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 + 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 OpenGl_ResourcesMap; + typedef NCollection_Handle Handle(OpenGl_ResourcesMap); + typedef NCollection_Queue OpenGl_ResourcesQueue; + typedef NCollection_Handle 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__ diff --git a/src/OpenGl/OpenGl_Element.hxx b/src/OpenGl/OpenGl_Element.hxx index 24219c4142..e9d67731b8 100644 --- a/src/OpenGl/OpenGl_Element.hxx +++ b/src/OpenGl/OpenGl_Element.hxx @@ -25,14 +25,38 @@ 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 + 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 diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index 0df91400c2..c5d486fc21 100755 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -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 TheMapOfView (1, NCollection_BaseAllocator::CommonBaseAllocator()); - static NCollection_DataMap TheMapOfWS (1, NCollection_BaseAllocator::CommonBaseAllocator()); - static NCollection_DataMap 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& OpenGl_GraphicDriver::GetMapOfViews() -{ - return TheMapOfView; -} - -// ======================================================================= -// function : GetMapOfWorkspaces +// function : UserDrawCallback // purpose : // ======================================================================= -NCollection_DataMap& OpenGl_GraphicDriver::GetMapOfWorkspaces() +OpenGl_GraphicDriver::OpenGl_UserDrawCallback_t& OpenGl_GraphicDriver::UserDrawCallback() { - return TheMapOfWS; + return myUserDrawCallback; } // ======================================================================= -// function : GetMapOfStructures +// function : DefaultTextHeight // purpose : // ======================================================================= -NCollection_DataMap& OpenGl_GraphicDriver::GetMapOfStructures() +Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const { - return TheMapOfStructure; + return 16.; } // ======================================================================= @@ -108,7 +93,7 @@ NCollection_DataMap& OpenGl_GraphicDriver:: // ======================================================================= void OpenGl_GraphicDriver::InvalidateAllWorkspaces() { - for (NCollection_DataMap::Iterator anIt (OpenGl_GraphicDriver::GetMapOfWorkspaces()); + for (NCollection_DataMap::Iterator anIt (myMapOfWS); anIt.More(); anIt.Next()) { anIt.ChangeValue()->EraseAnimation(); @@ -133,6 +118,21 @@ void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn) TheToUseVbo = theToTurnOn; } +// ======================================================================= +// function : GetSharedContext +// purpose : +// ======================================================================= +const Handle(OpenGl_Context)& OpenGl_GraphicDriver::GetSharedContext() const +{ + if (myMapOfWS.IsEmpty()) + { + return TheNullGlCtx; + } + + NCollection_DataMap::Iterator anIter (myMapOfWS); + return anIter.Value()->GetGlContext(); +} + // ======================================================================= // function : MemoryInfo // purpose : diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx index 457995809b..01f02b98be 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.hxx +++ b/src/OpenGl/OpenGl_GraphicDriver.hxx @@ -23,6 +23,7 @@ #include #include +#include #include @@ -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
@@ -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& GetMapOfViews(); + //! Method to setup UserDraw callback + Standard_EXPORT OpenGl_UserDrawCallback_t& UserDrawCallback(); - //! Access the global map of workspaces. - static NCollection_DataMap& GetMapOfWorkspaces(); +private: - //! Access the global map of structures. - static NCollection_DataMap& 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 myMapOfView; + NCollection_DataMap myMapOfWS; + NCollection_DataMap myMapOfStructure; + OpenGl_UserDrawCallback_t myUserDrawCallback; + }; #endif //_OpenGl_GraphicDriver_HeaderFile diff --git a/src/OpenGl/OpenGl_GraphicDriver_3.cxx b/src/OpenGl/OpenGl_GraphicDriver_3.cxx index 72e0715e8b..04fdd15dde 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_3.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_3.cxx @@ -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(); } diff --git a/src/OpenGl/OpenGl_GraphicDriver_4.cxx b/src/OpenGl/OpenGl_GraphicDriver_4.cxx index 9734c2a97f..1b849af60f 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_4.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_4.cxx @@ -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::Iterator - aStructIt (GetMapOfStructures ()); - + NCollection_DataMap::Iterator aStructIt (myMapOfStructure); for( ; aStructIt.More (); aStructIt.Next ()) { OpenGl_Structure* aStruct = aStructIt.ChangeValue (); diff --git a/src/OpenGl/OpenGl_GraphicDriver_7.cxx b/src/OpenGl/OpenGl_GraphicDriver_7.cxx index 1b4d667b64..d67a84f327 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_7.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_7.cxx @@ -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; } diff --git a/src/OpenGl/OpenGl_GraphicDriver_713.cxx b/src/OpenGl/OpenGl_GraphicDriver_713.cxx index 13c03843fd..b31fb20208 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_713.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_713.cxx @@ -20,7 +20,6 @@ #include -#include #include #include @@ -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); + } } } diff --git a/src/OpenGl/OpenGl_GraphicDriver_9.cxx b/src/OpenGl/OpenGl_GraphicDriver_9.cxx index b867ad5c0c..edc9c58175 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_9.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_9.cxx @@ -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, diff --git a/src/OpenGl/OpenGl_Group.cxx b/src/OpenGl/OpenGl_Group.cxx index a69dc98419..51a5919df9 100644 --- a/src/OpenGl/OpenGl_Group.cxx +++ b/src/OpenGl/OpenGl_Group.cxx @@ -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); +} diff --git a/src/OpenGl/OpenGl_Group.hxx b/src/OpenGl/OpenGl_Group.hxx index 76822b46ab..d2cbee1aec 100644 --- a/src/OpenGl/OpenGl_Group.hxx +++ b/src/OpenGl/OpenGl_Group.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_ResourceVBO.cxx b/src/OpenGl/OpenGl_IndexBuffer.cxx old mode 100755 new mode 100644 similarity index 54% rename from src/OpenGl/OpenGl_ResourceVBO.cxx rename to src/OpenGl/OpenGl_IndexBuffer.cxx index f252562835..a2816aa08a --- a/src/OpenGl/OpenGl_ResourceVBO.cxx +++ b/src/OpenGl/OpenGl_IndexBuffer.cxx @@ -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 @@ -17,24 +16,26 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. +#include -#include #include -#include +#include -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; } diff --git a/src/OpenGl/OpenGl_ResourceVBO.hxx b/src/OpenGl/OpenGl_IndexBuffer.hxx old mode 100755 new mode 100644 similarity index 53% rename from src/OpenGl/OpenGl_ResourceVBO.hxx rename to src/OpenGl/OpenGl_IndexBuffer.hxx index 064335ba7f..65ced7f980 --- a/src/OpenGl/OpenGl_ResourceVBO.hxx +++ b/src/OpenGl/OpenGl_IndexBuffer.hxx @@ -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 @@ -17,40 +16,25 @@ // 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 -#include -#include - -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__ diff --git a/src/OpenGl/OpenGl_Marker.cxx b/src/OpenGl/OpenGl_Marker.cxx index 741d235101..1f19e07ba4 100644 --- a/src/OpenGl/OpenGl_Marker.cxx +++ b/src/OpenGl/OpenGl_Marker.cxx @@ -29,6 +29,11 @@ /*----------------------------------------------------------------------*/ +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 ); diff --git a/src/OpenGl/OpenGl_Marker.hxx b/src/OpenGl/OpenGl_Marker.hxx index 87348fd18e..c8c0e061c9 100644 --- a/src/OpenGl/OpenGl_Marker.hxx +++ b/src/OpenGl/OpenGl_Marker.hxx @@ -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: diff --git a/src/OpenGl/OpenGl_MarkerSet.cxx b/src/OpenGl/OpenGl_MarkerSet.cxx index b09bffeedd..c2a4dd4163 100644 --- a/src/OpenGl/OpenGl_MarkerSet.cxx +++ b/src/OpenGl/OpenGl_MarkerSet.cxx @@ -140,4 +140,7 @@ void OpenGl_MarkerSet::Render (const Handle(OpenGl_Workspace) &AWorkspace) const } } -/*----------------------------------------------------------------------*/ +void OpenGl_MarkerSet::Release (const Handle(OpenGl_Context)& theContext) +{ + // +} diff --git a/src/OpenGl/OpenGl_MarkerSet.hxx b/src/OpenGl/OpenGl_MarkerSet.hxx index 5f4d19e89d..4840f0cbed 100644 --- a/src/OpenGl/OpenGl_MarkerSet.hxx +++ b/src/OpenGl/OpenGl_MarkerSet.hxx @@ -29,20 +29,27 @@ 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 diff --git a/src/OpenGl/OpenGl_Polygon.cxx b/src/OpenGl/OpenGl_Polygon.cxx index 902297fd88..d370ef8616 100644 --- a/src/OpenGl/OpenGl_Polygon.cxx +++ b/src/OpenGl/OpenGl_Polygon.cxx @@ -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) +{ + // +} diff --git a/src/OpenGl/OpenGl_Polygon.hxx b/src/OpenGl/OpenGl_Polygon.hxx index b6638a887d..6e9d19b035 100644 --- a/src/OpenGl/OpenGl_Polygon.hxx +++ b/src/OpenGl/OpenGl_Polygon.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_Polyline.cxx b/src/OpenGl/OpenGl_Polyline.cxx index ef27a8bc75..05dd82a682 100644 --- a/src/OpenGl/OpenGl_Polyline.cxx +++ b/src/OpenGl/OpenGl_Polyline.cxx @@ -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 diff --git a/src/OpenGl/OpenGl_Polyline.hxx b/src/OpenGl/OpenGl_Polyline.hxx index c3b2cccf79..ac17e10903 100644 --- a/src/OpenGl/OpenGl_Polyline.hxx +++ b/src/OpenGl/OpenGl_Polyline.hxx @@ -30,20 +30,27 @@ 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 diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index b0dd084a6d..63457f082d 100755 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -18,27 +18,18 @@ // and conditions governing the rights and limitations under the License. -#include +#include #include #include #include #include -#include -#include #include #include #include -enum -{ - VBO_NOT_INITIALIZED = -1, - VBO_ERROR = 0, - VBO_OK = 1 -}; - namespace { static unsigned long vRand = 1L; @@ -51,218 +42,97 @@ 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) diff --git a/src/OpenGl/OpenGl_PrimitiveArray.hxx b/src/OpenGl/OpenGl_PrimitiveArray.hxx index 7336404132..4d4a4fd28a 100644 --- a/src/OpenGl/OpenGl_PrimitiveArray.hxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.hxx @@ -21,7 +21,7 @@ #ifndef OpenGl_PrimitiveArray_Header #define OpenGl_PrimitiveArray_Header -#include +#include #include #include @@ -29,7 +29,6 @@ #include 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: diff --git a/src/OpenGl/OpenGl_Resource.cxx b/src/OpenGl/OpenGl_Resource.cxx index 030a123f13..5092167e94 100644 --- a/src/OpenGl/OpenGl_Resource.cxx +++ b/src/OpenGl/OpenGl_Resource.cxx @@ -19,5 +19,8 @@ #include -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() {} diff --git a/src/OpenGl/OpenGl_Resource.hxx b/src/OpenGl/OpenGl_Resource.hxx index c7cd264f94..449249b0f3 100755 --- a/src/OpenGl/OpenGl_Resource.hxx +++ b/src/OpenGl/OpenGl_Resource.hxx @@ -17,51 +17,45 @@ // 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 - -#include -#include -#include +#include +#include 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 index bcfec366f5..0000000000 --- a/src/OpenGl/OpenGl_ResourceCleaner.cxx +++ /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 -#include - -//======================================================================= -//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 index dd5a234580..0000000000 --- a/src/OpenGl/OpenGl_ResourceCleaner.hxx +++ /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 -#include -#include -#include -#include -#include - -class OpenGl_Resource; -class Handle(OpenGl_Resource); -class Handle(OpenGl_Context); - -typedef NCollection_Queue QueueOfResources; -typedef NCollection_DataMap DataMapOfContextsResources; -typedef NCollection_Map 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 diff --git a/src/OpenGl/OpenGl_ResourceTexture.cxx b/src/OpenGl/OpenGl_ResourceTexture.cxx index c48056e4ca..fd3eb8dd34 100755 --- a/src/OpenGl/OpenGl_ResourceTexture.cxx +++ b/src/OpenGl/OpenGl_ResourceTexture.cxx @@ -19,16 +19,40 @@ #include +#include #include 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; + } } diff --git a/src/OpenGl/OpenGl_ResourceTexture.hxx b/src/OpenGl/OpenGl_ResourceTexture.hxx index 57c4dfd729..c117ef9ac5 100755 --- a/src/OpenGl/OpenGl_ResourceTexture.hxx +++ b/src/OpenGl/OpenGl_ResourceTexture.hxx @@ -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: diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index 94b165786e..8730522a4b 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -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 (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 (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 : diff --git a/src/OpenGl/OpenGl_Structure.hxx b/src/OpenGl/OpenGl_Structure.hxx index a71545d9e0..11d6985823 100644 --- a/src/OpenGl/OpenGl_Structure.hxx +++ b/src/OpenGl/OpenGl_Structure.hxx @@ -37,9 +37,10 @@ typedef NCollection_List 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 diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index 0bc7cc02a5..ca4b8251bf 100644 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -214,4 +214,7 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace) &AWorkspace) const } } -/*----------------------------------------------------------------------*/ +void OpenGl_Text::Release (const Handle(OpenGl_Context)& theContext) +{ + // +} diff --git a/src/OpenGl/OpenGl_Text.hxx b/src/OpenGl/OpenGl_Text.hxx index cb93717591..3251b43899 100644 --- a/src/OpenGl/OpenGl_Text.hxx +++ b/src/OpenGl/OpenGl_Text.hxx @@ -32,25 +32,32 @@ 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 diff --git a/src/OpenGl/OpenGl_TextureBox.cxx b/src/OpenGl/OpenGl_TextureBox.cxx index d9ca2cf899..3342ff25ce 100755 --- a/src/OpenGl/OpenGl_TextureBox.cxx +++ b/src/OpenGl/OpenGl_TextureBox.cxx @@ -74,8 +74,8 @@ #include #include #include -#include #include +#include #include // 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)); - } -} diff --git a/src/OpenGl/OpenGl_TextureBox.hxx b/src/OpenGl/OpenGl_TextureBox.hxx index bbe34d19c4..05d4f254a3 100755 --- a/src/OpenGl/OpenGl_TextureBox.hxx +++ b/src/OpenGl/OpenGl_TextureBox.hxx @@ -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 index 0000000000..405b6fdc9a --- /dev/null +++ b/src/OpenGl/OpenGl_TextureBufferArb.cxx @@ -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 + +#include +#include + +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 index 0000000000..8c0ed1a204 --- /dev/null +++ b/src/OpenGl/OpenGl_TextureBufferArb.hxx @@ -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 +#include + +//! 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 index 0000000000..436e67d35c --- /dev/null +++ b/src/OpenGl/OpenGl_VertexBuffer.cxx @@ -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 + +#include +#include + +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 (myComponentsNb), myDataType, 0, NULL); + break; + } + case GL_NORMAL_ARRAY: + { + glNormalPointer (myDataType, 0, NULL); + break; + } + case GL_TEXTURE_COORD_ARRAY: + { + glTexCoordPointer (static_cast (myComponentsNb), myDataType, 0, NULL); + break; + } + case GL_COLOR_ARRAY: + { + glColorPointer (static_cast (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 index 0000000000..d6916159b7 --- /dev/null +++ b/src/OpenGl/OpenGl_VertexBuffer.hxx @@ -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 +#include + +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 index 0000000000..b150cb8b93 --- /dev/null +++ b/src/OpenGl/OpenGl_VertexBufferEditor.hxx @@ -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 +#include + +#include + +//! 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 +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 myTmpBuffer; //!< temporary array + +}; + +#endif // _OpenGl_VertexBufferEditor_H__ diff --git a/src/OpenGl/OpenGl_Window.cxx b/src/OpenGl/OpenGl_Window.cxx index a2507668e1..0f4be46287 100644 --- a/src/OpenGl/OpenGl_Window.cxx +++ b/src/OpenGl/OpenGl_Window.cxx @@ -24,8 +24,6 @@ #include #include -#include -#include #include #include @@ -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::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; +} diff --git a/src/OpenGl/OpenGl_Window.hxx b/src/OpenGl/OpenGl_Window.hxx index 12babfc1ad..783ae5cb41 100644 --- a/src/OpenGl/OpenGl_Window.hxx +++ b/src/OpenGl/OpenGl_Window.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index a52fd0f5fb..8a773bb8ff 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -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), diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index d689a1f32c..b927c46b0d 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -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(); diff --git a/src/OpenGl/OpenGl_Workspace_2.cxx b/src/OpenGl/OpenGl_Workspace_2.cxx index c7297e4ef6..edd0231b63 100644 --- a/src/OpenGl/OpenGl_Workspace_2.cxx +++ b/src/OpenGl/OpenGl_Workspace_2.cxx @@ -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); } /*----------------------------------------------------------------------*/ diff --git a/src/OpenGl/OpenGl_Workspace_4.cxx b/src/OpenGl/OpenGl_Workspace_4.cxx index 3b4f0c6ad6..0eecbccd9f 100644 --- a/src/OpenGl/OpenGl_Workspace_4.cxx +++ b/src/OpenGl/OpenGl_Workspace_4.cxx @@ -25,7 +25,6 @@ #endif #include -#include #include #include @@ -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; diff --git a/src/QABugs/QABugs_17.cxx b/src/QABugs/QABugs_17.cxx index e1648e0dfa..79b5318433 100644 --- a/src/QABugs/QABugs_17.cxx +++ b/src/QABugs/QABugs_17.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -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; diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index 04df995a20..fab3967484 100755 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -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 (MyWindow); + aWin.Nullify(); } /*----------------------------------------------------------------------*/ diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 34d5cee963..330d9b806d 100755 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -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", diff --git a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx index 2d36855400..58332c6715 100644 --- a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx +++ b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx @@ -23,6 +23,8 @@ #include +#include +#include #include #include #include @@ -32,20 +34,18 @@ #include #include #include -#include #include #include #include #include -#include -#include -#include +#include #include #include #include #include #include #include +#include #include #include @@ -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); diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 530979b9d0..754411d248 100755 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -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() ) { diff --git a/src/Visual3d/Visual3d_ViewManager.cxx b/src/Visual3d/Visual3d_ViewManager.cxx index 5b0ba0967e..90ccd311e3 100755 --- a/src/Visual3d/Visual3d_ViewManager.cxx +++ b/src/Visual3d/Visual3d_ViewManager.cxx @@ -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) { diff --git a/src/VoxelClient/VoxelClient_VisDrawer.cxx b/src/VoxelClient/VoxelClient_VisDrawer.cxx index e75fbc7228..88497ec46d 100755 --- a/src/VoxelClient/VoxelClient_VisDrawer.cxx +++ b/src/VoxelClient/VoxelClient_VisDrawer.cxx @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include @@ -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; } } diff --git a/src/VoxelClient/VoxelClient_VisDrawer.h b/src/VoxelClient/VoxelClient_VisDrawer.h index cb89ac2bfd..a36cca95ea 100755 --- a/src/VoxelClient/VoxelClient_VisDrawer.h +++ b/src/VoxelClient/VoxelClient_VisDrawer.h @@ -24,6 +24,8 @@ #include "Voxel_VisData.h" #include +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(); -- 2.20.1