4 // This demonstates the use of the DeferredShadingStage and the
5 // Shader/TrapezoidalShadowMapEngine with it.
7 // The program must be run from the Examples/Advanced/DeferredShading directory
8 // so that it can find the files with the GLSL source for the shader programs.
10 // Please take a look at the keyboard glut callback for the interface
14 #ifdef OSG_BUILD_ACTIVE
18 #include <OSGGLUTWindow.h>
19 #include <OSGSceneFileHandler.h>
20 #include <OSGSimpleGeometry.h>
21 #include <OSGSimpleSceneManager.h>
22 #include <OSGSimpleTexturedMaterial.h>
24 #include <OSGDeferredShadingStage.h>
25 #include <OSGDirectionalLight.h>
26 #include <OSGPointLight.h>
27 #include <OSGSpotLight.h>
29 #include <OSGShaderShadowMapEngine.h>
30 #include <OSGTrapezoidalShadowMapEngine.h>
33 #include <OSGShaderProgram.h>
34 #include <OSGShaderProgramChunk.h>
36 #else // OSG_BUILD_INTEGRATED
38 #include <OpenSG/OSGGL.h>
39 #include <OpenSG/OSGGLUT.h>
40 #include <OpenSG/OSGGLUTWindow.h>
41 #include <OpenSG/OSGSceneFileHandler.h>
42 #include <OpenSG/OSGSimpleGeometry.h>
43 #include <OpenSG/OSGSimpleSceneManager.h>
44 #include <OpenSG/OSGSimpleTexturedMaterial.h>
46 #include <OpenSG/OSGDeferredShadingStage.h>
47 #include <OpenSG/OSGDirectionalLight.h>
48 #include <OpenSG/OSGPointLight.h>
49 #include <OpenSG/OSGSpotLight.h>
51 #include <OpenSG/OSGShaderShadowMapEngine.h>
52 #include <OpenSG/OSGTrapezoidalShadowMapEngine.h>
55 #include <OpenSG/OSGShaderProgram.h>
56 #include <OpenSG/OSGShaderProgramChunk.h>
58 #endif // OSG_BUILD_INTEGRATED
73 LightEngine::LightTypeE lightType
;
74 ShadowTypeE shadowType
;
79 ShaderProgramUnrecPtr lightVP
;
80 ShaderProgramUnrecPtr lightFP
;
81 ShaderProgramChunkUnrecPtr lightSH
;
84 lightType (LightEngine::Spot
),
98 std::ostream
&operator << (std::ostream
&os
, const LightInfo
&li
);
102 SimpleSceneManagerRefPtr mgr
;
103 GLUTWindowUnrecPtr glutWin
;
107 NodeUnrecPtr dsStageN
;
108 DeferredShadingStageUnrecPtr dsStage
;
113 std::vector
<LightInfo
> lightInfos
;
118 LightEngine::LightTypeE newLightType
;
119 ShadowTypeE newShadowType
;
123 UInt32 shadowMapWidth
;
124 UInt32 shadowMapHeight
;
140 animateLights (false ),
141 colorLights (false ),
143 newLightType (LightEngine::Spot
),
144 newShadowType (ST_NONE
),
148 shadowMapWidth (128 ),
149 shadowMapHeight(128 )
156 const std::string
dsGBufferVPFile ("DSGBuffer.vp.glsl" );
157 const std::string
dsGBufferFPFile ("DSGBuffer.fp.glsl" );
159 const std::string
dsAmbientVPFile ("DSAmbient.vp.glsl" );
160 const std::string
dsAmbientFPFile ("DSAmbient.fp.glsl" );
162 const std::string
dsDirLightVPFile ("DSDirLight.vp.glsl" );
163 const std::string
dsDirLightFPFile ("DSDirLight.fp.glsl" );
164 const std::string
dsDirLightShadowFPFile ("DSDirLightShadow.fp.glsl" );
166 const std::string
dsPointLightVPFile ("DSPointLight.vp.glsl" );
167 const std::string
dsPointLightFPFile ("DSPointLight.fp.glsl" );
168 const std::string
dsPointLightShadowFPFile("DSPointLightShadow.fp.glsl");
170 const std::string
dsSpotLightVPFile ("DSSpotLight.vp.glsl" );
171 const std::string
dsSpotLightFPFile ("DSSpotLight.fp.glsl" );
172 const std::string
dsSpotLightShadowFPFile ("DSSpotLightShadow.fp.glsl" );
174 const std::string
dsUnknownFile ("unknownFile");
176 void initialize(int argc
, char *argv
[]);
177 void cleanup (void );
179 void buildDSStage (void );
180 NodeTransitPtr
loadScene (const std::string
&fileName
);
181 NodeTransitPtr
buildTestScene(UInt32 nX
, UInt32 nZ
);
183 void addLight (LightEngine::LightTypeE lightType
, ShadowTypeE shadowType
);
184 void setShadow(UInt32 lightIdx
, ShadowTypeE shadowType
);
185 void setColorLights(bool colLights
);
187 int setupGLUT (int *argc
, char *argv
[]);
188 void keyboard(unsigned char k
, int , int );
190 int main(int argc
, char *argv
[])
192 initialize(argc
, argv
);
195 // keyboard('+', 0, 0);
208 void initialize(int argc
, char *argv
[])
212 gv
= new GlobalValues
;
213 gv
->animateLights
= false;
214 gv
->colorLights
= false;
215 gv
->newLightType
= LightEngine::Spot
;
216 gv
->newShadowType
= ST_NONE
;
217 gv
->currentLight
= -1;
218 gv
->shadowMapWidth
= 1024;
219 gv
->shadowMapHeight
= 1024;
221 int glutWinId
= setupGLUT(&argc
, argv
);
223 gv
->glutWin
= GLUTWindow::create();
224 gv
->glutWin
->setGlutId(glutWinId
);
225 gv
->glutWin
->init ( );
227 gv
->mgr
= SimpleSceneManager::create();
229 // tell the manager what to manage
230 gv
->mgr
->setWindow(gv
->glutWin
);
232 // HACK: force creation of internal SSM objects (vp, cam, bg etc)
233 gv
->mgr
->setRoot(NULL
);
235 gv
->mgr
->getWindow()->getPort(0)->setSize(0.1f
, 0.f
, 0.8f
, 1.f
);
237 // create a "scene" to show
240 std::string fileName
= argv
[1];
242 gv
->sceneN
= makeCoredNode
<Group
>();
244 gv
->objN
= loadScene(fileName
);
245 gv
->sceneN
->addChild(gv
->objN
);
248 if(gv
->sceneN
== NULL
)
250 gv
->sceneN
= makeCoredNode
<Group
>();
251 gv
->objN
= buildTestScene(5, 5);
253 gv
->sceneN
->addChild(gv
->objN
);
256 gv
->rootN
= makeCoredNode
<Group
>();
260 gv
->dsStageN
->addChild(gv
->sceneN
);
261 gv
->rootN
->addChild(gv
->dsStageN
);
263 gv
->mgr
->setRoot(gv
->rootN
);
278 // creates the deferred shading stage and configures the required buffers.
279 // this assumes that all materials in the scene are regular enough as to be
280 // written with a single shader to the buffers (e.g. everything has a single
282 // alternatively the GBufferProgram can be left empty and all materials in the
283 // scene are set up to write to the correct buffers.
284 void buildDSStage(void)
286 ShaderProgramUnrecPtr vpGBuffer
= ShaderProgram::createVertexShader ();
287 ShaderProgramUnrecPtr fpGBuffer
= ShaderProgram::createFragmentShader();
289 ShaderProgramUnrecPtr vpAmbient
= ShaderProgram::createVertexShader ();
290 ShaderProgramUnrecPtr fpAmbient
= ShaderProgram::createFragmentShader();
292 ShaderProgramChunkUnrecPtr shGBuffer
= ShaderProgramChunk::create();
293 ShaderProgramChunkUnrecPtr shAmbient
= ShaderProgramChunk::create();
295 gv
->dsStage
= DeferredShadingStage::create();
296 gv
->dsStageN
= makeNodeFor(gv
->dsStage
);
298 gv
->dsStage
->setCamera(gv
->mgr
->getCamera());
300 // positions (RGB) + ambient (A) term buffer
301 gv
->dsStage
->editMFPixelFormats()->push_back(Image::OSG_RGBA_PF
);
302 gv
->dsStage
->editMFPixelTypes ()->push_back(Image::OSG_FLOAT32_IMAGEDATA
);
304 // normals (RGB) buffer
305 gv
->dsStage
->editMFPixelFormats()->push_back(Image::OSG_RGB_PF
);
306 gv
->dsStage
->editMFPixelTypes ()->push_back(Image::OSG_FLOAT32_IMAGEDATA
);
308 // diffuse (RGB) buffer
309 gv
->dsStage
->editMFPixelFormats()->push_back(Image::OSG_RGB_PF
);
310 gv
->dsStage
->editMFPixelTypes ()->push_back(Image::OSG_UINT8_IMAGEDATA
);
312 // G Buffer shader (one for the whole scene)
313 vpGBuffer
->readProgram(dsGBufferVPFile
.c_str());
314 fpGBuffer
->readProgram(dsGBufferFPFile
.c_str());
316 fpGBuffer
->addUniformVariable
<Int32
>("tex0", 0);
318 shGBuffer
->addShader(vpGBuffer
);
319 shGBuffer
->addShader(fpGBuffer
);
321 gv
->dsStage
->setGBufferProgram(shGBuffer
);
324 vpAmbient
->readProgram(dsAmbientVPFile
.c_str());
325 fpAmbient
->readProgram(dsAmbientFPFile
.c_str());
327 fpAmbient
->addUniformVariable
<Int32
>("texBufNorm", 1);
329 shAmbient
->addShader(vpAmbient
);
330 shAmbient
->addShader(fpAmbient
);
332 gv
->dsStage
->setAmbientProgram(shAmbient
);
335 std::string
mapShadowType(ShadowTypeE shadowType
)
337 std::string shadow
= "unknown";
350 shadow
= "Trapezoidal";
357 std::string
mapLightType(LightEngine::LightTypeE lightType
)
359 std::string light
= "unknown";
363 case LightEngine::Directional
:
364 light
= "Directional";
367 case LightEngine::Point
:
371 case LightEngine::Spot
:
379 // file containing vertex shader code for the light type
380 const std::string
&getLightVPFile(
381 LightEngine::LightTypeE lightType
,
382 ShadowTypeE shadowType
)
386 case LightEngine::Directional
:
387 return dsDirLightVPFile
;
389 case LightEngine::Point
:
390 return dsPointLightVPFile
;
392 case LightEngine::Spot
:
393 return dsSpotLightVPFile
;
396 return dsUnknownFile
;
399 // file containing fragment shader code for the light type
400 const std::string
&getLightFPFile(
401 LightEngine::LightTypeE lightType
,
402 ShadowTypeE shadowType
)
406 case LightEngine::Directional
:
407 if(shadowType
== ST_NONE
)
408 return dsDirLightFPFile
;
410 return dsDirLightShadowFPFile
;
412 case LightEngine::Point
:
413 if(shadowType
== ST_NONE
)
414 return dsPointLightFPFile
;
416 return dsPointLightShadowFPFile
;
418 case LightEngine::Spot
:
419 if(shadowType
== ST_NONE
)
420 return dsSpotLightFPFile
;
422 return dsSpotLightShadowFPFile
;
425 return dsUnknownFile
;
429 // adds a light of given type to the scene and makes it cast shadows
430 // of the given type.
431 void addLight(LightEngine::LightTypeE lightType
, ShadowTypeE shadowType
)
434 TransformUnrecPtr beacon
= Transform::create();
435 li
.beaconN
= makeNodeFor(beacon
);
437 li
.lightVP
= ShaderProgram ::createVertexShader ();
438 li
.lightFP
= ShaderProgram ::createFragmentShader();
439 li
.lightSH
= ShaderProgramChunk::create ();
440 li
.lightType
= lightType
;
441 li
.shadowType
= shadowType
;
445 case LightEngine::Directional
:
447 DirectionalLightUnrecPtr dirL
= DirectionalLight::create();
453 case LightEngine::Point
:
455 PointLightUnrecPtr pointL
= PointLight::create();
456 pointL
->setConstantAttenuation(1.0);
457 //pointL->setLinearAttenuation (1.e-5);
458 //pointL->setQuadraticAttenuation(2.e-5);
464 case LightEngine::Spot
:
466 SpotLightUnrecPtr spotL
= SpotLight::create();
467 spotL
->setPosition (Pnt3f(0.f
, 0.f
, 0.f
));
468 spotL
->setDirection(Vec3f(0.f
, 0.f
, -1.f
));
469 spotL
->setSpotCutOff(Pi
/6.f
);
470 spotL
->setSpotExponent(3.f
);
471 spotL
->setConstantAttenuation(1.0);
472 //spotL->setLinearAttenuation (1.e-5);
473 //spotL->setQuadraticAttenuation(2.e-5);
480 li
.light
->setBeacon(li
.beaconN
);
481 li
.lightN
= makeNodeFor(li
.light
);
483 li
.lightFP
->addUniformVariable
<Int32
>("texBufPos", 0);
484 li
.lightFP
->addUniformVariable
<Int32
>("texBufNorm", 1);
485 li
.lightFP
->addUniformVariable
<Int32
>("texBufDiff", 2);
487 li
.lightSH
->addShader(li
.lightVP
);
488 li
.lightSH
->addShader(li
.lightFP
);
490 gv
->rootN
->addChild(li
.beaconN
);
491 //gv->rootN->addChild(li.lightN );
493 gv
->dsStage
->editMFLights ()->push_back(li
.light
);
494 gv
->dsStage
->editMFLightPrograms()->push_back(li
.lightSH
);
496 gv
->lightInfos
.push_back(li
);
498 setShadow(gv
->lightInfos
.size() - 1, shadowType
);
500 setColorLights(gv
->colorLights
);
502 // add a coordinate system to show light position
503 // OSG::NodeUnrecPtr lightAxisN = OSG::makeCoordAxis(2.f);
504 // li.beaconN->addChild(lightAxisN);
507 void subLight(UInt32 lightIdx
)
509 OSG_ASSERT(lightIdx
< gv
->lightInfos
.size());
510 OSG_ASSERT(lightIdx
< gv
->dsStage
->getMFLights ()->size());
511 OSG_ASSERT(lightIdx
< gv
->dsStage
->getMFLightPrograms()->size());
513 gv
->dsStage
->editMFLights ()->erase(lightIdx
);
514 // gv->dsStage->editMFLights ()->begin() + lightIdx);
515 gv
->dsStage
->editMFLightPrograms()->erase(lightIdx
);
516 // gv->dsStage->editMFLightPrograms()->begin() + lightIdx);
518 LightInfo
&li
= gv
->lightInfos
[lightIdx
];
519 gv
->rootN
->subChild(li
.beaconN
);
521 //gv->rootN->subChild(li.lightN );
523 gv
->lightInfos
.erase(gv
->lightInfos
.begin() + lightIdx
);
525 setColorLights(gv
->colorLights
);
528 void setShadow(UInt32 lightIdx
, ShadowTypeE shadowType
)
530 OSG_ASSERT(lightIdx
< gv
->lightInfos
.size());
531 OSG_ASSERT(lightIdx
< gv
->dsStage
->getMFLights ()->size());
532 OSG_ASSERT(lightIdx
< gv
->dsStage
->getMFLightPrograms()->size());
534 LightInfo
&li
= gv
->lightInfos
[lightIdx
];
536 // li.lightSH->removeObjFromVertexShader (li.lightVP);
537 // li.lightSH->removeObjFromFragmentShader(li.lightFP);
543 li
.light
->setLightEngine(NULL
);
545 gv
->dsStage
->editMFLights ();
546 gv
->dsStage
->editMFLightPrograms();
548 li
.shadowType
= ST_NONE
;
554 ShaderShadowMapEngineUnrecPtr shadowEng
=
555 ShaderShadowMapEngine::create();
557 shadowEng
->setWidth (gv
->shadowMapWidth
);
558 shadowEng
->setHeight(gv
->shadowMapHeight
);
559 shadowEng
->setOffsetFactor( 4.5f
);
560 shadowEng
->setOffsetBias (16.f
);
561 shadowEng
->setForceTextureUnit(3);
563 gv
->dsStage
->editMFLights ();
564 gv
->dsStage
->editMFLightPrograms();
566 li
.light
->setLightEngine(shadowEng
);
567 li
.shadowType
= ST_STANDARD
;
573 if(li
.lightType
!= LightEngine::Directional
)
575 TrapezoidalShadowMapEngineUnrecPtr shadowEng
=
576 TrapezoidalShadowMapEngine::create();
578 shadowEng
->setWidth (gv
->shadowMapWidth
);
579 shadowEng
->setHeight(gv
->shadowMapHeight
);
580 shadowEng
->setOffsetFactor( 4.5f
);
581 shadowEng
->setOffsetBias (16.f
);
582 shadowEng
->setForceTextureUnit(3);
584 gv
->dsStage
->editMFLights ();
585 gv
->dsStage
->editMFLightPrograms();
587 li
.light
->setLightEngine(shadowEng
);
588 li
.shadowType
= ST_TRAPEZOID
;
592 std::cout
<< "TSM not supported for diretional lights."
599 std::string vpFile
= getLightVPFile(li
.lightType
, li
.shadowType
);
600 std::string fpFile
= getLightFPFile(li
.lightType
, li
.shadowType
);
602 std::cerr
<< "vpFile [" << vpFile
<< "]" <<std::endl
;
603 std::cerr
<< "fpFile [" << fpFile
<< "]" <<std::endl
;
605 li
.lightVP
->readProgram(vpFile
.c_str());
606 li
.lightFP
->readProgram(fpFile
.c_str());
608 li
.lightFP
->addUniformVariable
<Int32
>("texBufPos", 0);
609 li
.lightFP
->addUniformVariable
<Int32
>("texBufNorm", 1);
610 li
.lightFP
->addUniformVariable
<Int32
>("texBufDiff", 2);
612 // li.lightSH->addVertexShader (li.lightVP);
613 // li.lightSH->addFragmentShader(li.lightFP);
616 void setColorLights(bool colLights
)
618 if(gv
->lightInfos
.size() > 1)
620 if(colLights
== true)
623 for(UInt32 i
= 0; i
< gv
->lightInfos
.size(); ++i
)
625 gv
->lightInfos
[i
].light
->setDiffuse(
626 Color4f( Real32(i
+1) / gv
->lightInfos
.size(),
628 1.f
- (Real32(i
+1) / gv
->lightInfos
.size()),
634 // set lights to grey
635 for(UInt32 i
= 0; i
< gv
->lightInfos
.size(); ++i
)
637 gv
->lightInfos
[i
].light
->setDiffuse(
638 Color4f(1.f
/ gv
->lightInfos
.size(),
639 1.f
/ gv
->lightInfos
.size(),
640 1.f
/ gv
->lightInfos
.size(),
645 else if(gv
->lightInfos
.empty() == false)
647 gv
->lightInfos
[0].light
->setDiffuse(Color4f(1.f
, 1.f
, 1.f
, 1.f
));
651 gv
->dsStage
->editMFLights();
653 gv
->colorLights
= colLights
;
656 void updateLightBeacon(OSG::UInt32 lightIdx
, OSG::Time t
)
658 OSG_ASSERT(lightIdx
< gv
->lightInfos
.size());
659 OSG_ASSERT(lightIdx
< gv
->dsStage
->getMFLights ()->size());
660 OSG_ASSERT(lightIdx
< gv
->dsStage
->getMFLightPrograms()->size());
662 Transform
*beacon
= dynamic_cast<Transform
*>(
663 gv
->lightInfos
[lightIdx
].beaconN
->getCore());
672 gv
->objN
->updateVolume();
673 gv
->objN
->getVolume().getBounds(bbMin
, bbMax
);
674 gv
->objN
->getVolume().getCenter(bbCenter
);
676 UInt32 numLights
= gv
->lightInfos
.size();
677 Real32 lightFract
= Real32(lightIdx
+ 1) / Real32(numLights
);
679 Vec3f bbDiag
= (bbMax
- bbMin
);
680 Real32 bbDiagLen
= bbDiag
.length();
682 Real32 angle1
= osgMod(t
/ 10.0, Real64(2.f
* Pi
));
683 Real32 angle2
= (2.f
* Pi
/ numLights
);
684 Real32 shiftVal
= 0.5f
* osgSin(4.f
* (lightFract
* angle2
+ angle1
)) + 0.25;
686 // translate to "above" center of the model
688 matXform0
.setTranslate(bbCenter
.subZero() +
689 Vec3f(0.f
, shiftVal
* bbDiag
[1] * 1.1, 0.f
));
693 Quaternion
rot1(Vec3f(0.f
, 1.f
, 0.f
), (lightIdx
+ 1) * angle2
+ angle1
);
694 matXform1
.setRotate(rot1
);
696 // translate 0.5 * bb diag along x
698 matXform2
.setTranslate(Vec3f(0.5f
* bbDiagLen
, 0.f
, 0.f
));
700 matXform0
.mult(matXform1
);
701 matXform0
.mult(matXform2
);
703 // align to face center
704 Pnt3f
lightAt(bbCenter
- Vec3f(0.f
, 0.25 * bbDiag
[1], 0.f
));
706 matXform0Inv
.invertFrom(matXform0
);
707 matXform0Inv
.mult (lightAt
, lightAt
);
710 Quaternion
rot2(Vec3f(0.f
, 0.f
, -1.),
712 matXform3
.setRotate(rot2
);
714 matXform0
.mult(matXform3
);
716 // shift towards center
718 //matXform4.setTranslate(Vec3f(0.f, 0.f, shiftVal * bbDiagLen));
720 //matXform0.mult(matXform4);
723 beacon
->setMatrix(matXform0
);
726 NodeTransitPtr
loadScene(const std::string
&fileName
)
728 NodeTransitPtr retVal
;
729 NodeUnrecPtr fileSceneN
= SceneFileHandler::the()->read(fileName
.c_str());
731 if(fileSceneN
== NULL
)
736 fileSceneN
->updateVolume();
737 const BoxVolume
&bvol
= fileSceneN
->getVolume();
740 bvol
.getBounds(pmin
, pmax
);
741 Vec3f vdiag
= pmax
- pmin
;
742 Real32 diag
= vdiag
.length();
744 TransformUnrecPtr xform
= Transform::create();
745 NodeUnrecPtr xformN
= makeNodeFor(xform
);
749 matXForm
.setRotate(Quaternion(Vec3f(1.f
, 0.f
, 0.f
), -Pi
/2));
751 mat
.setTranslate(Vec3f(0.f
, 0.f
, - 0.4 * diag
));
755 xform
->setMatrix(matXForm
);
757 GeometryUnrecPtr plane
= makePlaneGeo(4.f
* diag
, 4.f
* diag
, 1, 1);
758 NodeUnrecPtr planeN
= makeNodeFor(plane
);
762 128, 128, 128, 255, 255, 255,
763 255, 255, 255, 128, 128, 128
766 ImageUnrecPtr texImg
= Image::create();
767 texImg
->set(Image::OSG_RGB_PF
, 2, 2, 1, 1, 1, 0.0, pixelData
);
769 SimpleTexturedMaterialUnrecPtr smat
= SimpleTexturedMaterial::create();
770 smat
->setImage(texImg
);
771 smat
->setMinFilter(GL_NEAREST
);
772 smat
->setMagFilter(GL_NEAREST
);
774 // plane->setMaterial(smat);
775 plane
->setMaterial(getDefaultMaterial());
777 xformN
->addChild(planeN
);
778 gv
->sceneN
->addChild(xformN
);
785 NodeTransitPtr
buildTestScene(UInt32 nX
, UInt32 nZ
)
790 Real32 startX
= - stepX
* (nX
-1) / 2.;
791 Real32 startZ
= - stepZ
* (nZ
-1) / 2.;
793 NodeTransitPtr groupN
= makeCoredNode
<Group
>();
794 // GeometryUnrecPtr objGeo = makeBoxGeo(1.f, 1.f, 1.f, 1, 1, 1);
795 // GeometryUnrecPtr objGeo = makeLatLongSphereGeo(16, 16, 1.f);
796 GeometryUnrecPtr objGeo
= makeSphereGeo(2, 1.f
);
798 for(UInt32 iX
= 0; iX
< nX
; ++iX
)
800 for(UInt32 iZ
= 0; iZ
< nZ
; ++iZ
)
802 NodeUnrecPtr objGeoN
= makeNodeFor(objGeo
);
803 TransformUnrecPtr xform
= Transform::create();
804 NodeUnrecPtr xformN
= makeNodeFor(xform
);
807 Vec3f
vecTrans(startX
+ iX
* stepX
,
808 4.f
* osgCos(Pi
/5.f
* Real32(iX
+ iZ
)),
809 startZ
+ iZ
* stepZ
);
811 std::cout
<< "iX " << iX
<< " iZ " << iZ
<< " vecTrans " << vecTrans
<< std::endl
;
812 matXForm
.setTranslate(vecTrans
);
813 xform
->setMatrix(matXForm
);
815 xformN
->addChild(objGeoN
);
816 groupN
->addChild(xformN
);
818 // add a 2nd layer of objects
819 NodeUnrecPtr objGeoN2
= makeNodeFor(objGeo
);
820 TransformUnrecPtr xform2
= Transform::create();
821 NodeUnrecPtr xformN2
= makeNodeFor(xform2
);
824 matXForm2
.setTranslate(Vec3f(startX
+ iX
* stepX
,
826 startZ
+ iZ
* stepZ
));
827 xform2
->setMatrix(matXForm2
);
829 xformN2
->addChild(objGeoN2
);
830 groupN
->addChild(xformN2
);
835 TransformUnrecPtr xform
= Transform::create();
836 NodeUnrecPtr xformN
= makeNodeFor(xform
);
839 matXForm
.setTranslate(Vec3f(0.f
, -5.f
, 0.f
));
840 matXForm
.setRotate (Quaternion(Vec3f(1.f
, 0.f
, 0.f
), -PiHalf
));
841 xform
->setMatrix(matXForm
);
843 NodeUnrecPtr planeGeoN
= makePlane(nX
* stepX
, nZ
* stepZ
, 1, 1);
845 xformN
->addChild(planeGeoN
);
846 groupN
->addChild(xformN
);
850 xform
= Transform::create();
851 xformN
= makeNodeFor(xform
);
853 matXForm
.setIdentity();
854 matXForm
.setTranslate(Vec3f(0.f
, 15.f
, -20.f
));
855 xform
->setMatrix(matXForm
);
857 NodeUnrecPtr boxGeoN
= makeBox(nX
* stepX
, 35.f
, 2.f
, 1, 1, 1);
859 xformN
->addChild(boxGeoN
);
860 groupN
->addChild(xformN
);
865 std::ostream
&operator << (std::ostream
&os
, const LightInfo
&li
)
867 os
<< "lightType " << mapLightType(li
.lightType
)
868 << " " << (li
.light
->getOn() ? "on" : "off")
869 << " shadowType " << mapShadowType(li
.shadowType
);
875 // GLUT callback functions
878 // react to size changes
879 void reshape(int w
, int h
)
881 gv
->mgr
->resize(w
, h
);
887 // static OSG::Time tStart = OSG::getSystemTime();
888 static OSG::Time tLast
= OSG::getSystemTime();
889 static OSG::Time tAnim
= OSG::getSystemTime();
890 static OSG::Time tFrames
= OSG::getSystemTime();
891 static OSG::UInt32 frames
= 0;
893 OSG::Time tNow
= OSG::getSystemTime();
895 if(gv
->animateLights
== true)
897 tAnim
+= (tNow
- tLast
);
900 for(UInt32 i
= 0; i
< gv
->lightInfos
.size(); ++i
)
902 updateLightBeacon(i
, tAnim
);
907 if(tNow
- tFrames
> 1.f
)
909 std::cout
<< "delta t: " << (tNow
- tFrames
) << " frames: " << frames
<< std::endl
;
916 commitChangesAndClear();
921 // react to mouse button presses
922 void mouse(int button
, int state
, int x
, int y
)
925 gv
->mgr
->mouseButtonRelease(button
, x
, y
);
927 gv
->mgr
->mouseButtonPress(button
, x
, y
);
932 // react to mouse motions with pressed buttons
933 void motion(int x
, int y
)
935 gv
->mgr
->mouseMove(x
, y
);
939 void keyboard(unsigned char k
, int , int )
953 // all lights no shadow
954 for(UInt32 i
= 0; i
< gv
->lightInfos
.size(); ++i
)
956 setShadow(i
, ST_NONE
);
957 std::cout
<< "changed shadow type for light "
958 << i
<< " " << gv
->lightInfos
[i
]
966 // all lights standard shadows
967 for(UInt32 i
= 0; i
< gv
->lightInfos
.size(); ++i
)
969 setShadow(i
, ST_STANDARD
);
970 std::cout
<< "changed shadow type for light "
971 << i
<< " " << gv
->lightInfos
[i
]
979 // all lights TSM shadows
980 for(UInt32 i
= 0; i
< gv
->lightInfos
.size(); ++i
)
982 setShadow(i
, ST_TRAPEZOID
);
983 std::cout
<< "changed shadow type for light "
984 << i
<< " " << gv
->lightInfos
[i
]
992 // toggle lights moving
993 gv
->animateLights
= !gv
->animateLights
;
995 std::cout
<< "animating lights: " << gv
->animateLights
<< std::endl
;
1001 // toggle all lights white/colorful
1002 gv
->colorLights
= !gv
->colorLights
;
1004 std::cout
<< "color lights: " << gv
->colorLights
<< std::endl
;
1006 setColorLights(gv
->colorLights
);
1012 // toggle current light on/off
1013 if(gv
->currentLight
< Int32(gv
->lightInfos
.size()) &&
1014 gv
->currentLight
>= 0 )
1016 Light
*light
= gv
->lightInfos
[gv
->currentLight
].light
;
1018 light
->setOn(!light
->getOn());
1020 std::cout
<< gv
->lightInfos
[gv
->currentLight
] << std::endl
;
1028 addLight (gv
->newLightType
, gv
->newShadowType
);
1030 std::cout
<< "added light " << (gv
->lightInfos
.size() - 1) << " "
1031 << gv
->lightInfos
.back()
1038 // remove current light
1039 if(gv
->currentLight
< Int32(gv
->lightInfos
.size()) &&
1040 gv
->currentLight
>= 0 )
1042 std::cout
<< "removing light " << gv
->currentLight
<< " "
1043 << gv
->lightInfos
[gv
->currentLight
]
1046 subLight(gv
->currentLight
);
1053 // cycle through shadow types for current light
1054 if(gv
->currentLight
< Int32(gv
->lightInfos
.size()) &&
1055 gv
->currentLight
>= 0 )
1057 if(gv
->lightInfos
[gv
->currentLight
].shadowType
== ST_NONE
)
1059 setShadow(gv
->currentLight
, ST_STANDARD
);
1061 else if(gv
->lightInfos
[gv
->currentLight
].shadowType
== ST_STANDARD
)
1063 setShadow(gv
->currentLight
, ST_TRAPEZOID
);
1067 setShadow(gv
->currentLight
, ST_NONE
);
1070 std::cout
<< "changed shadow type for light "
1071 << gv
->currentLight
<< " "
1072 << gv
->lightInfos
[gv
->currentLight
]
1080 // select previous light
1081 gv
->currentLight
+= 1;
1082 if(gv
->currentLight
>= Int32(gv
->lightInfos
.size()))
1083 gv
->currentLight
= 0;
1085 if(gv
->currentLight
< Int32(gv
->lightInfos
.size()) &&
1086 gv
->currentLight
>= 0 )
1088 std::cout
<< "currentLight " << gv
->currentLight
1089 << " (total: " << gv
->lightInfos
.size() << ") "
1090 << gv
->lightInfos
[gv
->currentLight
]
1098 // select next light
1099 gv
->currentLight
-= 1;
1101 if(gv
->currentLight
< 0)
1102 gv
->currentLight
= gv
->lightInfos
.size() - 1;
1104 if(gv
->currentLight
< Int32(gv
->lightInfos
.size()) &&
1105 gv
->currentLight
>= 0 )
1107 std::cout
<< "currentLight " << gv
->currentLight
1108 << " (total: " << gv
->lightInfos
.size() << ") "
1109 << gv
->lightInfos
[gv
->currentLight
]
1117 glutPostRedisplay();
1120 // just request a redraw
1123 glutPostRedisplay();
1126 // setup the GLUT library which handles the windows for us
1127 int setupGLUT(int *argc
, char *argv
[])
1129 glutInit(argc
, argv
);
1130 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
1132 int winid
= glutCreateWindow("OpenSG");
1134 glutReshapeFunc(reshape
);
1135 glutDisplayFunc(display
);
1136 glutMouseFunc(mouse
);
1137 glutMotionFunc(motion
);
1138 glutKeyboardFunc(keyboard
);
1141 glutReshapeWindow(1400, 1050);