From: asl Date: Thu, 23 Aug 2018 05:42:40 +0000 (+0300) Subject: 0030076: Visualization, TKV3d - API to update certain vertex attribute(s) without... X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=cfdc5f633c7abce20e78ea6c3b66fff3f949abf8;p=occt-copy.git 0030076: Visualization, TKV3d - API to update certain vertex attribute(s) without recomputing a presentation Graphic3d_Buffer and classes for arrays of primitives support now the non-interleaved mode for the attributes storage --- diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index 2c15a0d70f..51e4b71c75 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -19,6 +19,8 @@ Graphic3d_AspectMarker3d.hxx Graphic3d_AspectText3d.cxx Graphic3d_AspectText3d.hxx Graphic3d_AspectTextDefinitionError.hxx +Graphic3d_AttribBuffer.cxx +Graphic3d_AttribBuffer.hxx Graphic3d_BndBox3d.hxx Graphic3d_BndBox4d.hxx Graphic3d_BndBox4f.hxx diff --git a/src/Graphic3d/Graphic3d_ArrayOfPoints.hxx b/src/Graphic3d/Graphic3d_ArrayOfPoints.hxx index 99c5ae0b88..89f8e8d8ce 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfPoints.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPoints.hxx @@ -29,8 +29,10 @@ public: //! @param theHasVNormals when TRUE, AddVertex(Point,Normal) should be used for specifying vertex normal Graphic3d_ArrayOfPoints (const Standard_Integer theMaxVertexs, const Standard_Boolean theHasVColors = Standard_False, - const Standard_Boolean theHasVNormals = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POINTS, theMaxVertexs, 0, 0, theHasVNormals, theHasVColors, Standard_False, Standard_False) {} + const Standard_Boolean theHasVNormals = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POINTS, theMaxVertexs, 0, 0, theHasVNormals, theHasVColors, Standard_False, Standard_False, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_ArrayOfPolygons.hxx b/src/Graphic3d/Graphic3d_ArrayOfPolygons.hxx index 7459670e84..d7f93ad45d 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfPolygons.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPolygons.hxx @@ -95,8 +95,10 @@ public: const Standard_Boolean theHasVNormals = Standard_False, const Standard_Boolean theHasVColors = Standard_False, const Standard_Boolean theHasBColors = Standard_False, - const Standard_Boolean theHasVTexels = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POLYGONS, theMaxVertexs, theMaxBounds, theMaxEdges, theHasVNormals, theHasVColors, theHasBColors, theHasVTexels) {} + const Standard_Boolean theHasVTexels = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POLYGONS, theMaxVertexs, theMaxBounds, theMaxEdges, theHasVNormals, theHasVColors, theHasBColors, theHasVTexels, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_ArrayOfPolylines.hxx b/src/Graphic3d/Graphic3d_ArrayOfPolylines.hxx index e7aed22903..28fc7a8717 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfPolylines.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPolylines.hxx @@ -93,8 +93,10 @@ public: const Standard_Integer theMaxBounds = 0, const Standard_Integer theMaxEdges = 0, const Standard_Boolean theHasVColors = Standard_False, - const Standard_Boolean theHasBColors = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POLYLINES, theMaxVertexs, theMaxBounds, theMaxEdges, Standard_False, theHasVColors, theHasBColors, Standard_False) {} + const Standard_Boolean theHasBColors = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POLYLINES, theMaxVertexs, theMaxBounds, theMaxEdges, Standard_False, theHasVColors, theHasBColors, Standard_False, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx index 2e9ccce9e2..3a676d252f 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx @@ -53,7 +53,9 @@ Graphic3d_ArrayOfPrimitives::Graphic3d_ArrayOfPrimitives (const Graphic3d_TypeOf const Standard_Boolean theHasVNormals, const Standard_Boolean theHasVColors, const Standard_Boolean theHasFColors, - const Standard_Boolean theHasVTexels) + const Standard_Boolean theHasVTexels, + const Standard_Boolean theIsInterleaved, + const Standard_Boolean theIsMutable) : myType (theType), myMaxBounds (0), myMaxVertexs (0), @@ -63,7 +65,7 @@ Graphic3d_ArrayOfPrimitives::Graphic3d_ArrayOfPrimitives (const Graphic3d_TypeOf myVCol (0) { Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); - myAttribs = new Graphic3d_Buffer (anAlloc); + myAttribs = new Graphic3d_AttribBuffer(anAlloc, theIsInterleaved, theIsMutable); if (theMaxVertexs < 1) { return; @@ -146,17 +148,23 @@ Graphic3d_ArrayOfPrimitives::Graphic3d_ArrayOfPrimitives (const Graphic3d_TypeOf break; case Graphic3d_TOA_NORM: { - myVNor = static_cast(myAttribs->AttributeOffset (anAttribIter)); + if(theIsInterleaved) + myVNor = static_cast(myAttribs->AttributeOffset (anAttribIter)); + myINor = anAttribIter; break; } case Graphic3d_TOA_UV: { - myVTex = static_cast(myAttribs->AttributeOffset (anAttribIter)); + if (theIsInterleaved) + myVTex = static_cast(myAttribs->AttributeOffset (anAttribIter)); + myITex = anAttribIter; break; } case Graphic3d_TOA_COLOR: { - myVCol = static_cast(myAttribs->AttributeOffset (anAttribIter)); + if (theIsInterleaved) + myVCol = static_cast(myAttribs->AttributeOffset (anAttribIter)); + myICol = anAttribIter; break; } } diff --git a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.hxx b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.hxx index 490574872a..7115359f1f 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfPrimitives.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPrimitives.hxx @@ -16,7 +16,7 @@ #define _Graphic3d_ArrayOfPrimitives_HeaderFile #include -#include +#include #include #include #include @@ -68,7 +68,7 @@ public: Standard_EXPORT virtual ~Graphic3d_ArrayOfPrimitives(); //! Returns vertex attributes buffer (colors, normals, texture coordinates). - const Handle(Graphic3d_Buffer)& Attributes() const { return myAttribs; } + const Handle(Graphic3d_AttribBuffer)& Attributes() const { return myAttribs; } //! Returns the type of this primitive Graphic3d_TypeOfPrimitiveArray Type() const { return myType; } @@ -77,13 +77,13 @@ public: Standard_EXPORT Standard_CString StringType() const; //! Returns TRUE when vertex normals array is defined. - Standard_Boolean HasVertexNormals() const { return myVNor != 0; } + Standard_Boolean HasVertexNormals() const { return myINor != 0; } //! Returns TRUE when vertex colors array is defined. - Standard_Boolean HasVertexColors() const { return myVCol != 0; } + Standard_Boolean HasVertexColors() const { return myICol != 0; } //! Returns TRUE when vertex texels array is defined. - Standard_Boolean HasVertexTexels() const { return myVTex != 0; } + Standard_Boolean HasVertexTexels() const { return myITex != 0; } //! Returns the number of defined vertex Standard_Integer VertexNumber() const { return !myAttribs.IsNull() ? myAttribs->NbElements : -1; } @@ -345,10 +345,10 @@ public: throw Standard_OutOfRange ("BAD VERTEX index"); } - if (myVCol != 0) + if (myICol != 0) { Graphic3d_Vec4ub *aColorPtr = - reinterpret_cast(myAttribs->changeValue (theIndex - 1) + size_t(myVCol)); + reinterpret_cast(myAttribs->changeValue (theIndex - 1, myICol) + size_t(myVCol)); aColorPtr->SetValues (Standard_Byte(theR * 255.0), Standard_Byte(theG * 255.0), Standard_Byte(theB * 255.0), 255); @@ -370,10 +370,10 @@ public: throw Standard_OutOfRange ("BAD VERTEX index"); } - if (myVCol != 0) + if (myICol != 0) { Graphic3d_Vec4ub *aColorPtr = - reinterpret_cast(myAttribs->changeValue (theIndex - 1) + size_t(myVCol)); + reinterpret_cast(myAttribs->changeValue (theIndex - 1, myICol) + size_t(myVCol)); (*aColorPtr) = theColor; } myAttribs->NbElements = Max (theIndex, myAttribs->NbElements); @@ -395,9 +395,9 @@ public: throw Standard_OutOfRange ("BAD VERTEX index"); } - if (myVCol != 0) + if (myICol != 0) { - *reinterpret_cast(myAttribs->changeValue (theIndex - 1) + size_t(myVCol)) = theColor32; + *reinterpret_cast(myAttribs->changeValue (theIndex - 1, myICol) + size_t(myVCol)) = theColor32; } } @@ -420,9 +420,9 @@ public: throw Standard_OutOfRange("BAD VERTEX index"); } - if (myVNor != 0) + if (myINor != 0) { - Graphic3d_Vec3& aVec = *reinterpret_cast(myAttribs->changeValue (theIndex - 1) + size_t(myVNor)); + Graphic3d_Vec3& aVec = *reinterpret_cast(myAttribs->changeValue (theIndex - 1, myINor) + size_t(myVNor)); aVec.x() = Standard_ShortReal (theNX); aVec.y() = Standard_ShortReal (theNY); aVec.z() = Standard_ShortReal (theNZ); @@ -449,9 +449,9 @@ public: throw Standard_OutOfRange("BAD VERTEX index"); } - if (myVTex != 0) + if (myITex != 0) { - Graphic3d_Vec2& aVec = *reinterpret_cast(myAttribs->changeValue (theIndex - 1) + size_t(myVTex)); + Graphic3d_Vec2& aVec = *reinterpret_cast(myAttribs->changeValue (theIndex - 1, myITex) + size_t(myVTex)); aVec.x() = Standard_ShortReal (theTX); aVec.y() = Standard_ShortReal (theTY); } @@ -480,7 +480,7 @@ public: throw Standard_OutOfRange ("BAD VERTEX index"); } - const Graphic3d_Vec3& aVec = myAttribs->Value (theRank - 1); + const Graphic3d_Vec3& aVec = myAttribs->Value (theRank - 1, 0); theX = Standard_Real(aVec.x()); theY = Standard_Real(aVec.y()); theZ = Standard_Real(aVec.z()); @@ -499,7 +499,7 @@ public: Graphic3d_Vec4ub& theColor) const { if (myAttribs.IsNull() - || myVCol == 0) + || myICol == 0) { throw Standard_OutOfRange ("Primitive array does not define color attribute"); } @@ -518,7 +518,7 @@ public: { theR = theG = theB = 0.0; if (myAttribs.IsNull() - || myVCol == 0) + || myICol == 0) { return; } @@ -537,7 +537,7 @@ public: //! Returns the vertex color values at rank theRank from the vertex table if defined. void VertexColor (const Standard_Integer theRank, Standard_Integer& theColor) const { - if (myVCol != 0) + if (myICol != 0) { theColor = *reinterpret_cast(myAttribs->value (theRank - 1) + size_t(myVCol)); } @@ -565,7 +565,7 @@ public: throw Standard_OutOfRange ("BAD VERTEX index"); } - if (myVNor != 0) + if (myINor != 0) { const Graphic3d_Vec3& aVec = *reinterpret_cast(myAttribs->value (theRank - 1) + size_t(myVNor)); theNX = Standard_Real(aVec.x()); @@ -596,7 +596,7 @@ public: throw Standard_OutOfRange ("BAD VERTEX index"); } - if (myVTex != 0) + if (myITex != 0) { const Graphic3d_Vec2& aVec = *reinterpret_cast(myAttribs->value (theRank - 1) + size_t(myVTex)); theTX = Standard_Real(aVec.x()); @@ -773,21 +773,26 @@ protected: //! @name protected constructors const Standard_Boolean theHasVNormals, const Standard_Boolean theHasVColors, const Standard_Boolean theHasBColors, - const Standard_Boolean theHasVTexels); + const Standard_Boolean theHasVTexels, + const Standard_Boolean theIsInterleaved, + const Standard_Boolean theIsMutable); private: //! @name private fields Handle(Graphic3d_IndexBuffer) myIndices; - Handle(Graphic3d_Buffer) myAttribs; + Handle(Graphic3d_AttribBuffer) myAttribs; Handle(Graphic3d_BoundBuffer) myBounds; Graphic3d_TypeOfPrimitiveArray myType; Standard_Integer myMaxBounds; Standard_Integer myMaxVertexs; Standard_Integer myMaxEdges; + Standard_Byte myVNor; Standard_Byte myVTex; Standard_Byte myVCol; - + Standard_Integer myINor; + Standard_Integer myITex; + Standard_Integer myICol; }; #endif // _Graphic3d_ArrayOfPrimitives_HeaderFile diff --git a/src/Graphic3d/Graphic3d_ArrayOfQuadrangleStrips.hxx b/src/Graphic3d/Graphic3d_ArrayOfQuadrangleStrips.hxx index 8f6fbac071..b0b4b58a33 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfQuadrangleStrips.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfQuadrangleStrips.hxx @@ -53,8 +53,10 @@ public: const Standard_Boolean theHasVNormals = Standard_False, const Standard_Boolean theHasVColors = Standard_False, const Standard_Boolean theHasSColors = Standard_False, - const Standard_Boolean theHasVTexels = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_QUADRANGLESTRIPS, theMaxVertexs, theMaxStrips, 0, theHasVNormals, theHasVColors, theHasSColors, theHasVTexels) {} + const Standard_Boolean theHasVTexels = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_QUADRANGLESTRIPS, theMaxVertexs, theMaxStrips, 0, theHasVNormals, theHasVColors, theHasSColors, theHasVTexels, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_ArrayOfQuadrangles.hxx b/src/Graphic3d/Graphic3d_ArrayOfQuadrangles.hxx index eb6671b454..131ade83d4 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfQuadrangles.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfQuadrangles.hxx @@ -54,8 +54,10 @@ public: const Standard_Integer theMaxEdges = 0, const Standard_Boolean theHasVNormals = Standard_False, const Standard_Boolean theHasVColors = Standard_False, - const Standard_Boolean theHasVTexels = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_QUADRANGLES, theMaxVertexs, 0, theMaxEdges, theHasVNormals, theHasVColors, Standard_False, theHasVTexels) {} + const Standard_Boolean theHasVTexels = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_QUADRANGLES, theMaxVertexs, 0, theMaxEdges, theHasVNormals, theHasVColors, Standard_False, theHasVTexels, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_ArrayOfSegments.hxx b/src/Graphic3d/Graphic3d_ArrayOfSegments.hxx index 07750ff7fb..3507611740 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfSegments.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfSegments.hxx @@ -51,8 +51,10 @@ public: //! @param theHasVColors when TRUE, AddVertex(Point,Color) should be used for specifying vertex color Graphic3d_ArrayOfSegments (const Standard_Integer theMaxVertexs, const Standard_Integer theMaxEdges = 0, - const Standard_Boolean theHasVColors = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_SEGMENTS, theMaxVertexs, 0, theMaxEdges, Standard_False, theHasVColors, Standard_False, Standard_False) {} + const Standard_Boolean theHasVColors = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_SEGMENTS, theMaxVertexs, 0, theMaxEdges, Standard_False, theHasVColors, Standard_False, Standard_False, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_ArrayOfTriangleFans.hxx b/src/Graphic3d/Graphic3d_ArrayOfTriangleFans.hxx index 366d781133..f27c88b4d0 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfTriangleFans.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfTriangleFans.hxx @@ -51,8 +51,10 @@ public: const Standard_Boolean theHasVNormals = Standard_False, const Standard_Boolean theHasVColors = Standard_False, const Standard_Boolean theHasBColors = Standard_False, - const Standard_Boolean theHasVTexels = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLEFANS, theMaxVertexs, theMaxFans, 0, theHasVNormals, theHasVColors, theHasBColors, theHasVTexels) {} + const Standard_Boolean theHasVTexels = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLEFANS, theMaxVertexs, theMaxFans, 0, theHasVNormals, theHasVColors, theHasBColors, theHasVTexels, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_ArrayOfTriangleStrips.hxx b/src/Graphic3d/Graphic3d_ArrayOfTriangleStrips.hxx index e1a05e470a..a738ad44bf 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfTriangleStrips.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfTriangleStrips.hxx @@ -56,8 +56,10 @@ public: const Standard_Boolean theHasVNormals = Standard_False, const Standard_Boolean theHasVColors = Standard_False, const Standard_Boolean theHasBColors = Standard_False, - const Standard_Boolean theHasVTexels = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLESTRIPS, theMaxVertexs, theMaxStrips, 0, theHasVNormals, theHasVColors, theHasBColors, theHasVTexels) {} + const Standard_Boolean theHasVTexels = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLESTRIPS, theMaxVertexs, theMaxStrips, 0, theHasVNormals, theHasVColors, theHasBColors, theHasVTexels, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_ArrayOfTriangles.hxx b/src/Graphic3d/Graphic3d_ArrayOfTriangles.hxx index e4035a7450..c33a5382bf 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfTriangles.hxx +++ b/src/Graphic3d/Graphic3d_ArrayOfTriangles.hxx @@ -54,8 +54,10 @@ public: const Standard_Integer theMaxEdges = 0, const Standard_Boolean theHasVNormals = Standard_False, const Standard_Boolean theHasVColors = Standard_False, - const Standard_Boolean theHasVTexels = Standard_False) - : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLES, theMaxVertexs, 0, theMaxEdges, theHasVNormals, theHasVColors, Standard_False, theHasVTexels) {} + const Standard_Boolean theHasVTexels = Standard_False, + const Standard_Boolean theIsInterleaved = Standard_True, + const Standard_Boolean theIsMutable = Standard_False) + : Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLES, theMaxVertexs, 0, theMaxEdges, theHasVNormals, theHasVColors, Standard_False, theHasVTexels, theIsInterleaved, theIsMutable) {} }; diff --git a/src/Graphic3d/Graphic3d_AttribBuffer.cxx b/src/Graphic3d/Graphic3d_AttribBuffer.cxx new file mode 100644 index 0000000000..9df60114a4 --- /dev/null +++ b/src/Graphic3d/Graphic3d_AttribBuffer.cxx @@ -0,0 +1,75 @@ +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +Graphic3d_AttribBuffer::Graphic3d_AttribBuffer(const Handle(NCollection_BaseAllocator)& theAlloc, + Standard_Boolean isInterleaved, Standard_Boolean isMutable) + : Graphic3d_Buffer(theAlloc, isInterleaved, isMutable) +{ +} + +Standard_Boolean Graphic3d_AttribBuffer::Invalidate(int theAttributeIndex) +{ + if (!IsMutable() || IsInterleaved()) + return false; + + Graphic3d_Range aRange; + aRange.Start = AttributeOffset(theAttributeIndex); + aRange.Length = AttributeOffset(theAttributeIndex + 1) - aRange.Start; + Graphic3d_Buffer::Invalidate(aRange); + + return true; +} + +Standard_Boolean Graphic3d_AttribBuffer::Invalidate(int theAttributeIndex, int theStartVertexIndex, int theEndVertexIndex) +{ + if (!IsMutable() || IsInterleaved()) + return false; + + Graphic3d_Range aRange; + Standard_Integer anAttrOffset = AttributeOffset(theAttributeIndex); + Standard_Integer aStride = AttributesArray()[theAttributeIndex].Stride(); + aRange.Start = anAttrOffset + aStride * theStartVertexIndex; + aRange.Length = aStride * ( theEndVertexIndex - theStartVertexIndex + 1 ); + Graphic3d_Buffer::Invalidate(aRange); + + return true; +} + +Standard_Boolean Graphic3d_AttribBuffer::Invalidate(int theStartVertexIndex, int theEndVertexIndex) +{ + if (!IsMutable()) + return false; + + if (IsInterleaved()) + { + Graphic3d_Range aRange; + aRange.Start = Stride * theStartVertexIndex; + aRange.Length = Stride * (theEndVertexIndex - theStartVertexIndex + 1); + Graphic3d_Buffer::Invalidate(aRange); + return true; + } + else + { + Standard_Boolean isOK = true; + for (Standard_Integer i = 0, n = NbAttributes; i < n; i++) + { + bool isLocalOK = Invalidate(i, theStartVertexIndex, theEndVertexIndex); + isOK = isOK && isLocalOK; + } + return isOK; + } +} + + diff --git a/src/Graphic3d/Graphic3d_AttribBuffer.hxx b/src/Graphic3d/Graphic3d_AttribBuffer.hxx new file mode 100644 index 0000000000..d5a81e2950 --- /dev/null +++ b/src/Graphic3d/Graphic3d_AttribBuffer.hxx @@ -0,0 +1,40 @@ +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Graphic3d_AttribBuffer_HeaderFile +#define _Graphic3d_AttribBuffer_HeaderFile + +#include + +//! Buffer of vertex attributes. +class Graphic3d_AttribBuffer : public Graphic3d_Buffer +{ +public: + //! Empty constructor. + Standard_EXPORT Graphic3d_AttribBuffer(const Handle(NCollection_BaseAllocator)& theAlloc, + Standard_Boolean isInterleaved, Standard_Boolean isMutable); + + Standard_EXPORT Standard_Boolean Invalidate(Standard_Integer theAttributeIndex); + Standard_EXPORT Standard_Boolean Invalidate(Standard_Integer theAttributeIndex, + Standard_Integer theStartVertexIndex, + Standard_Integer theEndVertexIndex); + Standard_EXPORT Standard_Boolean Invalidate(Standard_Integer theStartVertexIndex, + Standard_Integer theEndVertexIndex); + +public: + DEFINE_STANDARD_RTTI_INLINE(Graphic3d_AttribBuffer, Graphic3d_Buffer) // Type definition +}; + +DEFINE_STANDARD_HANDLE(Graphic3d_AttribBuffer, Graphic3d_Buffer) + +#endif // _Graphic3d_AttribBuffer_HeaderFile diff --git a/src/Graphic3d/Graphic3d_Buffer.hxx b/src/Graphic3d/Graphic3d_Buffer.hxx index 6aaa671a37..3d68b6a832 100644 --- a/src/Graphic3d/Graphic3d_Buffer.hxx +++ b/src/Graphic3d/Graphic3d_Buffer.hxx @@ -17,6 +17,7 @@ #include #include #include +#include //! Type of attribute in Vertex Buffer enum Graphic3d_TypeOfAttribute @@ -68,17 +69,26 @@ struct Graphic3d_Attribute typedef NCollection_Array1 Graphic3d_Array1OfAttribute; +struct Graphic3d_Range +{ + Standard_Integer Start; + Standard_Integer Length; +}; + //! Buffer of vertex attributes. class Graphic3d_Buffer : public NCollection_Buffer { public: //! Empty constructor. - Graphic3d_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc) + Graphic3d_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc, + Standard_Boolean isInterleaved, Standard_Boolean isMutable) : NCollection_Buffer (theAlloc), Stride (0), NbElements (0), - NbAttributes (0) + NbAttributes (0), + bIsInterleaved(isInterleaved), + bIsMutable(isMutable) { // } @@ -109,6 +119,8 @@ public: { anOffset += Graphic3d_Attribute::Stride (Attribute (anAttribIter).DataType); } + if (!bIsInterleaved) + anOffset *= NbElements; return anOffset; } @@ -128,22 +140,34 @@ public: } //! Access specified element. - inline const Standard_Byte* value (const Standard_Integer theElem) const + inline const Standard_Byte* value (const Standard_Integer theElem, const Standard_Integer theAttribIndex = 0) const { - return myData + Stride * size_t(theElem); + if (bIsInterleaved) + return myData + Stride * size_t(theElem); + else + { + int aStrideI = AttributesArray()[theAttribIndex].Stride(); //TODO: correct attribute index + return myData + aStrideI * theElem; + } } //! Access specified element. - inline Standard_Byte* changeValue (const Standard_Integer theElem) + inline Standard_Byte* changeValue (const Standard_Integer theElem, const Standard_Integer theAttribIndex = 0) { - return myData + Stride * size_t(theElem); + if (bIsInterleaved) + return myData + Stride * size_t(theElem); + else + { + int aStrideI = AttributesArray()[theAttribIndex].Stride(); //TODO: correct attribute index + return myData + aStrideI * theElem; + } } //! Access element with specified position and type. template - inline const Type_t& Value (const Standard_Integer theElem) const + inline const Type_t& Value (const Standard_Integer theElem, const Standard_Integer theAttribIndex = 0) const { - return *reinterpret_cast(value (theElem)); + return *reinterpret_cast(value (theElem, theAttribIndex)); } //! Access element with specified position and type. @@ -163,7 +187,7 @@ public: } //! Allocates new empty array - bool Init (const Standard_Integer theNbElems, + Standard_Boolean Init (const Standard_Integer theNbElems, const Graphic3d_Attribute* theAttribs, const Standard_Integer theNbAttribs) { @@ -197,22 +221,52 @@ public: ChangeAttribute (anAttribIter) = theAttribs[anAttribIter]; } } + + if (!bIsInterleaved) + { + Stride = 0; + } + return true; } //! Allocates new empty array - bool Init (const Standard_Integer theNbElems, + Standard_Boolean Init (const Standard_Integer theNbElems, const Graphic3d_Array1OfAttribute& theAttribs) { return Init (theNbElems, &theAttribs.First(), theAttribs.Size()); } + inline Standard_Boolean IsInterleaved() const { return bIsInterleaved; } + inline Standard_Boolean IsMutable() const { return bIsMutable; } + + std::vector InvalidatedRanges() const + { + return Ranges; + } + + void Validate() + { + Ranges.clear(); + } + +protected: + void Invalidate(const Graphic3d_Range& theRange) + { + Ranges.push_back(theRange); + } + public: Standard_Integer Stride; //!< the distance to the attributes of the next vertex Standard_Integer NbElements; //!< number of the elements Standard_Integer NbAttributes; //!< number of vertex attributes +private: + Standard_Boolean bIsInterleaved; + Standard_Boolean bIsMutable; + std::vector Ranges; + public: DEFINE_STANDARD_RTTI_INLINE(Graphic3d_Buffer,NCollection_Buffer) // Type definition diff --git a/src/Graphic3d/Graphic3d_IndexBuffer.hxx b/src/Graphic3d/Graphic3d_IndexBuffer.hxx index 6b6bc9ebbc..10d953df3c 100644 --- a/src/Graphic3d/Graphic3d_IndexBuffer.hxx +++ b/src/Graphic3d/Graphic3d_IndexBuffer.hxx @@ -23,7 +23,7 @@ public: //! Empty constructor. Graphic3d_IndexBuffer (const Handle(NCollection_BaseAllocator)& theAlloc) - : Graphic3d_Buffer (theAlloc) {} + : Graphic3d_Buffer (theAlloc, true, false) {} //! Allocates new empty index array template @@ -76,6 +76,14 @@ public: } } + //! Invalidate the given indices + Standard_Boolean Invalidate(Standard_Integer theStartIndex, Standard_Integer theEndIndex) + { + Graphic3d_Range aRange; + aRange.Start = Stride * theStartIndex; + aRange.Length = Stride * (theEndIndex - theStartIndex + 1); + } + public: DEFINE_STANDARD_RTTI_INLINE(Graphic3d_IndexBuffer,Graphic3d_Buffer) // Type definition diff --git a/src/OpenGl/OpenGl_BackgroundArray.cxx b/src/OpenGl/OpenGl_BackgroundArray.cxx index f760dcfc98..e133714c6f 100644 --- a/src/OpenGl/OpenGl_BackgroundArray.cxx +++ b/src/OpenGl/OpenGl_BackgroundArray.cxx @@ -35,7 +35,7 @@ OpenGl_BackgroundArray::OpenGl_BackgroundArray (const Graphic3d_TypeOfBackground myToUpdate (Standard_False) { Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); - myAttribs = new Graphic3d_Buffer (anAlloc); + myAttribs = new Graphic3d_Buffer (anAlloc, true, false); myDrawMode = GL_TRIANGLE_STRIP; diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.cxx b/src/OpenGl/OpenGl_CappingPlaneResource.cxx index d551231791..7e4f030f3a 100755 --- a/src/OpenGl/OpenGl_CappingPlaneResource.cxx +++ b/src/OpenGl/OpenGl_CappingPlaneResource.cxx @@ -72,7 +72,7 @@ OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d { // Fill primitive array Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); - Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (anAlloc); + Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (anAlloc, true, false); Graphic3d_Attribute anAttribInfo[] = { { Graphic3d_TOA_POS, Graphic3d_TOD_VEC4 }, diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index 71c96fe539..5a8123211d 100644 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -74,14 +74,16 @@ public: //! Create uninitialized VBO. OpenGl_VertexBufferT (const Graphic3d_Attribute* theAttribs, const Standard_Integer theStride) - : Stride (theStride) + : Stride (theStride), + NbElements(1) { memcpy (Attribs, theAttribs, sizeof(Graphic3d_Attribute) * NbAttributes); } //! Create uninitialized VBO. OpenGl_VertexBufferT (const Graphic3d_Buffer& theAttribs) - : Stride (theAttribs.Stride) + : Stride (theAttribs.IsInterleaved() ? theAttribs.Stride : 0), + NbElements(theAttribs.IsInterleaved() ? 1 : theAttribs.NbElements) { memcpy (Attribs, theAttribs.AttributesArray(), sizeof(Graphic3d_Attribute) * NbAttributes); } @@ -160,7 +162,7 @@ public: } TheBaseClass::bindAttribute (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset); - anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType); + anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType) * NbElements; } } @@ -183,7 +185,7 @@ public: Graphic3d_Attribute Attribs[NbAttributes]; Standard_Integer Stride; - + Standard_Integer NbElements; }; // ======================================================================= @@ -225,7 +227,8 @@ Standard_Boolean OpenGl_PrimitiveArray::initNormalVbo (const Handle(OpenGl_Conte } // specify data type as Byte and NbComponents as Stride, so that OpenGl_VertexBuffer::EstimatedDataSize() will return correct value - if (!myVboAttribs->init (theCtx, myAttribs->Stride, myAttribs->NbElements, myAttribs->Data(), GL_UNSIGNED_BYTE, myAttribs->Stride)) + int aStride = myAttribs->IsInterleaved() ? myAttribs->Stride : myAttribs->AttributeOffset(myAttribs->NbAttributes) / myAttribs->NbElements; + if (!myVboAttribs->init (theCtx, aStride, myAttribs->NbElements, myAttribs->Data(), GL_UNSIGNED_BYTE, aStride)) { TCollection_ExtendedString aMsg; aMsg += "VBO creation for Primitive Array has failed for "; @@ -297,7 +300,8 @@ Standard_Boolean OpenGl_PrimitiveArray::buildVBO (const Handle(OpenGl_Context)& && initNormalVbo (theCtx)) { if (!theCtx->caps->keepArrayData - && !theToKeepData) + && !theToKeepData + && !myAttribs->IsMutable()) { myIndices.Nullify(); myAttribs.Nullify(); @@ -344,7 +348,8 @@ Standard_Boolean OpenGl_PrimitiveArray::buildVBO (const Handle(OpenGl_Context)& } myVboAttribs = aVboAttribs; if (!theCtx->caps->keepArrayData - && !theToKeepData) + && !theToKeepData + && !myAttribs->IsMutable()) { // does not make sense for compatibility mode //myIndices.Nullify(); @@ -354,6 +359,19 @@ Standard_Boolean OpenGl_PrimitiveArray::buildVBO (const Handle(OpenGl_Context)& return Standard_True; } +Standard_Boolean OpenGl_PrimitiveArray::updateVBO(const Handle(OpenGl_Context)& theCtx) const +{ + const std::vector& ranges = myAttribs->InvalidatedRanges(); + for (size_t i = 0, n = ranges.size(); i < n; i++) + { + Graphic3d_Range aRange = ranges[i]; + theCtx->core15fwd->glBufferSubData(myVboAttribs->GetTarget(), + aRange.Start, aRange.Length, myAttribs->Data() + aRange.Start); + } + myAttribs->Validate(); + return Standard_True; +} + // ======================================================================= // function : drawArray // purpose : @@ -738,6 +756,9 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace myIsVboInit = Standard_True; } + if (!myAttribs.IsNull() && myAttribs->IsMutable() && myAttribs->InvalidatedRanges().size() > 0) + updateVBO(aCtx); + // Temporarily disable environment mapping Handle(OpenGl_TextureSet) aTextureBack; bool toDrawArray = true; @@ -983,7 +1004,7 @@ Standard_Boolean OpenGl_PrimitiveArray::processIndices (const Handle(OpenGl_Cont if (myAttribs->NbElements > std::numeric_limits::max()) { - Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (new NCollection_AlignedAllocator (16)); + Handle(Graphic3d_Buffer) anAttribs = new Graphic3d_Buffer (new NCollection_AlignedAllocator (16), true, false); if (!anAttribs->Init (myIndices->NbElements, myAttribs->AttributesArray(), myAttribs->NbAttributes)) { return Standard_False; // failed to initialize attribute array diff --git a/src/OpenGl/OpenGl_PrimitiveArray.hxx b/src/OpenGl/OpenGl_PrimitiveArray.hxx index 258497db75..a7185b06fb 100644 --- a/src/OpenGl/OpenGl_PrimitiveArray.hxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.hxx @@ -107,6 +107,8 @@ protected: Standard_EXPORT Standard_Boolean buildVBO (const Handle(OpenGl_Context)& theCtx, const Standard_Boolean theToKeepData) const; + Standard_EXPORT Standard_Boolean updateVBO(const Handle(OpenGl_Context)& theCtx) const; + Standard_EXPORT void clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const; private: diff --git a/src/Select3D/Select3D_BVHIndexBuffer.hxx b/src/Select3D/Select3D_BVHIndexBuffer.hxx index 85d8240c0e..ceaf913a9b 100644 --- a/src/Select3D/Select3D_BVHIndexBuffer.hxx +++ b/src/Select3D/Select3D_BVHIndexBuffer.hxx @@ -28,7 +28,7 @@ public: //! Empty constructor. Select3D_BVHIndexBuffer (const Handle(NCollection_BaseAllocator)& theAlloc) - : Graphic3d_Buffer (theAlloc), myHasPatches (false) {} + : Graphic3d_Buffer (theAlloc, true, false), myHasPatches (false) {} bool HasPatches() const { return myHasPatches; }