Use vector of primitives instead of associative map

This commit is contained in:
matsukaze 2014-02-08 19:49:27 -05:00
parent 18e219b5c0
commit 00e0ea9b0c
2 changed files with 75 additions and 51 deletions

View file

@ -360,7 +360,7 @@ void PrimitiveRenderer::initializeGL() {
glGenBuffers(1, &_vertexBufferId); glGenBuffers(1, &_vertexBufferId);
// Set up the element array buffer containing the index ids // Set up the element array buffer containing the index ids
_maxTriElementCount = _maxCount * 3 * 2; _maxTriElementCount = _maxCount * _sIndicesPerTri * 2;
int size = _maxTriElementCount * sizeof(GLint); int size = _maxTriElementCount * sizeof(GLint);
_gpuMemoryUsage += size; _gpuMemoryUsage += size;
@ -379,25 +379,27 @@ void PrimitiveRenderer::initializeGL() {
glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
// Initialize the first vertex element in the buffer to all zeros, the // Reserve the the first element for the degenerate case
// degenerate case
_vertexElementCount = 1; _vertexElementCount = 1;
_triElementCount = 1; _triElementCount = 1;
VertexElement v; // Initialize the first tri element in the buffer to all zeros, the
memset(&v, 0, sizeof(v)); // degenerate case
transferVertexElement(0, &v);
deconstructTriElement(0); deconstructTriElement(0);
// Initialize the first vertex element in the buffer to all zeros, the
// degenerate case
deconstructVertexElement(0);
GLint err = glGetError(); GLint err = glGetError();
} }
void PrimitiveRenderer::initializeBookkeeping() { void PrimitiveRenderer::initializeBookkeeping() {
// Start primitive count at one, because zero is reserved for the degenerate triangle // Start primitive count at one, because zero is reserved for the degenerate triangle
_primitives.resize(_maxCount + 1);
_primitiveCount = 1; _primitiveCount = 1;
_cpuMemoryUsage = sizeof(PrimitiveRenderer); _cpuMemoryUsage = sizeof(PrimitiveRenderer) + _primitives.size() * sizeof(Primitive *);
} }
void PrimitiveRenderer::terminate() { void PrimitiveRenderer::terminate() {
@ -415,6 +417,14 @@ void PrimitiveRenderer::terminateGL() {
void PrimitiveRenderer::terminateBookkeeping() { void PrimitiveRenderer::terminateBookkeeping() {
for (int i = _primitiveCount + 1; --i > 0; ) {
Primitive* primitive = _primitives[i];
if (primitive) {
_cpuMemoryUsage -= primitive->getMemoryUsage();
_primitives[i] = 0;
delete primitive;
}
}
// Drain all of the queues, stop updating the counters // Drain all of the queues, stop updating the counters
while (_availableVertexElementIndex.remove() != 0) while (_availableVertexElementIndex.remove() != 0)
; ;
@ -425,22 +435,10 @@ void PrimitiveRenderer::terminateBookkeeping() {
while (_deconstructTriElementIndex.remove() != 0) while (_deconstructTriElementIndex.remove() != 0)
; ;
_vertexElementCount = 0; _vertexElementCount = 1;
_triElementCount = 0; _triElementCount = 1;
_primitiveCount = 1;
QMap<int, Primitive *>::iterator it = _indexToPrimitiveMap.begin();
QMap<int, Primitive *>::iterator end = _indexToPrimitiveMap.end();
for ( ; it != end; ++it) {
Primitive* primitive = it.value();
if (primitive) {
_cpuMemoryUsage -= primitive->getMemoryUsage();
delete primitive;
}
}
_cpuMemoryUsage -= _indexToPrimitiveMap.size() * sizeof(Primitive*);
_indexToPrimitiveMap.clear();
} }
void PrimitiveRenderer::constructElements( void PrimitiveRenderer::constructElements(
@ -460,6 +458,8 @@ void PrimitiveRenderer::constructElements(
vertexElementIndexList.push_back(index); vertexElementIndexList.push_back(index);
VertexElement* vertex = *it; VertexElement* vertex = *it;
transferVertexElement(index, vertex); transferVertexElement(index, vertex);
} else {
break;
} }
} }
} }
@ -486,6 +486,8 @@ void PrimitiveRenderer::constructElements(
tri->id = index; tri->id = index;
transferTriElement(index, tri->indices); transferTriElement(index, tri->indices);
} else {
break;
} }
} }
} else { } else {
@ -510,6 +512,7 @@ void PrimitiveRenderer::deconstructElements(
_deconstructTriElementIndex.add(tri->id); _deconstructTriElementIndex.add(tri->id);
} }
} }
// Return the vertex element index to the available queue, it is not necessary // Return the vertex element index to the available queue, it is not necessary
// to zero the data // to zero the data
{ {
@ -525,7 +528,6 @@ void PrimitiveRenderer::deconstructElements(
} }
} }
// destroy primitive
delete primitive; delete primitive;
} }
@ -533,11 +535,13 @@ int PrimitiveRenderer::getAvailablePrimitiveIndex() {
// Check the available primitive index queue first for an available index. // Check the available primitive index queue first for an available index.
int index = _availablePrimitiveIndex.remove(); int index = _availablePrimitiveIndex.remove();
// Remember that the primitive index 0 is used not used. // Remember that the primitive index 0 is not used.
if (index == 0) { if (index == 0) {
// There are no primitive indices available from the queue, // There are no primitive indices available from the queue,
// make one up // make one up
index = _primitiveCount++; if (_primitiveCount < _maxCount) {
index = _primitiveCount++;
}
} }
return index; return index;
} }
@ -581,12 +585,24 @@ void PrimitiveRenderer::deconstructTriElement(
int idx int idx
) { ) {
// Set the element to the degenerate case. // Set the tri element to the degenerate case.
int degenerate[3] = { 0, 0, 0 }; static int degenerate[3] = { 0, 0, 0 };
transferTriElement(idx, degenerate); transferTriElement(idx, degenerate);
} }
void PrimitiveRenderer::deconstructVertexElement(
int idx
) {
// Set the vertex element to the degenerate case.
VertexElement degenerate;
memset(&degenerate, 0, sizeof(degenerate));
transferVertexElement(idx, &degenerate);
}
void PrimitiveRenderer::transferVertexElement( void PrimitiveRenderer::transferVertexElement(
int idx, int idx,
VertexElement* vertex VertexElement* vertex
@ -603,7 +619,7 @@ void PrimitiveRenderer::transferTriElement(
) { ) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _triBufferId); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _triBufferId);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, idx * sizeof(GLint) * 3, sizeof(GLint) * 3, tri); glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, idx * _sBytesPerTriElement, _sBytesPerTriElement, tri);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }
@ -617,10 +633,9 @@ int PrimitiveRenderer::vAdd(
try { try {
// Take ownership of primitive, including responsibility // Take ownership of primitive, including responsibility
// for destruction // for destruction
_indexToPrimitiveMap[index] = primitive; _primitives[index] = primitive;
_constructPrimitiveIndex.add(index); _constructPrimitiveIndex.add(index);
_cpuMemoryUsage += primitive->getMemoryUsage(); _cpuMemoryUsage += primitive->getMemoryUsage();
_cpuMemoryUsage += sizeof(Primitive*);
} catch(...) { } catch(...) {
// STL failed, recycle the index // STL failed, recycle the index
_availablePrimitiveIndex.add(index); _availablePrimitiveIndex.add(index);
@ -638,8 +653,9 @@ void PrimitiveRenderer::vRemove(
QMutexLocker lock(&_guard); QMutexLocker lock(&_guard);
// Locate and remove the primitive by id in the associative map // Locate and remove the primitive by id in the associative map
Primitive* primitive = _indexToPrimitiveMap.take(index); Primitive* primitive = _primitives[index];
if (primitive) { if (primitive) {
_primitives[index] = 0;
_cpuMemoryUsage -= primitive->getMemoryUsage(); _cpuMemoryUsage -= primitive->getMemoryUsage();
deconstructElements(primitive); deconstructElements(primitive);
_availablePrimitiveIndex.add(index); _availablePrimitiveIndex.add(index);
@ -653,19 +669,6 @@ void PrimitiveRenderer::vRelease() {
QMutexLocker lock(&_guard); QMutexLocker lock(&_guard);
terminateBookkeeping(); terminateBookkeeping();
#if 0
QMap<int, Primitive *>::iterator it = _indexToPrimitiveMap.begin();
QMap<int, Primitive *>::iterator end = _indexToPrimitiveMap.end();
for ( ; it != end; ++it) {
Primitive* primitive = it->second;
if (primitive) {
it->second = 0;
deconstructElements(primitive);
_availablePrimitiveIndex.add(it->first);
}
}
#endif
} }
void PrimitiveRenderer::vRender() { void PrimitiveRenderer::vRender() {
@ -681,7 +684,7 @@ void PrimitiveRenderer::vRender() {
} }
while ((id = _constructPrimitiveIndex.remove()) != 0) { while ((id = _constructPrimitiveIndex.remove()) != 0) {
Primitive* primitive = _indexToPrimitiveMap[id]; Primitive* primitive = _primitives[id];
if (primitive) { if (primitive) {
constructElements(primitive); constructElements(primitive);
@ -692,10 +695,10 @@ void PrimitiveRenderer::vRender() {
} }
} }
// The application uses clockwise winding for the definition of front face, but I // The application uses clockwise winding for the definition of front face, this renderer
// arbitrarily chose counter-clockwise (that is the gl default) to construct the triangulation // aalso uses clockwise (that is the gl default) to construct the triangulation
// so... // so...
//glFrontFace(GL_CCW); //glFrontFace(GL_CW);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferId); glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferId);

View file

@ -48,8 +48,16 @@ typedef
} TriElement; } TriElement;
/// Vertex element list container.
///
typedef QVector<VertexElement *> VertexElementList; typedef QVector<VertexElement *> VertexElementList;
/// Vertex element index list container.
///
typedef QVector<int> VertexElementIndexList; typedef QVector<int> VertexElementIndexList;
/// Triangle element list container
///
typedef QVector<TriElement *> TriElementList; typedef QVector<TriElement *> TriElementList;
/// ///
@ -120,10 +128,14 @@ private:
virtual TriElementList& vTriElements() = 0; virtual TriElementList& vTriElements() = 0;
/// Release vertex elements. /// Release vertex elements.
/// Service implementer to provide private override for this method
/// in derived class
/// ///
virtual void vReleaseVertexElements() = 0; virtual void vReleaseVertexElements() = 0;
/// Get memory usage. /// Get memory usage.
/// Service implementer to provide private override for this method
/// in derived class
/// ///
virtual int vGetMemoryUsage() = 0; virtual int vGetMemoryUsage() = 0;
@ -132,7 +144,7 @@ private:
/// ///
/// @class Cube /// @class Cube
/// Class for accessing the vertex and tri elements of a cube /// Class for accessing the vertex and triangle elements of a cube
/// ///
class Cube: public Primitive { class Cube: public Primitive {
public: public:
@ -365,6 +377,12 @@ private:
int idx int idx
); );
/// Deconstruct the vertex element from the GL buffer.
///
void deconstructVertexElement(
int idx
);
/// Transfer the vertex element to the GL buffer. /// Transfer the vertex element to the GL buffer.
/// ///
void transferVertexElement( void transferVertexElement(
@ -445,7 +463,7 @@ private:
int _triElementCount; ///< Count of triangles int _triElementCount; ///< Count of triangles
int _maxTriElementCount; ///< Max count of triangles int _maxTriElementCount; ///< Max count of triangles
QMap<int, Primitive*> _indexToPrimitiveMap; ///< Associative map between index and primitive QVector<Primitive *> _primitives; ///< Vector of primitive
int _primitiveCount; ///< Count of primitives int _primitiveCount; ///< Count of primitives
Queue<int, SingleThreaded, SingleThreaded> _availablePrimitiveIndex; ///< Queue of primitive indices available Queue<int, SingleThreaded, SingleThreaded> _availablePrimitiveIndex; ///< Queue of primitive indices available
@ -461,6 +479,9 @@ private:
int _gpuMemoryUsage; int _gpuMemoryUsage;
int _cpuMemoryUsage; int _cpuMemoryUsage;
static const int _sIndicesPerTri = 3;
static const int _sBytesPerTriElement = sizeof(GLint) * _sIndicesPerTri;
}; };