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 #include <osg/PrimitiveSet>
14 #include <osg/BufferObject>
15 #include <osg/State>
16 #include <osg/Notify>
17
18 using namespace osg;
19
getNumPrimitives() const20 unsigned int PrimitiveSet::getNumPrimitives() const
21 {
22 switch(_mode)
23 {
24 case(POINTS): return getNumIndices();
25 case(LINES): return getNumIndices()/2;
26 case(TRIANGLES): return getNumIndices()/3;
27 case(QUADS): return getNumIndices()/4;
28 case(LINE_STRIP):
29 case(LINE_LOOP):
30 case(TRIANGLE_STRIP):
31 case(TRIANGLE_FAN):
32 case(QUAD_STRIP):
33 case(PATCHES):
34 case(POLYGON): return (getNumIndices()>0) ? 1 : 0;
35 }
36 return 0;
37 }
38
draw(State & state,bool) const39 void DrawArrays::draw(State& state, bool) const
40 {
41 #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
42 GLenum mode = _mode;
43 if (_mode==GL_QUADS)
44 {
45 state.drawQuads(_first, _count, _numInstances);
46 return;
47 }
48 else if (mode==GL_POLYGON)
49 {
50 mode = GL_TRIANGLE_FAN;
51 }
52 else if (mode==GL_QUAD_STRIP)
53 {
54 mode = GL_TRIANGLE_STRIP;
55 }
56
57 if (_numInstances>=1) state.glDrawArraysInstanced(mode,_first,_count, _numInstances);
58 else glDrawArrays(mode,_first,_count);
59 #else
60 if (_numInstances>=1) state.glDrawArraysInstanced(_mode,_first,_count, _numInstances);
61 else glDrawArrays(_mode,_first,_count);
62 #endif
63 }
64
accept(PrimitiveFunctor & functor) const65 void DrawArrays::accept(PrimitiveFunctor& functor) const
66 {
67 functor.drawArrays(_mode,_first,_count);
68 }
69
accept(PrimitiveIndexFunctor & functor) const70 void DrawArrays::accept(PrimitiveIndexFunctor& functor) const
71 {
72 functor.drawArrays(_mode,_first,_count);
73 }
74
getNumPrimitives() const75 unsigned int DrawArrayLengths::getNumPrimitives() const
76 {
77 switch(_mode)
78 {
79 case(POINTS): return getNumIndices();
80 case(LINES): return getNumIndices()/2;
81 case(TRIANGLES): return getNumIndices()/3;
82 case(QUADS): return getNumIndices()/4;
83 case(LINE_STRIP):
84 case(LINE_LOOP):
85 case(TRIANGLE_STRIP):
86 case(TRIANGLE_FAN):
87 case(QUAD_STRIP):
88 case(PATCHES):
89 case(POLYGON): return size();
90 }
91 return 0;
92 }
93
draw(State & state,bool) const94 void DrawArrayLengths::draw(State& state, bool) const
95 {
96 GLenum mode = _mode;
97 #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
98 if (_mode==GL_QUADS)
99 {
100 GLint first = _first;
101 for(vector_type::const_iterator itr=begin();
102 itr!=end();
103 ++itr)
104 {
105 state.drawQuads(first, *itr, _numInstances);
106 first += *itr;
107 }
108
109 return;
110 }
111 if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
112 if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
113 #endif
114
115 GLint first = _first;
116 for(vector_type::const_iterator itr=begin();
117 itr!=end();
118 ++itr)
119 {
120 if (_numInstances>=1) state.glDrawArraysInstanced(mode,first,*itr,_numInstances);
121 else glDrawArrays(mode,first,*itr);
122 first += *itr;
123 }
124
125 }
126
accept(PrimitiveFunctor & functor) const127 void DrawArrayLengths::accept(PrimitiveFunctor& functor) const
128 {
129 GLint first = _first;
130 for(vector_type::const_iterator itr=begin();
131 itr!=end();
132 ++itr)
133 {
134 functor.drawArrays(_mode,first,*itr);
135 first += *itr;
136 }
137 }
138
accept(PrimitiveIndexFunctor & functor) const139 void DrawArrayLengths::accept(PrimitiveIndexFunctor& functor) const
140 {
141 GLint first = _first;
142 for(vector_type::const_iterator itr=begin();
143 itr!=end();
144 ++itr)
145 {
146 functor.drawArrays(_mode,first,*itr);
147 first += *itr;
148 }
149 }
150
getNumIndices() const151 unsigned int DrawArrayLengths::getNumIndices() const
152 {
153 unsigned int count = 0;
154 for(vector_type::const_iterator itr=begin();
155 itr!=end();
156 ++itr)
157 {
158 count += *itr;
159 }
160 return count;
161 }
162
~DrawElementsUByte()163 DrawElementsUByte::~DrawElementsUByte()
164 {
165 releaseGLObjects();
166 }
167
draw(State & state,bool useVertexBufferObjects) const168 void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const
169 {
170 GLenum mode = _mode;
171 #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
172 if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
173 if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
174 #endif
175
176 if (useVertexBufferObjects)
177 {
178 GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
179 state.bindElementBufferObject(ebo);
180 if (ebo)
181 {
182 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
183 else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
184 }
185 else
186 {
187 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
188 else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, &front());
189 }
190 }
191 else
192 {
193 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
194 else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, &front());
195 }
196 }
197
accept(PrimitiveFunctor & functor) const198 void DrawElementsUByte::accept(PrimitiveFunctor& functor) const
199 {
200 if (!empty()) functor.drawElements(_mode,size(),&front());
201 }
202
accept(PrimitiveIndexFunctor & functor) const203 void DrawElementsUByte::accept(PrimitiveIndexFunctor& functor) const
204 {
205 if (!empty()) functor.drawElements(_mode,size(),&front());
206 }
207
offsetIndices(int offset)208 void DrawElementsUByte::offsetIndices(int offset)
209 {
210 for(iterator itr=begin();
211 itr!=end();
212 ++itr)
213 {
214 *itr += offset;
215 }
216 }
217
218
~DrawElementsUShort()219 DrawElementsUShort::~DrawElementsUShort()
220 {
221 releaseGLObjects();
222 }
223
draw(State & state,bool useVertexBufferObjects) const224 void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
225 {
226 GLenum mode = _mode;
227 #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
228 if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
229 if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
230 #endif
231
232 if (useVertexBufferObjects)
233 {
234 GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
235 state.bindElementBufferObject(ebo);
236 if (ebo)
237 {
238 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
239 else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
240 }
241 else
242 {
243 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
244 else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, &front());
245 }
246 }
247 else
248 {
249 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
250 else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, &front());
251 }
252 }
253
accept(PrimitiveFunctor & functor) const254 void DrawElementsUShort::accept(PrimitiveFunctor& functor) const
255 {
256 if (!empty()) functor.drawElements(_mode,size(),&front());
257 }
258
accept(PrimitiveIndexFunctor & functor) const259 void DrawElementsUShort::accept(PrimitiveIndexFunctor& functor) const
260 {
261 if (!empty()) functor.drawElements(_mode,size(),&front());
262 }
263
offsetIndices(int offset)264 void DrawElementsUShort::offsetIndices(int offset)
265 {
266 for(iterator itr=begin();
267 itr!=end();
268 ++itr)
269 {
270 *itr += offset;
271 }
272 }
273
274
~DrawElementsUInt()275 DrawElementsUInt::~DrawElementsUInt()
276 {
277 releaseGLObjects();
278 }
279
draw(State & state,bool useVertexBufferObjects) const280 void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const
281 {
282 GLenum mode = _mode;
283 #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
284 if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
285 if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
286 #endif
287
288 if (useVertexBufferObjects)
289 {
290 GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
291 state.bindElementBufferObject(ebo);
292 if (ebo)
293 {
294 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
295 else glDrawElements(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
296 }
297 else
298 {
299 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
300 else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front());
301 }
302 }
303 else
304 {
305 if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
306 else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front());
307 }
308 }
309
accept(PrimitiveFunctor & functor) const310 void DrawElementsUInt::accept(PrimitiveFunctor& functor) const
311 {
312 if (!empty()) functor.drawElements(_mode,size(),&front());
313 }
314
accept(PrimitiveIndexFunctor & functor) const315 void DrawElementsUInt::accept(PrimitiveIndexFunctor& functor) const
316 {
317 if (!empty()) functor.drawElements(_mode,size(),&front());
318 }
319
offsetIndices(int offset)320 void DrawElementsUInt::offsetIndices(int offset)
321 {
322 for(iterator itr=begin();
323 itr!=end();
324 ++itr)
325 {
326 *itr += offset;
327 }
328 }
329