From a157628b08eee4e60bd2ac7c275b2175759f56df Mon Sep 17 00:00:00 2001 From: Takahito Tejima Date: Wed, 22 Aug 2012 13:57:36 -0700 Subject: [PATCH] OsdMesh refactoring. Added OsdElementArrayBuffer and OsdPtexCoordinatesTextureBuffer, which manage GL resources on behalf of OsdMesh. --- examples/glutViewer/viewer.cpp | 23 ++++---- .../OpenSubdivPtexShader.cpp | 36 ++++++------- .../mayaViewer/OpenSubdivDrawOverride.cpp | 39 +++++++------- examples/ptexViewer/viewer.cpp | 35 ++++++------ opensubdiv/osd/CMakeLists.txt | 4 ++ opensubdiv/osd/mesh.cpp | 54 +++++++------------ opensubdiv/osd/mesh.h | 17 +++--- 7 files changed, 98 insertions(+), 110 deletions(-) diff --git a/examples/glutViewer/viewer.cpp b/examples/glutViewer/viewer.cpp index 6b72eadd..c282123f 100644 --- a/examples/glutViewer/viewer.cpp +++ b/examples/glutViewer/viewer.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -244,12 +245,10 @@ std::vector g_orgPositions, Scheme g_scheme; -int g_numIndices = 0; int g_level = 2; int g_kernel = OpenSubdiv::OsdKernelDispatcher::kCPU; float g_moveScale = 1.0f; -GLuint g_indexBuffer; GLuint g_quadFillProgram = 0, g_quadLineProgram = 0, g_triFillProgram = 0, @@ -262,6 +261,7 @@ std::vector g_coarseVertexSharpness; OpenSubdiv::OsdMesh * g_osdmesh = 0; OpenSubdiv::OsdVertexBuffer * g_vertexBuffer = 0; +OpenSubdiv::OsdElementArrayBuffer *g_elementArrayBuffer = 0; //------------------------------------------------------------------------------ inline void @@ -615,12 +615,8 @@ createOsdMesh( const char * shape, int level, int kernel, Scheme scheme=kCatmark delete hmesh; // update element array buffer - const std::vector &indices = g_osdmesh->GetFarMesh()->GetFaceVertices(level); - - g_numIndices = (int)indices.size(); - g_scheme = scheme; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indexBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*g_numIndices, &(indices[0]), GL_STATIC_DRAW); + if (g_elementArrayBuffer) delete g_elementArrayBuffer; + g_elementArrayBuffer = g_osdmesh->CreateElementArrayBuffer(level); // compute model bounding float min[3] = { FLT_MAX, FLT_MAX, FLT_MAX}; @@ -721,7 +717,7 @@ display() { glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, 0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, (float*)12); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_elementArrayBuffer->GetGlBuffer()); GLenum primType = GL_LINES_ADJACENCY; if (g_scheme == kLoop) { @@ -732,7 +728,7 @@ display() { } if (g_wire > 0) { - glDrawElements(primType, g_numIndices, GL_UNSIGNED_INT, NULL); + glDrawElements(primType, g_elementArrayBuffer->GetNumIndices(), GL_UNSIGNED_INT, NULL); } if (g_wire == 0 || g_wire == 2) { @@ -745,7 +741,7 @@ display() { } else { glProgramUniform4f(lineProgram, fragColor, 1, 1, 1, 1); } - glDrawElements(primType, g_numIndices, GL_UNSIGNED_INT, NULL); + glDrawElements(primType, g_elementArrayBuffer->GetNumIndices(), GL_UNSIGNED_INT, NULL); } glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); @@ -822,6 +818,9 @@ void quit() { if (g_vertexBuffer) delete g_vertexBuffer; + if (g_elementArrayBuffer) + delete g_elementArrayBuffer; + #ifdef OPENSUBDIV_HAS_CUDA cudaDeviceReset(); #endif @@ -1023,8 +1022,6 @@ int main(int argc, char ** argv) { filename = argv[i]; } - glGenBuffers(1, &g_indexBuffer); - modelMenu(0); glutIdleFunc(idle); diff --git a/examples/mayaPtexViewer_siggraph2012/OpenSubdivPtexShader.cpp b/examples/mayaPtexViewer_siggraph2012/OpenSubdivPtexShader.cpp index 8c149f01..417ea1c7 100644 --- a/examples/mayaPtexViewer_siggraph2012/OpenSubdivPtexShader.cpp +++ b/examples/mayaPtexViewer_siggraph2012/OpenSubdivPtexShader.cpp @@ -90,6 +90,8 @@ #include #include #include +#include +#include #include #include @@ -809,6 +811,8 @@ private: OpenSubdiv::OsdMesh *_osdmesh; // OpenSubdiv::OsdVertexBuffer *_vertexBuffer; OpenSubdiv::OsdVertexBuffer *_positionBuffer, *_normalBuffer; + OpenSubdiv::OsdElementArrayBuffer *_elementArrayBuffer; + OpenSubdiv::OsdPtexCoordinatesTextureBuffer *_ptexCoordinatesTextureBuffer; MFloatPointArray _pointArray; MFloatVectorArray _normalArray; @@ -822,9 +826,6 @@ private: int _interpBoundary; int _scheme; - int _numIndices; - GLuint _indexBuffer; - bool _needsUpdate; bool _needsInitializeOsd; bool _needsInitializeIndexBuffer; @@ -835,11 +836,11 @@ OsdPtexMeshData::OsdPtexMeshData(MObject mesh) : _hbrmesh(NULL), _osdmesh(NULL), // _vertexBuffer(NULL), _positionBuffer(NULL), _normalBuffer(NULL), + _elementArrayBuffer(NULL), + _ptexCoordinatesTextureBuffer(NULL), _level(0), _interpBoundary(0), _scheme(0), - _numIndices(0), - _indexBuffer(0), _needsUpdate(false), _needsInitializeOsd(false), _needsInitializeIndexBuffer(false) @@ -853,9 +854,8 @@ OsdPtexMeshData::~OsdPtexMeshData() // if (_vertexBuffer) delete _vertexBuffer; if (_positionBuffer) delete _positionBuffer; if (_normalBuffer) delete _normalBuffer; - if (_indexBuffer) - glDeleteBuffers(1, &_indexBuffer); - + if (_elementArrayBuffer) delete _elementArrayBuffer; + if (_ptexCoordinatesTextureBuffer) delete _ptexCoordinatesTextureBuffer; } void @@ -1059,15 +1059,13 @@ OsdPtexMeshData::updateGeometry(const MHWRender::MVertexBuffer *points, const MH void OsdPtexMeshData::initializeIndexBuffer() { - // update element array buffer - const std::vector indices = _osdmesh->GetFarMesh()->GetFaceVertices(_level); - _numIndices = (int)indices.size(); + // create element array buffer + if (_elementArrayBuffer) delete _elementArrayBuffer; + _elementArrayBuffer = _osdmesh->CreateElementArrayBuffer(_level); - if (_indexBuffer == 0) - glGenBuffers(1, &_indexBuffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*_numIndices, - &(indices[0]), GL_STATIC_DRAW); + // create ptex coordinates texture buffer + if (_ptexCoordinatesTextureBuffer) delete _ptexCoordinatesTextureBuffer; + _ptexCoordinatesTextureBuffer = _osdmesh->CreatePtexCoordinatesTextureBuffer(_level); _needsInitializeIndexBuffer = false; } @@ -1084,7 +1082,7 @@ OsdPtexMeshData::bindPtexCoordinates(GLuint program) const glProgramUniform1i(program, ptexLevel, 1<<_level); glProgramUniform1i(program, texIndices, 0); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_BUFFER, _osdmesh->GetPtexCoordinatesTextureBuffer(_level)); + glBindTexture(GL_TEXTURE_BUFFER, _ptexCoordinatesTextureBuffer->GetGlTexture()); } void @@ -1125,10 +1123,10 @@ OsdPtexMeshData::draw(GLuint program) const glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 3, 0); #endif - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _elementArrayBuffer->GetGlBuffer()); CHECK_GL_ERROR("before draw elements\n"); - glDrawElements(GL_LINES_ADJACENCY, _numIndices, GL_UNSIGNED_INT, 0); + glDrawElements(GL_LINES_ADJACENCY, _elementArrayBuffer->GetNumIndices(), GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); diff --git a/examples/mayaViewer/OpenSubdivDrawOverride.cpp b/examples/mayaViewer/OpenSubdivDrawOverride.cpp index 3782c937..8a4f23c1 100644 --- a/examples/mayaViewer/OpenSubdivDrawOverride.cpp +++ b/examples/mayaViewer/OpenSubdivDrawOverride.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #include "hbrUtil.h" @@ -125,8 +126,8 @@ public: void Populate(MObject mesh); void UpdatePoints(MObject mesh); - int GetElementBuffer() const { return _index; } - int GetNumIndices() const { return _numIndices; } + int GetElementBuffer() const { return _elementArrayBuffer->GetGlBuffer(); } + int GetNumIndices() const { return _elementArrayBuffer->GetNumIndices(); } int GetVertexBuffer() const { return _vertexBuffer->GetGpuBuffer(); } int GetVaryingBuffer() const { return _varyingBuffer->GetGpuBuffer(); } int GetVertexStride() const { return _vertexBuffer->GetNumElements() * sizeof(float); } @@ -148,9 +149,8 @@ private: OpenSubdiv::OsdMesh *_osdmesh; OpenSubdiv::OsdVertexBuffer *_vertexBuffer, *_varyingBuffer; - GLuint _index; + OpenSubdiv::OsdElementArrayBuffer *_elementArrayBuffer; - int _numIndices; float _cachedTotal; }; @@ -191,16 +191,20 @@ bool OpenSubdivDrawOverride::_loop = false; SubdivUserData::SubdivUserData(bool loop) : MUserData(false /*don't delete after draw */), - _loop(loop) + _loop(loop), + _vertexBuffer(NULL), + _varyingBuffer(NULL), + _elementArrayBuffer(NULL) { _osdmesh = new OpenSubdiv::OsdMesh(); - glGenBuffers(1, &_index); } SubdivUserData::~SubdivUserData() { + if (_vertexBuffer) delete _vertexBuffer; + if (_varyingBuffer) delete _varyingBuffer; + if (_elementArrayBuffer) delete _elementArrayBuffer; delete _osdmesh; - glDeleteBuffers(1, &_index); } void @@ -289,25 +293,22 @@ SubdivUserData::Populate(MObject mesh) edgeCreaseIndices, edgeCreases, interpBoundary, _loop); - if (_vertexBuffer) delete _vertexBuffer; - int kernel = OpenSubdiv::OsdKernelDispatcher::kCPU; if (OpenSubdiv::OsdKernelDispatcher::HasKernelType(OpenSubdiv::OsdKernelDispatcher::kOPENMP)) { kernel = OpenSubdiv::OsdKernelDispatcher::kOPENMP; } _osdmesh->Create(hbrMesh, level, kernel); - - // create vertex buffer - _vertexBuffer = _osdmesh->InitializeVertexBuffer(6 /* position + normal */); - delete hbrMesh; - // update element array buffer - const std::vector indices = _osdmesh->GetFarMesh()->GetFaceVertices(level); - _numIndices = (int)indices.size(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _index); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*_numIndices, - &(indices[0]), GL_STATIC_DRAW); + // create vertex buffer + if (_vertexBuffer) { + delete _vertexBuffer; + } + _vertexBuffer = _osdmesh->InitializeVertexBuffer(6 /* position + normal */); + + // create element array buffer + if (_elementArrayBuffer) delete _elementArrayBuffer; + _elementArrayBuffer = _osdmesh->CreateElementArrayBuffer(level); _cachedTotal = -1; UpdatePoints(mesh); diff --git a/examples/ptexViewer/viewer.cpp b/examples/ptexViewer/viewer.cpp index 88a13d3b..b17e4506 100644 --- a/examples/ptexViewer/viewer.cpp +++ b/examples/ptexViewer/viewer.cpp @@ -68,6 +68,8 @@ #include #include #include +#include +#include #include "../common/stopwatch.h" @@ -135,14 +137,14 @@ Stopwatch g_fpsTimer; // geometry std::vector g_positions, g_normals; -int g_numIndices = 0; -GLuint g_indexBuffer; GLuint g_program = 0; GLuint g_debugProgram = 0; OpenSubdiv::OsdMesh * g_osdmesh = 0; OpenSubdiv::OsdVertexBuffer * g_vertexBuffer = 0; +OpenSubdiv::OsdElementArrayBuffer * g_elementArrayBuffer = 0; +OpenSubdiv::OsdPtexCoordinatesTextureBuffer * g_ptexCoordinatesTextureBuffer = 0; OpenSubdiv::OsdPTexture * g_osdPTexImage = 0; OpenSubdiv::OsdPTexture * g_osdPTexDisplacement = 0; OpenSubdiv::OsdPTexture * g_osdPTexOcclusion = 0; @@ -510,7 +512,7 @@ void linkProgram() { glProgramUniform1i(g_program, ptexLevel, 1<GetPtexCoordinatesTextureBuffer(g_level)); + glBindTexture(GL_TEXTURE_BUFFER, g_ptexCoordinatesTextureBuffer->GetGlTexture()); // color ptex GLint texData = glGetUniformLocation(g_program, "textureImage_Data"); @@ -562,9 +564,6 @@ createOsdMesh(int level, int kernel) { // Hbr mesh can be deleted delete hmesh; - // update element array buffer - const std::vector &indices = g_osdmesh->GetFarMesh()->GetFaceVertices(level); - // generate oOsdPTexture if (g_osdPTexDisplacement) delete g_osdPTexDisplacement; if (g_osdPTexOcclusion) delete g_osdPTexOcclusion; @@ -590,12 +589,14 @@ createOsdMesh(int level, int kernel) { ptexOcclusion->release(); } - // bind index buffer - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indexBuffer); - - g_numIndices = (int)indices.size(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*g_numIndices, &(indices[0]), GL_STATIC_DRAW); + // create element array buffer + if (g_elementArrayBuffer) delete g_elementArrayBuffer; + g_elementArrayBuffer = g_osdmesh->CreateElementArrayBuffer(level); + // create ptex coordinates buffer + if (g_ptexCoordinatesTextureBuffer) delete g_ptexCoordinatesTextureBuffer; + g_ptexCoordinatesTextureBuffer = g_osdmesh->CreatePtexCoordinatesTextureBuffer(level); + updateGeom(); linkProgram(); @@ -722,13 +723,13 @@ display() { glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, 0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 6, (float*)12); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_elementArrayBuffer->GetGlBuffer()); glPolygonMode(GL_FRONT_AND_BACK, g_wire==0 ? GL_LINE : GL_FILL); // glPatchParameteri(GL_PATCH_VERTICES, 4); // glDrawElements(GL_PATCHES, g_numIndices, GL_UNSIGNED_INT, 0); - glDrawElements(GL_LINES_ADJACENCY, g_numIndices, GL_UNSIGNED_INT, 0); + glDrawElements(GL_LINES_ADJACENCY, g_elementArrayBuffer->GetNumIndices(), GL_UNSIGNED_INT, 0); glUseProgram(0); @@ -808,6 +809,12 @@ void quit() { if (g_vertexBuffer) delete g_vertexBuffer; + if (g_elementArrayBuffer) + delete g_elementArrayBuffer; + + if (g_ptexCoordinatesTextureBuffer) + delete g_ptexCoordinatesTextureBuffer; + #ifdef OPENSUBDIV_HAS_CUDA cudaDeviceReset(); #endif @@ -985,8 +992,6 @@ int main(int argc, char ** argv) { return 1; } - glGenBuffers(1, &g_indexBuffer); - createOsdMesh(g_level, g_kernel); fitFrame(); diff --git a/opensubdiv/osd/CMakeLists.txt b/opensubdiv/osd/CMakeLists.txt index 1c8220d9..e8aea7cf 100644 --- a/opensubdiv/osd/CMakeLists.txt +++ b/opensubdiv/osd/CMakeLists.txt @@ -68,8 +68,10 @@ include_directories( set(SOURCE_FILES cpuDispatcher.cpp cpuKernel.cpp + elementArrayBuffer.cpp kernelDispatcher.cpp mesh.cpp + ptexCoordinatesTextureBuffer.cpp vertexBuffer.cpp ) @@ -87,8 +89,10 @@ set(PRIVATE_HEADER_FILES set(PUBLIC_HEADER_FILES cpuDispatcher.h cpuKernel.h + elementArrayBuffer.h kernelDispatcher.h mesh.h + ptexCoordinatesTextureBuffer.h vertex.h vertexBuffer.h ) diff --git a/opensubdiv/osd/mesh.cpp b/opensubdiv/osd/mesh.cpp index d6dd731c..7335b9ae 100644 --- a/opensubdiv/osd/mesh.cpp +++ b/opensubdiv/osd/mesh.cpp @@ -55,12 +55,6 @@ // a particular purpose and non-infringement. // -#if not defined(__APPLE__) - #include -#else - #include -#endif - #include #include "../version.h" @@ -79,7 +73,8 @@ #include "../osd/local.h" #include "../osd/kernelDispatcher.h" #include "../osd/cpuDispatcher.h" - +#include "../osd/elementArrayBuffer.h" +#include "../osd/ptexCoordinatesTextureBuffer.h" namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { @@ -94,11 +89,6 @@ OsdMesh::~OsdMesh() { if(_farMesh) delete _farMesh; - // delete ptex coordinates - for (int i=0; i<(int)_ptexCoordinates.size(); ++i) { - if (glIsTexture(_ptexCoordinates[i])) - glDeleteTextures(1,&_ptexCoordinates[i]); - } } void @@ -176,30 +166,6 @@ OsdMesh::Create(OsdHbrMesh *hbrMesh, int level, int kernel, std::vector * r if (remap) (*remap)=meshFactory.GetRemappingTable(); - // create ptex coordinates if exists in hbr - for (int i=0; i<(int)_ptexCoordinates.size(); ++i) { - if (glIsTexture(_ptexCoordinates[i])) - glDeleteTextures(1,&_ptexCoordinates[i]); - } - _ptexCoordinates.resize(level, 0); - for (int i=0; i & ptexCoordinates = _farMesh->GetPtexCoordinates(i+1); - if (ptexCoordinates.empty()) - continue; - - int size = (int)ptexCoordinates.size() * sizeof(GLint); - const void *data = &ptexCoordinates[0]; - - GLuint buffer; - glGenBuffers(1, & buffer ); - glBindBuffer( GL_TEXTURE_BUFFER, buffer ); - glBufferData( GL_TEXTURE_BUFFER, size, data, GL_STATIC_DRAW); - - glGenTextures(1, & _ptexCoordinates[i]); - glBindTexture( GL_TEXTURE_BUFFER, _ptexCoordinates[i]); - glTexBuffer( GL_TEXTURE_BUFFER, GL_RG32I, buffer); - glDeleteBuffers(1, & buffer ); - } return true; } @@ -211,6 +177,22 @@ OsdMesh::InitializeVertexBuffer(int numElements) { return _dispatcher->InitializeVertexBuffer(numElements, GetTotalVertices()); } +OsdElementArrayBuffer * +OsdMesh::CreateElementArrayBuffer(int level) { + + if (!_farMesh) + return NULL; + return new OsdElementArrayBuffer(_farMesh, level); +} + +OsdPtexCoordinatesTextureBuffer * +OsdMesh::CreatePtexCoordinatesTextureBuffer(int level) { + + if (!_farMesh) + return NULL; + return new OsdPtexCoordinatesTextureBuffer(_farMesh, level); +} + void OsdMesh::Subdivide(OsdVertexBuffer *vertex, OsdVertexBuffer *varying) { diff --git a/opensubdiv/osd/mesh.h b/opensubdiv/osd/mesh.h index 92c3b3b6..3e8484de 100644 --- a/opensubdiv/osd/mesh.h +++ b/opensubdiv/osd/mesh.h @@ -80,8 +80,8 @@ typedef HbrHalfedge OsdHbrHalfedge; template class FarMesh; class OsdKernelDispatcher; - -class OsdPtexIndicesBuffer; +class OsdElementArrayBuffer; +class OsdPtexCoordinatesTextureBuffer; class OsdMesh { @@ -101,8 +101,15 @@ public: int GetLevel() const { return _level; } + // creates and initializes vertex buffer. Must call Creates() before calling this function. OsdVertexBuffer * InitializeVertexBuffer(int numElements); + // creates element indices buffer for given level. Must call Creates() before calling this function. + OsdElementArrayBuffer * CreateElementArrayBuffer(int level); + + // creates ptex-coordinates buffer for given level. Must call Creates() before calling this function. + OsdPtexCoordinatesTextureBuffer * CreatePtexCoordinatesTextureBuffer(int level); + // for non-interleaved vertex data void Subdivide(OsdVertexBuffer *vertex, OsdVertexBuffer *varying = NULL); @@ -117,10 +124,6 @@ public: int GetNumCoarseVertices() const { return _farMesh->GetNumCoarseVertices(); } - // Returns the texture buffer containing the ptex face index for each face of - // the mesh. - GLuint GetPtexCoordinatesTextureBuffer(int level) const { return _ptexCoordinates[level-1]; } - protected: void createTables( FarSubdivisionTables const * tables ); @@ -133,8 +136,6 @@ protected: OsdKernelDispatcher * _dispatcher; - std::vector _ptexCoordinates; // index of the coarse parent face + sub-face coordinates (cf. far) - }; } // end namespace OPENSUBDIV_VERSION