root/OpenSceneGraph/trunk/examples/osgteapot/osgteapot.cpp @ 1832

Revision 1832, 12.9 kB (checked in by robert, 11 years ago)

Changed the Viewer::realize() calls across to not using the threading paramter
leaving it up to the Viewer to specify the mode (which by default is MultiThreaded?).
Added a check for the presence of osgParticle systems so that threading is
disabled in this case.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/Geode>
2#include <osg/TexGen>
3#include <osg/Texture2D>
4
5#include <osgDB/ReadFile>
6
7#include <osgProducer/Viewer>
8
9
10// The classic OpenGL teapot... taken form glut-3.7/lib/glut/glut_teapot.c
11
12/* Copyright (c) Mark J. Kilgard, 1994. */
13
14/**
15(c) Copyright 1993, Silicon Graphics, Inc.
16
17ALL RIGHTS RESERVED
18
19Permission to use, copy, modify, and distribute this software
20for any purpose and without fee is hereby granted, provided
21that the above copyright notice appear in all copies and that
22both the copyright notice and this permission notice appear in
23supporting documentation, and that the name of Silicon
24Graphics, Inc. not be used in advertising or publicity
25pertaining to distribution of the software without specific,
26written prior permission.
27
28THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
29"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
30OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
31MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  IN NO
32EVENT SHALL SILICON GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE
33ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
34CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
35INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
36SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
37NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF THE POSSIBILITY
38OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
40PERFORMANCE OF THIS SOFTWARE.
41
42US Government Users Restricted Rights
43
44Use, duplication, or disclosure by the Government is subject to
45restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
46(c)(1)(ii) of the Rights in Technical Data and Computer
47Software clause at DFARS 252.227-7013 and/or in similar or
48successor clauses in the FAR or the DOD or NASA FAR
49Supplement.  Unpublished-- rights reserved under the copyright
50laws of the United States.  Contractor/manufacturer is Silicon
51Graphics, Inc., 2011 N.  Shoreline Blvd., Mountain View, CA
5294039-7311.
53
54OpenGL(TM) is a trademark of Silicon Graphics, Inc.
55*/
56
57
58/* Rim, body, lid, and bottom data must be reflected in x and
59   y; handle and spout data across the y axis only.  */
60
61static int patchdata[][16] =
62{
63    /* rim */
64  {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11,
65    12, 13, 14, 15},
66    /* body */
67  {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
68    24, 25, 26, 27},
69  {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36,
70    37, 38, 39, 40},
71    /* lid */
72  {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101,
73    101, 0, 1, 2, 3,},
74  {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112,
75    113, 114, 115, 116, 117},
76    /* bottom */
77  {118, 118, 118, 118, 124, 122, 119, 121, 123, 126,
78    125, 120, 40, 39, 38, 37},
79    /* handle */
80  {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
81    53, 54, 55, 56},
82  {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
83    28, 65, 66, 67},
84    /* spout */
85  {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
86    80, 81, 82, 83},
87  {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
88    92, 93, 94, 95}
89};
90/* *INDENT-OFF* */
91
92static float cpdata[][3] =
93{
94    {0.2, 0, 2.7}, {0.2, -0.112, 2.7}, {0.112, -0.2, 2.7}, {0,
95    -0.2, 2.7}, {1.3375, 0, 2.53125}, {1.3375, -0.749, 2.53125},
96    {0.749, -1.3375, 2.53125}, {0, -1.3375, 2.53125}, {1.4375,
97    0, 2.53125}, {1.4375, -0.805, 2.53125}, {0.805, -1.4375,
98    2.53125}, {0, -1.4375, 2.53125}, {1.5, 0, 2.4}, {1.5, -0.84,
99    2.4}, {0.84, -1.5, 2.4}, {0, -1.5, 2.4}, {1.75, 0, 1.875},
100    {1.75, -0.98, 1.875}, {0.98, -1.75, 1.875}, {0, -1.75,
101    1.875}, {2, 0, 1.35}, {2, -1.12, 1.35}, {1.12, -2, 1.35},
102    {0, -2, 1.35}, {2, 0, 0.9}, {2, -1.12, 0.9}, {1.12, -2,
103    0.9}, {0, -2, 0.9}, {-2, 0, 0.9}, {2, 0, 0.45}, {2, -1.12,
104    0.45}, {1.12, -2, 0.45}, {0, -2, 0.45}, {1.5, 0, 0.225},
105    {1.5, -0.84, 0.225}, {0.84, -1.5, 0.225}, {0, -1.5, 0.225},
106    {1.5, 0, 0.15}, {1.5, -0.84, 0.15}, {0.84, -1.5, 0.15}, {0,
107    -1.5, 0.15}, {-1.6, 0, 2.025}, {-1.6, -0.3, 2.025}, {-1.5,
108    -0.3, 2.25}, {-1.5, 0, 2.25}, {-2.3, 0, 2.025}, {-2.3, -0.3,
109    2.025}, {-2.5, -0.3, 2.25}, {-2.5, 0, 2.25}, {-2.7, 0,
110    2.025}, {-2.7, -0.3, 2.025}, {-3, -0.3, 2.25}, {-3, 0,
111    2.25}, {-2.7, 0, 1.8}, {-2.7, -0.3, 1.8}, {-3, -0.3, 1.8},
112    {-3, 0, 1.8}, {-2.7, 0, 1.575}, {-2.7, -0.3, 1.575}, {-3,
113    -0.3, 1.35}, {-3, 0, 1.35}, {-2.5, 0, 1.125}, {-2.5, -0.3,
114    1.125}, {-2.65, -0.3, 0.9375}, {-2.65, 0, 0.9375}, {-2,
115    -0.3, 0.9}, {-1.9, -0.3, 0.6}, {-1.9, 0, 0.6}, {1.7, 0,
116    1.425}, {1.7, -0.66, 1.425}, {1.7, -0.66, 0.6}, {1.7, 0,
117    0.6}, {2.6, 0, 1.425}, {2.6, -0.66, 1.425}, {3.1, -0.66,
118    0.825}, {3.1, 0, 0.825}, {2.3, 0, 2.1}, {2.3, -0.25, 2.1},
119    {2.4, -0.25, 2.025}, {2.4, 0, 2.025}, {2.7, 0, 2.4}, {2.7,
120    -0.25, 2.4}, {3.3, -0.25, 2.4}, {3.3, 0, 2.4}, {2.8, 0,
121    2.475}, {2.8, -0.25, 2.475}, {3.525, -0.25, 2.49375},
122    {3.525, 0, 2.49375}, {2.9, 0, 2.475}, {2.9, -0.15, 2.475},
123    {3.45, -0.15, 2.5125}, {3.45, 0, 2.5125}, {2.8, 0, 2.4},
124    {2.8, -0.15, 2.4}, {3.2, -0.15, 2.4}, {3.2, 0, 2.4}, {0, 0,
125    3.15}, {0.8, 0, 3.15}, {0.8, -0.45, 3.15}, {0.45, -0.8,
126    3.15}, {0, -0.8, 3.15}, {0, 0, 2.85}, {1.4, 0, 2.4}, {1.4,
127    -0.784, 2.4}, {0.784, -1.4, 2.4}, {0, -1.4, 2.4}, {0.4, 0,
128    2.55}, {0.4, -0.224, 2.55}, {0.224, -0.4, 2.55}, {0, -0.4,
129    2.55}, {1.3, 0, 2.55}, {1.3, -0.728, 2.55}, {0.728, -1.3,
130    2.55}, {0, -1.3, 2.55}, {1.3, 0, 2.4}, {1.3, -0.728, 2.4},
131    {0.728, -1.3, 2.4}, {0, -1.3, 2.4}, {0, 0, 0}, {1.425,
132    -0.798, 0}, {1.5, 0, 0.075}, {1.425, 0, 0}, {0.798, -1.425,
133    0}, {0, -1.5, 0.075}, {0, -1.425, 0}, {1.5, -0.84, 0.075},
134    {0.84, -1.5, 0.075}
135};
136
137static float tex[2][2][2] =
138{
139  { {0, 0},
140    {1, 0}},
141  { {0, 1},
142    {1, 1}}
143};
144
145/* *INDENT-ON* */
146
147static void
148teapot(GLint grid, GLenum type)
149{
150  float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
151  long i, j, k, l;
152
153  glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT);
154  glEnable(GL_AUTO_NORMAL);
155  glEnable(GL_NORMALIZE);
156  glEnable(GL_MAP2_VERTEX_3);
157  glEnable(GL_MAP2_TEXTURE_COORD_2);
158  for (i = 0; i < 10; i++) {
159    for (j = 0; j < 4; j++) {
160      for (k = 0; k < 4; k++) {
161        for (l = 0; l < 3; l++) {
162          p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
163          q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];
164          if (l == 1)
165            q[j][k][l] *= -1.0;
166          if (i < 6) {
167            r[j][k][l] =
168              cpdata[patchdata[i][j * 4 + (3 - k)]][l];
169            if (l == 0)
170              r[j][k][l] *= -1.0;
171            s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
172            if (l == 0)
173              s[j][k][l] *= -1.0;
174            if (l == 1)
175              s[j][k][l] *= -1.0;
176          }
177        }
178      }
179    }
180    glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2,
181      &tex[0][0][0]);
182    glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
183      &p[0][0][0]);
184    glMapGrid2f(grid, 0.0, 1.0, grid, 0.0, 1.0);
185    glEvalMesh2(type, 0, grid, 0, grid);
186    glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
187      &q[0][0][0]);
188    glEvalMesh2(type, 0, grid, 0, grid);
189    if (i < 6) {
190      glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
191        &r[0][0][0]);
192      glEvalMesh2(type, 0, grid, 0, grid);
193      glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
194        &s[0][0][0]);
195      glEvalMesh2(type, 0, grid, 0, grid);
196    }
197  }
198  glPopAttrib();
199}
200
201
202// Now the OSG wrapper for the above OpenGL code, the most complicated bit is computing
203// the bounding box for the above example, normally you'll find this the easy bit.
204class Teapot : public osg::Drawable
205{
206    public:
207        Teapot() {}
208
209        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
210        Teapot(const Teapot& teapot,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
211            osg::Drawable(teapot,copyop) {}
212
213        META_Object(myTeapotApp,Teapot)
214
215
216        // the draw immediate mode method is where the OSG wraps up the drawing of
217        // of OpenGL primitives.
218        virtual void drawImplementation(osg::State&) const
219        {
220            // teapot(..) doens't use vertex arrays at all so we don't need to toggle their state
221            // if we did we'd need to something like following call
222            // state.disableAllVertexArrays(), see src/osg/Geometry.cpp for the low down.
223       
224            // just call the OpenGL code.
225            teapot(14,GL_FILL);
226        }
227       
228       
229    protected:
230   
231        virtual ~Teapot() {}
232       
233        // we need to set up the bounding box of the data too, so that the scene graph knows where this
234        // objects is, for both positioning the camera at start up, and most importantly for culling.
235        virtual bool computeBound() const
236        {
237            _bbox.init();
238
239            // follow is some truely horrible code required to calculate the
240            // bounding box of the teapot.  Have used the original code above to do
241            // help compute it.
242            float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
243            long i, j, k, l;
244
245            for (i = 0; i < 10; i++) {
246              for (j = 0; j < 4; j++) {
247                for (k = 0; k < 4; k++) {
248               
249                  for (l = 0; l < 3; l++) {
250                    p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
251                    q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];
252                    if (l == 1)
253                      q[j][k][l] *= -1.0;
254                     
255                    if (i < 6) {
256                      r[j][k][l] =
257                        cpdata[patchdata[i][j * 4 + (3 - k)]][l];
258                      if (l == 0)
259                        r[j][k][l] *= -1.0;
260                      s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
261                      if (l == 0)
262                        s[j][k][l] *= -1.0;
263                      if (l == 1)
264                        s[j][k][l] *= -1.0;
265                    }
266                  }
267                 
268                  _bbox.expandBy(osg::Vec3(p[j][k][0],p[j][k][1],p[j][k][2]));
269                  _bbox.expandBy(osg::Vec3(q[j][k][0],q[j][k][1],q[j][k][2]));
270
271                  if (i < 6)
272                  {
273                    _bbox.expandBy(osg::Vec3(r[j][k][0],r[j][k][1],r[j][k][2]));
274                    _bbox.expandBy(osg::Vec3(s[j][k][0],s[j][k][1],s[j][k][2]));
275                  }
276                 
277                 
278                }
279              }
280            }
281
282            _bbox_computed = true;
283            return true;
284        }
285};
286
287
288osg::Geode* createTeapot()
289{
290    osg::Geode* geode = new osg::Geode();
291
292    // add the teapot to the geode.
293    geode->addDrawable( new Teapot );
294
295    // add a reflection map to the teapot.     
296    osg::Image* image = osgDB::readImageFile("Images/reflect.rgb");
297    if (image)
298    {
299        osg::Texture2D* texture = new osg::Texture2D;
300        texture->setImage(image);
301
302        osg::TexGen* texgen = new osg::TexGen;
303        texgen->setMode(osg::TexGen::SPHERE_MAP);
304
305        osg::StateSet* stateset = new osg::StateSet;
306        stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
307        stateset->setTextureAttributeAndModes(0,texgen,osg::StateAttribute::ON);
308       
309        geode->setStateSet(stateset);
310    }
311   
312    return geode;
313}
314
315int main( int argc, char **argv )
316{
317
318    // use an ArgumentParser object to manage the program arguments.
319    osg::ArgumentParser arguments(&argc,argv);
320
321    // set up the usage document, in case we need to print out how to use this program.
322    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
323    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
324   
325    // construct the viewer.
326    osgProducer::Viewer viewer(arguments);
327
328    // set up the value with sensible default event handlers.
329    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
330
331    // get details on keyboard and mouse bindings used by the viewer.
332    viewer.getUsage(*arguments.getApplicationUsage());
333
334    // if user request help write it out to cout.
335    if (arguments.read("-h") || arguments.read("--help"))
336    {
337        arguments.getApplicationUsage()->write(std::cout);
338        return 1;
339    }
340
341    // any option left unread are converted into errors to write out later.
342    arguments.reportRemainingOptionsAsUnrecognized();
343
344    // report any errors if they have occured when parsing the program aguments.
345    if (arguments.errors())
346    {
347        arguments.writeErrorMessages(std::cout);
348        return 1;
349    }
350
351    // add model to viewer.
352    viewer.setSceneData( createTeapot() );
353
354    // create the windows and run the threads.
355    viewer.realize();
356
357    while( !viewer.done() )
358    {
359        // wait for all cull and draw threads to complete.
360        viewer.sync();
361
362        // update the scene by traversing it with the the update visitor which will
363        // call all node update callbacks and animations.
364        viewer.update();
365         
366        // fire off the cull and draw traversals of the scene.
367        viewer.frame();
368       
369    }
370   
371    // wait for all cull and draw threads to complete before exit.
372    viewer.sync();
373
374    return 0;
375}
Note: See TracBrowser for help on using the browser.