openscenegraph
TriangleIndexFunctor
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
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
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_TRIANGLEINDEXFUNCTOR
15#define OSG_TRIANGLEINDEXFUNCTOR 1
16
17#include <osg/PrimitiveSet>
18#include <osg/Notify>
19
20namespace osg {
21
22template<class T>
23class TriangleIndexFunctor : public PrimitiveIndexFunctor, public T
24{
25public:
26
27 virtual void setVertexArray(unsigned int,const Vec2*) {}
28 virtual void setVertexArray(unsigned int ,const Vec3*) {}
29 virtual void setVertexArray(unsigned int,const Vec4*) {}
30 virtual void setVertexArray(unsigned int,const Vec2d*) {}
31 virtual void setVertexArray(unsigned int ,const Vec3d*) {}
32 virtual void setVertexArray(unsigned int,const Vec4d*) {}
33
34 virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
35 {
36 switch(mode)
37 {
38 case(GL_TRIANGLES):
39 {
40 unsigned int pos=first;
41 for(GLsizei i=2;i<count;i+=3,pos+=3)
42 {
43 this->operator()(pos,pos+1,pos+2);
44 }
45 break;
46 }
47 case(GL_TRIANGLE_STRIP):
48 {
49 unsigned int pos=first;
50 for(GLsizei i=2;i<count;++i,++pos)
51 {
52 if ((i%2)) this->operator()(pos,pos+2,pos+1);
53 else this->operator()(pos,pos+1,pos+2);
54 }
55 break;
56 }
57 case(GL_QUADS):
58 {
59 unsigned int pos=first;
60 for(GLsizei i=3;i<count;i+=4,pos+=4)
61 {
62 this->operator()(pos,pos+1,pos+2);
63 this->operator()(pos,pos+2,pos+3);
64 }
65 break;
66 }
67 case(GL_QUAD_STRIP):
68 {
69 unsigned int pos=first;
70 for(GLsizei i=3;i<count;i+=2,pos+=2)
71 {
72 this->operator()(pos,pos+1,pos+2);
73 this->operator()(pos+1,pos+3,pos+2);
74 }
75 break;
76 }
77 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
78 case(GL_TRIANGLE_FAN):
79 {
80 unsigned int pos=first+1;
81 for(GLsizei i=2;i<count;++i,++pos)
82 {
83 this->operator()(first,pos,pos+1);
84 }
85 break;
86 }
87 case(GL_POINTS):
88 case(GL_LINES):
89 case(GL_LINE_STRIP):
90 case(GL_LINE_LOOP):
91 default:
92 // can't be converted into to triangles.
93 break;
94 }
95 }
96
97 virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
98 {
99 if (indices==0 || count==0) return;
100
101 typedef GLubyte Index;
102 typedef const Index* IndexPointer;
103
104 switch(mode)
105 {
106 case(GL_TRIANGLES):
107 {
108 IndexPointer ilast = &indices[count];
109 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
110 this->operator()(*iptr,*(iptr+1),*(iptr+2));
111 break;
112 }
113 case(GL_TRIANGLE_STRIP):
114 {
115 IndexPointer iptr = indices;
116 for(GLsizei i=2;i<count;++i,++iptr)
117 {
118 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
119 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
120 }
121 break;
122 }
123 case(GL_QUADS):
124 {
125 IndexPointer iptr = indices;
126 for(GLsizei i=3;i<count;i+=4,iptr+=4)
127 {
128 this->operator()(*(iptr),*(iptr+1),*(iptr+2));
129 this->operator()(*(iptr),*(iptr+2),*(iptr+3));
130 }
131 break;
132 }
133 case(GL_QUAD_STRIP):
134 {
135 IndexPointer iptr = indices;
136 for(GLsizei i=3;i<count;i+=2,iptr+=2)
137 {
138 this->operator()(*(iptr),*(iptr+1),*(iptr+2));
139 this->operator()(*(iptr+1),*(iptr+3),*(iptr+2));
140 }
141 break;
142 }
143 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
144 case(GL_TRIANGLE_FAN):
145 {
146 IndexPointer iptr = indices;
147 Index first = *iptr;
148 ++iptr;
149 for(GLsizei i=2;i<count;++i,++iptr)
150 {
151 this->operator()(first,*(iptr),*(iptr+1));
152 }
153 break;
154 }
155 case(GL_POINTS):
156 case(GL_LINES):
157 case(GL_LINE_STRIP):
158 case(GL_LINE_LOOP):
159 default:
160 // can't be converted into to triangles.
161 break;
162 }
163 }
164
165 virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)
166 {
167 if (indices==0 || count==0) return;
168
169 typedef GLushort Index;
170 typedef const Index* IndexPointer;
171
172 switch(mode)
173 {
174 case(GL_TRIANGLES):
175 {
176 IndexPointer ilast = &indices[count];
177 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
178 this->operator()(*iptr,*(iptr+1),*(iptr+2));
179 break;
180 }
181 case(GL_TRIANGLE_STRIP):
182 {
183 IndexPointer iptr = indices;
184 for(GLsizei i=2;i<count;++i,++iptr)
185 {
186 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
187 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
188 }
189 break;
190 }
191 case(GL_QUADS):
192 {
193 IndexPointer iptr = indices;
194 for(GLsizei i=3;i<count;i+=4,iptr+=4)
195 {
196 this->operator()(*(iptr),*(iptr+1),*(iptr+2));
197 this->operator()(*(iptr),*(iptr+2),*(iptr+3));
198 }
199 break;
200 }
201 case(GL_QUAD_STRIP):
202 {
203 IndexPointer iptr = indices;
204 for(GLsizei i=3;i<count;i+=2,iptr+=2)
205 {
206 this->operator()(*(iptr),*(iptr+1),*(iptr+2));
207 this->operator()(*(iptr+1),*(iptr+3),*(iptr+2));
208 }
209 break;
210 }
211 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
212 case(GL_TRIANGLE_FAN):
213 {
214 IndexPointer iptr = indices;
215 Index first = *iptr;
216 ++iptr;
217 for(GLsizei i=2;i<count;++i,++iptr)
218 {
219 this->operator()(first,*(iptr),*(iptr+1));
220 }
221 break;
222 }
223 case(GL_POINTS):
224 case(GL_LINES):
225 case(GL_LINE_STRIP):
226 case(GL_LINE_LOOP):
227 default:
228 // can't be converted into to triangles.
229 break;
230 }
231 }
232
233 virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)
234 {
235 if (indices==0 || count==0) return;
236
237 typedef GLuint Index;
238 typedef const Index* IndexPointer;
239
240 switch(mode)
241 {
242 case(GL_TRIANGLES):
243 {
244 IndexPointer ilast = &indices[count];
245 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
246 this->operator()(*iptr,*(iptr+1),*(iptr+2));
247 break;
248 }
249 case(GL_TRIANGLE_STRIP):
250 {
251 IndexPointer iptr = indices;
252 for(GLsizei i=2;i<count;++i,++iptr)
253 {
254 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
255 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
256 }
257 break;
258 }
259 case(GL_QUADS):
260 {
261 IndexPointer iptr = indices;
262 for(GLsizei i=3;i<count;i+=4,iptr+=4)
263 {
264 this->operator()(*(iptr),*(iptr+1),*(iptr+2));
265 this->operator()(*(iptr),*(iptr+2),*(iptr+3));
266 }
267 break;
268 }
269 case(GL_QUAD_STRIP):
270 {
271 IndexPointer iptr = indices;
272 for(GLsizei i=3;i<count;i+=2,iptr+=2)
273 {
274 this->operator()(*(iptr),*(iptr+1),*(iptr+2));
275 this->operator()(*(iptr+1),*(iptr+3),*(iptr+2));
276 }
277 break;
278 }
279 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
280 case(GL_TRIANGLE_FAN):
281 {
282 IndexPointer iptr = indices;
283 Index first = *iptr;
284 ++iptr;
285 for(GLsizei i=2;i<count;++i,++iptr)
286 {
287 this->operator()(first,*(iptr),*(iptr+1));
288 }
289 break;
290 }
291 case(GL_POINTS):
292 case(GL_LINES):
293 case(GL_LINE_STRIP):
294 case(GL_LINE_LOOP):
295 default:
296 // can't be converted into to triangles.
297 break;
298 }
299 }
300};
301
302}
303
304#endif