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

Revision 4202, 13.1 kB (checked in by robert, 9 years ago)

Added new Node/Drawable::s/getInitialBound and Node/Drawable::s/getComputeBoundCallback
methods and reimplement computeBound so that it passes back a bounding volume rather
than modifying the local one.

  • 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        // we need to set up the bounding box of the data too, so that the scene graph knows where this
230        // objects is, for both positioning the camera at start up, and most importantly for culling.
231        virtual osg::BoundingBox computeBound() const
232        {
233            osg::BoundingBox bbox;
234
235            // follow is some truely horrible code required to calculate the
236            // bounding box of the teapot.  Have used the original code above to do
237            // help compute it.
238            float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
239            long i, j, k, l;
240
241            for (i = 0; i < 10; i++) {
242              for (j = 0; j < 4; j++) {
243                for (k = 0; k < 4; k++) {
244               
245                  for (l = 0; l < 3; l++) {
246                    p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
247                    q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];
248                    if (l == 1)
249                      q[j][k][l] *= -1.0;
250                     
251                    if (i < 6) {
252                      r[j][k][l] =
253                        cpdata[patchdata[i][j * 4 + (3 - k)]][l];
254                      if (l == 0)
255                        r[j][k][l] *= -1.0;
256                      s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
257                      if (l == 0)
258                        s[j][k][l] *= -1.0;
259                      if (l == 1)
260                        s[j][k][l] *= -1.0;
261                    }
262                  }
263                 
264                  bbox.expandBy(osg::Vec3(p[j][k][0],p[j][k][1],p[j][k][2]));
265                  bbox.expandBy(osg::Vec3(q[j][k][0],q[j][k][1],q[j][k][2]));
266
267                  if (i < 6)
268                  {
269                    bbox.expandBy(osg::Vec3(r[j][k][0],r[j][k][1],r[j][k][2]));
270                    bbox.expandBy(osg::Vec3(s[j][k][0],s[j][k][1],s[j][k][2]));
271                  }
272                 
273                 
274                }
275              }
276            }
277
278            return bbox;
279        }
280
281    protected:
282   
283        virtual ~Teapot() {}
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()->setDescription(arguments.getApplicationName()+" is the example which demonstrates how to encpsulate OpenGL rendering code via sublcassing of osg::Drawable..");
323    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
324    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
325   
326    // construct the viewer.
327    osgProducer::Viewer viewer(arguments);
328
329    // set up the value with sensible default event handlers.
330    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
331
332    // get details on keyboard and mouse bindings used by the viewer.
333    viewer.getUsage(*arguments.getApplicationUsage());
334
335    // if user request help write it out to cout.
336    if (arguments.read("-h") || arguments.read("--help"))
337    {
338        arguments.getApplicationUsage()->write(std::cout);
339        return 1;
340    }
341
342    // any option left unread are converted into errors to write out later.
343    arguments.reportRemainingOptionsAsUnrecognized();
344
345    // report any errors if they have occured when parsing the program aguments.
346    if (arguments.errors())
347    {
348        arguments.writeErrorMessages(std::cout);
349        return 1;
350    }
351
352    // add model to viewer.
353    viewer.setSceneData( createTeapot() );
354
355    // create the windows and run the threads.
356    viewer.realize();
357
358    while( !viewer.done() )
359    {
360        // wait for all cull and draw threads to complete.
361        viewer.sync();
362
363        // update the scene by traversing it with the the update visitor which will
364        // call all node update callbacks and animations.
365        viewer.update();
366         
367        // fire off the cull and draw traversals of the scene.
368        viewer.frame();
369       
370    }
371   
372    // wait for all cull and draw threads to complete before exit.
373    viewer.sync();
374
375    return 0;
376}
Note: See TracBrowser for help on using the browser.