adding vertexbuffer class (incomplete)

This commit is contained in:
Takahito Tejima 2012-06-12 09:28:00 -07:00
parent 66820d3c5a
commit 340b89f99a
10 changed files with 224 additions and 398 deletions

View File

@ -82,19 +82,12 @@ OsdCpuKernelDispatcher::DeviceTable::Copy( int size, const void *table ) {
}
}
OsdCpuKernelDispatcher::OsdCpuKernelDispatcher( int levels, int numVertexElements, int numVaryingElements )
: OsdKernelDispatcher(levels), _vertexBuffer(0), _varyingBuffer(0), _vbo(NULL), _varyingVbo(NULL), _numVertexElements(numVertexElements), _numVaryingElements(numVaryingElements) {
OsdCpuKernelDispatcher::OsdCpuKernelDispatcher( int levels )
: OsdKernelDispatcher(levels) {
_tables.resize(TABLE_MAX);
}
OsdCpuKernelDispatcher::~OsdCpuKernelDispatcher() {
if(_vbo)
delete[] _vbo;
if(_varyingVbo)
delete[] _varyingVbo;
}
OsdCpuKernelDispatcher::~OsdCpuKernelDispatcher() { }
void
OsdCpuKernelDispatcher::CopyTable(int tableIndex, size_t size, const void *ptr) {
@ -108,94 +101,24 @@ OsdCpuKernelDispatcher::BeginLaunchKernel() { }
void
OsdCpuKernelDispatcher::EndLaunchKernel() { }
void
OsdCpuKernelDispatcher::BindVertexBuffer(GLuint vertexBuffer, GLuint varyingBuffer) {
_vertexBuffer = vertexBuffer;
_varyingBuffer = varyingBuffer;
OsdVertexBuffer *
OsdCpuKernelDispatcher::InitializeVertexBuffer(int numElements, int count)
{
return new OsdCpuVertexBuffer(numElements, count);
}
void
OsdCpuKernelDispatcher::UpdateVertexBuffer(size_t size, void *ptr) {
OsdCpuKernelDispatcher::BindVertexBuffer(OsdVertexBuffer *vertex, OsdVertexBuffer *varying) {
memcpy(_vbo, ptr, size);
_vertexBuffer = dynamic_cast<OsdCpuVertexBuffer *>(vertex);
_varyingBuffer = dynamic_cast<OsdCpuVertexBuffer *>(varying);
}
void
OsdCpuKernelDispatcher::UpdateVaryingBuffer(size_t size, void *ptr) {
memcpy(_varyingVbo, ptr, size);
}
void
OsdCpuKernelDispatcher::MapVertexBuffer() {
// XXX not efficient for CPU
// copy vbo content to kernel-buffer
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &_vboSize);
if (_vbo)
delete[] _vbo;
_vbo = new float[_vboSize/sizeof(float)];
// too slow...
float *buffer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
if (buffer) {
memcpy(_vbo, buffer, _vboSize);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void
OsdCpuKernelDispatcher::MapVaryingBuffer() {
if (_varyingBuffer) {
glBindBuffer(GL_ARRAY_BUFFER, _varyingBuffer);
glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &_varyingVboSize);
if (_varyingVbo)
delete[] _varyingVbo;
_varyingVbo = new float[_varyingVboSize/sizeof(float)];
float *buffer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
if (buffer)
memcpy(_varyingVbo, buffer, _varyingVboSize);
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
void
OsdCpuKernelDispatcher::UnmapVertexBuffer() {
// write back kernel-buffer to vbo
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
float *buffer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (buffer)
memcpy(buffer, _vbo, _vboSize);
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void
OsdCpuKernelDispatcher::UnmapVaryingBuffer() {
if (_varyingBuffer) {
// write back kernel-buffer to vbo
glBindBuffer(GL_ARRAY_BUFFER, _varyingBuffer);
float *buffer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (buffer)
memcpy(buffer, _varyingVbo, _varyingVboSize);
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
OsdCpuKernelDispatcher::UnbindVertexBuffer()
{
_vertexBuffer = NULL;
_varyingBuffer = NULL;
}
void
@ -204,20 +127,26 @@ OsdCpuKernelDispatcher::Synchronize() { }
void
OsdCpuKernelDispatcher::ApplyCatmarkFaceVerticesKernel( FarMesh<OsdVertex> * mesh, int offset, int level, int start, int end, void * data) const {
VertexDescriptor vd(_numVertexElements, _numVaryingElements);
VertexDescriptor vd(_vertexBuffer->GetNumElements(), _varyingBuffer->GetNumElements());
computeFace(&vd, _vbo, _varyingVbo,
computeFace(&vd, _vertexBuffer->GetCpuBuffer(), _varyingBuffer->GetCpuBuffer(),
(int*)_tables[F_IT].devicePtr + _tableOffsets[F_IT][level-1],
(int*)_tables[F_ITa].devicePtr + _tableOffsets[F_ITa][level-1],
offset, start, end);
float *p = _vertexBuffer->GetCpuBuffer();
for(int i = 0; i < 150; i+=3){
printf("%f %f %f\n", p[0], p[1], p[2]);
p+=3;
}
}
void
OsdCpuKernelDispatcher::ApplyCatmarkEdgeVerticesKernel( FarMesh<OsdVertex> * mesh, int offset, int level, int start, int end, void * data) const {
VertexDescriptor vd(_numVertexElements, _numVaryingElements);
VertexDescriptor vd(_vertexBuffer->GetNumElements(), _varyingBuffer->GetNumElements());
computeEdge(&vd, _vbo, _varyingVbo,
computeEdge(&vd, _vertexBuffer->GetCpuBuffer(), _varyingBuffer->GetCpuBuffer(),
(int*)_tables[E_IT].devicePtr + _tableOffsets[E_IT][level-1],
(float*)_tables[E_W].devicePtr + _tableOffsets[E_W][level-1],
offset,
@ -227,9 +156,9 @@ OsdCpuKernelDispatcher::ApplyCatmarkEdgeVerticesKernel( FarMesh<OsdVertex> * mes
void
OsdCpuKernelDispatcher::ApplyCatmarkVertexVerticesKernelB( FarMesh<OsdVertex> * mesh, int offset, int level, int start, int end, void * data) const {
VertexDescriptor vd(_numVertexElements, _numVaryingElements);
VertexDescriptor vd(_vertexBuffer->GetNumElements(), _varyingBuffer->GetNumElements());
computeVertexB(&vd, _vbo, _varyingVbo,
computeVertexB(&vd, _vertexBuffer->GetCpuBuffer(), _varyingBuffer->GetCpuBuffer(),
(int*)_tables[V_ITa].devicePtr + _tableOffsets[V_ITa][level-1],
(int*)_tables[V_IT].devicePtr + _tableOffsets[V_IT][level-1],
(float*)_tables[V_W].devicePtr + _tableOffsets[V_W][level-1],
@ -239,9 +168,9 @@ OsdCpuKernelDispatcher::ApplyCatmarkVertexVerticesKernelB( FarMesh<OsdVertex> *
void
OsdCpuKernelDispatcher::ApplyCatmarkVertexVerticesKernelA( FarMesh<OsdVertex> * mesh, int offset, bool pass, int level, int start, int end, void * data) const {
VertexDescriptor vd(_numVertexElements, _numVaryingElements);
VertexDescriptor vd(_vertexBuffer->GetNumElements(), _varyingBuffer->GetNumElements());
computeVertexA(&vd, _vbo, _varyingVbo,
computeVertexA(&vd, _vertexBuffer->GetCpuBuffer(), _varyingBuffer->GetCpuBuffer(),
(int*)_tables[V_ITa].devicePtr + _tableOffsets[V_ITa][level-1],
(float*)_tables[V_W].devicePtr + _tableOffsets[V_W][level-1],
offset, start, end, pass);
@ -250,9 +179,9 @@ OsdCpuKernelDispatcher::ApplyCatmarkVertexVerticesKernelA( FarMesh<OsdVertex> *
void
OsdCpuKernelDispatcher::ApplyLoopEdgeVerticesKernel( FarMesh<OsdVertex> * mesh, int offset, int level, int start, int end, void * data) const {
VertexDescriptor vd(_numVertexElements, _numVaryingElements);
VertexDescriptor vd(_vertexBuffer->GetNumElements(), _varyingBuffer->GetNumElements());
computeEdge(&vd, _vbo, _varyingVbo,
computeEdge(&vd, _vertexBuffer->GetCpuBuffer(), _varyingBuffer->GetCpuBuffer(),
(int*)_tables[E_IT].devicePtr + _tableOffsets[E_IT][level-1],
(float*)_tables[E_W].devicePtr + _tableOffsets[E_W][level-1],
offset,
@ -262,9 +191,9 @@ OsdCpuKernelDispatcher::ApplyLoopEdgeVerticesKernel( FarMesh<OsdVertex> * mesh,
void
OsdCpuKernelDispatcher::ApplyLoopVertexVerticesKernelB( FarMesh<OsdVertex> * mesh, int offset, int level, int start, int end, void * data) const {
VertexDescriptor vd(_numVertexElements, _numVaryingElements);
VertexDescriptor vd(_vertexBuffer->GetNumElements(), _varyingBuffer->GetNumElements());
computeLoopVertexB(&vd, _vbo, _varyingVbo,
computeLoopVertexB(&vd, _vertexBuffer->GetCpuBuffer(), _varyingBuffer->GetCpuBuffer(),
(int*)_tables[V_ITa].devicePtr + _tableOffsets[V_ITa][level-1],
(int*)_tables[V_IT].devicePtr + _tableOffsets[V_IT][level-1],
(float*)_tables[V_W].devicePtr + _tableOffsets[V_W][level-1],
@ -274,9 +203,9 @@ OsdCpuKernelDispatcher::ApplyLoopVertexVerticesKernelB( FarMesh<OsdVertex> * mes
void
OsdCpuKernelDispatcher::ApplyLoopVertexVerticesKernelA( FarMesh<OsdVertex> * mesh, int offset, bool pass, int level, int start, int end, void * data) const {
VertexDescriptor vd(_numVertexElements, _numVaryingElements);
VertexDescriptor vd(_vertexBuffer->GetNumElements(), _varyingBuffer->GetNumElements());
computeVertexA(&vd, _vbo, _varyingVbo,
computeVertexA(&vd, _vertexBuffer->GetCpuBuffer(), _varyingBuffer->GetCpuBuffer(),
(int*)_tables[V_ITa].devicePtr + _tableOffsets[V_ITa][level-1],
(float*)_tables[V_W].devicePtr + _tableOffsets[V_W][level-1],
offset, start, end, pass);

View File

@ -72,7 +72,7 @@ namespace OPENSUBDIV_VERSION {
class OsdCpuKernelDispatcher : public OsdKernelDispatcher
{
public:
OsdCpuKernelDispatcher(int levels, int numVertexElements, int numVaryingElements);
OsdCpuKernelDispatcher(int levels);
virtual ~OsdCpuKernelDispatcher();
virtual void ApplyCatmarkFaceVerticesKernel(FarMesh<OsdVertex> * mesh, int offset, int level, int start, int end, void * data) const;
@ -95,24 +95,16 @@ public:
virtual void EndLaunchKernel();
virtual void BindVertexBuffer(GLuint vertexBuffer, GLuint varyingBuffer);
virtual OsdVertexBuffer *InitializeVertexBuffer(int numElements, int count);
virtual void UpdateVertexBuffer(size_t size, void *ptr);
virtual void BindVertexBuffer(OsdVertexBuffer *vertex, OsdVertexBuffer *varying);
virtual void UpdateVaryingBuffer(size_t size, void *ptr);
virtual void MapVertexBuffer();
virtual void MapVaryingBuffer();
virtual void UnmapVertexBuffer();
virtual void UnmapVaryingBuffer();
virtual void UnbindVertexBuffer();
virtual void Synchronize();
static OsdKernelDispatcher * Create(int levels, int numVertexElements, int numVaryingElements) {
return new OsdCpuKernelDispatcher(levels, numVertexElements, numVaryingElements);
static OsdKernelDispatcher * Create(int levels) {
return new OsdCpuKernelDispatcher(levels);
}
static void Register() {
Factory::GetInstance().Register("omp", Create);
@ -129,18 +121,9 @@ protected:
void *devicePtr;
};
OsdCpuVertexBuffer *_vertexBuffer, *_varyingBuffer;
std::vector<DeviceTable> _tables;
GLuint _vertexBuffer,
_varyingBuffer;
float *_vbo,
*_varyingVbo;
int _vboSize,
_varyingVboSize,
_numVertexElements,
_numVaryingElements;
};
} // end namespace OPENSUBDIV_VERSION

View File

@ -87,12 +87,10 @@ OsdCudaKernelDispatcher::DeviceTable::Copy(int size, const void *ptr) {
cudaMemcpy(devicePtr, ptr, size, cudaMemcpyHostToDevice);
}
OsdCudaKernelDispatcher::OsdCudaKernelDispatcher(int levels, int numVertexElements, int numVaryingElements)
OsdCudaKernelDispatcher::OsdCudaKernelDispatcher(int levels)
: OsdKernelDispatcher(levels),
_cudaVertexResource(NULL),
_cudaVaryingResource(NULL),
_numVertexElements(numVertexElements),
_numVaryingElements(numVaryingElements)
_cudaVaryingResource(NULL)
{
_tables.resize(TABLE_MAX);
}
@ -114,57 +112,42 @@ OsdCudaKernelDispatcher::BeginLaunchKernel() { }
void
OsdCudaKernelDispatcher::EndLaunchKernel() { }
void
OsdCudaKernelDispatcher::BindVertexBuffer(GLuint vertexBuffer, GLuint varyingBuffer) {
cudaGraphicsGLRegisterBuffer(&_cudaVertexResource, vertexBuffer, cudaGraphicsMapFlagsWriteDiscard);
if (varyingBuffer)
cudaGraphicsGLRegisterBuffer(&_cudaVaryingResource, varyingBuffer, cudaGraphicsMapFlagsWriteDiscard);
OsdVertexBuffer *
OsdCudaKernelDispatcher::InitializeVertexBuffer(int numElements, int count)
{
return new OsdGpuVertexBuffer(numElements, count);
}
void
OsdCudaKernelDispatcher::UpdateVertexBuffer(size_t size, void *ptr) {
cudaMemcpy(_deviceVertices, ptr, size, cudaMemcpyHostToDevice);
}
void
OsdCudaKernelDispatcher::UpdateVaryingBuffer(size_t size, void *ptr) {
if(_cudaVaryingResource)
cudaMemcpy(_deviceVaryings, ptr, size, cudaMemcpyHostToDevice);
}
void
OsdCudaKernelDispatcher::MapVertexBuffer() {
OsdCudaKernelDispatcher::BindVertexBuffer(OsdVertexBuffer *vertex, OsdVertexBuffer *varying) {
OsdGpuVertexBuffer *bVertex = dynamic_cast<OsdGpuVertexBuffer *>(vertex);
OsdGpuVertexBuffer *bVarying = dynamic_cast<OsdGpuVertexBuffer *>(varying);
size_t num_bytes;
if (bVertex) {
cudaGraphicsGLRegisterBuffer(&_cudaVertexResource, bVertex->GetGpuBuffer(), cudaGraphicsMapFlagsWriteDiscard);
cudaGraphicsMapResources(1, &_cudaVertexResource, 0);
cudaGraphicsResourceGetMappedPointer((void **)&_deviceVertices, &num_bytes, _cudaVertexResource);
}
void
OsdCudaKernelDispatcher::MapVaryingBuffer()
{
if (_cudaVaryingResource) {
size_t num_bytes;
if (bVarying) {
cudaGraphicsGLRegisterBuffer(&_cudaVaryingResource, bVarying->GetGpuBuffer(), cudaGraphicsMapFlagsWriteDiscard);
cudaGraphicsMapResources(1, &_cudaVaryingResource, 0);
cudaGraphicsResourceGetMappedPointer((void **)&_deviceVaryings, &num_bytes, _cudaVaryingResource);
}
}
void
OsdCudaKernelDispatcher::UnmapVertexBuffer() {
OsdCudaKernelDispatcher::UnbindVertexBuffer()
{
if (_cudaVertexResource)
cudaGraphicsUnmapResources(1, &_cudaVertexResource, 0);
}
void
OsdCudaKernelDispatcher::UnmapVaryingBuffer() {
if (_cudaVaryingResource)
cudaGraphicsUnmapResources(1, &_cudaVaryingResource, 0);
cudaGraphicsUnmapResources(1, &_cudaVertexResource, 0);
_cudaVertexResource = NULL;
_cudaVaryingResource = NULL;
}
void

View File

@ -74,7 +74,7 @@ struct DeviceVertex;
class OsdCudaKernelDispatcher : public OsdKernelDispatcher
{
public:
OsdCudaKernelDispatcher(int levels, int numVertexElements, int numVaryingElements);
OsdCudaKernelDispatcher(int levels);
virtual ~OsdCudaKernelDispatcher();
@ -101,25 +101,16 @@ public:
virtual void EndLaunchKernel();
virtual OsdVertexBuffer *InitializeVertexBuffer(int numElements, int count);
virtual void BindVertexBuffer(GLuint vertexBuffer, GLuint varyingBuffer);
virtual void BindVertexBuffer(OsdVertexBuffer *vertex, OsdVertexBuffer *varying);
virtual void UpdateVertexBuffer(size_t size, void *ptr);
virtual void UpdateVaryingBuffer(size_t size, void *ptr);
virtual void MapVertexBuffer();
virtual void MapVaryingBuffer();
virtual void UnmapVertexBuffer();
virtual void UnmapVaryingBuffer();
virtual void UnbindVertexBuffer();
virtual void Synchronize();
static OsdKernelDispatcher * Create(int levels, int numVertexElements, int numVaryingElements){
return new OsdCudaKernelDispatcher(levels, numVertexElements, numVaryingElements);
static OsdKernelDispatcher * Create(int levels) {
return new OsdCudaKernelDispatcher(levels);
}
static void Register() {
Factory::GetInstance().Register("cuda", Create);

View File

@ -88,12 +88,9 @@ static const char *shaderDefines = ""
#endif
;
OsdGlslKernelDispatcher::OsdGlslKernelDispatcher(int levels, int numVertexElements, int numVaryingElements)
: OsdKernelDispatcher(levels),
_numVertexElements(numVertexElements),
_numVarying(numVaryingElements)
OsdGlslKernelDispatcher::OsdGlslKernelDispatcher(int levels)
: OsdKernelDispatcher(levels)
{
_numVarying = 0; // XXX
_vertexBuffer = 0;
_varyingBuffer = 0;
_prgKernel = 0;
@ -211,26 +208,36 @@ OsdGlslKernelDispatcher::EndLaunchKernel() {
glDisable(GL_RASTERIZER_DISCARD);
glUseProgram(0);
// XXX Unbind table buffer
}
OsdVertexBuffer *
OsdGlslKernelDispatcher::InitializeVertexBuffer(int numElements, int count)
{
return new OsdGpuVertexBuffer(numElements, count);
}
void
OsdGlslKernelDispatcher::BindVertexBuffer(GLuint vertexBuffer, GLuint varyingBuffer) {
OsdGlslKernelDispatcher::BindVertexBuffer(OsdVertexBuffer *vertex, OsdVertexBuffer *varying) {
glUseProgram(_prgKernel);
OsdGpuVertexBuffer *bVertex = dynamic_cast<OsdGpuVertexBuffer *>(vertex);
OsdGpuVertexBuffer *bVarying = dynamic_cast<OsdGpuVertexBuffer *>(varying);
CHECK_GL_ERROR("BindVertexBufferA, glUniform %d\n", _vertexUniform);
glUniform1i(_vertexUniform, 0);
CHECK_GL_ERROR("BindVertexBufferB, glUniform %d\n", _vertexUniform);
bindTextureBuffer(_vertexUniform, vertexBuffer, _vertexTexture, GL_RGB32F, 0);
_vertexBuffer = vertexBuffer;
if (varyingBuffer) {
bindTextureBuffer(_varyingUniform, varyingBuffer, _varyingTexture, GL_R32F, 0);
_varyingBuffer = varyingBuffer;
if (bVertex) {
_vertexBuffer = bVertex->GetGpuBuffer();
bindTextureBuffer(_vertexUniform, _vertexBuffer, _vertexTexture, GL_RGB32F, 0);
}
#if 0
if (bVarying) {
_varyingBuffer = bVarying->GetGpuBuffer();
bindTextureBuffer(_varyingUniform, _varyingBuffer, _varyingTexture, GL_R32F, 0);
}
glUseProgram(_prgKernel);
glUniform1i(_vertexUniform, 0);
#if 0 // experiment to use image store function
glActiveTexture(GL_TEXTURE0 + 0);
glBindImageTextureEXT(0, _vertexTexture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
@ -243,41 +250,10 @@ OsdGlslKernelDispatcher::BindVertexBuffer(GLuint vertexBuffer, GLuint varyingBuf
}
void
OsdGlslKernelDispatcher::UpdateVertexBuffer(size_t size, void *ptr) {
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
float * pointer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
memcpy(pointer, ptr, size);
glUnmapBuffer(GL_ARRAY_BUFFER);
OsdGlslKernelDispatcher::UnbindVertexBuffer()
{
}
void
OsdGlslKernelDispatcher::UpdateVaryingBuffer(size_t size, void *ptr) {
if (_varyingBuffer) {
glBindBuffer(GL_ARRAY_BUFFER, _varyingBuffer);
float * pointer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
memcpy(pointer, ptr, size);
glUnmapBuffer(GL_ARRAY_BUFFER);
}
}
void
OsdGlslKernelDispatcher::MapVertexBuffer() {
}
void
OsdGlslKernelDispatcher::MapVaryingBuffer() {
}
void
OsdGlslKernelDispatcher::UnmapVertexBuffer() {
// UnbindTableBuffer();
}
void
OsdGlslKernelDispatcher::UnmapVaryingBuffer() {
}
void
OsdGlslKernelDispatcher::Synchronize() {

View File

@ -65,7 +65,7 @@ namespace OPENSUBDIV_VERSION {
class OsdGlslKernelDispatcher : public OsdKernelDispatcher {
public:
OsdGlslKernelDispatcher(int levels, int numVertexElements, int numVaryingElements);
OsdGlslKernelDispatcher(int levels);
virtual ~OsdGlslKernelDispatcher();
@ -92,24 +92,16 @@ public:
virtual void EndLaunchKernel();
virtual void BindVertexBuffer(GLuint vertexBuffer, GLuint varyingBuffer);
virtual OsdVertexBuffer *InitializeVertexBuffer(int numElements, int count);
virtual void UpdateVertexBuffer(size_t size, void *ptr);
virtual void BindVertexBuffer(OsdVertexBuffer *vertex, OsdVertexBuffer *varying);
virtual void UpdateVaryingBuffer(size_t size, void *ptr);
virtual void MapVertexBuffer();
virtual void MapVaryingBuffer();
virtual void UnmapVertexBuffer();
virtual void UnmapVaryingBuffer();
virtual void UnbindVertexBuffer();
virtual void Synchronize();
static OsdKernelDispatcher * Create(int levels, int numVertexElements, int numVaryingElements){
return new OsdGlslKernelDispatcher(levels, numVertexElements, numVaryingElements);
static OsdKernelDispatcher * Create(int levels) {
return new OsdGlslKernelDispatcher(levels);
}
static void Register() {
Factory::GetInstance().Register("glsl", Create);

View File

@ -58,6 +58,7 @@
#define OSD_KERNEL_DISPATCHER_H
#include "vertex.h"
#include "vertexBuffer.h"
#include "../far/dispatcher.h"
@ -84,20 +85,11 @@ public:
virtual void EndLaunchKernel() = 0;
virtual OsdVertexBuffer *InitializeVertexBuffer(int numElements, int count) = 0;
virtual void BindVertexBuffer(GLuint vertexBuffer, GLuint varyingBuffer) = 0;
virtual void BindVertexBuffer(OsdVertexBuffer *vertex, OsdVertexBuffer *varying) = 0;
virtual void UpdateVertexBuffer(size_t size, void *ptr) = 0;
virtual void UpdateVaryingBuffer(size_t size, void *ptr) = 0;
virtual void MapVertexBuffer() = 0;
virtual void MapVaryingBuffer() = 0;
virtual void UnmapVertexBuffer() = 0;
virtual void UnmapVaryingBuffer() = 0;
virtual void UnbindVertexBuffer() = 0;
virtual void Synchronize() = 0;
@ -110,9 +102,9 @@ public:
_tableOffsets[tableIndex][i] = table[i] - table[0];
}
static OsdKernelDispatcher *CreateKernelDispatcher( const std::string &kernel, int levels, int numVertexElements, int numVaryingElements ) {
static OsdKernelDispatcher *CreateKernelDispatcher( const std::string &kernel, int levels ) {
return Factory::GetInstance().Create( kernel, levels, numVertexElements, numVaryingElements );
return Factory::GetInstance().Create( kernel, levels );
}
enum { E_IT,
@ -129,7 +121,7 @@ protected:
class Factory {
public:
typedef OsdKernelDispatcher *(*Creator)( int levels, int numVertexElements, int numVaryingElements );
typedef OsdKernelDispatcher *(*Creator)( int levels );
typedef std::map<const std::string, Creator> CreatorMap;
bool Register(const std::string &kernel, Creator creator) {
@ -140,10 +132,10 @@ protected:
return _creators.erase(kernel) == 1;
}
OsdKernelDispatcher *Create ( const std::string &kernel, int levels, int numVertexElements, int numVaryingElements ) {
OsdKernelDispatcher *Create ( const std::string &kernel, int levels ) {
CreatorMap::const_iterator it = _creators.find(kernel);
if (it != _creators.end())
return (it->second)(levels, numVertexElements, numVaryingElements);
return (it->second)(levels);
return NULL;
}

View File

@ -67,11 +67,9 @@
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
OsdMesh::OsdMesh(int numVertexElements, int numVaryingElements)
: _numVertexElements(numVertexElements), _numVaryingElements(numVaryingElements), _mMesh(NULL), _dispatcher(NULL) {
OsdMesh::OsdMesh()
: _mMesh(NULL), _dispatcher(NULL) {
glGenBuffers(1, &_vertexBuffer);
glGenBuffers(1, &_varyingBuffer);
}
OsdMesh::~OsdMesh() {
@ -79,8 +77,6 @@ OsdMesh::~OsdMesh() {
if(_dispatcher) delete _dispatcher;
if(_mMesh) delete _mMesh;
glDeleteBuffers(1, &_vertexBuffer);
glDeleteBuffers(1, &_varyingBuffer);
}
bool
@ -88,7 +84,7 @@ OsdMesh::Create(OsdHbrMesh *hbrMesh, int level, const std::string &kernel) {
if (_dispatcher)
delete _dispatcher;
_dispatcher = OsdKernelDispatcher::CreateKernelDispatcher(kernel, level, _numVertexElements, _numVaryingElements);
_dispatcher = OsdKernelDispatcher::CreateKernelDispatcher(kernel, level);
if(_dispatcher == NULL){
OSD_ERROR("Unknown kernel %s\n", kernel.c_str());
return false;
@ -128,81 +124,28 @@ OsdMesh::Create(OsdHbrMesh *hbrMesh, int level, const std::string &kernel) {
CHECK_GL_ERROR("Mesh, update tables\n");
// vbo prep
int vertexSize = _mMesh->GetNumVertices() * _numVertexElements * sizeof(float);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertexSize, 0, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERROR("Mesh, vertex buffer %d\n", _vertexBuffer);
int varyingSize = _mMesh->GetNumVertices() * _numVaryingElements * sizeof(float);
glBindBuffer(GL_ARRAY_BUFFER, _varyingBuffer);
glBufferData(GL_ARRAY_BUFFER, varyingSize, 0, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERROR("Mesh, varying buffer %d\n", _varyingBuffer);
_dispatcher->BindVertexBuffer(_vertexBuffer, varyingSize ? _varyingBuffer : 0);
return true;
}
void
OsdMesh::UpdatePoints(const std::vector<float> &points) {
int numCoarseVertices = _mMesh->GetNumCoarseVertices();
if(numCoarseVertices * _numVertexElements != points.size()) {
OSD_ERROR("UpdatePoints points size mismatch %d != %d\n", numCoarseVertices, (int)points.size());
return;
}
float * updateVertexBuffer = new float[GetNumCoarseVertices() * _numVertexElements];
float *p = updateVertexBuffer;
for (int i = 0; i < numCoarseVertices; ++i)
for (int j = 0; j < _numVertexElements; ++j)
*p++ = points[i*_numVertexElements+j];
// send to gpu
_dispatcher->MapVertexBuffer();
// copy _updateVertexBuffer to each kernel's local memory
int size = numCoarseVertices * _numVertexElements * sizeof(float);
_dispatcher->UpdateVertexBuffer(size, updateVertexBuffer);
_dispatcher->UnmapVertexBuffer();
delete[] updateVertexBuffer;
OsdVertexBuffer *
OsdMesh::InitializeVertexBuffer(int numElements)
{
if (!_dispatcher) return NULL;
return _dispatcher->InitializeVertexBuffer(numElements, GetTotalVertices());
}
void
OsdMesh::UpdateVaryings(const std::vector<float> &varyings) {
OsdMesh::Subdivide(OsdVertexBuffer *vertex, OsdVertexBuffer *varying) {
int numCoarseVertices = _mMesh->GetNumCoarseVertices();
if (numCoarseVertices * _numVaryingElements != varyings.size()) {
OSD_ERROR("UpdateVaryings array size mismatch %d != %d\n", numCoarseVertices, (int)varyings.size());
return;
}
_dispatcher->BindVertexBuffer(vertex, varying);
// send to gpu
_dispatcher->MapVaryingBuffer();
int size = numCoarseVertices * _numVaryingElements * sizeof(float);
_dispatcher->UpdateVaryingBuffer(size, (void*)&varyings[0]);
_dispatcher->UnmapVaryingBuffer();
}
void
OsdMesh::Subdivide() {
_dispatcher->MapVertexBuffer();
_dispatcher->MapVaryingBuffer();
_dispatcher->BeginLaunchKernel();
_mMesh->Subdivide(_level+1);
_dispatcher->EndLaunchKernel();
_dispatcher->UnmapVertexBuffer();
_dispatcher->UnmapVaryingBuffer();
_dispatcher->UnbindVertexBuffer();
}
void
@ -211,33 +154,6 @@ OsdMesh::Synchronize() {
_dispatcher->Synchronize();
}
void
OsdMesh::GetRefinedPoints(std::vector<float> &refinedPoints) {
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
int size = 0;
glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
int numTotalVertices = _mMesh->GetNumVertices();
if (size != numTotalVertices*_numVertexElements*sizeof(float)) {
OSD_ERROR("vertex count mismatch %d != %d\n", (int)(size/_numVertexElements/sizeof(float)), numTotalVertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return;
}
refinedPoints.resize(numTotalVertices*_numVertexElements);
float *p = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
if (p)
for (int i = 0; i < numTotalVertices; ++i)
for (int j = 0; j < _numVertexElements; ++j)
refinedPoints[i*_numVertexElements+j] = *p++;
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -61,7 +61,8 @@
#include <vector>
#include <GL/glew.h>
#include "../osd/vertex.h"
#include "vertex.h"
#include "vertexBuffer.h"
#include "../far/mesh.h"
#include "../hbr/mesh.h"
@ -82,37 +83,21 @@ typedef HbrFace<OsdVertex> OsdHbrFace;
class OsdMesh {
public:
OsdMesh(int numVertexElements, int numVaryingElements);
OsdMesh();
virtual ~OsdMesh();
bool Create(OsdHbrMesh *hbrMesh, int level, const std::string &kernel);
void UpdatePoints(const std::vector<float> &points);
void GetRefinedPoints(std::vector<float> &refinedPoints);
void UpdateVaryings(const std::vector<float> &varyings);
void GetRefinedVaryings(std::vector<float> &refinedVaryings);
FarMesh<OsdVertex> *GetFarMesh() { return _mMesh; }
OsdVertexBuffer *InitializeVertexBuffer(int numElements);
void Subdivide();
void Subdivide(OsdVertexBuffer *vertex, OsdVertexBuffer *varying);
void Synchronize();
int GetNumVertexElements() const { return _numVertexElements; }
int GetNumVaryingElements() const { return _numVaryingElements; }
GLuint GetVertexBuffer() const { return _vertexBuffer; }
GLuint GetVaryingBuffer() const { return _varyingBuffer; }
int GetTotalVertices() const { return _mMesh->GetNumVertices(); }
int GetNumCoarseVertices() const { return _mMesh->GetNumCoarseVertices(); }
@ -121,11 +106,7 @@ protected:
FarMesh<OsdVertex> *_mMesh;
int _numVertexElements,
_numVaryingElements,
_level;
GLuint _vertexBuffer, _varyingBuffer;
int _level;
OsdKernelDispatcher * _dispatcher;
};

View File

@ -0,0 +1,83 @@
#ifndef OSD_VERTEX_BUFFER_H
#define OSD_VERTEX_BUFFER_H
#include <GL/glew.h>
#include <string.h> // memcpy (tobe moved to cpp)
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
class OsdVertexBuffer {
public:
virtual ~OsdVertexBuffer() {}
virtual void UpdateData(const float *src, int count) = 0;
virtual GLuint GetGpuBuffer() = 0;
};
class OsdGpuVertexBuffer : public OsdVertexBuffer {
public:
OsdGpuVertexBuffer(int numElements, int count) : _vbo(0), _numElements(numElements) {
int stride = numElements * count * sizeof(float);
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, stride, 0, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
virtual ~OsdGpuVertexBuffer() {
glDeleteBuffers(1, &_vbo);
}
virtual void UpdateData(const float *src, int count) {
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
float * pointer = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
memcpy(pointer, src, _numElements * count * sizeof(float));
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
virtual GLuint GetGpuBuffer() {
return _vbo;
}
private:
GLuint _vbo;
int _numElements;
};
class OsdCpuVertexBuffer : public OsdVertexBuffer {
public:
OsdCpuVertexBuffer(int numElements, int count) : _cpuVbo(NULL), _vboSize(0), _numElements(numElements), _vbo(0) {
_cpuVbo = new float[numElements * count];
_vboSize = numElements * count;
}
virtual ~OsdCpuVertexBuffer() {
if(_cpuVbo) delete[] _cpuVbo;
if(_vbo) glDeleteBuffers(1, &_vbo);
}
virtual void UpdateData(const float *src, int count) {
memcpy(_cpuVbo, src, _numElements * count * sizeof(float));
}
float *GetCpuBuffer() {
return _cpuVbo;
}
virtual GLuint GetGpuBuffer() {
if(!_vbo) glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, _vboSize * sizeof(float), _cpuVbo, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return _vbo;
}
int GetNumElements() const {
return _numElements;
}
private:
float *_cpuVbo;
int _vboSize;
int _numElements;
GLuint _vbo;
};
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OSD_VERTEX_BUFFER_H