openscenegraph
TriangleLinePointIndexFunctor
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
2 *
3 * This application is open source and may be redistributed and/or modified
4 * freely and without restriction, both in commercial and non commercial
5 * applications, as long as this copyright notice is maintained.
6 *
7 * This application is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 *
11 */
12
13#ifndef TRIANGLE_LINE_POINT_INDEX_FUNCTOR
14#define TRIANGLE_LINE_POINT_INDEX_FUNCTOR
15
16#include <osg/PrimitiveSet>
17#include <osg/Array>
18
19namespace osg {
20
21template<class T>
22class TriangleLinePointIndexFunctor : public osg::PrimitiveIndexFunctor, public T
23{
24public:
25 virtual void setVertexArray(unsigned int,const osg::Vec2*)
26 {}
27
28 virtual void setVertexArray(unsigned int ,const osg::Vec3* )
29 {}
30
31 virtual void setVertexArray(unsigned int,const osg::Vec4* )
32 {}
33
34 virtual void setVertexArray(unsigned int,const osg::Vec2d*)
35 {}
36
37 virtual void setVertexArray(unsigned int ,const osg::Vec3d* )
38 {}
39
40 virtual void setVertexArray(unsigned int,const osg::Vec4d* )
41 {}
42
43 virtual void begin(GLenum mode) {
44 _modeCache = mode;
45 _indexCache.clear();
46 }
47
48 virtual void vertex(unsigned int vert) {
49 _indexCache.push_back(vert);
50 }
51
52 virtual void end() {
53 if (!_indexCache.empty()) {
54 drawElements(_modeCache,_indexCache.size(),&_indexCache.front());
55 }
56 }
57
58 virtual void drawArrays(GLenum mode, GLint first, GLsizei count) {
59 switch(mode)
60 {
61 case(GL_TRIANGLES):
62 {
63 unsigned int pos=first;
64 for(GLsizei i = 2 ; i < count ; i += 3, pos += 3) {
65 this->operator()(pos, pos + 1, pos + 2);
66 }
67 break;
68 }
69 case(GL_TRIANGLE_STRIP):
70 {
71 unsigned int pos = first;
72 for(GLsizei i = 2 ; i < count ; ++ i, ++ pos) {
73 if ((i%2)) this->operator()(pos, pos + 2, pos + 1);
74 else this->operator()(pos, pos + 1, pos + 2);
75 }
76 break;
77 }
78 case(GL_QUADS):
79 {
80 unsigned int pos = first;
81 for(GLsizei i = 3 ; i < count ; i += 4, pos += 4) {
82 this->operator()(pos,pos + 1, pos + 2);
83 this->operator()(pos,pos + 2, pos + 3);
84 }
85 break;
86 }
87 case(GL_QUAD_STRIP):
88 {
89 unsigned int pos = first;
90 for(GLsizei i = 3 ; i < count ; i += 2, pos += 2) {
91 this->operator()(pos, pos + 1,pos + 2);
92 this->operator()(pos + 1,pos + 3,pos + 2);
93 }
94 break;
95 }
96 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
97 case(GL_TRIANGLE_FAN):
98 {
99 unsigned int pos = first + 1;
100 for(GLsizei i = 2 ; i < count ; ++ i, ++ pos) {
101 this->operator()(first, pos, pos + 1);
102 }
103 break;
104 }
105 case(GL_LINES):
106 {
107 unsigned int pos = first;
108 for(GLsizei i = 0 ; i < count ; i += 2, pos += 2) {
109 this->operator()(pos, pos + 1);
110 }
111 break;
112 }
113 case(GL_LINE_STRIP):
114 {
115 unsigned int pos = first;
116 for(GLsizei i = 0 ; i < count - 1 ; i += 1, pos += 1) {
117 this->operator()(pos, pos + 1);
118 }
119 break;
120 }
121 case(GL_LINE_LOOP):
122 {
123 unsigned int pos = first;
124 for(GLsizei i = 0 ; i < count - 1 ; i += 1, pos += 1) {
125 this->operator()(pos, pos + 1);
126 }
127 this->operator()(pos, first);
128 break;
129 }
130 case(GL_POINTS):
131 {
132 unsigned int pos=first;
133 for(GLsizei i = 0 ; i < count ; ++ i) {
134 this->operator()(pos + i);
135 }
136 break;
137 }
138 default:
139 break;
140 }
141 }
142
143 template<typename I>
144 void drawElements(GLenum mode, GLsizei count, const I* indices)
145 {
146 typedef I Index;
147 typedef const I* IndexPointer;
148
149 if (indices == 0 || count == 0) {
150 return;
151 }
152
153 switch(mode)
154 {
155 case(GL_TRIANGLES):
156 {
157 IndexPointer ilast = &indices[count];
158 for(IndexPointer iptr = indices ; iptr < ilast ; iptr += 3) {
159 this->operator()(*iptr, *(iptr + 1), *(iptr + 2));
160 }
161 break;
162 }
163 case(GL_TRIANGLE_STRIP):
164 {
165 IndexPointer iptr = indices;
166 for(GLsizei i = 2 ; i < count ; ++ i, ++ iptr) {
167 if ((i%2)) this->operator()(*(iptr), *(iptr + 2), *(iptr + 1));
168 else this->operator()(*(iptr), *(iptr + 1), *(iptr + 2));
169 }
170 break;
171 }
172 case(GL_QUADS):
173 {
174 IndexPointer iptr = indices;
175 for(GLsizei i = 3 ; i < count ; i += 4, iptr += 4) {
176 this->operator()(*(iptr), *(iptr + 1), *(iptr + 2));
177 this->operator()(*(iptr), *(iptr + 2), *(iptr + 3));
178 }
179 break;
180 }
181 case(GL_QUAD_STRIP):
182 {
183 IndexPointer iptr = indices;
184 for(GLsizei i = 3 ; i < count ; i += 2, iptr += 2) {
185 this->operator()(*(iptr), *(iptr + 1), *(iptr + 2));
186 this->operator()(*(iptr + 1), *(iptr + 3), *(iptr + 2));
187 }
188 break;
189 }
190 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
191 case(GL_TRIANGLE_FAN):
192 {
193 IndexPointer iptr = indices;
194 Index first = *iptr;
195 ++iptr;
196 for(GLsizei i = 2 ; i < count ; ++ i, ++ iptr) {
197 this->operator()(first, *(iptr), *(iptr + 1));
198 }
199 break;
200 }
201 case(GL_LINES):
202 {
203 const I* iptr = indices;
204 for(GLsizei i = 0 ; i < count ; i += 2, iptr += 2) {
205 this->operator()(*iptr, *(iptr + 1));
206 }
207 break;
208 }
209 case(GL_LINE_STRIP):
210 {
211 const I* iptr = indices;
212 for(GLsizei i = 0 ; i < count - 1 ; i += 1, iptr += 1) {
213 this->operator()(*iptr, *(iptr + 1));
214 }
215 break;
216 }
217 case(GL_LINE_LOOP):
218 {
219 const I* iptr = indices;
220 I first = *iptr;
221 for(GLsizei i = 0 ; i < count - 1 ; i += 1, iptr += 1) {
222 this->operator()(*iptr, *(iptr + 1));
223 }
224 this->operator()(*iptr, first);
225 break;
226 }
227 case GL_POINTS:
228 {
229 IndexPointer ilast = &indices[count];
230 for(IndexPointer iptr = indices ; iptr < ilast ; iptr += 1) {
231 this->operator()(*iptr);
232 }
233 break;
234 }
235 default:
236 break;
237 }
238 }
239
240 virtual void drawElements(GLenum mode, GLsizei count, const GLubyte* indices) {
241 drawElements<GLubyte>(mode, count, indices);
242 }
243
244 virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) {
245 drawElements<GLushort>(mode, count, indices);
246 }
247
248 virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) {
249 drawElements<GLuint>(mode, count, indices);
250 }
251
252
253 GLenum _modeCache;
254 std::vector<GLuint> _indexCache;
255 std::vector<unsigned int> _remap;
256};
257
258}
259
260#endif