Don't expand all the trees into display lists.

This can chew up large amounts of memory for questionable gains. We do
let the tree model geometry be in a display list if OSG chooses to put
it there.

Various renaming and cleanup. Save some memory by reverting
ShaderGeometry's base class back to osg::Drawable.
This commit is contained in:
Tim Moore
2009-01-30 11:17:02 +01:00
parent 7151c3fac1
commit 3ff13189aa
2 changed files with 89 additions and 51 deletions
+80 -46
View File
@@ -34,72 +34,44 @@ namespace simgear
{ {
void ShaderGeometry::addTree(const TreeBin::Tree& t) void ShaderGeometry::addTree(const TreeBin::Tree& t)
{ {
if (!getVertexArray()) { if (!_posScaleArray.valid()) {
setVertexData(_geometry->getVertexData()); _posScaleArray = new Vec4Array();
setNormalData(_geometry->getNormalData()); _vertexAttribArray = new FloatArray();
setTexCoordData(0, _geometry->getTexCoordData(0));
setColorArray(new Vec4Array());
setColorBinding(Geometry::BIND_PER_PRIMITIVE_SET);
setVertexAttribArray(1, new FloatArray());
setVertexAttribBinding(1, Geometry::BIND_PER_PRIMITIVE_SET);
} }
Vec4Array *colors = static_cast<Vec4Array*>(getColorArray()); _posScaleArray->push_back(Vec4(t.position.osg(), t.scale));
FloatArray *vertexAttribs _vertexAttribArray->push_back((float)t.texture_index / varieties);
= static_cast<FloatArray*>(getVertexAttribArray(1));
colors->push_back(Vec4(t.position.osg(), t.scale));
vertexAttribs->push_back((float)t.texture_index / varieties);
dirtyDisplayList();
dirtyBound(); dirtyBound();
} }
// The good bits from osg::Geometry::drawImplementation
void ShaderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const void ShaderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
{ {
osg::State& state = *renderInfo.getState(); State& state = *renderInfo.getState();
const Extensions* extensions = getExtensions(state.getContextID(), true); const Extensions* extensions = getExtensions(state.getContextID(), true);
state.setVertexPointer(_vertexData.array->getDataSize(), Vec4Array::const_iterator citer = _posScaleArray->begin();
_vertexData.array->getDataType(), 0, Vec4Array::const_iterator cend = _posScaleArray->end();
_vertexData.array->getDataPointer()); FloatArray::const_iterator viter = _vertexAttribArray->begin();
if (_normalData.array.valid())
state.setNormalPointer(_normalData.array->getDataType(), 0,
_normalData.array->getDataPointer());
else
state.disableNormalPointer();
Array* texArray = _texCoordList[0].array.get();
state.setTexCoordPointer(0, texArray->getDataSize(),
texArray->getDataType(), 0,
texArray->getDataPointer());
const Vec4Array* colors = static_cast<const Vec4Array*>(getColorArray());
const FloatArray* vertexAttribs
= static_cast<const FloatArray*>(getVertexAttribArray(1));
Vec4Array::const_iterator citer = colors->begin(), cend = colors->end();
FloatArray::const_iterator viter = vertexAttribs->begin();
const Geometry::PrimitiveSetList& modelSets
= _geometry->getPrimitiveSetList();
for (; citer != cend; ++citer, ++viter) { for (; citer != cend; ++citer, ++viter) {
const Vec4& color = *citer; const Vec4& color = *citer;
const float attrib = *viter; const float attrib = *viter;
glColor4fv(color.ptr()); glColor4fv(color.ptr());
extensions->glVertexAttrib1f(1, attrib); extensions->glVertexAttrib1f(1, attrib);
for (Geometry::PrimitiveSetList::const_iterator piter = modelSets.begin(), _geometry->draw(renderInfo);
e = modelSets.end();
piter != e;
++piter)
(*piter)->draw(state, false);
} }
} }
BoundingBox ShaderGeometry::computeBound() const BoundingBox ShaderGeometry::computeBound() const
{ {
BoundingBox geom_box = _geometry->getBound(); const BoundingBox& geom_box = _geometry->getBound();
BoundingBox bb; BoundingBox bb;
unsigned numSets = _geometry->getNumPrimitiveSets(); const Vec4Array* posScales = _posScaleArray.get();
const Vec4Array* posScales = static_cast<const Vec4Array*>(getColorArray());
if (!posScales) if (!posScales)
return bb; return bb;
size_t numPosScales = posScales->size(); size_t numPosScales = posScales->size();
for (int i = 0; i < numPosScales; i += numSets) { for (Vec4Array::const_iterator iter = _posScaleArray->begin(),
const Vec4& posScale((*posScales)[i]); e = _posScaleArray->end();
iter != e;
++iter) {
const Vec4& posScale = *iter;
const float scale = posScale.w(); const float scale = posScale.w();
const Vec3 pos(posScale.x(), posScale.y(), posScale.z()); const Vec3 pos(posScale.x(), posScale.y(), posScale.z());
for (unsigned j = 0; j < 7; ++j) for (unsigned j = 0; j < 7; ++j)
@@ -122,6 +94,45 @@ bool ShaderGeometry_readLocalData(Object& obj, Input& fr)
geom._geometry = drawable; geom._geometry = drawable;
} }
} }
int capacity = 0;
if (fr.matchSequence("posScale %i {")) {
int entry = fr[1].getNoNestedBrackets();
int capacity;
fr[1].getInt(capacity);
Vec4Array* posScale = new Vec4Array;
posScale->reserve(capacity);
fr += 3;
while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) {
Vec4 v;
if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y())
&& fr[2].getFloat(v.z()) && fr[3].getFloat(v.w())) {
fr += 4;
posScale->push_back(v);
}
else ++fr;
}
++fr;
geom._posScaleArray = posScale;
}
if (fr.matchSequence("variety %i {")) {
int entry = fr[1].getNoNestedBrackets();
int capacity;
fr[1].getInt(capacity);
FloatArray* variety = new FloatArray;
variety->reserve(capacity);
fr += 3;
while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) {
float val;
if (fr[0].getFloat(val)) {
++fr;
variety->push_back(val);
}
else ++fr;
}
++fr;
geom._vertexAttribArray = variety;
}
return iteratorAdvanced; return iteratorAdvanced;
} }
@@ -131,6 +142,29 @@ bool ShaderGeometry_writeLocalData(const Object& obj, Output& fw)
fw.indent() << "geometry" << std::endl; fw.indent() << "geometry" << std::endl;
fw.writeObject(*geom._geometry); fw.writeObject(*geom._geometry);
if (geom._posScaleArray.valid()) {
fw.indent() << "posScale " << geom._posScaleArray->size() << " {\n";
fw.moveIn();
for (Vec4Array::const_iterator iter = geom._posScaleArray->begin();
iter != geom._posScaleArray->end();
++iter) {
fw.indent() << iter->x() << " " << iter->y() << " " << iter->z() << " "
<< iter->w() << "\n";
}
fw.moveOut();
fw.indent() << "}\n";
}
if (geom._vertexAttribArray.valid()) {
fw.indent() << "variety" << geom._vertexAttribArray->size() << " {\n";
fw.moveIn();
for (FloatArray::const_iterator iter = geom._vertexAttribArray->begin();
iter != geom._vertexAttribArray->end();
++iter) {
fw.indent() << *iter << "\n";
}
fw.moveOut();
fw.indent() << "}\n";
}
return true; return true;
} }
@@ -138,7 +172,7 @@ osgDB::RegisterDotOsgWrapperProxy shaderGeometryProxy
( (
new ShaderGeometry, new ShaderGeometry,
"ShaderGeometry", "ShaderGeometry",
"Object Drawable Geometry ShaderGeometry", "Object Drawable ShaderGeometry",
&ShaderGeometry_readLocalData, &ShaderGeometry_readLocalData,
&ShaderGeometry_writeLocalData &ShaderGeometry_writeLocalData
); );
+7 -3
View File
@@ -24,6 +24,7 @@
#include <vector> #include <vector>
#include <osg/Array>
#include <osg/BoundingBox> #include <osg/BoundingBox>
#include <osg/CopyOp> #include <osg/CopyOp>
#include <osg/Drawable> #include <osg/Drawable>
@@ -37,22 +38,24 @@
namespace simgear namespace simgear
{ {
class ShaderGeometry : public osg::Geometry class ShaderGeometry : public osg::Drawable
{ {
public: public:
ShaderGeometry() : ShaderGeometry() :
varieties(1) varieties(1)
{ {
setSupportsDisplayList(false);
} }
ShaderGeometry(int v) : ShaderGeometry(int v) :
varieties(v) varieties(v)
{ {
setSupportsDisplayList(false);
} }
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/ /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
ShaderGeometry(const ShaderGeometry& ShaderGeometry,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): ShaderGeometry(const ShaderGeometry& ShaderGeometry,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
osg::Geometry(ShaderGeometry,copyop) {} osg::Drawable(ShaderGeometry,copyop) {}
META_Object(flightgear, ShaderGeometry); META_Object(flightgear, ShaderGeometry);
@@ -69,11 +72,12 @@ class ShaderGeometry : public osg::Geometry
osg::ref_ptr<osg::Geometry> _geometry; osg::ref_ptr<osg::Geometry> _geometry;
int varieties; int varieties;
osg::ref_ptr<osg::Vec4Array> _posScaleArray;
osg::ref_ptr<osg::FloatArray> _vertexAttribArray;
protected: protected:
virtual ~ShaderGeometry() {} virtual ~ShaderGeometry() {}
}; };
} }