diff --git a/examples/glViewer/viewer.cpp b/examples/glViewer/viewer.cpp index 40382e36..261e8c61 100644 --- a/examples/glViewer/viewer.cpp +++ b/examples/glViewer/viewer.cpp @@ -906,7 +906,7 @@ enum Effect { kPoint = 6, }; -typedef std::pair EffectDesc; +typedef std::pair EffectDesc; class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry { @@ -1075,7 +1075,7 @@ GetEffect() //------------------------------------------------------------------------------ static GLuint -bindProgram(Effect effect, OpenSubdiv::FarPatchTables::PatchArray const & patch) +bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch) { EffectDesc effectDesc(patch.GetDescriptor(), effect); EffectDrawRegistry::ConfigType * @@ -1206,7 +1206,7 @@ display() { glBindVertexArray(g_vao); - OpenSubdiv::FarPatchTables::PatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays; + OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays; // cv drawing /* @@ -1233,9 +1233,9 @@ display() { glBeginQuery(GL_PRIMITIVES_GENERATED, g_primQuery); for (int i=0; i<(int)patches.size(); ++i) { - OpenSubdiv::FarPatchTables::PatchArray const & patch = patches[i]; + OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i]; - OpenSubdiv::FarPatchTables::Descriptor desc = patch.GetDescriptor(); + OpenSubdiv::OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor(); OpenSubdiv::FarPatchTables::Type patchType = desc.GetType(); int patchPattern = desc.GetPattern(); int patchRotation = desc.GetRotation(); diff --git a/opensubdiv/far/patchTables.h b/opensubdiv/far/patchTables.h index bbc0a5b0..4c82cf58 100644 --- a/opensubdiv/far/patchTables.h +++ b/opensubdiv/far/patchTables.h @@ -257,19 +257,15 @@ public: public: /// Default constructor. Descriptor() : - _type(NON_PATCH), _pattern(NON_TRANSITION), _rotation(0), - _maxValence(0), _subpatch(0), _numElements(0) { } + _type(NON_PATCH), _pattern(NON_TRANSITION), _rotation(0) {} /// Constructor - Descriptor(int type, int pattern, unsigned char rotation, - unsigned char maxValence=0, unsigned char subpatch=0, unsigned char numElements=0) : - _type((Type)type), _pattern((TransitionPattern)pattern), _rotation(rotation), - _maxValence(maxValence), _subpatch(subpatch), _numElements(numElements) { } + Descriptor(int type, int pattern, unsigned char rotation) : + _type((Type)type), _pattern((TransitionPattern)pattern), _rotation(rotation) { } /// Copy Constructor Descriptor( Descriptor const & d ) : - _type(d.GetType()), _pattern(d.GetPattern()), _rotation(d.GetRotation()), - _maxValence(d.GetMaxValence()), _subpatch(d.GetSubPatch()), _numElements(d.GetNumElements()) { } + _type(d.GetType()), _pattern(d.GetPattern()), _rotation(d.GetRotation()) { } /// Returns the type of the patch Type GetType() const { @@ -295,21 +291,6 @@ public: short GetNumControlVertices() const { return GetNumControlVertices( this->GetType() ); } - - /// Returns the subpatch id (used in osd context) - unsigned char GetSubPatch() const { - return _subpatch; - } - - /// Returns the max valence (used in osd context) - unsigned char GetMaxValence() const { - return _maxValence; - } - - /// Returns the number of vertex elements (used in osd context) - unsigned char GetNumElements() const { - return _numElements; - } /// Iterates through the patches in the following preset order /// @@ -358,9 +339,6 @@ public: Type _type:4; TransitionPattern _pattern:3; unsigned char _rotation:2; - unsigned char _maxValence:5; // not used in far - unsigned char _subpatch:2; // not used in far - unsigned char _numElements:5; // not used in far }; /// \brief Descriptor iterator class @@ -395,45 +373,57 @@ public: class PatchArray { public: + struct ArrayRange { + ArrayRange( unsigned int vertIndex, unsigned int patchIndex, unsigned int npatches, unsigned int quadOffsetIndex ) : + vertIndex(vertIndex), patchIndex(patchIndex), npatches(npatches), quadOffsetIndex(quadOffsetIndex) { } + + unsigned int vertIndex, // absolute index to the first control vertex of the first patch in the PTable + patchIndex, // absolute index of the first patch in the array + npatches, // number of patches in the array + quadOffsetIndex; // absolute index of the first quad offset entry + }; + /// Constructor. PatchArray( Descriptor desc, unsigned int vertIndex, unsigned int patchIndex, unsigned int npatches, unsigned int quadOffsetIndex ) : - _desc(desc), _vertIndex(vertIndex), _patchIndex(patchIndex), _npatches(npatches), _quadOffsetIndex(quadOffsetIndex) { } + _desc(desc), _range(vertIndex, patchIndex, npatches, quadOffsetIndex) { } /// Returns a patch descriptor defining the type of patches in the array Descriptor GetDescriptor() const { return _desc; } - + + /// Returns a array range struct + ArrayRange const & GetArrayRange() const { + return _range; + } + /// Returns the index of the first control vertex of the first patch /// of this array in the global PTable unsigned int GetVertIndex() const { - return _vertIndex; + return _range.vertIndex; } /// Returns the global index of the first patch in this array (Used to /// access ptex / fvar table data) unsigned int GetPatchIndex() const { - return _patchIndex; + return _range.patchIndex; } /// Returns the number of patches in the array unsigned int GetNumPatches() const { - return _npatches; + return _range.npatches; } unsigned int GetQuadOffsetIndex() const { - return _quadOffsetIndex; + return _range.quadOffsetIndex; } private: template friend class FarPatchTablesFactory; - Descriptor _desc; // type of patches in the array - - unsigned int _vertIndex, // absolute index to the first control vertex of the first patch in the PTable - _patchIndex, // absolute index of the first patch in the array - _npatches, // number of patches in the array - _quadOffsetIndex; // absolute index of the first quad offset entry + Descriptor _desc; // type of patches in the array + + ArrayRange _range; // index locators in the array }; typedef std::vector PatchArrayVector; @@ -579,21 +569,15 @@ inline bool FarPatchTables::Descriptor::operator < ( Descriptor const other ) const { return _pattern < other._pattern or ((_pattern == other._pattern) and (_type < other._type or ((_type == other._type) and - (_rotation < other._rotation or ((_rotation == other._rotation) and - (_subpatch < other._subpatch or ((_subpatch == other._subpatch) and - (_maxValence < other._maxValence or ((_maxValence == other._maxValence) and - (_numElements < other._numElements)))))))))); -} + (_rotation < other._rotation)))); +} // True if the descriptors are identical inline bool FarPatchTables::Descriptor::operator == ( Descriptor const other ) const { return _pattern == other._pattern and _type == other._type and - _rotation == other._rotation and - _subpatch == other._subpatch and - _maxValence == other._maxValence and - _numElements == other._numElements; + _rotation == other._rotation; } // Returns a pointer to the array of patches matching the descriptor diff --git a/opensubdiv/osd/drawContext.cpp b/opensubdiv/osd/drawContext.cpp index 8d688fc8..520b1924 100644 --- a/opensubdiv/osd/drawContext.cpp +++ b/opensubdiv/osd/drawContext.cpp @@ -56,6 +56,25 @@ namespace OPENSUBDIV_VERSION { OsdDrawContext::~OsdDrawContext() {} +// Allows ordering of patches by type +bool +OsdDrawContext::PatchDescriptor::operator < ( PatchDescriptor const other ) const { + + return _farDesc < other._farDesc or (_farDesc == other._farDesc and + (_subPatch < other._subPatch or ((_subPatch == other._subPatch) and + (_maxValence < other._maxValence or ((_maxValence == other._maxValence) and + (_numElements < other._numElements)))))); +} + +// True if the descriptors are identical +bool +OsdDrawContext::PatchDescriptor::operator == ( PatchDescriptor const other ) const { + return _farDesc == other._farDesc and + _subPatch == other._subPatch and + _maxValence == other._maxValence and + _numElements == other._numElements; +} + void OsdDrawContext::createPatchArrays(FarPatchTables const * patchTables, int numElements) { @@ -82,18 +101,9 @@ OsdDrawContext::createPatchArrays(FarPatchTables const * patchTables, int numEle FarPatchTables::Descriptor srcDesc = parray.GetDescriptor(); for (int j = 0; j < numSubPatches; ++j) { - FarPatchTables::Descriptor desc(srcDesc.GetType(), - srcDesc.GetPattern(), - srcDesc.GetRotation(), - maxValence, - j, - numElements); + PatchDescriptor desc(srcDesc, maxValence, j, numElements); - patchArrays.push_back(FarPatchTables::PatchArray(desc, - parray.GetVertIndex(), - parray.GetPatchIndex(), - parray.GetNumPatches(), - parray.GetQuadOffsetIndex())); + patchArrays.push_back(PatchArray(desc, parray.GetArrayRange())); } } } diff --git a/opensubdiv/osd/drawContext.h b/opensubdiv/osd/drawContext.h index cbb02d02..1a550b43 100644 --- a/opensubdiv/osd/drawContext.h +++ b/opensubdiv/osd/drawContext.h @@ -69,12 +69,111 @@ namespace OPENSUBDIV_VERSION { class OsdDrawContext { public: + class PatchDescriptor { + public: + PatchDescriptor(FarPatchTables::Descriptor farDesc, unsigned char maxValence, + unsigned char subPatch, unsigned char numElements) : + _farDesc(farDesc), _maxValence(maxValence), _subPatch(subPatch), _numElements(numElements) { } + + + /// Returns the type of the patch + FarPatchTables::Type GetType() const { + return _farDesc.GetType(); + } + + /// Returns the transition pattern of the patch if any (5 types) + FarPatchTables::TransitionPattern GetPattern() const { + return _farDesc.GetPattern(); + } + + /// Returns the rotation of the patch (4 rotations) + unsigned char GetRotation() const { + return _farDesc.GetRotation(); + } + + /// Returns the number of control vertices expected for a patch of the + /// type described + int GetNumControlVertices() const { + return _farDesc.GetNumControlVertices(); + } + + /// Returns the max valence + int GetMaxValence() const { + return _maxValence; + } + + /// Returns the subpatch id + int GetSubPatch() const { + return _subPatch; + } + + /// Returns the number of vertex elements + int GetNumElements() const { + return _numElements; + } + + /// Allows ordering of patches by type + bool operator < ( PatchDescriptor const other ) const; + + /// True if the descriptors are identical + bool operator == ( PatchDescriptor const other ) const; + + private: + FarPatchTables::Descriptor _farDesc; + unsigned char _maxValence; + unsigned char _subPatch; + unsigned char _numElements; + }; + + class PatchArray { + public: + PatchArray(PatchDescriptor desc, FarPatchTables::PatchArray::ArrayRange const & range) : + _desc(desc), _range(range) { } + + /// Returns a patch descriptor defining the type of patches in the array + PatchDescriptor GetDescriptor() const { + return _desc; + } + + /// Returns a array range struct + FarPatchTables::PatchArray::ArrayRange const & GetArrayRange() const { + return _range; + } + + /// Returns the index of the first control vertex of the first patch + /// of this array in the global PTable + unsigned int GetVertIndex() const { + return _range.vertIndex; + } + + /// Returns the global index of the first patch in this array (Used to + /// access ptex / fvar table data) + unsigned int GetPatchIndex() const { + return _range.patchIndex; + } + + /// Returns the number of patches in the array + unsigned int GetNumPatches() const { + return _range.npatches; + } + + unsigned int GetQuadOffsetIndex() const { + return _range.quadOffsetIndex; + } + + private: + PatchDescriptor _desc; + FarPatchTables::PatchArray::ArrayRange _range; + }; + + typedef std::vector PatchArrayVector; + OsdDrawContext() : _isAdaptive(false) {} virtual ~OsdDrawContext(); bool IsAdaptive() const { return _isAdaptive; } - FarPatchTables::PatchArrayVector patchArrays; + PatchArrayVector patchArrays; protected: void createPatchArrays(FarPatchTables const * patchTables, int numElements); diff --git a/opensubdiv/osd/glDrawContext.cpp b/opensubdiv/osd/glDrawContext.cpp index 60fe2b31..84a610a5 100644 --- a/opensubdiv/osd/glDrawContext.cpp +++ b/opensubdiv/osd/glDrawContext.cpp @@ -103,57 +103,52 @@ OsdGLDrawContext::SupportsAdaptiveTessellation() } bool -OsdGLDrawContext::allocate(FarMesh *farMesh, - GLuint vbo, - int numElements, - bool requireFVarData) +OsdGLDrawContext::allocateUniform(FarMesh *farMesh, + GLuint vbo, + int numElements, + bool requireFVarData) { - FarPatchTables const * patchTables = farMesh->GetPatchTables(); - if (not patchTables) { - // uniform patches - _isAdaptive = false; + // XXX: farmesh should have FarDensePatchTable for dense mesh indices. + // instead of GetFaceVertices(). + const FarSubdivisionTables *tables = farMesh->GetSubdivisionTables(); + int level = tables->GetMaxLevel(); + const std::vector &indices = farMesh->GetFaceVertices(level-1); - // XXX: farmesh should have FarDensePatchTable for dense mesh indices. - // instead of GetFaceVertices(). - const FarSubdivisionTables *tables = farMesh->GetSubdivisionTables(); - int level = tables->GetMaxLevel(); - const std::vector &indices = farMesh->GetFaceVertices(level-1); + int numIndices = (int)indices.size(); - int numIndices = (int)indices.size(); - - // Allocate and fill index buffer. - glGenBuffers(1, &patchIndexBuffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchIndexBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - numIndices * sizeof(unsigned int), &(indices[0]), GL_STATIC_DRAW); + // Allocate and fill index buffer. + glGenBuffers(1, &patchIndexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchIndexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + numIndices * sizeof(unsigned int), &(indices[0]), GL_STATIC_DRAW); #if defined(GL_ES_VERSION_2_0) - // OpenGLES 2 supports only triangle topologies for filled - // primitives i.e. not QUADS or PATCHES or LINES_ADJACENCY - // For the convenience of clients build build a triangles - // index buffer by splitting quads. - int numQuads = indices.size() / 4; - int numTrisIndices = numQuads * 6; + // OpenGLES 2 supports only triangle topologies for filled + // primitives i.e. not QUADS or PATCHES or LINES_ADJACENCY + // For the convenience of clients build build a triangles + // index buffer by splitting quads. + int numQuads = indices.size() / 4; + int numTrisIndices = numQuads * 6; - std::vector trisIndices; - trisIndices.reserve(numTrisIndices); - for (int i=0; i trisIndices; + trisIndices.reserve(numTrisIndices); + for (int i=0; i *farMesh, patchArrays.push_back(array); */ - // Allocate ptex coordinate buffer + // Allocate ptex coordinate buffer #if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1) - GLuint ptexCoordinateBuffer = 0; - glGenTextures(1, &ptexCoordinateTextureBuffer); - glGenBuffers(1, &ptexCoordinateBuffer); - glBindBuffer(GL_TEXTURE_BUFFER, ptexCoordinateBuffer); + GLuint ptexCoordinateBuffer = 0; + glGenTextures(1, &ptexCoordinateTextureBuffer); + glGenBuffers(1, &ptexCoordinateBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, ptexCoordinateBuffer); - const std::vector &ptexCoordinates = - farMesh->GetPtexCoordinates(level-1); - int size = (int)ptexCoordinates.size() * sizeof(FarPtexCoord); + const std::vector &ptexCoordinates = + farMesh->GetPtexCoordinates(level-1); + int size = (int)ptexCoordinates.size() * sizeof(FarPtexCoord); - glBufferData(GL_TEXTURE_BUFFER, size, &(ptexCoordinates[0]), GL_STATIC_DRAW); + glBufferData(GL_TEXTURE_BUFFER, size, &(ptexCoordinates[0]), GL_STATIC_DRAW); - glBindTexture(GL_TEXTURE_BUFFER, ptexCoordinateTextureBuffer); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, ptexCoordinateBuffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); - glDeleteBuffers(1, &ptexCoordinateBuffer); + glBindTexture(GL_TEXTURE_BUFFER, ptexCoordinateTextureBuffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, ptexCoordinateBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + glDeleteBuffers(1, &ptexCoordinateBuffer); #endif - // Allocate fvar data buffer if requested (for non-adaptive) - if (requireFVarData) { + // Allocate fvar data buffer if requested (for non-adaptive) + if (requireFVarData) { #if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1) - GLuint fvarDataBuffer = 0; - glGenTextures(1, &fvarDataTextureBuffer); - glGenBuffers(1, &fvarDataBuffer); - glBindBuffer(GL_TEXTURE_BUFFER, fvarDataBuffer); + GLuint fvarDataBuffer = 0; + glGenTextures(1, &fvarDataTextureBuffer); + glGenBuffers(1, &fvarDataBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, fvarDataBuffer); - const std::vector &fvarData = farMesh->GetFVarData(level-1); - int size = (int)fvarData.size() * sizeof(float); + const std::vector &fvarData = farMesh->GetFVarData(level-1); + int size = (int)fvarData.size() * sizeof(float); - glBufferData(GL_TEXTURE_BUFFER, size, &(fvarData[0]), GL_STATIC_DRAW); + glBufferData(GL_TEXTURE_BUFFER, size, &(fvarData[0]), GL_STATIC_DRAW); - glBindTexture(GL_TEXTURE_BUFFER, fvarDataTextureBuffer); - glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, fvarDataBuffer); - glDeleteBuffers(1, &fvarDataBuffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); + glBindTexture(GL_TEXTURE_BUFFER, fvarDataTextureBuffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, fvarDataBuffer); + glDeleteBuffers(1, &fvarDataBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); #endif - } + } - return true; + return true; +} +bool +OsdGLDrawContext::allocate(FarMesh *farMesh, + GLuint vbo, + int numElements, + bool requireFVarData) +{ + FarPatchTables const * patchTables = farMesh->GetPatchTables(); + + if (not patchTables) { + // uniform patches + _isAdaptive = false; + + // XXX: this function will be retired once uniform patches are integrated into patcharray. + return allocateUniform(farMesh, vbo, numElements, requireFVarData); } // adaptive patches @@ -304,5 +314,7 @@ OsdGLDrawContext::allocate(FarMesh *farMesh, return true; } + + } // end namespace OPENSUBDIV_VERSION } // end namespace OpenSubdiv diff --git a/opensubdiv/osd/glDrawContext.h b/opensubdiv/osd/glDrawContext.h index f9f3fd0d..794e7343 100644 --- a/opensubdiv/osd/glDrawContext.h +++ b/opensubdiv/osd/glDrawContext.h @@ -124,6 +124,10 @@ private: bool allocate(FarMesh *farMesh, GLuint vbo, int numElements, bool requireFVarData); + + bool allocateUniform(FarMesh *farMesh, + GLuint vbo, int numElements, + bool requireFVarData); }; } // end namespace OPENSUBDIV_VERSION diff --git a/opensubdiv/osd/glDrawRegistry.cpp b/opensubdiv/osd/glDrawRegistry.cpp index 320c7adb..b79155c4 100644 --- a/opensubdiv/osd/glDrawRegistry.cpp +++ b/opensubdiv/osd/glDrawRegistry.cpp @@ -105,7 +105,7 @@ static const char *transitionShaderSource = OsdGLDrawRegistryBase::~OsdGLDrawRegistryBase() {} OsdGLDrawSourceConfig * -OsdGLDrawRegistryBase::_CreateDrawSourceConfig(FarPatchTables::Descriptor const & desc) +OsdGLDrawRegistryBase::_CreateDrawSourceConfig(OsdDrawContext::PatchDescriptor const & desc) { OsdGLDrawSourceConfig * sconfig = _NewDrawSourceConfig(); @@ -293,7 +293,7 @@ _CompileShader( OsdGLDrawConfig * OsdGLDrawRegistryBase::_CreateDrawConfig( - FarPatchTables::Descriptor const & desc, + OsdDrawContext::PatchDescriptor const & desc, OsdGLDrawSourceConfig const * sconfig) { assert(sconfig); diff --git a/opensubdiv/osd/glDrawRegistry.h b/opensubdiv/osd/glDrawRegistry.h index cc90b6e3..a065dbc0 100644 --- a/opensubdiv/osd/glDrawRegistry.h +++ b/opensubdiv/osd/glDrawRegistry.h @@ -99,7 +99,7 @@ struct OsdGLDrawSourceConfig : public OsdDrawSourceConfig { class OsdGLDrawRegistryBase { public: - typedef FarPatchTables::Descriptor DescType; + typedef OsdDrawContext::PatchDescriptor DescType; typedef OsdGLDrawConfig ConfigType; typedef OsdGLDrawSourceConfig SourceConfigType; @@ -116,7 +116,7 @@ protected: _CreateDrawSourceConfig(DescType const & desc); }; -template class OsdGLDrawRegistry : public OsdGLDrawRegistryBase {