split patch descriptor into two parts, far intrinsic properties and osd's.

more OsdGLDrawContext clean up.
This commit is contained in:
Takahito Tejima 2013-05-09 13:14:02 -07:00
parent ecced51814
commit 3eaf0362bd
8 changed files with 247 additions and 138 deletions

View File

@ -906,7 +906,7 @@ enum Effect {
kPoint = 6,
};
typedef std::pair<OpenSubdiv::FarPatchTables::Descriptor, Effect> EffectDesc;
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor, Effect> EffectDesc;
class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry<EffectDesc> {
@ -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();

View File

@ -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 {
@ -296,21 +292,6 @@ public:
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
///
/// NON_TRANSITION ( REGULAR
@ -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 <class T> friend class FarPatchTablesFactory;
Descriptor _desc; // type of patches in the array
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
ArrayRange _range; // index locators in the array
};
typedef std::vector<PatchArray> PatchArrayVector;
@ -579,10 +569,7 @@ 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
@ -590,10 +577,7 @@ 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

View File

@ -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()));
}
}
}

View File

@ -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<PatchArray> PatchArrayVector;
OsdDrawContext() : _isAdaptive(false) {}
virtual ~OsdDrawContext();
bool IsAdaptive() const { return _isAdaptive; }
FarPatchTables::PatchArrayVector patchArrays;
PatchArrayVector patchArrays;
protected:
void createPatchArrays(FarPatchTables const * patchTables, int numElements);

View File

@ -103,57 +103,52 @@ OsdGLDrawContext::SupportsAdaptiveTessellation()
}
bool
OsdGLDrawContext::allocate(FarMesh<OsdVertex> *farMesh,
GLuint vbo,
int numElements,
bool requireFVarData)
OsdGLDrawContext::allocateUniform(FarMesh<OsdVertex> *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<OsdVertex> *tables = farMesh->GetSubdivisionTables();
int level = tables->GetMaxLevel();
const std::vector<int> &indices = farMesh->GetFaceVertices(level-1);
// XXX: farmesh should have FarDensePatchTable for dense mesh indices.
// instead of GetFaceVertices().
const FarSubdivisionTables<OsdVertex> *tables = farMesh->GetSubdivisionTables();
int level = tables->GetMaxLevel();
const std::vector<int> &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<short> trisIndices;
trisIndices.reserve(numTrisIndices);
for (int i=0; i<numQuads; ++i) {
const int * quad = &indices[i*4];
trisIndices.push_back(short(quad[0]));
trisIndices.push_back(short(quad[1]));
trisIndices.push_back(short(quad[2]));
std::vector<short> trisIndices;
trisIndices.reserve(numTrisIndices);
for (int i=0; i<numQuads; ++i) {
const int * quad = &indices[i*4];
trisIndices.push_back(short(quad[0]));
trisIndices.push_back(short(quad[1]));
trisIndices.push_back(short(quad[2]));
trisIndices.push_back(short(quad[2]));
trisIndices.push_back(short(quad[3]));
trisIndices.push_back(short(quad[0]));
}
trisIndices.push_back(short(quad[2]));
trisIndices.push_back(short(quad[3]));
trisIndices.push_back(short(quad[0]));
}
// Allocate and fill triangles index buffer.
glGenBuffers(1, &patchTrianglesIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchTrianglesIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
numTrisIndices * sizeof(short), &(trisIndices[0]), GL_STATIC_DRAW);
// Allocate and fill triangles index buffer.
glGenBuffers(1, &patchTrianglesIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchTrianglesIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
numTrisIndices * sizeof(short), &(trisIndices[0]), GL_STATIC_DRAW);
#endif
/*
@ -166,47 +161,62 @@ OsdGLDrawContext::allocate(FarMesh<OsdVertex> *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<FarPtexCoord> &ptexCoordinates =
farMesh->GetPtexCoordinates(level-1);
int size = (int)ptexCoordinates.size() * sizeof(FarPtexCoord);
const std::vector<FarPtexCoord> &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, 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) {
#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);
const std::vector<float> &fvarData = farMesh->GetFVarData(level-1);
int size = (int)fvarData.size() * sizeof(float);
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);
glDeleteBuffers(1, &ptexCoordinateBuffer);
#endif
}
// 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);
return true;
}
bool
OsdGLDrawContext::allocate(FarMesh<OsdVertex> *farMesh,
GLuint vbo,
int numElements,
bool requireFVarData)
{
FarPatchTables const * patchTables = farMesh->GetPatchTables();
const std::vector<float> &fvarData = farMesh->GetFVarData(level-1);
int size = (int)fvarData.size() * sizeof(float);
if (not patchTables) {
// uniform patches
_isAdaptive = false;
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);
#endif
}
return true;
// 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<OsdVertex> *farMesh,
return true;
}
} // end namespace OPENSUBDIV_VERSION
} // end namespace OpenSubdiv

View File

@ -124,6 +124,10 @@ private:
bool allocate(FarMesh<OsdVertex> *farMesh,
GLuint vbo, int numElements,
bool requireFVarData);
bool allocateUniform(FarMesh<OsdVertex> *farMesh,
GLuint vbo, int numElements,
bool requireFVarData);
};
} // end namespace OPENSUBDIV_VERSION

View File

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

View File

@ -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 DESC_TYPE = FarPatchTables::Descriptor,
template <class DESC_TYPE = OsdDrawContext::PatchDescriptor,
class CONFIG_TYPE = OsdGLDrawConfig,
class SOURCE_CONFIG_TYPE = OsdGLDrawSourceConfig >
class OsdGLDrawRegistry : public OsdGLDrawRegistryBase {