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-29 07:22:42 +01:00
parent 7151c3fac1
commit 3ff13189aa
2 changed files with 89 additions and 51 deletions

View File

@@ -34,72 +34,44 @@ namespace simgear
{
void ShaderGeometry::addTree(const TreeBin::Tree& t)
{
if (!getVertexArray()) {
setVertexData(_geometry->getVertexData());
setNormalData(_geometry->getNormalData());
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);
if (!_posScaleArray.valid()) {
_posScaleArray = new Vec4Array();
_vertexAttribArray = new FloatArray();
}
Vec4Array *colors = static_cast<Vec4Array*>(getColorArray());
FloatArray *vertexAttribs
= static_cast<FloatArray*>(getVertexAttribArray(1));
colors->push_back(Vec4(t.position.osg(), t.scale));
vertexAttribs->push_back((float)t.texture_index / varieties);
dirtyDisplayList();
_posScaleArray->push_back(Vec4(t.position.osg(), t.scale));
_vertexAttribArray->push_back((float)t.texture_index / varieties);
dirtyBound();
}
// The good bits from osg::Geometry::drawImplementation
void ShaderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
{
osg::State& state = *renderInfo.getState();
State& state = *renderInfo.getState();
const Extensions* extensions = getExtensions(state.getContextID(), true);
state.setVertexPointer(_vertexData.array->getDataSize(),
_vertexData.array->getDataType(), 0,
_vertexData.array->getDataPointer());
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();
Vec4Array::const_iterator citer = _posScaleArray->begin();
Vec4Array::const_iterator cend = _posScaleArray->end();
FloatArray::const_iterator viter = _vertexAttribArray->begin();
for (; citer != cend; ++citer, ++viter) {
const Vec4& color = *citer;
const float attrib = *viter;
glColor4fv(color.ptr());
extensions->glVertexAttrib1f(1, attrib);
for (Geometry::PrimitiveSetList::const_iterator piter = modelSets.begin(),
e = modelSets.end();
piter != e;
++piter)
(*piter)->draw(state, false);
_geometry->draw(renderInfo);
}
}
BoundingBox ShaderGeometry::computeBound() const
{
BoundingBox geom_box = _geometry->getBound();
const BoundingBox& geom_box = _geometry->getBound();
BoundingBox bb;
unsigned numSets = _geometry->getNumPrimitiveSets();
const Vec4Array* posScales = static_cast<const Vec4Array*>(getColorArray());
const Vec4Array* posScales = _posScaleArray.get();
if (!posScales)
return bb;
size_t numPosScales = posScales->size();
for (int i = 0; i < numPosScales; i += numSets) {
const Vec4& posScale((*posScales)[i]);
for (Vec4Array::const_iterator iter = _posScaleArray->begin(),
e = _posScaleArray->end();
iter != e;
++iter) {
const Vec4& posScale = *iter;
const float scale = posScale.w();
const Vec3 pos(posScale.x(), posScale.y(), posScale.z());
for (unsigned j = 0; j < 7; ++j)
@@ -122,6 +94,45 @@ bool ShaderGeometry_readLocalData(Object& obj, Input& fr)
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;
}
@@ -131,6 +142,29 @@ bool ShaderGeometry_writeLocalData(const Object& obj, Output& fw)
fw.indent() << "geometry" << std::endl;
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;
}
@@ -138,7 +172,7 @@ osgDB::RegisterDotOsgWrapperProxy shaderGeometryProxy
(
new ShaderGeometry,
"ShaderGeometry",
"Object Drawable Geometry ShaderGeometry",
"Object Drawable ShaderGeometry",
&ShaderGeometry_readLocalData,
&ShaderGeometry_writeLocalData
);

View File

@@ -24,6 +24,7 @@
#include <vector>
#include <osg/Array>
#include <osg/BoundingBox>
#include <osg/CopyOp>
#include <osg/Drawable>
@@ -37,22 +38,24 @@
namespace simgear
{
class ShaderGeometry : public osg::Geometry
class ShaderGeometry : public osg::Drawable
{
public:
ShaderGeometry() :
varieties(1)
{
{
setSupportsDisplayList(false);
}
ShaderGeometry(int v) :
varieties(v)
{
{
setSupportsDisplayList(false);
}
/** Copy constructor using CopyOp to manage deep vs 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);
@@ -69,11 +72,12 @@ class ShaderGeometry : public osg::Geometry
osg::ref_ptr<osg::Geometry> _geometry;
int varieties;
osg::ref_ptr<osg::Vec4Array> _posScaleArray;
osg::ref_ptr<osg::FloatArray> _vertexAttribArray;
protected:
virtual ~ShaderGeometry() {}
};
}