Some scene graph optimizations

When loading terrain, use DrawElementsUShort where possible.

Don't chunk unconnected triangles in the terrain into seperate
Geometry sets; make the sets as big as possible.
This commit is contained in:
timoore
2007-11-18 23:30:34 +00:00
parent d4d4ed22a0
commit 49473845cf
2 changed files with 50 additions and 8 deletions
+43 -6
View File
@@ -54,6 +54,44 @@ struct SGVertNormTex {
SGVec2f texCoord; SGVec2f texCoord;
}; };
// Use a DrawElementsUShort if there are few enough vertices,
// otherwise fallback to DrawElementsUInt. Hide the differences
// between the two from the rest of the code.
//
// We don't bother with DrawElementsUByte because that is generally
// not an advantage on modern hardware.
class DrawElementsFacade {
public:
DrawElementsFacade(unsigned numVerts) :
_ushortElements(0), _uintElements(0)
{
if (numVerts > 65535)
_uintElements
= new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
else
_ushortElements
= new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES);
}
void push_back(unsigned val)
{
if (_uintElements)
_uintElements->push_back(val);
else
_ushortElements->push_back(val);
}
osg::DrawElements* getDrawElements()
{
if (_uintElements)
return _uintElements;
return _ushortElements;
}
protected:
osg::DrawElementsUShort* _ushortElements;
osg::DrawElementsUInt* _uintElements;
};
class SGTexturedTriangleBin : public SGTriangleBin<SGVertNormTex> { class SGTexturedTriangleBin : public SGTriangleBin<SGVertNormTex> {
public: public:
@@ -124,8 +162,7 @@ public:
const unsigned invalid = ~unsigned(0); const unsigned invalid = ~unsigned(0);
std::vector<unsigned> indexMap(getNumVertices(), invalid); std::vector<unsigned> indexMap(getNumVertices(), invalid);
osg::DrawElementsUInt* drawElements; DrawElementsFacade deFacade(vertices->size());
drawElements = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
for (index_type i = 0; i < triangles.size(); ++i) { for (index_type i = 0; i < triangles.size(); ++i) {
triangle_ref triangle = triangles[i]; triangle_ref triangle = triangles[i];
if (indexMap[triangle[0]] == invalid) { if (indexMap[triangle[0]] == invalid) {
@@ -134,7 +171,7 @@ public:
normals->push_back(getVertex(triangle[0]).normal.osg()); normals->push_back(getVertex(triangle[0]).normal.osg());
texCoords->push_back(getVertex(triangle[0]).texCoord.osg()); texCoords->push_back(getVertex(triangle[0]).texCoord.osg());
} }
drawElements->push_back(indexMap[triangle[0]]); deFacade.push_back(indexMap[triangle[0]]);
if (indexMap[triangle[1]] == invalid) { if (indexMap[triangle[1]] == invalid) {
indexMap[triangle[1]] = vertices->size(); indexMap[triangle[1]] = vertices->size();
@@ -142,7 +179,7 @@ public:
normals->push_back(getVertex(triangle[1]).normal.osg()); normals->push_back(getVertex(triangle[1]).normal.osg());
texCoords->push_back(getVertex(triangle[1]).texCoord.osg()); texCoords->push_back(getVertex(triangle[1]).texCoord.osg());
} }
drawElements->push_back(indexMap[triangle[1]]); deFacade.push_back(indexMap[triangle[1]]);
if (indexMap[triangle[2]] == invalid) { if (indexMap[triangle[2]] == invalid) {
indexMap[triangle[2]] = vertices->size(); indexMap[triangle[2]] = vertices->size();
@@ -150,9 +187,9 @@ public:
normals->push_back(getVertex(triangle[2]).normal.osg()); normals->push_back(getVertex(triangle[2]).normal.osg());
texCoords->push_back(getVertex(triangle[2]).texCoord.osg()); texCoords->push_back(getVertex(triangle[2]).texCoord.osg());
} }
drawElements->push_back(indexMap[triangle[2]]); deFacade.push_back(indexMap[triangle[2]]);
} }
geometry->addPrimitiveSet(drawElements); geometry->addPrimitiveSet(deFacade.getDrawElements());
return geometry; return geometry;
} }
+6 -1
View File
@@ -360,7 +360,12 @@ struct SGTileGeometryBin {
osg::Geode* geode = new osg::Geode; osg::Geode* geode = new osg::Geode;
SGMaterialTriangleMap::const_iterator i; SGMaterialTriangleMap::const_iterator i;
for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) { for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
#define CHUNCKED // CHUNCKED (sic) here splits up unconnected triangles parts of
// the mesh into different Geometry sets, presumably for better
// culling. I (timoore) believe it is more performant to build
// the biggest indexed sets possible at the expense of tight
// culling.
//#define CHUNCKED
#ifdef CHUNCKED #ifdef CHUNCKED
SGMaterial *mat = matlib->find(i->first); SGMaterial *mat = matlib->find(i->first);