]> git.mxchange.org Git - simgear.git/blob - simgear/scene/tgdb/ShaderGeometry.cxx
Fix VS2010 lack of fminf
[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::addObject(const Vec3& position, float scale,
36                                int texture_index)
37 {
38     if (!_posScaleArray.valid()) {
39         _posScaleArray = new Vec4Array();
40         _vertexAttribArray = new FloatArray();
41     }
42     _posScaleArray->push_back(Vec4(position, scale));
43     _vertexAttribArray->push_back((float)texture_index / varieties);
44     dirtyBound();
45 }
46
47 void ShaderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
48 {
49     State& state = *renderInfo.getState();
50     const Extensions* extensions = getExtensions(state.getContextID(), true);
51     Vec4Array::const_iterator citer = _posScaleArray->begin();
52     Vec4Array::const_iterator cend = _posScaleArray->end();
53     FloatArray::const_iterator viter = _vertexAttribArray->begin();
54     for (; citer != cend; ++citer, ++viter) {
55         const Vec4& color = *citer;
56         const float attrib = *viter;
57         glColor4fv(color.ptr());
58         extensions->glVertexAttrib1f(1, attrib);
59         _geometry->draw(renderInfo);
60     }
61 }
62
63 BoundingBox
64 #if OSG_VERSION_LESS_THAN(3,3,2)
65 ShaderGeometry::computeBound()
66 #else
67 ShaderGeometry::computeBoundingBox()
68 #endif
69 const
70 {
71     const BoundingBox& geom_box =
72 #if OSG_VERSION_LESS_THAN(3,3,2)
73       _geometry->getBound();
74 #else
75       _geometry->getBoundingBox();
76 #endif
77
78     BoundingBox bb;
79     const Vec4Array* posScales = _posScaleArray.get();
80     if (!posScales)
81         return bb;
82 //    size_t numPosScales = posScales->size();
83     for (Vec4Array::const_iterator iter = _posScaleArray->begin(),
84              e = _posScaleArray->end();
85          iter != e;
86          ++iter) {
87         const Vec4& posScale = *iter;
88         const float scale = posScale.w();
89         const Vec3 pos(posScale.x(), posScale.y(), posScale.z());
90         for (unsigned j = 0; j < 7; ++j)
91             bb.expandBy(geom_box.corner(j) * scale + pos);
92     }
93     return bb;
94 }
95
96 bool ShaderGeometry_readLocalData(Object& obj, Input& fr)
97 {
98     bool iteratorAdvanced = false;
99
100     ShaderGeometry& geom = static_cast<ShaderGeometry&>(obj);
101
102     if ((fr[0].matchWord("geometry"))) {
103         ++fr;
104         iteratorAdvanced = true;
105         osg::Geometry* drawable = dynamic_cast<osg::Geometry*>(fr.readDrawable());
106         if (drawable) {
107             geom._geometry = drawable;
108         }
109     }
110 //    int capacity = 0;
111     if (fr.matchSequence("posScale %i {")) {
112         int entry = fr[1].getNoNestedBrackets();
113         int capacity;
114         fr[1].getInt(capacity);
115         Vec4Array* posScale = new Vec4Array;
116         posScale->reserve(capacity);
117         fr += 3;
118         while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) {
119             Vec4 v;
120             if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y())
121                 && fr[2].getFloat(v.z()) && fr[3].getFloat(v.w())) {
122                 fr += 4;
123                 posScale->push_back(v);
124             }
125             else ++fr;
126         }
127         ++fr;
128         geom._posScaleArray = posScale;
129     }
130     if (fr.matchSequence("variety %i {")) {
131         int entry = fr[1].getNoNestedBrackets();
132         int capacity;
133         fr[1].getInt(capacity);
134         FloatArray* variety = new FloatArray;
135         variety->reserve(capacity);
136         fr += 3;
137         while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) {
138             float val;
139             if (fr[0].getFloat(val)) {
140                 ++fr;
141                 variety->push_back(val);
142             }
143             else ++fr;
144         }
145         ++fr;
146         geom._vertexAttribArray = variety;
147     }
148
149     return iteratorAdvanced;
150 }
151
152 bool ShaderGeometry_writeLocalData(const Object& obj, Output& fw)
153 {
154     const ShaderGeometry& geom = static_cast<const ShaderGeometry&>(obj);
155
156     fw.indent() << "geometry" << std::endl;
157     fw.writeObject(*geom._geometry);
158     if (geom._posScaleArray.valid()) {
159         fw.indent() << "posScale " << geom._posScaleArray->size() << " {\n";
160         fw.moveIn();
161         for (Vec4Array::const_iterator iter = geom._posScaleArray->begin();
162              iter != geom._posScaleArray->end();
163              ++iter) {
164             fw.indent() << iter->x() << " " << iter->y() << " " << iter->z() << " "
165                         << iter->w() << "\n";
166         }
167         fw.moveOut();
168         fw.indent() << "}\n";
169     }
170     if (geom._vertexAttribArray.valid()) {
171         fw.indent() << "variety" << geom._vertexAttribArray->size() << " {\n";
172         fw.moveIn();
173         for (FloatArray::const_iterator iter = geom._vertexAttribArray->begin();
174              iter != geom._vertexAttribArray->end();
175              ++iter) {
176             fw.indent() << *iter << "\n";
177         }
178         fw.moveOut();
179         fw.indent() << "}\n";
180     }
181     return true;
182 }
183
184 osgDB::RegisterDotOsgWrapperProxy shaderGeometryProxy
185 (
186     new ShaderGeometry,
187     "ShaderGeometry",
188     "Object Drawable ShaderGeometry",
189     &ShaderGeometry_readLocalData,
190     &ShaderGeometry_writeLocalData
191     );
192 }
193