From: Tim Moore Date: Wed, 21 Jan 2009 21:20:03 +0000 (+0100) Subject: Rewrite ShaderGeometry to use display lists and OSG primitives. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=3c74fea08760810234c7175cdcabe3eaf334d80a;p=simgear.git Rewrite ShaderGeometry to use display lists and OSG primitives. Based on a patch from Yon Uriarte. Eliminate _trees list from ShaderGeometry Use the position and scale values that are already available. --- diff --git a/simgear/scene/tgdb/ShaderGeometry.cxx b/simgear/scene/tgdb/ShaderGeometry.cxx index a6a7c1ed..632555fc 100644 --- a/simgear/scene/tgdb/ShaderGeometry.cxx +++ b/simgear/scene/tgdb/ShaderGeometry.cxx @@ -25,35 +25,52 @@ #include "ShaderGeometry.hxx" +#include + using namespace osg; using namespace osgDB; namespace simgear { -void ShaderGeometry::drawImplementation(RenderInfo& renderInfo) const +void ShaderGeometry::addTree(const TreeBin::Tree& t) { - osg::State& state = *renderInfo.getState(); - const Extensions* extensions = getExtensions(state.getContextID(),true); - - for(TreeBin::TreeList::const_iterator t = _trees.begin(); t != _trees.end(); ++t) - { - extensions->glVertexAttrib1f(1, (float) t->texture_index/varieties); - glColor4f(t->position.x(), t->position.y(), t->position.z(), t->scale); - _geometry->draw(renderInfo); + 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); } + Geometry::PrimitiveSetList& modelSets = _geometry->getPrimitiveSetList(); + size_t numSets = modelSets.size(); + Vec4Array *colors = static_cast(getColorArray()); + FloatArray *vertexAttribs + = static_cast(getVertexAttribArray(1)); + colors->insert(colors->end(), numSets, Vec4(t.position.osg(), t.scale)); + vertexAttribs->insert(vertexAttribs->end(), numSets, + (float)t.texture_index / varieties); + _primitives.insert(_primitives.end(), modelSets.begin(), modelSets.end()); + dirtyDisplayList(); + dirtyBound(); } BoundingBox ShaderGeometry::computeBound() const { BoundingBox geom_box = _geometry->getBound(); BoundingBox bb; - for(TreeBin::TreeList::const_iterator itr = _trees.begin(); - itr != _trees.end(); - ++itr) { - bb.expandBy(geom_box.corner(0)*itr->scale + - osg::Vec3( itr->position.x(), itr->position.y(), itr->position.z() )); - bb.expandBy(geom_box.corner(7)*itr->scale + - osg::Vec3( itr->position.x(), itr->position.y(), itr->position.z() )); + unsigned numSets = _geometry->getNumPrimitiveSets(); + const Vec4Array* posScales = static_cast(getColorArray()); + if (!posScales) + return bb; + size_t numPosScales = posScales->size(); + for (int i = 0; i < numPosScales; i += numSets) { + const Vec4& posScale((*posScales)[i]); + const float scale = posScale.w(); + const Vec3 pos(posScale.x(), posScale.y(), posScale.z()); + for (unsigned j = 0; j < 7; ++j) + bb.expandBy(geom_box.corner(j) * scale + pos); } return bb; } @@ -67,34 +84,11 @@ bool ShaderGeometry_readLocalData(Object& obj, Input& fr) if ((fr[0].matchWord("geometry"))) { ++fr; iteratorAdvanced = true; - osg::Drawable* drawable = fr.readDrawable(); + osg::Geometry* drawable = dynamic_cast(fr.readDrawable()); if (drawable) { geom._geometry = drawable; } } - if ((fr.matchSequence("instances %i"))) { - int entry = fr[0].getNoNestedBrackets(); - int capacity; - fr[1].getInt(capacity); - geom._trees.reserve(capacity); - fr += 3; - iteratorAdvanced = true; - // skip { - while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) { - SGVec3f v; - int t; - float s; - if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) - && fr[2].getFloat(v.z()) && fr[3].getInt(t) && fr[4].getFloat(s)) { - fr += 4; - //SGVec3f* v = new SGVec3f(v.x(), v.y(), v.z()); - //TreeBin::Tree tree = new TreeBin::Tree(v, t, s); - geom._trees.push_back(TreeBin::Tree(v, t, s)); - } else { - ++fr; - } - } - } return iteratorAdvanced; } @@ -104,18 +98,6 @@ bool ShaderGeometry_writeLocalData(const Object& obj, Output& fw) fw.indent() << "geometry" << std::endl; fw.writeObject(*geom._geometry); - fw.indent() << "instances " << geom._trees.size() << std::endl; - fw.indent() << "{" << std::endl; - fw.moveIn(); - for (TreeBin::TreeList::const_iterator iter - = geom._trees.begin(); - iter != geom._trees.end(); - ++iter) { - fw.indent() << iter->position.x() << " " << iter->position.y() << " " << iter->position.z() << " " - << iter->texture_index << " " << iter->scale << std::endl; - } - fw.moveOut(); - fw.indent() << "}" << std::endl; return true; } @@ -123,8 +105,9 @@ osgDB::RegisterDotOsgWrapperProxy shaderGeometryProxy ( new ShaderGeometry, "ShaderGeometry", - "Object Drawable ShaderGeometry", + "Object Drawable Geometry ShaderGeometry", &ShaderGeometry_readLocalData, &ShaderGeometry_writeLocalData ); } + diff --git a/simgear/scene/tgdb/ShaderGeometry.hxx b/simgear/scene/tgdb/ShaderGeometry.hxx index 9814af28..0044dd4e 100644 --- a/simgear/scene/tgdb/ShaderGeometry.hxx +++ b/simgear/scene/tgdb/ShaderGeometry.hxx @@ -37,45 +37,36 @@ namespace simgear { -class ShaderGeometry : public osg::Drawable +class ShaderGeometry : public osg::Geometry { public: - ShaderGeometry() + ShaderGeometry() : + varieties(1) { - setUseDisplayList(false); } ShaderGeometry(int v) : varieties(v) { - setUseDisplayList(false); } /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ ShaderGeometry(const ShaderGeometry& ShaderGeometry,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): - osg::Drawable(ShaderGeometry,copyop) {} + osg::Geometry(ShaderGeometry,copyop) {} META_Object(flightgear, ShaderGeometry); - typedef std::vector PositionSizeList; - - virtual void drawImplementation(osg::RenderInfo& renderInfo) const; virtual osg::BoundingBox computeBound() const; - - void setGeometry(osg::Drawable* geometry) + void setGeometry(osg::Geometry* geometry) { _geometry = geometry; } - void addTree(TreeBin::Tree tree) - { - _trees.push_back(tree); - } - - osg::ref_ptr _geometry; + void addTree(const TreeBin::Tree& tree); + + osg::ref_ptr _geometry; - TreeBin::TreeList _trees; int varieties; protected: diff --git a/simgear/scene/tgdb/TreeBin.cxx b/simgear/scene/tgdb/TreeBin.cxx index b4219f33..1b3355dd 100644 --- a/simgear/scene/tgdb/TreeBin.cxx +++ b/simgear/scene/tgdb/TreeBin.cxx @@ -128,11 +128,17 @@ osg::Geometry* createOrthQuads(float w, float h, int varieties, const osg::Matri static char vertexShaderSource[] = "varying float fogFactor;\n" +#ifndef TSG_PACKED_ATTRIBUTES "attribute float textureIndex;\n" +#endif "\n" "void main(void)\n" "{\n" +#ifdef TSG_PACKED_ATTRIBUTES + " gl_TexCoord[0] = gl_MultiTexCoord0;\n" +#else " gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndex, 0.0, 0.0, 0.0);\n" +#endif " vec3 position = gl_Vertex.xyz * gl_Color.w + gl_Color.xyz;\n" " gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n" " vec3 ecPosition = vec3(gl_ModelViewMatrix * vec4(position, 1.0));\n" @@ -247,7 +253,9 @@ osg::Group* createForest(TreeBin& forest, const osg::Matrix& transform) baseTextureSampler = new osg::Uniform("baseTexture", 0); Shader* vertex_shader = new Shader(Shader::VERTEX, vertexShaderSource); program->addShader(vertex_shader); +#ifndef TSG_PACKED_ATTRIBUTES program->addBindAttribLocation("textureIndex", 1); +#endif Shader* fragment_shader = new Shader(Shader::FRAGMENT, fragmentShaderSource);