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

Revision 7074, 12.6 kB (checked in by robert, 7 years ago)

Added include/osg/GLObjects + .cpp which provide osg::flush*DeletedGLObjects() methods.

Added and cleaned up DeleteHandler? calls in osgViewer to help avoid crashes on exit.

Changed DatabasePager? across to dynamically checcking osg::getCompileContext(..)

Updated wrappers.

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