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

View File

@ -54,6 +54,44 @@ struct SGVertNormTex {
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> {
public:
@ -124,8 +162,7 @@ public:
const unsigned invalid = ~unsigned(0);
std::vector<unsigned> indexMap(getNumVertices(), invalid);
osg::DrawElementsUInt* drawElements;
drawElements = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
DrawElementsFacade deFacade(vertices->size());
for (index_type i = 0; i < triangles.size(); ++i) {
triangle_ref triangle = triangles[i];
if (indexMap[triangle[0]] == invalid) {
@ -134,7 +171,7 @@ public:
normals->push_back(getVertex(triangle[0]).normal.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) {
indexMap[triangle[1]] = vertices->size();
@ -142,7 +179,7 @@ public:
normals->push_back(getVertex(triangle[1]).normal.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) {
indexMap[triangle[2]] = vertices->size();
@ -150,9 +187,9 @@ public:
normals->push_back(getVertex(triangle[2]).normal.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;
}

View File

@ -360,7 +360,12 @@ struct SGTileGeometryBin {
osg::Geode* geode = new osg::Geode;
SGMaterialTriangleMap::const_iterator 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
SGMaterial *mat = matlib->find(i->first);