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