1 // OpenSG Tutorial Example: Occlusion Culling
4 // Three algorithms are implemented "stop an wait", "multi frame"
5 // and "hierarchical multi frame"
7 // --- stop and wait ---
8 // Renders the scene in front to back order. For each object (except for the
9 // front most object) a bounding box is drawn with an occlusion query.
10 // The result is fetched immediately afterwards and if the box was visible
11 // the corresponding object is drawn.
12 // This is quite slow because of the front to back sorted rendering and
13 // the occlusions queries are stalling the graphics pipeline.
15 // --- multi frame ---
16 // Renders the whole scene first (with state sorting) and keeps
17 // the depth buffer. For each object a bounding box is drawn
18 // with an occlusion query. The results are fetched in the next frame,
19 // if the box was visible the corresponding object is drawn.
20 // This is really fast but can lead to render errors on fast camera movements.
22 // --- hierarchical multi frame ---
23 // Similar to multi frame but it tries to reduce the number of
24 // occlusion tests by doing hierarchical occlusion tests.
28 #ifdef OSG_BUILD_ACTIVE
29 // GLUT is used for window handling
32 // General OpenSG configuration, needed everywhere
33 #include <OSGConfig.h>
35 // The GLUT-OpenSG connection class
36 #include <OSGGLUTWindow.h>
38 // A little helper to simplify scene management and interaction
39 #include <OSGSimpleSceneManager.h>
41 // Methods to create simple geometry: boxes, spheres, tori etc.
42 #include <OSGSimpleGeometry.h>
44 #include <OSGGradientBackground.h>
46 #include <OSGImageFileHandler.h>
47 #include <OSGPathHandler.h>
49 #include <OSGSceneFileHandler.h>
50 #include <OSGGraphOpSeq.h>
51 #include <OSGVerifyGeoGraphOp.h>
52 #include <OSGStripeGraphOp.h>
53 #include <OSGRenderAction.h>
55 // GLUT is used for window handling
56 #include <OpenSG/OSGGLUT.h>
58 // General OpenSG configuration, needed everywhere
59 #include <OpenSG/OSGConfig.h>
61 // The GLUT-OpenSG connection class
62 #include <OpenSG/OSGGLUTWindow.h>
64 // A little helper to simplify scene management and interaction
65 #include <OpenSG/OSGSimpleSceneManager.h>
67 // Methods to create simple geometry: boxes, spheres, tori etc.
68 #include <OpenSG/OSGSimpleGeometry.h>
70 #include <OpenSG/OSGGradientBackground.h>
72 #include <OpenSG/OSGImageFileHandler.h>
73 #include <OpenSG/OSGPathHandler.h>
75 #include <OpenSG/OSGSceneFileHandler.h>
76 #include <OpenSG/OSGGraphOpSeq.h>
77 #include <OpenSG/OSGVerifyGeoGraphOp.h>
78 #include <OpenSG/OSGStripeGraphOp.h>
79 #include <OpenSG/OSGRenderAction.h>
82 OSG::SimpleSceneManagerRefPtr mgr
;
83 OSG::NodeRefPtr scene
;
85 // Standard GLUT callback functions
91 void reshape( int w
, int h
)
100 mgr
->mouseMove( x
, y
);
105 mouse(int button
, int state
, int x
, int y
)
108 mgr
->mouseButtonRelease( button
, x
, y
);
110 mgr
->mouseButtonPress( button
, x
, y
);
115 key(unsigned char key
, int , int )
123 case 'a': mgr
->turnHeadlightOn();
125 case 's': mgr
->turnHeadlightOff();
127 case 'l': mgr
->useOpenSGLogo();
129 case 'f': mgr
->setNavigationMode(OSG::Navigator::FLY
);
131 case 't': mgr
->setNavigationMode(OSG::Navigator::TRACKBALL
);
133 case 'q': mgr
->setStatistics(true);
135 case 'w': mgr
->setStatistics(false);
137 case 'o': OSG::SceneFileHandler::the()->write(scene
, "out.osb");
141 OSG::RenderAction
*ract
= mgr
->getRenderAction();
142 ract
->setOcclusionCulling(!ract
->getOcclusionCulling());
143 printf("Occlusion culling %s.\n", ract
->getOcclusionCulling() ? "enabled" : "disabled");
150 // Initialize GLUT & OpenSG and set up the scene
151 int main (int argc
, char **argv
)
154 OSG::osgInit(argc
,argv
);
157 glutInit(&argc
, argv
);
158 glutInitDisplayMode( GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
159 int winid
= glutCreateWindow("OpenSG");
160 glutReshapeFunc(reshape
);
161 glutDisplayFunc(display
);
162 glutMouseFunc(mouse
);
163 glutMotionFunc(motion
);
164 glutKeyboardFunc(key
);
166 // open a new scope, because the pointers below should go out of scope
167 // before entering glutMainLoop.
168 // Otherwise OpenSG will complain about objects being alive after shutdown.
170 // the connection between GLUT and OpenSG
171 OSG::GLUTWindowRefPtr gwin
= OSG::GLUTWindow::create();
172 gwin
->setGlutId(winid
);
175 const char *fileName
= (argc
> 1) ? argv
[1] : NULL
;
178 scene
= OSG::SceneFileHandler::the()->read(fileName
, NULL
);
182 printf("No filename given creating a default scene.\n");
183 // ok we create some spheres and one big torus around them
184 // so we can see the occlusion culling.
186 scene
= OSG::makeCoredNode
<OSG::Group
>();
188 OSG::NodeRefPtr spheres
= OSG::makeCoredNode
<OSG::Group
>();
191 for(OSG::Real32 y
=-0.5f
;y
<0.5f
;y
+=0.1f
)
193 for(OSG::Real32 x
=-0.5f
;x
<0.5f
;x
+=0.1f
)
196 m
.setTranslate(x
, y
, 0.0f
);
197 OSG::TransformRefPtr sphere_trans
;
198 OSG::NodeRefPtr sphere_trans_node
= OSG::makeCoredNode
<OSG::Transform
>(&sphere_trans
);
199 sphere_trans
->setMatrix(m
);
201 OSG::NodeRefPtr sphere
= OSG::makeSphere(3, 0.1f
);
202 sphere_trans_node
->addChild(sphere
);
204 spheres
->addChild(sphere_trans_node
);
209 OSG::NodeRefPtr torus
= OSG::makeTorus(0.5f
, 2.0f
, 32, 32);
211 scene
->addChild(spheres
);
212 scene
->addChild(torus
);
215 // create the SimpleSceneManager helper
216 mgr
= OSG::SimpleSceneManager::create();
218 mgr
->setWindow( gwin
);
219 mgr
->setRoot( scene
);
220 mgr
->setStatistics(true);
224 // create a gradient background.
225 OSG::GradientBackgroundRefPtr gback
= OSG::GradientBackground::create();
227 gback
->addLine(OSG::Color3f(0.7f
, 0.7f
, 0.8f
), 0);
228 gback
->addLine(OSG::Color3f(0.0f
, 0.1f
, 0.3f
), 1);
230 OSG::WindowRefPtr win
= mgr
->getWindow();
231 for(OSG::UInt32 i
= 0; i
< win
->getMFPort()->size(); ++i
)
233 OSG::ViewportRefPtr vp
= win
->getPort(i
);
234 vp
->setBackground(gback
);
237 OSG::commitChanges();
240 // enable occlusion culling.
241 OSG::RenderAction
*ract
= mgr
->getRenderAction();
242 ract
->setOcclusionCulling(true);
244 printf("Occlusion culling enabled.\n");
245 printf("Press 'c' to toggle occlusion culling.\n");