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

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

Ported osgGLUT based src/Demos across to being osgProducer based, and placed
them in the new examples/ directory.

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