]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/tgdb/ShaderGeometry.cxx
Merge branch 'maint' into next
[simgear.git] / simgear / scene / tgdb / ShaderGeometry.cxx
index 7fdf657f05a0c2119f47edc7c377e0252bb7f055..265d90e7516d23d39218a728dd8fe72186e34122 100644 (file)
 
 #include "ShaderGeometry.hxx"
 
+#include <algorithm>
+
 using namespace osg;
 using namespace osgDB;
 
 namespace simgear
 {
-void ShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
+void ShaderGeometry::addTree(const TreeBin::Tree& t)
+{
+    if (!_posScaleArray.valid()) {
+        _posScaleArray = new Vec4Array();
+        _vertexAttribArray = new FloatArray();
+    }
+    _posScaleArray->push_back(Vec4(t.position.osg(), t.scale));
+    _vertexAttribArray->push_back((float)t.texture_index / varieties);
+    dirtyBound();
+}
+
+void ShaderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
 {
-    for(PositionSizeList::const_iterator itr = _trees.begin();
-        itr != _trees.end();
-        ++itr) {
-        glColor4fv(itr->ptr());
+    State& state = *renderInfo.getState();
+    const Extensions* extensions = getExtensions(state.getContextID(), true);
+    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);
         _geometry->draw(renderInfo);
     }
 }
 
 BoundingBox ShaderGeometry::computeBound() const
 {
-    BoundingBox geom_box = _geometry->getBound();
+    const BoundingBox& geom_box = _geometry->getBound();
     BoundingBox bb;
-    for(PositionSizeList::const_iterator itr = _trees.begin();
-        itr != _trees.end();
-        ++itr) {
-        bb.expandBy(geom_box.corner(0)*(*itr)[3] +
-                    Vec3((*itr)[0], (*itr)[1], (*itr)[2]));
-        bb.expandBy(geom_box.corner(7)*(*itr)[3] +
-                    Vec3((*itr)[0], (*itr)[1], (*itr)[2]));
+    const Vec4Array* posScales = _posScaleArray.get();
+    if (!posScales)
+        return bb;
+    size_t numPosScales = posScales->size();
+    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)
+            bb.expandBy(geom_box.corner(j) * scale + pos);
     }
     return bb;
 }
@@ -64,30 +89,50 @@ bool ShaderGeometry_readLocalData(Object& obj, Input& fr)
     if ((fr[0].matchWord("geometry"))) {
         ++fr;
         iteratorAdvanced = true;
-        Drawable* drawable = fr.readDrawable();
+        osg::Geometry* drawable = dynamic_cast<osg::Geometry*>(fr.readDrawable());
         if (drawable) {
             geom._geometry = drawable;
         }
     }
-    if ((fr.matchSequence("instances %i"))) {
-        int entry = fr[0].getNoNestedBrackets();
+    int capacity = 0;
+    if (fr.matchSequence("posScale %i {")) {
+        int entry = fr[1].getNoNestedBrackets();
         int capacity;
         fr[1].getInt(capacity);
-        geom._trees.reserve(capacity);
+        Vec4Array* posScale = new Vec4Array;
+        posScale->reserve(capacity);
         fr += 3;
-        iteratorAdvanced = true;
-        // skip {
         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;
-                    geom._trees.push_back(v);
-            } else {
+                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;
 }
 
@@ -97,18 +142,29 @@ 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 (ShaderGeometry::PositionSizeList::const_iterator iter
-             = geom._trees.begin();
-         iter != geom._trees.end();
-         ++iter) {
-        fw.indent() << iter->x() << " " << iter->y() << " " << iter->z() << " "
-                    << iter->w() << std::endl;
+    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";
     }
-    fw.moveOut();
-    fw.indent() << "}" << std::endl;
     return true;
 }
 
@@ -121,3 +177,4 @@ osgDB::RegisterDotOsgWrapperProxy shaderGeometryProxy
     &ShaderGeometry_writeLocalData
     );
 }
+