root/OpenSceneGraph/trunk/src/osgUtil/SceneGraphBuilder.cpp @ 7941

Revision 7941, 14.7 kB (checked in by robert, 7 years ago)

Removed gl and glu prefixes from SceneGraphBuilder? methods to avoid problems under Solaris

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#include <osgUtil/SceneGraphBuilder>
14
15#include <osg/Notify>
16#include <osg/io_utils>
17
18#include <osg/PrimitiveSet>
19#include <osg/Texture>
20#include <osg/AlphaFunc>
21#include <osg/BlendFunc>
22#include <osg/LineStipple>
23#include <osg/Depth>
24#include <osg/CullFace>
25#include <osg/FrontFace>
26#include <osg/LineWidth>
27#include <osg/Point>
28#include <osg/PolygonMode>
29#include <osg/PolygonOffset>
30#include <osg/PolygonStipple>
31#include <osg/ShadeModel>
32#include <osg/ShapeDrawable>
33
34using namespace osgUtil;
35
36SceneGraphBuilder::SceneGraphBuilder():
37    _normal(0.0f,0.0f,1.0f),
38    _color(1.0f,1.0f,1.0f,1.0f),
39    _texCoord(0.f,0.0f,0.0f,1.0f),
40    _statesetAssigned(false)
41{
42}
43
44
45///////////////////////////////////////////////////////////////////////////////////////////
46//
47// OpenGL 1.0 building methods
48//
49void SceneGraphBuilder::PushMatrix()
50{
51    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
52    else _matrixStack.push_back(_matrixStack.back());
53}
54
55void SceneGraphBuilder::PopMatrix()
56{
57    if (!_matrixStack.empty()) _matrixStack.pop_back();
58   
59    matrixChanged();
60}
61
62void SceneGraphBuilder::LoadIdentity()
63{
64    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
65    _matrixStack.back().makeIdentity();
66
67    matrixChanged();
68}
69
70void SceneGraphBuilder::LoadMatrixd(const GLdouble* m)
71{
72    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
73    _matrixStack.back().set(m);
74
75    matrixChanged();
76}
77
78void SceneGraphBuilder::MultMatrixd(const GLdouble* m)
79{
80    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
81    _matrixStack.back().preMult(osg::Matrixd(m));
82
83    matrixChanged();
84}
85
86void SceneGraphBuilder::Translated(GLdouble x, GLdouble y, GLdouble z)
87{
88    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
89    _matrixStack.back().preMult(osg::Matrixd::translate(x,y,z));
90
91    matrixChanged();
92}
93
94void SceneGraphBuilder::Scaled(GLdouble x, GLdouble y, GLdouble z)
95{
96    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
97    _matrixStack.back().preMult(osg::Matrixd::scale(x,y,z));
98
99    matrixChanged();
100}
101
102void SceneGraphBuilder::Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
103{
104    if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd());
105    _matrixStack.back().preMult(osg::Matrixd::rotate(osg::inDegrees(angle),x,y,z));
106
107    matrixChanged();
108}
109
110void SceneGraphBuilder::BlendFunc(GLenum srcFactor, GLenum dstFactor)
111{
112    addAttribute(new osg::BlendFunc(srcFactor, dstFactor));
113}
114
115void SceneGraphBuilder::CullFace(GLenum mode)
116{
117    addAttribute(new osg::CullFace(osg::CullFace::Mode(mode)));
118}
119
120void SceneGraphBuilder::DepthFunc(GLenum mode)
121{
122    addAttribute(new osg::Depth(osg::Depth::Function(mode)));
123}
124
125void SceneGraphBuilder::FrontFace(GLenum mode)
126{
127    addAttribute(new osg::FrontFace(osg::FrontFace::Mode(mode)));
128}
129
130void SceneGraphBuilder::LineStipple(GLint factor, GLushort pattern)
131{
132    addAttribute(new osg::LineStipple(factor, pattern));
133}
134
135void SceneGraphBuilder::LineWidth(GLfloat lineWidth)
136{
137    addAttribute(new osg::LineWidth(lineWidth));
138}
139
140void SceneGraphBuilder::PointSize(GLfloat pointSize)
141{
142    addAttribute(new osg::Point(pointSize));
143}
144
145void SceneGraphBuilder::PolygonMode(GLenum face, GLenum mode)
146{
147    addAttribute(new osg::PolygonMode(osg::PolygonMode::Face(face),osg::PolygonMode::Mode(mode)));
148}
149
150void SceneGraphBuilder::PolygonOffset(GLfloat factor, GLfloat units)
151{
152    addAttribute(new osg::PolygonOffset(factor,units));
153}
154
155void SceneGraphBuilder::PolygonStipple(const GLubyte* mask)
156{
157    addAttribute(new osg::PolygonStipple(mask));
158}
159
160void SceneGraphBuilder::ShadeModel(GLenum mode)
161{
162    addAttribute(new osg::ShadeModel(osg::ShadeModel::Mode(mode)));
163}
164void SceneGraphBuilder::Enable(GLenum mode)
165{
166    addMode(mode, true);
167}
168
169void SceneGraphBuilder::Disable(GLenum mode)
170{
171    addMode(mode, false);
172}
173
174void SceneGraphBuilder::Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
175{
176    _normalSet = true;
177    _color.set(red,green,blue,alpha);
178}
179
180void SceneGraphBuilder::Normal3f(GLfloat x, GLfloat y, GLfloat z)
181{
182    _normalSet = true;
183    _normal.set(x,y,z);
184}
185
186void SceneGraphBuilder::TexCoord1f(GLfloat x)
187{
188    _maxNumTexCoordComponents = 1;
189    _texCoord.set(x,0.0f,0.0f,1.0f);
190}
191
192void SceneGraphBuilder::TexCoord2f(GLfloat x, GLfloat y)
193{
194    _maxNumTexCoordComponents = 2;
195    _texCoord.set(x,y,0.0f,1.0f);
196}
197
198void SceneGraphBuilder::TexCoord3f(GLfloat x, GLfloat y, GLfloat z)
199{
200    _maxNumTexCoordComponents = 3;
201    _texCoord.set(x,y,z,1.0);
202}
203
204void SceneGraphBuilder::TexCoord4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
205{
206    _maxNumTexCoordComponents = 4;
207    _texCoord.set(x,y,z,w);
208}
209
210void SceneGraphBuilder::Vertex3f(GLfloat x, GLfloat y, GLfloat z)
211{
212    osg::Vec3 vertex(x,y,z);
213   
214    vertex = vertex * _matrixStack.back();
215   
216    if (_vertices.valid()) _vertices->push_back(vertex);
217    if (_normal.valid()) _normals->push_back(_normal);
218    if (_colors.valid()) _colors->push_back(_color);
219    if (_texCoords.valid()) _texCoords->push_back(_texCoord);
220}
221
222void SceneGraphBuilder::Begin(GLenum mode)
223{
224    // reset geometry
225    _primitiveMode = mode;
226    _vertices = new osg::Vec3Array;
227   
228    _normalSet = false;
229    _normals = new osg::Vec3Array;
230
231    _colorSet = false;
232    _colors = new osg::Vec4Array;
233
234    _maxNumTexCoordComponents = 0;
235    _texCoords = new osg::Vec4Array;
236
237}
238
239void SceneGraphBuilder::End()
240{
241    allocateGeometry();
242
243    _geometry->setVertexArray(_vertices.get());
244   
245    if (_colorSet)
246    {
247         _geometry->setColorArray(_colors.get());
248         _geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
249    }
250    else
251    {
252         osg::Vec4Array* colors = new osg::Vec4Array;
253         colors->push_back(_color);
254         
255         _geometry->setColorArray(colors);
256         _geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
257    }
258   
259    if (_normalSet)
260    {
261         _geometry->setNormalArray(_normals.get());
262         _geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
263    }
264    else
265    {
266         _geometry->setNormalBinding(osg::Geometry::BIND_OFF);
267    }
268   
269    if (_maxNumTexCoordComponents==1)
270    {
271        // convert Vec4Array into FloatArray
272        osg::FloatArray* texCoords = new osg::FloatArray;
273        for(osg::Vec4Array::iterator itr = _texCoords->begin();
274            itr != _texCoords->end();
275            ++itr)
276        {
277            texCoords->push_back(itr->x());
278        }
279         _geometry->setTexCoordArray(0, texCoords);
280    }
281    if (_maxNumTexCoordComponents==2)
282    {
283        // convert Vec4Array into FloatArray
284        osg::Vec2Array* texCoords = new osg::Vec2Array;
285        for(osg::Vec4Array::iterator itr = _texCoords->begin();
286            itr != _texCoords->end();
287            ++itr)
288        {
289            texCoords->push_back(osg::Vec2(itr->x(),itr->y()));
290        }
291         _geometry->setTexCoordArray(0, texCoords);
292    }
293    if (_maxNumTexCoordComponents==3)
294    {
295        // convert Vec4Array into FloatArray
296        osg::Vec3Array* texCoords = new osg::Vec3Array;
297        for(osg::Vec4Array::iterator itr = _texCoords->begin();
298            itr != _texCoords->end();
299            ++itr)
300        {
301            texCoords->push_back(osg::Vec3(itr->x(),itr->y(), itr->z()));
302        }
303         _geometry->setTexCoordArray(0, texCoords);
304    }
305    else if (_maxNumTexCoordComponents==4)
306    {
307         _geometry->setTexCoordArray(0, _texCoords.get());
308    }
309
310    _geometry->addPrimitiveSet(new osg::DrawArrays(_primitiveMode, 0, _vertices->size()));
311
312    completeGeometry();
313}
314
315///////////////////////////////////////////////////////////////////////////////////////////
316//
317//  GLU style building methods
318//
319void SceneGraphBuilder::QuadricDrawStyle(GLenum aDrawStyle)
320{
321    _quadricState._drawStyle = aDrawStyle;
322}
323
324void SceneGraphBuilder::QuadricNormals(GLenum aNormals)
325{
326    _quadricState._normals = aNormals;
327}
328
329void SceneGraphBuilder::QuadricOrientation(GLenum aOrientation)
330{
331    _quadricState._orientation = aOrientation;
332}
333
334void SceneGraphBuilder::QuadricTexture(GLboolean aTexture)
335{
336    _quadricState._texture = aTexture;
337}
338
339void SceneGraphBuilder::Cylinder(GLfloat        aBase,
340                             GLfloat        aTop,
341                             GLfloat        aHeight,
342                             GLint          aSlices,
343                             GLint          aStacks)
344{
345    osg::notify(osg::NOTICE)<<"SceneGraphBuilder::Cylinder("<<aBase<<", "<<aTop<<", "<<aHeight<<", "<<aSlices<<", "<<aStacks<<") not implemented yet"<<std::endl;
346}
347
348void SceneGraphBuilder::Disk(GLfloat        inner,
349                             GLfloat        outer,
350                             GLint          slices,
351                             GLint          /*loops*/)
352{
353    double angle = 0.0;
354    double delta = 2.0*osg::PI/double(slices-1);
355
356    if (_quadricState._normals!=GLU_NONE) Normal3f(0.0f,0.0f,1.0f);
357
358    switch(_quadricState._drawStyle)
359    {
360        case(GLU_POINT):
361        {
362            Begin(GL_POINTS);
363            if (_quadricState._texture) TexCoord2f(0.5f,0.5f);
364            Vertex3f(0.0f, 0.0f, 0.0f);
365            for(GLint i=0; i<slices; ++i, angle += delta)
366            {
367                if (_quadricState._texture) TexCoord2f(GLfloat(sin(angle)*0.5+0.5), GLfloat(cos(angle)*0.5+0.5));
368                Vertex3f(outer*GLfloat(sin(angle)), outer*GLfloat(cos(angle)), 0.0f);
369            }
370            End();
371            break;
372        }
373        case(GLU_LINE):
374        {
375            Begin(GL_LINE_LOOP);
376            for(GLint i=0; i<slices; ++i, angle += delta)
377            {
378                if (_quadricState._texture) TexCoord2f(GLfloat(sin(angle)*0.5+0.5), GLfloat(cos(angle)*0.5+0.5));
379                Vertex3f(outer*GLfloat(sin(angle)), outer*GLfloat(cos(angle)), 0.0f);
380            }
381            End();
382            break;
383        }
384        case(GLU_FILL):
385        {
386            Begin(GL_TRIANGLE_FAN);
387            if (_quadricState._texture) TexCoord2f(0.5f,0.5f);
388            Vertex3f(0.0f, 0.0f, 0.0f);
389            for(GLint i=0; i<slices; ++i, angle += delta)
390            {
391                if (_quadricState._texture) TexCoord2f(GLfloat(sin(angle)*0.5+0.5), GLfloat(cos(angle)*0.5+0.5));
392                Vertex3f(outer*GLfloat(sin(angle)), outer*GLfloat(cos(angle)), 0.0f);
393            }
394            End();
395            break;
396        }
397        case(GLU_SILHOUETTE):
398        {
399            Begin(GL_LINE_LOOP);
400            for(GLint i=0; i<slices; ++i, angle += delta)
401            {
402                if (_quadricState._texture) TexCoord2f(GLfloat(sin(angle)*0.5+0.5), GLfloat(cos(angle)*0.5+0.5));
403                Vertex3f(outer*GLfloat(sin(angle)), outer*GLfloat(cos(angle)), 0.0f);
404            }
405            End();
406            break;
407        }
408    }
409}
410
411void SceneGraphBuilder::PartialDisk(GLfloat        inner,
412                                    GLfloat        outer,
413                                    GLint          slices,
414                                    GLint          loops,
415                                    GLfloat        start,
416                                    GLfloat        sweep)
417{
418    osg::notify(osg::NOTICE)<<"SceneGraphBuilder::PartialDisk("<<inner<<", "<<outer<<", "<<slices<<", "<<loops<<", "<<start<<", "<<sweep<<") not implemented yet."<<std::endl;
419    osg::notify(osg::NOTICE)<<"   quadric("<<_quadricState._drawStyle<<", "<<_quadricState._normals<<", "<<_quadricState._orientation<<", "<<_quadricState._texture<<std::endl;
420}
421
422void SceneGraphBuilder::Sphere(GLfloat        radius,
423                               GLint          /*slices*/,
424                               GLint          /*stacks*/)
425{
426    addShape(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f), radius));
427}
428
429
430///////////////////////////////////////////////////////////////////////////////////////////
431//
432//  General scene graph building methods
433//
434
435osg::Node* SceneGraphBuilder::getScene()
436{
437    if (_group.valid() && _group->getNumChildren()>0) return _group.get();
438    else if (_transform.valid() && _transform->getNumChildren()>0) return _transform.get();
439    else if (_geode.valid() && _geode->getNumDrawables()>0) return _geode.get();
440
441    return 0;
442}
443
444osg::Node* SceneGraphBuilder::takeScene()
445{
446    osg::ref_ptr<osg::Node> node;
447   
448    if (_group.valid() && _group->getNumChildren()>0) node = _group.get();
449    else if (_transform.valid() && _transform->getNumChildren()>0) node = _transform.get();
450    else if (_geode.valid() && _geode->getNumDrawables()>0) node = _geode.get();
451   
452    // reset all the pointers to properly release the scene graph
453    _geometry = 0;
454    _geode = 0;
455    _transform = 0;
456    _group = 0;
457       
458    return node.release();
459}
460
461void SceneGraphBuilder::matrixChanged()
462{
463}
464
465void SceneGraphBuilder::addAttribute(osg::StateAttribute* attribute)
466{
467    allocateStateSet();
468    _stateset->setAttribute(attribute);
469}
470
471void SceneGraphBuilder::addMode(GLenum mode, bool enabled)
472{
473    allocateStateSet();
474    _stateset->setMode(mode, enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
475}
476
477
478void SceneGraphBuilder::addTextureAttribute(unsigned int unit, osg::StateAttribute* attribute)
479{
480    allocateStateSet();
481    _stateset->setTextureAttribute(unit, attribute);
482}
483
484void SceneGraphBuilder::addTextureMode(unsigned int unit, GLenum mode, bool enabled)
485{
486    allocateStateSet();
487    _stateset->setTextureMode(unit, mode, enabled ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
488}
489
490void SceneGraphBuilder::addShape(osg::Shape* shape)
491{
492    osg::ShapeDrawable* sd = new osg::ShapeDrawable(shape);
493    sd->setColor(_color);
494   
495    addDrawable(sd);
496}
497
498void SceneGraphBuilder::addDrawable(osg::Drawable* drawable)
499{
500    if (!_geode) _geode = new osg::Geode;
501
502    if (_stateset.valid())
503    {
504        drawable->setStateSet(_stateset.get());
505        _statesetAssigned = true;
506    }
507
508    _geode->addDrawable(drawable);
509}
510
511void SceneGraphBuilder::allocateStateSet()
512{
513    if (_statesetAssigned)
514    {
515        _stateset = dynamic_cast<osg::StateSet*>(_stateset->clone(osg::CopyOp::SHALLOW_COPY));
516        _statesetAssigned = false;
517    }
518   
519    if (!_stateset) _stateset = new osg::StateSet;
520}
521
522void SceneGraphBuilder::allocateGeometry()
523{
524    if (!_geometry)
525    {
526        _geometry = new osg::Geometry;
527    }
528}
529
530void SceneGraphBuilder::completeGeometry()
531{
532    if (_geometry.valid()) addDrawable(_geometry.get());
533    _geometry = 0;
534}
Note: See TracBrowser for help on using the browser.