]> git.mxchange.org Git - simgear.git/blob - simgear/scene/tgdb/ShaderGeometry.cxx
Merge branch 'topic/yontree' into next
[simgear.git] / simgear / scene / tgdb / ShaderGeometry.cxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2008 Stuart Buchanan
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #include <osgDB/Registry>
23 #include <osgDB/Input>
24 #include <osgDB/ParameterOutput>
25
26 #include "ShaderGeometry.hxx"
27
28 #include <algorithm>
29
30 using namespace osg;
31 using namespace osgDB;
32
33 namespace simgear
34 {
35 void ShaderGeometry::addTree(const TreeBin::Tree& t)
36 {
37     if (!getVertexArray()) {
38         setVertexData(_geometry->getVertexData());
39         setNormalData(_geometry->getNormalData());
40         setTexCoordData(0, _geometry->getTexCoordData(0));
41         setColorArray(new Vec4Array());
42         setColorBinding(Geometry::BIND_PER_PRIMITIVE_SET);
43         setVertexAttribArray(1, new FloatArray());
44         setVertexAttribBinding(1, Geometry::BIND_PER_PRIMITIVE_SET);
45     }
46     Vec4Array *colors = static_cast<Vec4Array*>(getColorArray());
47     FloatArray *vertexAttribs
48         = static_cast<FloatArray*>(getVertexAttribArray(1));
49     colors->push_back(Vec4(t.position.osg(), t.scale));
50     vertexAttribs->push_back((float)t.texture_index / varieties);
51     dirtyDisplayList();
52     dirtyBound();
53 }
54
55 // The good bits from osg::Geometry::drawImplementation
56 void ShaderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
57 {
58     osg::State& state = *renderInfo.getState();
59     const Extensions* extensions = getExtensions(state.getContextID(), true);
60     state.setVertexPointer(_vertexData.array->getDataSize(),
61                            _vertexData.array->getDataType(), 0,
62                            _vertexData.array->getDataPointer());
63     if (_normalData.array.valid())
64         state.setNormalPointer(_normalData.array->getDataType(), 0,
65                                _normalData.array->getDataPointer());
66     else
67         state.disableNormalPointer();
68     Array* texArray = _texCoordList[0].array.get();
69     state.setTexCoordPointer(0, texArray->getDataSize(),
70                              texArray->getDataType(), 0,
71                              texArray->getDataPointer());
72     const Vec4Array* colors = static_cast<const Vec4Array*>(getColorArray());
73     const FloatArray* vertexAttribs
74         = static_cast<const FloatArray*>(getVertexAttribArray(1));
75     Vec4Array::const_iterator citer = colors->begin(), cend = colors->end();
76     FloatArray::const_iterator viter = vertexAttribs->begin();
77     const Geometry::PrimitiveSetList& modelSets
78         = _geometry->getPrimitiveSetList();
79     for (; citer != cend; ++citer, ++viter) {
80         const Vec4& color = *citer;
81         const float attrib = *viter;
82         glColor4fv(color.ptr());
83         extensions->glVertexAttrib1f(1, attrib);
84         for (Geometry::PrimitiveSetList::const_iterator piter = modelSets.begin(),
85                  e = modelSets.end();
86              piter != e;
87             ++piter)
88             (*piter)->draw(state, false);
89     }
90 }
91
92 BoundingBox ShaderGeometry::computeBound() const
93 {
94     BoundingBox geom_box = _geometry->getBound();
95     BoundingBox bb;
96     unsigned numSets = _geometry->getNumPrimitiveSets();
97     const Vec4Array* posScales = static_cast<const Vec4Array*>(getColorArray());
98     if (!posScales)
99         return bb;
100     size_t numPosScales = posScales->size();
101     for (int i = 0; i < numPosScales; i += numSets) {
102         const Vec4& posScale((*posScales)[i]);
103         const float scale = posScale.w();
104         const Vec3 pos(posScale.x(), posScale.y(), posScale.z());
105         for (unsigned j = 0; j < 7; ++j)
106             bb.expandBy(geom_box.corner(j) * scale + pos);
107     }
108     return bb;
109 }
110
111 bool ShaderGeometry_readLocalData(Object& obj, Input& fr)
112 {
113     bool iteratorAdvanced = false;
114
115     ShaderGeometry& geom = static_cast<ShaderGeometry&>(obj);
116
117     if ((fr[0].matchWord("geometry"))) {
118         ++fr;
119         iteratorAdvanced = true;
120         osg::Geometry* drawable = dynamic_cast<osg::Geometry*>(fr.readDrawable());
121         if (drawable) {
122             geom._geometry = drawable;
123         }
124     }
125     return iteratorAdvanced;
126 }
127
128 bool ShaderGeometry_writeLocalData(const Object& obj, Output& fw)
129 {
130     const ShaderGeometry& geom = static_cast<const ShaderGeometry&>(obj);
131
132     fw.indent() << "geometry" << std::endl;
133     fw.writeObject(*geom._geometry);
134     return true;
135 }
136
137 osgDB::RegisterDotOsgWrapperProxy shaderGeometryProxy
138 (
139     new ShaderGeometry,
140     "ShaderGeometry",
141     "Object Drawable Geometry ShaderGeometry",
142     &ShaderGeometry_readLocalData,
143     &ShaderGeometry_writeLocalData
144     );
145 }
146