From Pavel Moloshtan, osgdepthshadow example
This commit is contained in:
@@ -168,6 +168,7 @@ EXAMPLE_DIRS = \
|
||||
osgsimple\
|
||||
osgshaders\
|
||||
osgshadowtexture\
|
||||
osgdepthshadow\
|
||||
osgshape\
|
||||
osgstereoimage\
|
||||
osgteapot\
|
||||
|
||||
@@ -1182,6 +1182,33 @@ Package=<4>
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Example osgdepthshadow"=.\examples\osgdepthshadow\osgdepthshadow.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osg
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgDB
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgGA
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgProducer
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Core osgUtil
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Example osgshape"=.\examples\osgshape\osgshape.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
|
||||
224
VisualStudio/examples/osgdepthshadow/osgshadowtexture.dsp
Normal file
224
VisualStudio/examples/osgdepthshadow/osgshadowtexture.dsp
Normal file
@@ -0,0 +1,224 @@
|
||||
# Microsoft Developer Studio Project File - Name="Example osgdepthshadow" - Package Owner=<4>
|
||||
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
|
||||
|
||||
CFG=Example osgdepthshadow - Win32 Release
|
||||
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
|
||||
!MESSAGE
|
||||
|
||||
!MESSAGE NMAKE /f "osgdepthshadow.mak".
|
||||
|
||||
!MESSAGE
|
||||
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
|
||||
!MESSAGE
|
||||
|
||||
!MESSAGE NMAKE /f "osgdepthshadow.mak" CFG="Example osgdepthshadow - Win32 Release"
|
||||
|
||||
!MESSAGE
|
||||
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
|
||||
!MESSAGE
|
||||
|
||||
!MESSAGE "Example osgdepthshadow - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
|
||||
!MESSAGE "Example osgdepthshadow - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
|
||||
!MESSAGE
|
||||
|
||||
|
||||
|
||||
# Begin Project
|
||||
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
|
||||
# PROP Scc_ProjName ""
|
||||
|
||||
# PROP Scc_LocalPath ""
|
||||
|
||||
CPP=cl.exe
|
||||
|
||||
RSC=rc.exe
|
||||
|
||||
|
||||
|
||||
!IF "$(CFG)" == "Example osgdepthshadow - Win32 Release"
|
||||
|
||||
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
|
||||
# PROP BASE Output_Dir "Release"
|
||||
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
|
||||
# PROP BASE Target_Dir ""
|
||||
|
||||
# PROP Use_MFC 0
|
||||
|
||||
# PROP Use_Debug_Libraries 0
|
||||
|
||||
# PROP Output_Dir "Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release"
|
||||
|
||||
# PROP Ignore_Export_Lib 0
|
||||
|
||||
# PROP Target_Dir ""
|
||||
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
|
||||
# ADD RSC /l 0x809 /d "NDEBUG"
|
||||
|
||||
BSC32=bscmake.exe
|
||||
|
||||
# ADD BASE BSC32 /nologo
|
||||
|
||||
# ADD BSC32 /nologo
|
||||
|
||||
LINK32=link.exe
|
||||
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
# ADD LINK32 opengl32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgdepthshadow.exe" /libpath:"../../../lib"
|
||||
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "Example osgdepthshadow - Win32 Debug"
|
||||
|
||||
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
|
||||
# PROP BASE Target_Dir ""
|
||||
|
||||
# PROP Use_MFC 0
|
||||
|
||||
# PROP Use_Debug_Libraries 1
|
||||
|
||||
# PROP Output_Dir "Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
|
||||
# PROP Ignore_Export_Lib 0
|
||||
|
||||
# PROP Target_Dir ""
|
||||
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_CONSOLE" /D "_MBCS" /D "FL_DLL" /D "WIN32" /D "_DEBUG" /YX /FD /c
|
||||
|
||||
# SUBTRACT CPP /Fr
|
||||
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
|
||||
# ADD RSC /l 0x809 /d "_DEBUG"
|
||||
|
||||
BSC32=bscmake.exe
|
||||
|
||||
# ADD BASE BSC32 /nologo
|
||||
|
||||
# ADD BSC32 /nologo
|
||||
|
||||
LINK32=link.exe
|
||||
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
# ADD LINK32 opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgdepthshadowd.exe" /pdbtype:sept /libpath:"../../../lib"
|
||||
|
||||
# SUBTRACT LINK32 /incremental:no
|
||||
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
|
||||
# Begin Target
|
||||
|
||||
|
||||
|
||||
# Name "Example osgdepthshadow - Win32 Release"
|
||||
|
||||
# Name "Example osgdepthshadow - Win32 Debug"
|
||||
|
||||
# Begin Group "Source Files"
|
||||
|
||||
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
|
||||
# Begin Source File
|
||||
|
||||
|
||||
|
||||
SOURCE=..\..\..\examples\osgdepthshadow\osgdepthshadow.cpp
|
||||
|
||||
# End Source File
|
||||
|
||||
# Begin Source File
|
||||
|
||||
|
||||
|
||||
SOURCE=..\..\..\examples\osgdepthshadow\CreateShadowedScene.cpp
|
||||
|
||||
# End Source File
|
||||
|
||||
# End Group
|
||||
|
||||
# Begin Group "Header Files"
|
||||
|
||||
|
||||
|
||||
# PROP Default_Filter ";h;hpp;hxx;hm;inl"
|
||||
|
||||
# Begin Source File
|
||||
|
||||
|
||||
|
||||
SOURCE=..\..\..\examples\osgdepthshadow\CreateShadowedScene.h
|
||||
|
||||
# End Source File
|
||||
|
||||
# End Group
|
||||
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
|
||||
|
||||
# PROP Default_Filter ""
|
||||
|
||||
# End Group
|
||||
|
||||
# End Target
|
||||
|
||||
# End Project
|
||||
|
||||
17
examples/osgdepthshadow/GNUmakefile
Normal file
17
examples/osgdepthshadow/GNUmakefile
Normal file
@@ -0,0 +1,17 @@
|
||||
TOPDIR = ../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
osgdepthshadow.cpp\
|
||||
|
||||
LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
|
||||
|
||||
INSTFILES = \
|
||||
$(CXXFILES)\
|
||||
GNUmakefile.inst=GNUmakefile
|
||||
|
||||
EXEC = osgdepthshadow
|
||||
|
||||
INC += $(X_INC)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
14
examples/osgdepthshadow/GNUmakefile.inst
Normal file
14
examples/osgdepthshadow/GNUmakefile.inst
Normal file
@@ -0,0 +1,14 @@
|
||||
TOPDIR = ../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
osgdepthshadow.cpp\
|
||||
|
||||
LIBS += -losgProducer -lProducer -losgText -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
|
||||
|
||||
EXEC = osgdepthshadow
|
||||
|
||||
INC += $(PRODUCER_INCLUDE_DIR) $(X_INC)
|
||||
LDFLAGS += $(PRODUCER_LIB_DIR)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
421
examples/osgdepthshadow/osgdepthshadow.cpp
Normal file
421
examples/osgdepthshadow/osgdepthshadow.cpp
Normal file
@@ -0,0 +1,421 @@
|
||||
#include <osgProducer/Viewer>
|
||||
|
||||
#include <osg/Projection>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Texture>
|
||||
#include <osg/TexGen>
|
||||
#include <osg/Geode>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/PolygonOffset>
|
||||
#include <osg/CullFace>
|
||||
#include <osg/TexEnvCombine>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Light>
|
||||
#include <osg/LightSource>
|
||||
#include <osg/PolygonOffset>
|
||||
#include <osg/CullFace>
|
||||
|
||||
#include <osgUtil/TransformCallback>
|
||||
#include <osgUtil/RenderToTextureStage>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
const int depth_texture_height = 256;
|
||||
const int depth_texture_width = 256;
|
||||
|
||||
ref_ptr<RefMatrix> bias = new RefMatrix(0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.5f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.5f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
class LightTransformCallback: public osg::NodeCallback
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
LightTransformCallback(float angular_velocity, float height, float radius):
|
||||
_angular_velocity(angular_velocity),
|
||||
_height(height),
|
||||
_radius(radius),
|
||||
_previous_traversal_number(-1),
|
||||
_previous_time(-1.0f),
|
||||
_angle(0)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(Node* node, NodeVisitor* nv);
|
||||
|
||||
protected:
|
||||
|
||||
float _angular_velocity;
|
||||
float _height;
|
||||
float _radius;
|
||||
int _previous_traversal_number;
|
||||
double _previous_time;
|
||||
float _angle;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
LightTransformCallback::operator()(Node* node, NodeVisitor* nv)
|
||||
{
|
||||
MatrixTransform* transform = dynamic_cast<MatrixTransform*>(node);
|
||||
if (nv && transform)
|
||||
{
|
||||
const FrameStamp* fs = nv->getFrameStamp();
|
||||
if (!fs) return; // not frame stamp, no handle on the time so can't move.
|
||||
|
||||
double new_time = fs->getReferenceTime();
|
||||
if (nv->getTraversalNumber() != _previous_traversal_number)
|
||||
{
|
||||
_angle += _angular_velocity * (new_time - _previous_time);
|
||||
|
||||
Matrix matrix = Matrix::rotate(atan(_height / _radius), -X_AXIS) *
|
||||
Matrix::rotate(PI_2, Y_AXIS) *
|
||||
Matrix::translate(Vec3(_radius, 0, 0)) *
|
||||
Matrix::rotate(_angle, Y_AXIS) *
|
||||
Matrix::translate(Vec3(0, _height, 0));
|
||||
|
||||
// update the specified transform
|
||||
transform->setMatrix(matrix);
|
||||
|
||||
_previous_traversal_number = nv->getTraversalNumber();
|
||||
}
|
||||
|
||||
_previous_time = new_time;
|
||||
}
|
||||
|
||||
// must call any nested node callbacks and continue subgraph traversal.
|
||||
traverse(node,nv);
|
||||
|
||||
}
|
||||
|
||||
class RenderToTextureCallback: public NodeCallback
|
||||
{
|
||||
public:
|
||||
RenderToTextureCallback(Node* subgraph,
|
||||
Texture2D* texture,
|
||||
MatrixTransform* light_transform,
|
||||
TexGen* tex_gen):
|
||||
_subgraph(subgraph),
|
||||
_texture(texture),
|
||||
_local_stateset(new StateSet),
|
||||
_viewport(new Viewport),
|
||||
_light_projection(new RefMatrix),
|
||||
_light_transform(light_transform),
|
||||
_tex_gen(tex_gen)
|
||||
{
|
||||
_local_stateset->setAttribute(_viewport.get());
|
||||
_local_stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
|
||||
ref_ptr<PolygonOffset> polygon_offset = new PolygonOffset;
|
||||
polygon_offset->setFactor(2.0f);
|
||||
polygon_offset->setUnits(6.0f);
|
||||
_local_stateset->setAttribute(polygon_offset.get(), StateAttribute::ON | StateAttribute::OVERRIDE);
|
||||
_local_stateset->setMode(GL_POLYGON_OFFSET_FILL, StateAttribute::ON | StateAttribute::OVERRIDE);
|
||||
|
||||
ref_ptr<CullFace> cull_face = new CullFace;
|
||||
cull_face->setMode(CullFace::BACK);
|
||||
_local_stateset->setAttribute(cull_face.get(), StateAttribute::ON | StateAttribute::OVERRIDE);
|
||||
_local_stateset->setMode(GL_CULL_FACE, StateAttribute::ON | StateAttribute::OVERRIDE);
|
||||
|
||||
_viewport->setViewport(0, 0, depth_texture_width, depth_texture_height);
|
||||
|
||||
float znear = 1.0f * _subgraph->getBound().radius();
|
||||
float zfar = 3.0f * _subgraph->getBound().radius();
|
||||
float top = 0.5f * _subgraph->getBound().radius();
|
||||
float right = 0.5f * _subgraph->getBound().radius();
|
||||
znear *= 0.8f;
|
||||
zfar *= 1.2f;
|
||||
_light_projection->makeFrustum(-right, right, -top, top, znear, zfar);
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
|
||||
osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
|
||||
if (cullVisitor && _texture.valid() && _subgraph.valid())
|
||||
{
|
||||
_request_render_to_depth_texture(*node, *cullVisitor);
|
||||
}
|
||||
|
||||
// must traverse the subgraph
|
||||
traverse(node,nv);
|
||||
}
|
||||
|
||||
void _request_render_to_depth_texture(osg::Node& node, osgUtil::CullVisitor& cv);
|
||||
|
||||
ref_ptr<osg::Node> _subgraph;
|
||||
ref_ptr<osg::Texture2D> _texture;
|
||||
ref_ptr<osg::StateSet> _local_stateset;
|
||||
ref_ptr<osg::Viewport> _viewport;
|
||||
ref_ptr<RefMatrix> _light_projection;
|
||||
ref_ptr<MatrixTransform> _light_transform;
|
||||
ref_ptr<TexGen> _tex_gen;
|
||||
};
|
||||
|
||||
void RenderToTextureCallback::_request_render_to_depth_texture(osg::Node&, osgUtil::CullVisitor& cv)
|
||||
{
|
||||
// create the render to texture stage.
|
||||
osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage;
|
||||
|
||||
// set up lighting.
|
||||
// currently ignore lights in the scene graph itself..
|
||||
// will do later.
|
||||
osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->_stage;
|
||||
|
||||
// set up the background color and clear mask.
|
||||
rtts->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
rtts->_colorMask = new ColorMask(false, false, false, false);
|
||||
|
||||
// set up to charge the same RenderStageLighting is the parent previous stage.
|
||||
rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
|
||||
|
||||
|
||||
// record the render bin, to be restored after creation
|
||||
// of the render to text
|
||||
osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin();
|
||||
|
||||
osgUtil::CullVisitor::ComputeNearFarMode saved_compute_near_far_mode = cv.getComputeNearFarMode();
|
||||
cv.setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
|
||||
// set the current renderbin to be the newly created stage.
|
||||
cv.setCurrentRenderBin(rtts.get());
|
||||
|
||||
ref_ptr<RefMatrix> light_view = new RefMatrix;
|
||||
light_view->makeLookAt(_light_transform->getMatrix().getTrans(), Vec3(0, 0, 0), Z_AXIS);
|
||||
Matrix texture_matrix = (*light_view.get()) * (*_light_projection.get()) * (*bias.get());
|
||||
_tex_gen->setPlane(TexGen::S, Vec4(texture_matrix(0, 0),
|
||||
texture_matrix(1, 0),
|
||||
texture_matrix(2, 0),
|
||||
texture_matrix(3, 0)));
|
||||
_tex_gen->setPlane(TexGen::T, Vec4(texture_matrix(0, 1),
|
||||
texture_matrix(1, 1),
|
||||
texture_matrix(2, 1),
|
||||
texture_matrix(3, 1)));
|
||||
_tex_gen->setPlane(TexGen::R, Vec4(texture_matrix(0, 2),
|
||||
texture_matrix(1, 2),
|
||||
texture_matrix(2, 2),
|
||||
texture_matrix(3, 2)));
|
||||
_tex_gen->setPlane(TexGen::Q, Vec4(texture_matrix(0, 3),
|
||||
texture_matrix(1, 3),
|
||||
texture_matrix(2, 3),
|
||||
texture_matrix(3, 3)));
|
||||
|
||||
cv.pushProjectionMatrix(_light_projection.get());
|
||||
cv.pushModelViewMatrix(light_view.get());
|
||||
cv.pushStateSet(_local_stateset.get());
|
||||
|
||||
// traverse the subgraph
|
||||
_subgraph->accept(cv);
|
||||
|
||||
cv.popStateSet();
|
||||
cv.popModelViewMatrix();
|
||||
cv.popProjectionMatrix();
|
||||
|
||||
cv.setComputeNearFarMode(saved_compute_near_far_mode);
|
||||
|
||||
// restore the previous renderbin.
|
||||
cv.setCurrentRenderBin(previousRenderBin);
|
||||
|
||||
if (rtts->_renderGraphList.size()==0 && rtts->_bins.size()==0)
|
||||
{
|
||||
// getting to this point means that all the subgraph has been
|
||||
// culled by small feature culling or is beyond LOD ranges.
|
||||
return;
|
||||
}
|
||||
|
||||
rtts->setViewport(_viewport.get());
|
||||
|
||||
// and the render to texture stage to the current stages
|
||||
// dependancy list.
|
||||
cv.getCurrentRenderBin()->_stage->addToDependencyList(rtts.get());
|
||||
|
||||
// if one exist attach texture to the RenderToTextureStage.
|
||||
rtts->setTexture(_texture.get());
|
||||
}
|
||||
|
||||
ref_ptr<MatrixTransform> _create_lights(ref_ptr<StateSet> root_stateset)
|
||||
{
|
||||
ref_ptr<MatrixTransform> transform_0 = new MatrixTransform;
|
||||
|
||||
// create a spot light.
|
||||
ref_ptr<Light> light_0 = new Light;
|
||||
light_0->setLightNum(0);
|
||||
light_0->setPosition(Vec4(0, 0, 0, 1.0f));
|
||||
light_0->setAmbient(Vec4(0.2f, 0.2f, 0.2f, 1.0f));
|
||||
light_0->setDiffuse(Vec4(1.0f, 0.5f, 0.5f, 1.0f));
|
||||
light_0->setSpotCutoff(60.0f);
|
||||
light_0->setSpotExponent(5.0f);
|
||||
|
||||
ref_ptr<LightSource> light_source_0 = new LightSource;
|
||||
light_source_0->setLight(light_0.get());
|
||||
light_source_0->setLocalStateSetModes(StateAttribute::ON);
|
||||
transform_0->setUpdateCallback(new LightTransformCallback(inDegrees(90.0f), 8, 5));
|
||||
transform_0->addChild(light_source_0.get());
|
||||
|
||||
ref_ptr<Geode> geode = new Geode;
|
||||
ref_ptr<ShapeDrawable> shape;
|
||||
ref_ptr<TessellationHints> hints = new TessellationHints;
|
||||
hints->setDetailRatio(0.3f);
|
||||
shape = new ShapeDrawable(new Sphere(Vec3(0.0f, 0.0f, 0.0f), 0.15f), hints.get());
|
||||
shape->setColor(Vec4(1.0f, 0.5f, 0.5f, 1.0f));
|
||||
geode->addDrawable(shape.get());
|
||||
shape = new ShapeDrawable(new Cylinder(Vec3(0.0f, 0.0f, -0.4f), 0.05f, 0.8f), hints.get());
|
||||
shape->setColor(Vec4(1.0f, 0.5f, 0.5f, 1.0f));
|
||||
geode->addDrawable(shape.get());
|
||||
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, StateAttribute::OFF);
|
||||
transform_0->addChild(geode.get());
|
||||
|
||||
light_source_0->setStateSetModes(*root_stateset.get(), StateAttribute::ON);
|
||||
|
||||
return transform_0;
|
||||
}
|
||||
|
||||
ref_ptr<Group> _create_scene()
|
||||
{
|
||||
ref_ptr<Group> scene = new Group;
|
||||
ref_ptr<Geode> geode_1 = new Geode;
|
||||
scene->addChild(geode_1.get());
|
||||
|
||||
ref_ptr<Geode> geode_2 = new Geode;
|
||||
ref_ptr<MatrixTransform> transform_2 = new MatrixTransform;
|
||||
transform_2->addChild(geode_2.get());
|
||||
transform_2->setUpdateCallback(new osgUtil::TransformCallback(Vec3(0, 0, 0), Y_AXIS, inDegrees(45.0f)));
|
||||
scene->addChild(transform_2.get());
|
||||
|
||||
ref_ptr<Geode> geode_3 = new Geode;
|
||||
ref_ptr<MatrixTransform> transform_3 = new MatrixTransform;
|
||||
transform_3->addChild(geode_3.get());
|
||||
transform_3->setUpdateCallback(new osgUtil::TransformCallback(Vec3(0, 0, 0), Y_AXIS, inDegrees(-22.5f)));
|
||||
scene->addChild(transform_3.get());
|
||||
|
||||
const float radius = 0.8f;
|
||||
const float height = 1.0f;
|
||||
ref_ptr<TessellationHints> hints = new TessellationHints;
|
||||
hints->setDetailRatio(2.0f);
|
||||
ref_ptr<ShapeDrawable> shape;
|
||||
|
||||
shape = new ShapeDrawable(new Box(Vec3(0.0f, -2.0f, 0.0f), 10, 0.1f, 10), hints.get());
|
||||
shape->setColor(Vec4(0.5f, 0.5f, 0.7f, 1.0f));
|
||||
geode_1->addDrawable(shape.get());
|
||||
|
||||
shape = new ShapeDrawable(new Sphere(Vec3(0.0f, 0.0f, 0.0f), radius * 2), hints.get());
|
||||
shape->setColor(Vec4(0.8f, 0.4f, 0.4f, 1.0f));
|
||||
geode_1->addDrawable(shape.get());
|
||||
|
||||
shape = new ShapeDrawable(new Sphere(Vec3(-3.0f, 0.0f, 0.0f), radius), hints.get());
|
||||
shape->setColor(Vec4(0.6f, 0.8f, 0.8f, 1.0f));
|
||||
geode_2->addDrawable(shape.get());
|
||||
|
||||
shape = new ShapeDrawable(new Box(Vec3(3.0f, 0.0f, 0.0f), 2 * radius), hints.get());
|
||||
shape->setColor(Vec4(0.4f, 0.9f, 0.3f, 1.0f));
|
||||
geode_2->addDrawable(shape.get());
|
||||
|
||||
shape = new ShapeDrawable(new Cone(Vec3(0.0f, 0.0f, -3.0f), radius, height), hints.get());
|
||||
shape->setColor(Vec4(0.2f, 0.5f, 0.7f, 1.0f));
|
||||
geode_2->addDrawable(shape.get());
|
||||
|
||||
shape = new ShapeDrawable(new Cylinder(Vec3(0.0f, 0.0f, 3.0f), radius, height), hints.get());
|
||||
shape->setColor(Vec4(1.0f, 0.3f, 0.3f, 1.0f));
|
||||
geode_2->addDrawable(shape.get());
|
||||
|
||||
shape = new ShapeDrawable(new Box(Vec3(0.0f, 3.0f, 0.0f), 2, 0.1f, 2), hints.get());
|
||||
shape->setColor(Vec4(0.8f, 0.8f, 0.4f, 1.0f));
|
||||
geode_3->addDrawable(shape.get());
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// use an ArgumentParser object to manage the program arguments.
|
||||
ArgumentParser arguments(&argc, argv);
|
||||
|
||||
// set up the usage document, in case we need to print out how to use this program.
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName() + " is the example which demonstrates using of GL_ARB_shadow extension implemented in osg::Texture class");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help", "Display this information");
|
||||
|
||||
// construct the viewer.
|
||||
osgProducer::Viewer viewer(arguments);
|
||||
|
||||
// set up the value with sensible default event handlers.
|
||||
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
|
||||
|
||||
// get details on keyboard and mouse bindings used by the viewer.
|
||||
viewer.getUsage(*arguments. getApplicationUsage());
|
||||
|
||||
// if user request help write it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
{
|
||||
arguments.getApplicationUsage()->write(std::cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// any option left unread are converted into errors to write out later.
|
||||
arguments.reportRemainingOptionsAsUnrecognized();
|
||||
|
||||
// report any errors if they have occured when parsing the program aguments.
|
||||
if (arguments.errors())
|
||||
{
|
||||
arguments.writeErrorMessages(std::cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ref_ptr<Group> scene = new Group;
|
||||
ref_ptr<Group> shadowed_scene = _create_scene();
|
||||
if (!shadowed_scene.valid()) return 1;
|
||||
scene->addChild(shadowed_scene.get());
|
||||
|
||||
ref_ptr<MatrixTransform> light_transform = _create_lights(scene->getOrCreateStateSet());
|
||||
if (!scene.valid()) return 1;
|
||||
scene->addChild(light_transform.get());
|
||||
|
||||
ref_ptr<Texture2D> texture = new Texture2D;
|
||||
texture->setInternalFormat(GL_DEPTH_COMPONENT);
|
||||
texture->setShadowComparison(true);
|
||||
texture->setShadowTextureMode(Texture::LUMINANCE);
|
||||
|
||||
ref_ptr<TexEnvCombine> tex_env_combine = new TexEnvCombine;
|
||||
tex_env_combine->setCombine_RGB(TexEnvCombine::INTERPOLATE);
|
||||
tex_env_combine->setSource0_RGB(TexEnvCombine::PREVIOUS);
|
||||
tex_env_combine->setOperand0_RGB(TexEnvCombine::SRC_COLOR);
|
||||
tex_env_combine->setSource1_RGB(TexEnvCombine::TEXTURE);
|
||||
tex_env_combine->setOperand1_RGB(TexEnvCombine::SRC_COLOR);
|
||||
tex_env_combine->setSource2_RGB(TexEnvCombine::CONSTANT);
|
||||
tex_env_combine->setOperand2_RGB(TexEnvCombine::SRC_COLOR);
|
||||
tex_env_combine->setConstantColor(Vec4(0.8f, 0.8f, 0.8f, 1.0f));
|
||||
|
||||
ref_ptr<TexGen> tex_gen = new TexGen;
|
||||
tex_gen->setMode(TexGen::EYE_LINEAR);
|
||||
shadowed_scene->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture.get(), StateAttribute::ON);
|
||||
shadowed_scene->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex_gen.get(), StateAttribute::ON);
|
||||
shadowed_scene->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex_env_combine.get(), StateAttribute::ON);
|
||||
|
||||
scene->setCullCallback(new RenderToTextureCallback(shadowed_scene.get(), texture.get(), light_transform.get(), tex_gen.get()));
|
||||
|
||||
// add model to viewer.
|
||||
viewer.setSceneData(scene.get());
|
||||
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
while (!viewer.done())
|
||||
{
|
||||
// wait for all cull and draw threads to complete.
|
||||
viewer.sync();
|
||||
|
||||
// update the scene by traversing it with the the update visitor which will
|
||||
// call all node update callbacks and animations.
|
||||
viewer.update();
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
viewer.frame();
|
||||
}
|
||||
|
||||
// wait for all cull and draw threads to complete before exit.
|
||||
viewer.sync();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user