1 // Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 # include <simgear_config.h>
22 #include "PrimitiveCollector.hxx"
24 #include <simgear/scene/util/OsgMath.hxx>
28 PrimitiveCollector::PrimitiveCollector() :
33 PrimitiveCollector::~PrimitiveCollector()
38 PrimitiveCollector::swap(PrimitiveCollector& primitiveFunctor)
40 _vertices.swap(primitiveFunctor._vertices);
41 std::swap(_mode, primitiveFunctor._mode);
45 PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec2* vertices)
48 _vertices.reserve(count);
49 for (unsigned i = 0; i < count; ++i)
50 addVertex(osg::Vec3d(vertices[i][0], vertices[i][1], 0));
54 PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec3* vertices)
57 _vertices.reserve(count);
58 for (unsigned i = 0; i < count; ++i)
59 addVertex(osg::Vec3d(vertices[i][0], vertices[i][1], vertices[i][2]));
63 PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec4* vertices)
66 _vertices.reserve(count);
67 for (unsigned i = 0; i < count; ++i)
68 addVertex(osg::Vec4d(vertices[i][0], vertices[i][1], vertices[i][2], vertices[i][3]));
72 PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec2d* vertices)
75 _vertices.reserve(count);
76 for (unsigned i = 0; i < count; ++i)
77 addVertex(osg::Vec3d(vertices[i][0], vertices[i][1], 0));
81 PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec3d* vertices)
84 _vertices.reserve(count);
85 for (unsigned i = 0; i < count; ++i)
86 addVertex(osg::Vec3d(vertices[i][0], vertices[i][1], vertices[i][2]));
90 PrimitiveCollector::setVertexArray(unsigned int count, const osg::Vec4d* vertices)
93 _vertices.reserve(count);
94 for (unsigned i = 0; i < count; ++i)
95 addVertex(osg::Vec4d(vertices[i][0], vertices[i][1], vertices[i][2], vertices[i][3]));
99 PrimitiveCollector::drawArrays(GLenum mode, GLint first, GLsizei count)
101 if (_vertices.empty() || count <= 0)
104 GLsizei end = first + count;
107 for (GLsizei i = first; i < end - 2; i += 3) {
108 addTriangle(i, i + 1, i + 2);
112 case (GL_TRIANGLE_STRIP):
113 for (GLsizei i = first; i < end - 2; ++i) {
114 addTriangle(i, i + 1, i + 2);
119 for (GLsizei i = first; i < end - 3; i += 4) {
120 addQuad(i, i + 1, i + 2, i + 3);
124 case (GL_QUAD_STRIP):
125 for (GLsizei i = first; i < end - 3; i += 2) {
126 addQuad(i, i + 1, i + 2, i + 3);
130 case (GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
131 case (GL_TRIANGLE_FAN):
132 for (GLsizei i = first; i < end - 2; ++i) {
133 addTriangle(first, i + 1, i + 2);
138 for (GLsizei i = first; i < end; ++i) {
144 for (GLsizei i = first; i < end - 1; i += 2) {
149 case (GL_LINE_STRIP):
150 for (GLsizei i = first; i < end - 1; ++i) {
156 for (GLsizei i = first; i < end - 1; ++i) {
159 addLine(end - 1, first);
167 template<typename index_type>
169 PrimitiveCollector::drawElementsTemplate(GLenum mode, GLsizei count, const index_type* indices)
171 if (_vertices.empty() || indices == 0 || count <= 0)
176 for (GLsizei i = 0; i < count - 2; i += 3) {
177 addTriangle(indices[i], indices[i + 1], indices[i + 2]);
181 case (GL_TRIANGLE_STRIP):
182 for (GLsizei i = 0; i < count - 2; ++i) {
183 addTriangle(indices[i], indices[i + 1], indices[i + 2]);
188 for (GLsizei i = 0; i < count - 3; i += 4) {
189 addQuad(indices[i], indices[i + 1], indices[i + 2], indices[i + 3]);
193 case (GL_QUAD_STRIP):
194 for (GLsizei i = 0; i < count - 3; i += 2) {
195 addQuad(indices[i], indices[i + 1], indices[i + 2], indices[i + 3]);
200 case (GL_TRIANGLE_FAN):
201 for (GLsizei i = 0; i < count - 2; ++i) {
202 addTriangle(indices[0], indices[i + 1], indices[i + 2]);
207 for(GLsizei i = 0; i < count; ++i) {
208 addPoint(indices[i]);
213 for (GLsizei i = 0; i < count - 1; i += 2) {
214 addLine(indices[i], indices[i + 1]);
218 case (GL_LINE_STRIP):
219 for (GLsizei i = 0; i < count - 1; ++i) {
220 addLine(indices[i], indices[i + 1]);
225 for (GLsizei i = 0; i < count - 1; ++i) {
226 addLine(indices[i], indices[i + 1]);
228 addLine(indices[count - 1], indices[0]);
237 PrimitiveCollector::drawElements(GLenum mode, GLsizei count, const GLubyte* indices)
239 drawElementsTemplate(mode, count, indices);
242 void PrimitiveCollector::drawElements(GLenum mode, GLsizei count, const GLushort* indices)
244 drawElementsTemplate(mode, count, indices);
248 PrimitiveCollector::drawElements(GLenum mode, GLsizei count, const GLuint* indices)
250 drawElementsTemplate(mode, count, indices);
254 PrimitiveCollector::begin(GLenum mode)
261 PrimitiveCollector::vertex(const osg::Vec2& v)
263 addVertex(osg::Vec3d(v[0], v[1], 0));
267 PrimitiveCollector::vertex(const osg::Vec3& v)
269 addVertex(osg::Vec3d(v[0], v[1], v[2]));
273 PrimitiveCollector::vertex(const osg::Vec4& v)
275 addVertex(osg::Vec4d(v[0], v[1], v[2], v[3]));
279 PrimitiveCollector::vertex(float x, float y)
281 addVertex(osg::Vec3d(x, y, 0));
285 PrimitiveCollector::vertex(float x, float y, float z)
287 addVertex(osg::Vec3d(x, y, z));
291 PrimitiveCollector::vertex(float x, float y, float z, float w)
293 addVertex(osg::Vec4d(x, y, z, w));
297 PrimitiveCollector::end()
299 if (_vertices.empty())
302 drawArrays(_mode, 0, _vertices.size());
306 PrimitiveCollector::addVertex(const osg::Vec3d& v)
308 _vertices.push_back(v);
312 PrimitiveCollector::addVertex(const osg::Vec4d& v)
314 _vertices.push_back(osg::Vec3d(v[0]/v[3], v[1]/v[3], v[2]/v[3]));
318 PrimitiveCollector::addPoint(unsigned i1)
320 if (_vertices.size() <= i1)
322 addPoint(_vertices[i1]);
326 PrimitiveCollector::addLine(unsigned i1, unsigned i2)
328 size_t size = _vertices.size();
329 if (size <= i1 || size <= i2)
331 addLine(_vertices[i1], _vertices[i2]);
335 PrimitiveCollector::addTriangle(unsigned i1, unsigned i2, unsigned i3)
337 size_t size = _vertices.size();
338 if (size <= i1 || size <= i2 || size <= i3)
340 addTriangle(_vertices[i1], _vertices[i2], _vertices[i3]);
344 PrimitiveCollector::addQuad(unsigned i1, unsigned i2, unsigned i3, unsigned i4)
346 addTriangle(i1, i2, i3);
347 addTriangle(i1, i3, i4);