OsdMesh refactoring. Added OsdElementArrayBuffer and OsdPtexCoordinatesTextureBuffer, which manage GL resources on behalf of OsdMesh.

This commit is contained in:
Takahito Tejima 2012-08-22 13:57:36 -07:00
parent 832670c9ff
commit a157628b08
7 changed files with 98 additions and 110 deletions

View File

@ -66,6 +66,7 @@
#include <osd/mutex.h>
#include <osd/vertex.h>
#include <osd/mesh.h>
#include <osd/elementArrayBuffer.h>
#include <osd/cpuDispatcher.h>
#include <osd/glslDispatcher.h>
@ -244,12 +245,10 @@ std::vector<float> 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<float> 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<int> &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);

View File

@ -90,6 +90,8 @@
#include <osd/mesh.h>
#include <osd/pTexture.h>
#include <osd/cpuDispatcher.h>
#include <osd/elementArrayBuffer.h>
#include <osd/ptexCoordinatesTextureBuffer.h>
#include <Ptexture.h>
#include <PtexUtils.h>
@ -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<int> 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);

View File

@ -65,6 +65,7 @@
#include <osd/cudaDispatcher.h>
#include <osd/mesh.h>
#include <osd/vertexBuffer.h>
#include <osd/elementArrayBuffer.h>
#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<int> 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);

View File

@ -68,6 +68,8 @@
#include <osd/cpuDispatcher.h>
#include <osd/glslDispatcher.h>
#include <osd/pTexture.h>
#include <osd/elementArrayBuffer.h>
#include <osd/ptexCoordinatesTextureBuffer.h>
#include "../common/stopwatch.h"
@ -135,14 +137,14 @@ Stopwatch g_fpsTimer;
// geometry
std::vector<float> 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<<g_level);
glProgramUniform1i(g_program, texIndices, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_BUFFER, g_osdmesh->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<int> &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();

View File

@ -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
)

View File

@ -55,12 +55,6 @@
// a particular purpose and non-infringement.
//
#if not defined(__APPLE__)
#include <GL/glew.h>
#else
#include <OpenGL/gl3.h>
#endif
#include <string.h>
#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<int> * 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<level; ++i) {
const std::vector<int> & 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) {

View File

@ -80,8 +80,8 @@ typedef HbrHalfedge<OsdVertex> OsdHbrHalfedge;
template <class T, class U> 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<OsdVertex> const * tables );
@ -133,8 +136,6 @@ protected:
OsdKernelDispatcher * _dispatcher;
std::vector<GLuint> _ptexCoordinates; // index of the coarse parent face + sub-face coordinates (cf. far)
};
} // end namespace OPENSUBDIV_VERSION