Optimising the way mesh data is sent to the GPU.

This commit is contained in:
David Williams 2007-09-30 23:39:48 +00:00
parent d0386f8853
commit 909d020bff
2 changed files with 41 additions and 55 deletions

View File

@ -10,6 +10,9 @@
namespace Ogre namespace Ogre
{ {
//IDEA - If profiling identifies this class as a bottleneck, we could implement a memory pooling system.
//All buffers could be powers of two, and we get the smallest one which is big enough for our needs.
//See http://www.ogre3d.org/wiki/index.php/DynamicGrowingBuffers
class SurfacePatchRenderable : public SimpleRenderable class SurfacePatchRenderable : public SimpleRenderable
{ {
public: public:

View File

@ -7,8 +7,25 @@ namespace Ogre
{ {
SurfacePatchRenderable::SurfacePatchRenderable(SurfacePatch& patchToRender, const String& material) SurfacePatchRenderable::SurfacePatchRenderable(SurfacePatch& patchToRender, const String& material)
{ {
//Set up what we can of the vertex data
mRenderOp.vertexData = new VertexData(); mRenderOp.vertexData = new VertexData();
mRenderOp.vertexData->vertexStart = 0;
mRenderOp.vertexData->vertexCount = 0;
mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
//Set up what we can of the index data
mRenderOp.indexData = new IndexData(); mRenderOp.indexData = new IndexData();
mRenderOp.useIndexes = true;
mRenderOp.indexData->indexStart = 0;
mRenderOp.indexData->indexCount = 0;
//Set up the vertex declaration
VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
decl->removeAllElements();
decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
decl->addElement(0, 3 * sizeof(float), VET_FLOAT3, VES_NORMAL);
decl->addElement(0, 6 * sizeof(float), VET_FLOAT1, VES_TEXTURE_COORDINATES);
this->setMaterial(material); this->setMaterial(material);
@ -28,35 +45,23 @@ namespace Ogre
void SurfacePatchRenderable::setGeometry(SurfacePatch& patchToRender) void SurfacePatchRenderable::setGeometry(SurfacePatch& patchToRender)
{ {
//LogManager::getSingleton().logMessage("In setGeometry()");
//Initialization stuff //Initialization stuff
mRenderOp.vertexData->vertexCount = patchToRender.getNoOfVertices(); mRenderOp.vertexData->vertexCount = patchToRender.getNoOfVertices();
mRenderOp.vertexData->vertexStart = 0;
mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; // OT_LINE_LIST, OT_LINE_STRIP
mRenderOp.useIndexes = true;
mRenderOp.indexData->indexStart = 0;
mRenderOp.indexData->indexCount = patchToRender.getNoOfTriangles() * 3; mRenderOp.indexData->indexCount = patchToRender.getNoOfTriangles() * 3;
//LogManager::getSingleton().logMessage("Finished initialisaing stuff");
VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding; VertexBufferBinding *bind = mRenderOp.vertexData->vertexBufferBinding;
//FIXME - this should be moved to constructor?
//LogManager::getSingleton().logMessage("Creating Vertex Declaration");
decl->removeAllElements();
decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
decl->addElement(0, 3 * sizeof(float), VET_FLOAT3, VES_NORMAL);
decl->addElement(0, 6 * sizeof(float), VET_FLOAT1, VES_TEXTURE_COORDINATES);
//LogManager::getSingleton().logMessage("Creating Vertex Buffer"); //LogManager::getSingleton().logMessage("Creating Vertex Buffer");
HardwareVertexBufferSharedPtr vbuf = HardwareVertexBufferSharedPtr vbuf =
HardwareBufferManager::getSingleton().createVertexBuffer( HardwareBufferManager::getSingleton().createVertexBuffer(
decl->getVertexSize(0), mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
mRenderOp.vertexData->vertexCount, mRenderOp.vertexData->vertexCount,
HardwareBuffer::HBU_STATIC_WRITE_ONLY); HardwareBuffer::HBU_STATIC_WRITE_ONLY,
false);
bind->setBinding(0, vbuf); bind->setBinding(0, vbuf);
@ -70,18 +75,14 @@ namespace Ogre
mRenderOp.indexData->indexBuffer = ibuf; mRenderOp.indexData->indexBuffer = ibuf;
// Drawing stuff std::vector<SurfaceVertex> vertexData;
//int size = verticesToSet.size(); vertexData.resize(patchToRender.getNoOfVertices());
Vector3 vaabMin; std::copy(patchToRender.getVerticesBegin(), patchToRender.getVerticesEnd(), vertexData.begin());
Vector3 vaabMax;
vaabMin.x = patchToRender.getVerticesBegin()->getPosition().x/2.0f; // Drawing stuff
vaabMin.y = patchToRender.getVerticesBegin()->getPosition().y/2.0f; Vector3 vaabMin = vertexData[0].getPosition().toOgreVector3();
vaabMin.z = patchToRender.getVerticesBegin()->getPosition().z/2.0f; Vector3 vaabMax = vertexData[vertexData.size()-1].getPosition().toOgreVector3();
vaabMax.x = patchToRender.getVerticesBegin()->getPosition().x/2.0f;
vaabMax.y = patchToRender.getVerticesBegin()->getPosition().y/2.0f;
vaabMax.z = patchToRender.getVerticesBegin()->getPosition().z/2.0f;
//LogManager::getSingleton().logMessage("Setting Vertex Data of size " + StringConverter::toString(size));
Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
@ -97,20 +98,6 @@ namespace Ogre
*prPos++ = vertexIter->getNormal().z; *prPos++ = vertexIter->getNormal().z;
*prPos++ = vertexIter->getAlpha(); *prPos++ = vertexIter->getAlpha();
if(vertexIter->getPosition().x < vaabMin.x)
vaabMin.x = vertexIter->getPosition().x;
if(vertexIter->getPosition().y < vaabMin.y)
vaabMin.y = vertexIter->getPosition().y;
if(vertexIter->getPosition().z < vaabMin.z)
vaabMin.z = vertexIter->getPosition().z;
if(vertexIter->getPosition().x > vaabMax.x)
vaabMax.x = vertexIter->getPosition().x;
if(vertexIter->getPosition().y > vaabMax.y)
vaabMax.y = vertexIter->getPosition().y;
if(vertexIter->getPosition().z > vaabMax.z)
vaabMax.z = vertexIter->getPosition().z;
} }
vbuf->unlock(); vbuf->unlock();
@ -132,29 +119,25 @@ namespace Ogre
pIdx++; pIdx++;
}*/ }*/
std::vector<SurfaceVertex> vertexData;
vertexData.resize(patchToRender.getNoOfVertices());
std::copy(patchToRender.getVerticesBegin(), patchToRender.getVerticesEnd(), vertexData.begin());
for(SurfaceTriangleConstIterator iterTriangles = patchToRender.getTrianglesBegin(); iterTriangles != patchToRender.getTrianglesEnd(); ++iterTriangles) for(SurfaceTriangleConstIterator iterTriangles = patchToRender.getTrianglesBegin(); iterTriangles != patchToRender.getTrianglesEnd(); ++iterTriangles)
{ {
std::vector<SurfaceVertex>::iterator iterVertex; std::vector<SurfaceVertex>::iterator iterVertex;
SurfaceEdgeIterator edgeIter; SurfaceEdgeIterator edgeIter;
edgeIter = iterTriangles->getEdge(); edgeIter = iterTriangles->getEdge();
iterVertex = find(vertexData.begin(), vertexData.end(), *(edgeIter->getTarget())); iterVertex = lower_bound(vertexData.begin(), vertexData.end(), *(edgeIter->getTarget()));
*pIdx = (iterVertex - vertexData.begin()); *pIdx = (iterVertex - vertexData.begin());
//LogManager::getSingleton().logMessage("Wrong pIdx = " + StringConverter::toString(*pIdx)); //LogManager::getSingleton().logMessage("Wrong pIdx = " + StringConverter::toString(*pIdx));
pIdx++; pIdx++;
edgeIter = edgeIter->getNextHalfEdge(); edgeIter = edgeIter->getNextHalfEdge();
iterVertex = find(vertexData.begin(), vertexData.end(), *(edgeIter->getTarget())); iterVertex = lower_bound(vertexData.begin(), vertexData.end(), *(edgeIter->getTarget()));
*pIdx = (iterVertex - vertexData.begin()); *pIdx = (iterVertex - vertexData.begin());
//LogManager::getSingleton().logMessage("Wrong pIdx = " + StringConverter::toString(*pIdx)); //LogManager::getSingleton().logMessage("Wrong pIdx = " + StringConverter::toString(*pIdx));
pIdx++; pIdx++;
edgeIter = edgeIter->getNextHalfEdge(); edgeIter = edgeIter->getNextHalfEdge();
iterVertex = find(vertexData.begin(), vertexData.end(), *(edgeIter->getTarget())); iterVertex = lower_bound(vertexData.begin(), vertexData.end(), *(edgeIter->getTarget()));
*pIdx = (iterVertex - vertexData.begin()); *pIdx = (iterVertex - vertexData.begin());
//LogManager::getSingleton().logMessage("Wrong pIdx = " + StringConverter::toString(*pIdx)); //LogManager::getSingleton().logMessage("Wrong pIdx = " + StringConverter::toString(*pIdx));
pIdx++; pIdx++;