root/OpenSceneGraph/trunk/src/osgUtil/ReversePrimitiveFunctor.cpp @ 13041

Revision 13041, 6.0 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
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#include <osgUtil/ReversePrimitiveFunctor>
15#include <algorithm>
16
17
18template <typename Type>
19osg::PrimitiveSet * drawElementsTemplate(GLenum mode,GLsizei count, const typename Type::value_type* indices)
20{
21     if (indices==0 || count==0) return NULL;
22
23     Type * dePtr = new Type(mode);
24     Type & de = *dePtr;
25     de.reserve(count);
26
27     typedef const typename Type::value_type* IndexPointer;
28
29     switch(mode)
30     {
31         case(GL_TRIANGLES):
32         {
33             IndexPointer ilast = &indices[count];
34
35             for (IndexPointer iptr=indices; iptr<ilast; iptr+=3)
36             {
37                 de.push_back(*(iptr));
38                 de.push_back(*(iptr+2));
39                 de.push_back(*(iptr+1));
40             }
41             break;
42         }
43         case (GL_QUADS):
44         {
45
46             IndexPointer ilast = &indices[count - 3];
47             for (IndexPointer iptr = indices; iptr<ilast; iptr+=4)
48             {
49                 de.push_back(*(iptr));
50                 de.push_back(*(iptr+3));
51                 de.push_back(*(iptr+2));
52                 de.push_back(*(iptr+1));
53             }
54             break;
55         }
56         case (GL_TRIANGLE_STRIP):
57         case (GL_QUAD_STRIP):
58         {
59             IndexPointer ilast = &indices[count];
60             for (IndexPointer iptr = indices; iptr<ilast; iptr+=2)
61             {
62                 de.push_back(*(iptr+1));
63                 de.push_back(*(iptr));
64             }
65             break;
66         }
67         case (GL_TRIANGLE_FAN):
68         {
69             de.push_back(*indices);
70
71             IndexPointer iptr = indices + 1;
72             IndexPointer ilast = &indices[count];
73             de.resize(count);
74             std::reverse_copy(iptr, ilast, de.begin() + 1);
75
76             break;
77         }
78         case (GL_POLYGON):
79         case (GL_POINTS):
80         case (GL_LINES):
81         case (GL_LINE_STRIP):
82         case (GL_LINE_LOOP):
83         {
84             IndexPointer iptr = indices;
85             IndexPointer ilast = &indices[count];
86             de.resize(count);
87             std::reverse_copy(iptr, ilast, de.begin());
88
89             break;
90         }
91         default:
92             break;
93     }
94
95     return &de;
96}
97
98namespace osgUtil {
99
100void ReversePrimitiveFunctor::drawArrays(GLenum mode, GLint first, GLsizei count)
101{
102    if (count==0) return ;
103
104    osg::DrawElementsUInt * dePtr = new osg::DrawElementsUInt(mode);
105    osg::DrawElementsUInt & de = *dePtr;
106    de.reserve(count);
107
108    GLint end = first + count;
109
110    switch (mode)
111    {
112        case (GL_TRIANGLES):
113        {
114            for (GLint i=first; i<end; i+=3)
115            {
116                de.push_back(i);
117                de.push_back(i+2);
118                de.push_back(i+1);
119            }
120            break;
121        }
122        case (GL_QUADS):
123        {
124            for (GLint i=first; i<end; i+=4)
125            {
126                de.push_back(i);
127                de.push_back(i+3);
128                de.push_back(i+2);
129                de.push_back(i+1);
130            }
131            break;
132        }
133        case (GL_TRIANGLE_STRIP):
134        case (GL_QUAD_STRIP):
135        {
136            for (GLint i=first; i<end; i+=2)
137            {
138                de.push_back(i+1);
139                de.push_back(i);
140            }
141            break;
142        }
143        case (GL_TRIANGLE_FAN):
144        {
145            de.push_back(first);
146
147            for (GLint i=end-1; i>first; i--)
148                de.push_back(i);
149
150            break;
151        }
152        case (GL_POLYGON):
153        case (GL_POINTS):
154        case (GL_LINES):
155        case (GL_LINE_STRIP):
156        case (GL_LINE_LOOP):
157        {
158            for (GLint i=end-1; i>=first; i--)
159                de.push_back(i);
160
161            break;
162        }
163        default:
164            break;
165    }
166
167    _reversedPrimitiveSet = &de;
168}
169
170void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
171{
172    _reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUByte>(mode, count, indices);
173}
174void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLushort* indices)
175{
176    _reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUShort>(mode, count, indices);
177}
178void ReversePrimitiveFunctor::drawElements(GLenum mode,GLsizei count,const GLuint* indices)
179{
180    _reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUInt>(mode, count, indices);
181}
182
183void ReversePrimitiveFunctor::begin(GLenum mode)
184{
185    if (_running)
186    {
187        OSG_WARN << "ReversePrimitiveFunctor : call \"begin\" without call \"end\"." << std::endl;
188    }
189    else
190    {
191        _running = true;
192
193        _reversedPrimitiveSet = new osg::DrawElementsUInt(mode);
194    }
195}
196
197void ReversePrimitiveFunctor::vertex(unsigned int pos)
198{
199    if (_running == false)
200    {
201        OSG_WARN << "ReversePrimitiveFunctor : call \"vertex(" << pos << ")\" without call \"begin\"." << std::endl;
202    }
203    else
204    {
205        static_cast<osg::DrawElementsUInt*>(_reversedPrimitiveSet.get())->push_back(pos);
206    }
207}
208
209void ReversePrimitiveFunctor::end()
210{
211    if (_running == false)
212    {
213        OSG_WARN << "ReversePrimitiveFunctor : call \"end\" without call \"begin\"." << std::endl;
214    }
215    else
216    {
217        _running = false;
218
219        osg::ref_ptr<osg::DrawElementsUInt> tmpDe(static_cast<osg::DrawElementsUInt*>(_reversedPrimitiveSet.get()));
220
221        _reversedPrimitiveSet = drawElementsTemplate<osg::DrawElementsUInt>(tmpDe->getMode(), tmpDe->size(), &(tmpDe->front()));
222    }
223}
224} // end osgUtil namespace
Note: See TracBrowser for help on using the browser.