1 // OpenSG example: dyndrawing2.cpp
4 // a) mouse => standard navigator
6 // '1': toggle between static and dynamic mode
15 #include <boost/tuple/tuple.hpp>
16 #include <boost/scoped_ptr.hpp>
17 #include <boost/random.hpp>
18 #include <boost/random/lagged_fibonacci.hpp>
20 #ifdef OSG_BUILD_ACTIVE
23 #include <OSGConfig.h>
24 #include <OSGSimpleGeometry.h>
25 #include <OSGGLUTWindow.h>
26 #include <OSGGradientBackground.h>
27 #include <OSGSimpleSceneManager.h>
28 #include <OSGSceneFileHandler.h>
29 #include <OSGAction.h>
30 #include <OSGFrameBufferObject.h>
31 #include <OSGRenderBuffer.h>
32 #include <OSGTextureBuffer.h>
33 #include <OSGSimpleStage.h>
34 #include <OSGPassiveViewport.h>
35 #include <OSGVisitSubTree.h>
37 #include <OSGTextureObjChunk.h>
38 #include <OSGFBOBackground.h>
39 #include <OSGFBOGrabForeground.h>
43 #include <OpenSG/OSGGLUT.h>
44 #include <OpenSG/OSGConfig.h>
45 #include <OpenSG/OSGSimpleGeometry.h>
46 #include <OpenSG/OSGGLUTWindow.h>
47 #include <OpenSG/OSGGradientBackground.h>
48 #include <OpenSG/OSGSimpleSceneManager.h>
49 #include <OpenSG/OSGSceneFileHandler.h>
50 #include <OpenSG/OSGAction.h>
51 #include <OpenSG/OSGFrameBufferObject.h>
52 #include <OpenSG/OSGRenderBuffer.h>
53 #include <OpenSG/OSGTextureBuffer.h>
54 #include <OpenSG/OSGSimpleStage.h>
55 #include <OpenSG/OSGPassiveViewport.h>
56 #include <OpenSG/OSGVisitSubTree.h>
57 #include <OpenSG/OSGImage.h>
58 #include <OpenSG/OSGTextureObjChunk.h>
59 #include <OpenSG/OSGFBOBackground.h>
63 OSG_USING_NAMESPACE
// just for convenience but not recommended
65 //#define USE_MULTISAMPLING
68 // The number of tori to render
69 // ============================
72 const int max_tori
= 500;
74 const int max_tori
= 10000;
78 // Helper class for building FBO used by SimpleFBO see below
79 // =========================================================
87 , pixel_format(Image::OSG_RGBA_PF
)
88 , type(Image::OSG_UINT8_IMAGEDATA
)
92 ~TextureData() {texObj
= NULL
; image
= NULL
; }
98 TextureObjChunkUnrecPtr texObj
;
102 typedef std::vector
<TextureData
> VecTextureDataT
;
105 FBOBuilder(const VecTextureDataT
& buffers
, bool depth
, bool stencil
, const TextureData
& ds_buffer
)
106 : _buffers(buffers
) , _depth(depth
) , _stencil(stencil
) , _ds_buffer(ds_buffer
) {}
110 FrameBufferObjectTransitPtr
operator()(UInt32 width
, UInt32 height
) const;
113 VecTextureDataT _buffers
;
116 TextureData _ds_buffer
;
119 FrameBufferObjectTransitPtr
FBOBuilder::operator()(
126 FrameBufferObjectUnrecPtr fbo
= FrameBufferObject::create();
128 // multiple color buffers
130 for (UInt32 idx
= 0; idx
< _buffers
.size(); ++idx
) {
134 if (_buffers
[idx
].enable
) {
135 ImageUnrecPtr texImg
= (_buffers
[idx
].image
== NULL
? Image::create() : _buffers
[idx
].image
);
136 TextureObjChunkUnrecPtr texObj
= (_buffers
[idx
].texObj
== NULL
? TextureObjChunk::create() : _buffers
[idx
].texObj
);
137 TextureBufferUnrecPtr texBuf
= TextureBuffer::create();
139 if (_buffers
[idx
].image
== NULL
)
140 texImg
->set(_buffers
[idx
].pixel_format
,
141 width
, height
, 1, 1, 1, 0.f
, NULL
,
143 _buffers
[idx
].main_memory
);
145 texObj
->setImage(texImg
);
146 texBuf
->setTexture(texObj
);
148 fbo
->setColorAttachment(texBuf
, idx
);
151 // no, then use simple render buffer
154 RenderBufferUnrecPtr renBuf
= RenderBuffer::create();
155 renBuf
->setInternalFormat(_buffers
[idx
].pixel_format
);
156 fbo
->setColorAttachment(renBuf
, idx
);
158 fbo
->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT
+ idx
);
161 // a sole depth buffer
163 if (_depth
&& !_stencil
) {
167 if (_ds_buffer
.enable
) {
168 ImageUnrecPtr texImg
= (_ds_buffer
.image
== NULL
? Image::create() : _ds_buffer
.image
);
169 TextureObjChunkUnrecPtr texObj
= (_ds_buffer
.texObj
== NULL
? TextureObjChunk::create() : _ds_buffer
.texObj
);
170 TextureBufferUnrecPtr texBuf
= TextureBuffer::create();
172 if (_ds_buffer
.image
== NULL
)
173 texImg
->set(_ds_buffer
.pixel_format
,
174 width
, height
, 1, 1, 1, 0.f
, NULL
,
176 _ds_buffer
.main_memory
);
178 texObj
->setImage(texImg
);
180 if (_ds_buffer
.texObj
== NULL
) {
181 texObj
->setInternalFormat(GL_DEPTH_COMPONENT24
);
182 texObj
->setExternalFormat(GL_DEPTH_COMPONENT24
);
184 texBuf
->setTexture(texObj
);
186 fbo
->setDepthAttachment(texBuf
);
189 // no, then use simple render buffer
192 RenderBufferUnrecPtr renBuf
= RenderBuffer::create();
193 renBuf
->setInternalFormat(GL_DEPTH_COMPONENT24
);
194 fbo
->setDepthAttachment(renBuf
);
198 // or a combined depth/stencil buffer
200 if (_depth
&& _stencil
) {
204 if (_ds_buffer
.enable
) {
205 ImageUnrecPtr texImg
= (_ds_buffer
.image
== NULL
? Image::create() : _ds_buffer
.image
);
206 TextureObjChunkUnrecPtr texObj
= (_ds_buffer
.texObj
== NULL
? TextureObjChunk::create() : _ds_buffer
.texObj
);
207 TextureBufferUnrecPtr texBuf
= TextureBuffer::create();
209 if (_ds_buffer
.image
== NULL
)
210 texImg
->set(GL_DEPTH_STENCIL_EXT
,
211 width
, height
, 1, 1, 1, 0.f
, NULL
,
212 GL_UNSIGNED_INT_24_8
,
213 _ds_buffer
.main_memory
);
215 texObj
->setImage(texImg
);
216 texObj
->setInternalFormat(GL_DEPTH24_STENCIL8_EXT
);
217 texObj
->setExternalFormat(GL_DEPTH_STENCIL_EXT
);
218 texBuf
->setTexture(texObj
);
220 fbo
->setDepthAttachment(texBuf
);
221 fbo
->setStencilAttachment(texBuf
);
224 // no, then use simple render buffer
227 RenderBufferUnrecPtr renBuf
= RenderBuffer::create();
228 renBuf
->setInternalFormat(GL_DEPTH24_STENCIL8
);
229 fbo
->setDepthAttachment(renBuf
);
230 fbo
->setStencilAttachment(renBuf
);
234 fbo
->setWidth (width
);
235 fbo
->setHeight(height
);
237 return FrameBufferObjectTransitPtr(fbo
);
241 // Convenience helper object wrapping the FBO uses FBOBuilder internally
242 // =====================================================================
247 SimpleFBO(UInt32 width
,
250 bool depth_stencil_textured
,
251 bool read_back_color
= true,
252 bool read_back_depth_stencil
= false);
254 SimpleFBO(UInt32 width
,
256 const std::vector
<FBOBuilder::TextureData
>& buffers
,
259 const FBOBuilder::TextureData
& ds_buffer
);
261 ~SimpleFBO() { _fbo
= NULL
; }
264 FrameBufferObject
* fbo () const { return _fbo
; }
266 FrameBufferAttachment
* colorBuffer (UInt32 idx
= 0) const { return _fbo
? _fbo
->getColorAttachments(idx
) : NULL
; }
267 FrameBufferAttachment
* depthBuffer () const { return _fbo
? _fbo
->getDepthAttachment() : NULL
; }
268 FrameBufferAttachment
* stencilBuffer () const { return _fbo
? _fbo
->getStencilAttachment() : NULL
;}
270 TextureObjChunk
* colorTexObj (UInt32 idx
= 0) const;
271 TextureObjChunk
* depthTexObj () const;
272 TextureObjChunk
* stencilTexObj () const;
275 FrameBufferObjectRecPtr _fbo
;
278 SimpleFBO::SimpleFBO(
282 bool depth_stencil_textured
,
283 bool read_back_color
,
284 bool read_back_depth_stencil
)
287 FBOBuilder::TextureData color_data
;
288 color_data
.enable
= color_textured
;
289 color_data
.main_memory
= read_back_color
;
291 FBOBuilder::TextureData depth_stencil_data
;
292 depth_stencil_data
.enable
= depth_stencil_textured
;
293 depth_stencil_data
.main_memory
= read_back_depth_stencil
;
295 FBOBuilder::VecTextureDataT color_vec
;
296 color_vec
.push_back(color_data
);
298 FBOBuilder
fbo_builder(color_vec
, true, true, depth_stencil_data
);
300 _fbo
= fbo_builder(width
, height
);
303 SimpleFBO::SimpleFBO(
306 const std::vector
<FBOBuilder::TextureData
>& buffers
,
309 const FBOBuilder::TextureData
& ds_buffer
)
312 FBOBuilder
fbo_builder(buffers
, depth
, stencil
, ds_buffer
);
314 _fbo
= fbo_builder(width
, height
);
317 TextureObjChunk
* SimpleFBO::colorTexObj(UInt32 idx
) const
319 TextureBuffer
* texBuf
= dynamic_cast<TextureBuffer
*>(colorBuffer(idx
));
321 return texBuf
->getTexture();
326 TextureObjChunk
* SimpleFBO::depthTexObj() const
328 TextureBuffer
* texBuf
= dynamic_cast<TextureBuffer
*>(depthBuffer());
330 return texBuf
->getTexture();
335 TextureObjChunk
* SimpleFBO::stencilTexObj() const
337 TextureBuffer
* texBuf
= dynamic_cast<TextureBuffer
*>(stencilBuffer());
339 return texBuf
->getTexture();
345 // function forward declarations
346 // =============================
348 static void cleanup(void);
349 static void display(void);
350 static void reshape(int w
, int h
);
351 static void mouse(int button
, int state
, int x
, int y
);
352 static void motion(int x
, int y
);
353 static void keyboard(unsigned char k
, int, int);
354 static int setupGLUT(int *argc
, char *argv
[]);
355 static int doMain(int argc
, char *argv
[]);
358 static NodeTransitPtr
createStaticScene();
359 static NodeTransitPtr
createDynamicScene();
361 static void applyRenderMode();
362 static void enableStaticRendering();
363 static void enableDynamicRendering();
366 static Node
* rootNode(Node
* node
);
370 // global state of example
371 // =======================
373 bool static_render_mode
;
374 SimpleSceneManagerRefPtr mgr
;
375 NodeRefPtr staticScene
;
376 NodeRefPtr dynamicScene
;
377 GLUTWindowRefPtr win
;
378 ViewportRefPtr viewport
;
379 GradientBackgroundRefPtr background
;
381 boost::scoped_ptr
<SimpleFBO
> spSimpleFBO
;
384 // functions implementation
385 // ========================
388 static void cleanup(void)
399 static void display(void)
405 static void reshape(int w
, int h
)
411 static void mouse(int button
, int state
, int x
, int y
)
414 mgr
->mouseButtonRelease(button
, x
, y
);
416 mgr
->mouseButtonPress(button
, x
, y
);
421 static void motion(int x
, int y
)
423 mgr
->mouseMove(x
, y
);
427 static void keyboard(unsigned char k
, int, int)
438 std::exit(EXIT_SUCCESS
);
444 static_render_mode
= !static_render_mode
;
455 static int setupGLUT(int *argc
, char *argv
[])
457 glutInit(argc
, argv
);
460 GLUT_RGB
| GLUT_DEPTH
| GLUT_STENCIL
| GLUT_DOUBLE
461 #ifdef USE_MULTISAMPLING
466 int winid
= glutCreateWindow("OpenSG");
468 glutReshapeFunc(reshape
);
469 glutDisplayFunc(display
);
470 glutIdleFunc(display
);
471 glutMouseFunc(mouse
);
472 glutMotionFunc(motion
);
473 glutKeyboardFunc(keyboard
);
481 static int doMain(int argc
, char *argv
[])
483 preloadSharedObject("OSGFileIO");
484 preloadSharedObject("OSGImageFileIO");
488 int winid
= setupGLUT(&argc
, argv
);
490 win
= GLUTWindow::create();
491 win
->setGlutId(winid
);
496 FWARNING(("No file given!\n"));
497 FWARNING(("Supported file formats:\n"));
499 std::list
<const char*> suffixes
;
500 SceneFileHandler::the()->getSuffixList(suffixes
);
502 for(std::list
<const char*>::iterator it
= suffixes
.begin();
503 it
!= suffixes
.end();
506 FWARNING(("%s\n", *it
));
509 staticScene
= createStaticScene();
513 staticScene
= SceneFileHandler::the()->read(argv
[1]);
516 dynamicScene
= createDynamicScene();
518 spSimpleFBO
.reset(new SimpleFBO(2, 2, true, true, true, false));
522 NodeUnrecPtr root
= makeCoredNode
<Group
>();
524 mgr
= SimpleSceneManager::create();
528 background
= GradientBackground::create();
529 background
->addLine(Color3f(0,0,0), 0);
530 background
->addLine(Color3f(1,1,1), 1);
532 viewport
= win
->getPort(0);
533 viewport
->setBackground(background
);
535 static_render_mode
= true;
544 // create an arbitrarly complex render scene
546 static NodeTransitPtr
createStaticScene()
548 NodeUnrecPtr root
= makeCoredNode
<Group
>();
550 typedef boost::mt19937 base_generator_type
;
551 static base_generator_type
generator(0);
552 static boost::uniform_01
<float> value
;
553 static boost::variate_generator
< base_generator_type
, boost::uniform_01
<float> > die(generator
, value
);
555 for (int i
= 0; i
< max_tori
; ++i
) {
556 NodeUnrecPtr scene
= makeTorus(.5, 2, 32, 32);
558 TransformUnrecPtr transformCore
= Transform::create();
563 float x
= 500.f
* die();
564 float y
= 500.f
* die();
565 float z
= 500.f
* die();
574 float a
= TwoPi
* die();
578 mat
.setTranslate(x
,y
,z
);
581 transformCore
->setMatrix(mat
);
583 NodeUnrecPtr trafo
= makeNodeFor(transformCore
);
585 trafo
->addChild(scene
);
587 root
->addChild(trafo
);
590 return NodeTransitPtr(root
);
593 static NodeTransitPtr
createDynamicScene()
595 NodeUnrecPtr scene
= makeCylinder(30, 100, 16, true, true, true);
596 return NodeTransitPtr(scene
);
599 static void applyRenderMode()
601 if (static_render_mode
)
603 enableStaticRendering();
607 enableDynamicRendering();
611 static void enableStaticRendering()
613 // UInt32 width = win->getWidth();
614 // UInt32 height = win->getHeight();
616 FBOGrabForegroundUnrecPtr fboGrabForeground
= FBOGrabForeground::create();
617 fboGrabForeground
->setFrameBufferObject(spSimpleFBO
->fbo());
618 fboGrabForeground
->setAutoResize(true);
620 viewport
->addForeground(fboGrabForeground
);
621 viewport
->setBackground(background
);
623 NodeUnrecPtr root
= makeCoredNode
<Group
>();
624 root
->addChild(staticScene
);
628 static void enableDynamicRendering()
630 FBOBackgroundUnrecPtr fboBckgnd
= FBOBackground::create();
631 fboBckgnd
->setFrameBufferObject(spSimpleFBO
->fbo());
633 viewport
->clearForegrounds();
634 viewport
->setBackground(fboBckgnd
);
636 NodeUnrecPtr root
= makeCoredNode
<Group
>();
637 root
->addChild(dynamicScene
);
642 static Node
* rootNode(Node
* node
)
647 node
= node
->getParent();
656 int main(int argc
, char *argv
[])
658 int ret
= doMain(argc
, argv
);