Removed now redundent osgshadowtexture and osgdepthshadow examples
This commit is contained in:
parent
2861ca6d1a
commit
abc2499e2d
@ -1,7 +0,0 @@
|
|||||||
#this file is automatically generated
|
|
||||||
|
|
||||||
|
|
||||||
SET(TARGET_SRC osgdepthshadow.cpp )
|
|
||||||
SET(TARGET_ADDED_LIBRARIES osgShadow )
|
|
||||||
#### end var setup ###
|
|
||||||
SETUP_EXAMPLE(osgdepthshadow)
|
|
@ -1,521 +0,0 @@
|
|||||||
/* OpenSceneGraph example, osgdepthshadow.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osgViewer/Viewer>
|
|
||||||
|
|
||||||
#include <osg/Projection>
|
|
||||||
#include <osg/Geometry>
|
|
||||||
#include <osg/Texture>
|
|
||||||
#include <osg/TexGen>
|
|
||||||
#include <osg/Geode>
|
|
||||||
#include <osg/ShapeDrawable>
|
|
||||||
#include <osg/PolygonOffset>
|
|
||||||
#include <osg/Texture2D>
|
|
||||||
#include <osg/MatrixTransform>
|
|
||||||
#include <osg/Light>
|
|
||||||
#include <osg/LightSource>
|
|
||||||
#include <osg/PolygonOffset>
|
|
||||||
#include <osg/CullFace>
|
|
||||||
#include <osg/Material>
|
|
||||||
#include <osg/TexEnvCombine>
|
|
||||||
#include <osg/TexEnv>
|
|
||||||
#include <osg/AnimationPath>
|
|
||||||
#include <osg/TexGenNode>
|
|
||||||
|
|
||||||
#include <osgDB/ReadFile>
|
|
||||||
|
|
||||||
#include <osgShadow/ShadowedScene>
|
|
||||||
#include <osgShadow/ShadowMap>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace osg;
|
|
||||||
|
|
||||||
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->getSimulationTime();
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ref_ptr<MatrixTransform> _create_lights()
|
|
||||||
{
|
|
||||||
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.0f, 0.0f, 0.0f, 1.0f));
|
|
||||||
light_0->setDiffuse(Vec4(1.0f, 0.8f, 0.8f, 1.0f));
|
|
||||||
light_0->setSpotCutoff(60.0f);
|
|
||||||
light_0->setSpotExponent(2.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());
|
|
||||||
|
|
||||||
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 osg::AnimationPathCallback(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 osg::AnimationPathCallback(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.8f, 0.8f, 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());
|
|
||||||
|
|
||||||
// material
|
|
||||||
ref_ptr<Material> matirial = new Material;
|
|
||||||
matirial->setColorMode(Material::DIFFUSE);
|
|
||||||
matirial->setAmbient(Material::FRONT_AND_BACK, Vec4(0, 0, 0, 1));
|
|
||||||
matirial->setSpecular(Material::FRONT_AND_BACK, Vec4(1, 1, 1, 1));
|
|
||||||
matirial->setShininess(Material::FRONT_AND_BACK, 64.0f);
|
|
||||||
scene->getOrCreateStateSet()->setAttributeAndModes(matirial.get(), StateAttribute::ON);
|
|
||||||
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class UpdateCameraAndTexGenCallback : public osg::NodeCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
UpdateCameraAndTexGenCallback(osg::MatrixTransform* light_transform, osg::Camera* Camera, osg::TexGenNode* texgenNode):
|
|
||||||
_light_transform(light_transform),
|
|
||||||
_Camera(Camera),
|
|
||||||
_texgenNode(texgenNode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
|
||||||
{
|
|
||||||
// first update subgraph to make sure objects are all moved into postion
|
|
||||||
traverse(node,nv);
|
|
||||||
|
|
||||||
// now compute the camera's view and projection matrix to point at the shadower (the camera's children)
|
|
||||||
osg::BoundingSphere bs;
|
|
||||||
for(unsigned int i=0; i<_Camera->getNumChildren(); ++i)
|
|
||||||
{
|
|
||||||
bs.expandBy(_Camera->getChild(i)->getBound());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bs.valid())
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) << "bb invalid"<<_Camera.get()<<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::Vec3 position = _light_transform->getMatrix().getTrans();
|
|
||||||
|
|
||||||
float centerDistance = (position-bs.center()).length();
|
|
||||||
|
|
||||||
float znear = centerDistance-bs.radius();
|
|
||||||
float zfar = centerDistance+bs.radius();
|
|
||||||
float zNearRatio = 0.001f;
|
|
||||||
if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// hack to illustrate the precision problems of excessive gap between near far range.
|
|
||||||
znear = 0.00001*zfar;
|
|
||||||
#endif
|
|
||||||
float top = (bs.radius()/centerDistance)*znear;
|
|
||||||
float right = top;
|
|
||||||
|
|
||||||
_Camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
|
||||||
_Camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
|
|
||||||
_Camera->setViewMatrixAsLookAt(position,bs.center(),osg::Vec3(0.0f,1.0f,0.0f));
|
|
||||||
|
|
||||||
// compute the matrix which takes a vertex from local coords into tex coords
|
|
||||||
// will use this later to specify osg::TexGen..
|
|
||||||
osg::Matrix MVPT = _Camera->getViewMatrix() *
|
|
||||||
_Camera->getProjectionMatrix() *
|
|
||||||
osg::Matrix::translate(1.0,1.0,1.0) *
|
|
||||||
osg::Matrix::scale(0.5f,0.5f,0.5f);
|
|
||||||
|
|
||||||
_texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR);
|
|
||||||
_texgenNode->getTexGen()->setPlanesFromMatrix(MVPT);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual ~UpdateCameraAndTexGenCallback() {}
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::MatrixTransform> _light_transform;
|
|
||||||
osg::ref_ptr<osg::Camera> _Camera;
|
|
||||||
osg::ref_ptr<osg::TexGenNode> _texgenNode;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
char fragmentShaderSource_noBaseTexture[] =
|
|
||||||
"uniform sampler2DShadow shadowTexture; \n"
|
|
||||||
"uniform vec2 ambientBias; \n"
|
|
||||||
"\n"
|
|
||||||
"void main(void) \n"
|
|
||||||
"{ \n"
|
|
||||||
" gl_FragColor = gl_Color * (ambientBias.x + shadow2DProj( shadowTexture, gl_TexCoord[0] ) * ambientBias.y); \n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
char fragmentShaderSource_withBaseTexture[] =
|
|
||||||
"uniform sampler2D baseTexture; \n"
|
|
||||||
"uniform sampler2DShadow shadowTexture; \n"
|
|
||||||
"uniform vec2 ambientBias; \n"
|
|
||||||
"\n"
|
|
||||||
"void main(void) \n"
|
|
||||||
"{ \n"
|
|
||||||
" vec4 color = gl_Color * texture2D( baseTexture, gl_TexCoord[0].xy ); \n"
|
|
||||||
" gl_FragColor = color * (ambientBias.x + shadow2DProj( shadowTexture, gl_TexCoord[1] ) * ambientBias.y); \n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
|
|
||||||
osg::Group* createShadowedScene(osg::Node* shadowed,osg::MatrixTransform* light_transform, unsigned int unit)
|
|
||||||
{
|
|
||||||
osg::Group* group = new osg::Group;
|
|
||||||
|
|
||||||
unsigned int tex_width = 1024;
|
|
||||||
unsigned int tex_height = 1024;
|
|
||||||
|
|
||||||
osg::Texture2D* texture = new osg::Texture2D;
|
|
||||||
texture->setTextureSize(tex_width, tex_height);
|
|
||||||
|
|
||||||
texture->setInternalFormat(GL_DEPTH_COMPONENT);
|
|
||||||
texture->setShadowComparison(true);
|
|
||||||
texture->setShadowTextureMode(Texture::LUMINANCE);
|
|
||||||
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
|
|
||||||
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
|
|
||||||
|
|
||||||
// set up the render to texture camera.
|
|
||||||
{
|
|
||||||
|
|
||||||
// create the camera
|
|
||||||
osg::Camera* camera = new osg::Camera;
|
|
||||||
|
|
||||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
|
||||||
camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
|
||||||
camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
|
|
||||||
|
|
||||||
// set viewport
|
|
||||||
camera->setViewport(0,0,tex_width,tex_height);
|
|
||||||
|
|
||||||
osg::StateSet* _local_stateset = camera->getOrCreateStateSet();
|
|
||||||
|
|
||||||
_local_stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
|
||||||
|
|
||||||
|
|
||||||
float factor = 0.0f;
|
|
||||||
float units = 1.0f;
|
|
||||||
|
|
||||||
ref_ptr<PolygonOffset> polygon_offset = new PolygonOffset;
|
|
||||||
polygon_offset->setFactor(factor);
|
|
||||||
polygon_offset->setUnits(units);
|
|
||||||
_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::FRONT);
|
|
||||||
_local_stateset->setAttribute(cull_face.get(), StateAttribute::ON | StateAttribute::OVERRIDE);
|
|
||||||
_local_stateset->setMode(GL_CULL_FACE, StateAttribute::ON | StateAttribute::OVERRIDE);
|
|
||||||
|
|
||||||
|
|
||||||
// set the camera to render before the main camera.
|
|
||||||
camera->setRenderOrder(osg::Camera::PRE_RENDER);
|
|
||||||
|
|
||||||
// tell the camera to use OpenGL frame buffer object where supported.
|
|
||||||
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
|
||||||
|
|
||||||
// attach the texture and use it as the color buffer.
|
|
||||||
camera->attach(osg::Camera::DEPTH_BUFFER, texture);
|
|
||||||
|
|
||||||
// add subgraph to render
|
|
||||||
camera->addChild(shadowed);
|
|
||||||
|
|
||||||
group->addChild(camera);
|
|
||||||
|
|
||||||
// create the texgen node to project the tex coords onto the subgraph
|
|
||||||
osg::TexGenNode* texgenNode = new osg::TexGenNode;
|
|
||||||
texgenNode->setTextureUnit(unit);
|
|
||||||
group->addChild(texgenNode);
|
|
||||||
|
|
||||||
// set an update callback to keep moving the camera and tex gen in the right direction.
|
|
||||||
group->setUpdateCallback(new UpdateCameraAndTexGenCallback(light_transform, camera, texgenNode));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// set the shadowed subgraph so that it uses the texture and tex gen settings.
|
|
||||||
{
|
|
||||||
osg::Group* shadowedGroup = new osg::Group;
|
|
||||||
shadowedGroup->addChild(shadowed);
|
|
||||||
group->addChild(shadowedGroup);
|
|
||||||
|
|
||||||
osg::StateSet* stateset = shadowedGroup->getOrCreateStateSet();
|
|
||||||
stateset->setTextureAttributeAndModes(unit,texture,osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureMode(unit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureMode(unit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureMode(unit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
|
|
||||||
|
|
||||||
stateset->setTextureMode(unit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
|
|
||||||
|
|
||||||
osg::Program* program = new osg::Program;
|
|
||||||
stateset->setAttribute(program);
|
|
||||||
|
|
||||||
if (unit==0)
|
|
||||||
{
|
|
||||||
osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_noBaseTexture);
|
|
||||||
program->addShader(fragment_shader);
|
|
||||||
|
|
||||||
osg::Uniform* shadowTextureSampler = new osg::Uniform("shadowTexture",(int)unit);
|
|
||||||
stateset->addUniform(shadowTextureSampler);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource_withBaseTexture);
|
|
||||||
program->addShader(fragment_shader);
|
|
||||||
|
|
||||||
osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0);
|
|
||||||
stateset->addUniform(baseTextureSampler);
|
|
||||||
|
|
||||||
osg::Uniform* shadowTextureSampler = new osg::Uniform("shadowTexture",(int)unit);
|
|
||||||
stateset->addUniform(shadowTextureSampler);
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::Uniform* ambientBias = new osg::Uniform("ambientBias",osg::Vec2(0.3f,1.2f));
|
|
||||||
stateset->addUniform(ambientBias);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the shadower and shadowed.
|
|
||||||
group->addChild(light_transform);
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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");
|
|
||||||
arguments.getApplicationUsage()->addCommandLineOption("--with-base-texture", "Adde base texture to shadowed model.");
|
|
||||||
arguments.getApplicationUsage()->addCommandLineOption("--no-base-texture", "Adde base texture to shadowed model.");
|
|
||||||
|
|
||||||
// construct the viewer.
|
|
||||||
osgViewer::Viewer viewer;
|
|
||||||
|
|
||||||
bool withBaseTexture = true;
|
|
||||||
while(arguments.read("--with-base-texture")) { withBaseTexture = true; }
|
|
||||||
while(arguments.read("--no-base-texture")) { withBaseTexture = false; }
|
|
||||||
|
|
||||||
// if user request help write it out to cout.
|
|
||||||
if (arguments.read("-h") || arguments.read("--help"))
|
|
||||||
{
|
|
||||||
arguments.getApplicationUsage()->write(std::cout);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (arguments.read("--sm"))
|
|
||||||
{
|
|
||||||
osgShadow::ShadowMap* sm = new osgShadow::ShadowMap;
|
|
||||||
sm->setTextureUnit( withBaseTexture ? 1 : 0 );
|
|
||||||
|
|
||||||
osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene = new osgShadow::ShadowedScene(sm);
|
|
||||||
|
|
||||||
|
|
||||||
ref_ptr<Group> created_scene = _create_scene();
|
|
||||||
if (!created_scene.valid()) return 1;
|
|
||||||
|
|
||||||
shadowedScene->addChild(_create_scene().get());
|
|
||||||
|
|
||||||
|
|
||||||
ref_ptr<MatrixTransform> scene = new MatrixTransform;
|
|
||||||
scene->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(125.0),1.0,0.0,0.0));
|
|
||||||
|
|
||||||
scene->addChild(_create_lights().get());
|
|
||||||
scene->addChild(shadowedScene.get());
|
|
||||||
|
|
||||||
if (withBaseTexture)
|
|
||||||
{
|
|
||||||
scene->getOrCreateStateSet()->setTextureAttributeAndModes( 0, new osg::Texture2D(osgDB::readImageFile("Images/lz.rgb")), osg::StateAttribute::ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewer.setSceneData(scene.get());
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ref_ptr<MatrixTransform> scene = new MatrixTransform;
|
|
||||||
scene->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(125.0),1.0,0.0,0.0));
|
|
||||||
|
|
||||||
ref_ptr<Group> created_scene = _create_scene();
|
|
||||||
if (!created_scene.valid()) return 1;
|
|
||||||
|
|
||||||
ref_ptr<MatrixTransform> light_transform = _create_lights();
|
|
||||||
if (!light_transform.valid()) return 1;
|
|
||||||
|
|
||||||
ref_ptr<Group> shadowedScene;
|
|
||||||
|
|
||||||
if (withBaseTexture)
|
|
||||||
{
|
|
||||||
scene->getOrCreateStateSet()->setTextureAttributeAndModes( 0, new osg::Texture2D(osgDB::readImageFile("Images/lz.rgb")), osg::StateAttribute::ON);
|
|
||||||
shadowedScene = createShadowedScene(created_scene.get(),light_transform.get(),1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shadowedScene = createShadowedScene(created_scene.get(),light_transform.get(),0);
|
|
||||||
}
|
|
||||||
|
|
||||||
scene->addChild(shadowedScene.get());
|
|
||||||
|
|
||||||
viewer.setSceneData(scene.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
// viewer.setUpViewOnSingleScreen();
|
|
||||||
|
|
||||||
|
|
||||||
return viewer.run();
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
#this file is automatically generated
|
|
||||||
|
|
||||||
|
|
||||||
SET(TARGET_SRC CreateShadowedScene.cpp osgshadowtexture.cpp )
|
|
||||||
SET(TARGET_H CreateShadowedScene.h )
|
|
||||||
SET(TARGET_ADDED_LIBRARIES osgShadow )
|
|
||||||
#### end var setup ###
|
|
||||||
SETUP_EXAMPLE(osgshadowtexture)
|
|
@ -1,224 +0,0 @@
|
|||||||
/* OpenSceneGraph example, osgshadowtexture.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osg/Texture2D>
|
|
||||||
#include <osg/Material>
|
|
||||||
#include <osg/LightSource>
|
|
||||||
#include <osg/Geode>
|
|
||||||
#include <osg/Geometry>
|
|
||||||
#include <osg/ShapeDrawable>
|
|
||||||
#include <osg/Camera>
|
|
||||||
#include <osg/TexGenNode>
|
|
||||||
#include <osg/Notify>
|
|
||||||
#include <osg/io_utils>
|
|
||||||
|
|
||||||
#include "CreateShadowedScene.h"
|
|
||||||
|
|
||||||
using namespace osg;
|
|
||||||
|
|
||||||
class UpdateCameraAndTexGenCallback : public osg::NodeCallback
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
UpdateCameraAndTexGenCallback(const osg::Vec3& position, osg::Camera* Camera, osg::TexGenNode* texgenNode):
|
|
||||||
_position(position),
|
|
||||||
_Camera(Camera),
|
|
||||||
_texgenNode(texgenNode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
|
||||||
{
|
|
||||||
// first update subgraph to make sure objects are all moved into postion
|
|
||||||
traverse(node,nv);
|
|
||||||
|
|
||||||
// now compute the camera's view and projection matrix to point at the shadower (the camera's children)
|
|
||||||
osg::BoundingSphere bs;
|
|
||||||
for(unsigned int i=0; i<_Camera->getNumChildren(); ++i)
|
|
||||||
{
|
|
||||||
bs.expandBy(_Camera->getChild(i)->getBound());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bs.valid())
|
|
||||||
{
|
|
||||||
osg::notify(osg::WARN) << "bb invalid"<<_Camera.get()<<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float centerDistance = (_position-bs.center()).length();
|
|
||||||
|
|
||||||
float znear = centerDistance-bs.radius();
|
|
||||||
float zfar = centerDistance+bs.radius();
|
|
||||||
float zNearRatio = 0.001f;
|
|
||||||
if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
|
|
||||||
|
|
||||||
float top = (bs.radius()/centerDistance)*znear;
|
|
||||||
float right = top;
|
|
||||||
|
|
||||||
_Camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
|
||||||
_Camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
|
|
||||||
_Camera->setViewMatrixAsLookAt(_position,bs.center(),osg::Vec3(0.0f,1.0f,0.0f));
|
|
||||||
|
|
||||||
// compute the matrix which takes a vertex from local coords into tex coords
|
|
||||||
// will use this later to specify osg::TexGen..
|
|
||||||
osg::Matrix MVPT = _Camera->getViewMatrix() *
|
|
||||||
_Camera->getProjectionMatrix() *
|
|
||||||
osg::Matrix::translate(1.0,1.0,1.0) *
|
|
||||||
osg::Matrix::scale(0.5f,0.5f,0.5f);
|
|
||||||
|
|
||||||
_texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR);
|
|
||||||
_texgenNode->getTexGen()->setPlanesFromMatrix(MVPT);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual ~UpdateCameraAndTexGenCallback() {}
|
|
||||||
|
|
||||||
osg::Vec3 _position;
|
|
||||||
osg::ref_ptr<osg::Camera> _Camera;
|
|
||||||
osg::ref_ptr<osg::TexGenNode> _texgenNode;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
osg::Group* createShadowedScene(osg::Node* shadower,osg::Node* shadowed,const osg::Vec3& lightPosition,float radius,unsigned int unit)
|
|
||||||
{
|
|
||||||
osg::Group* group = new osg::Group;
|
|
||||||
|
|
||||||
// add light source
|
|
||||||
{
|
|
||||||
osg::LightSource* lightSource = new osg::LightSource;
|
|
||||||
lightSource->getLight()->setPosition(osg::Vec4(lightPosition,1.0f));
|
|
||||||
lightSource->getLight()->setLightNum(0);
|
|
||||||
|
|
||||||
group->addChild(lightSource);
|
|
||||||
|
|
||||||
osg::Geode* lightgeode = new osg::Geode;
|
|
||||||
lightgeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
|
|
||||||
lightgeode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(lightPosition,radius)));
|
|
||||||
group->addChild(lightgeode);
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::Vec4 ambientLightColor(0.2,0.2f,0.2f,1.0f);
|
|
||||||
|
|
||||||
// add the shadower and shadowed.
|
|
||||||
group->addChild(shadower);
|
|
||||||
group->addChild(shadowed);
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int tex_width = 512;
|
|
||||||
unsigned int tex_height = 512;
|
|
||||||
|
|
||||||
osg::Texture2D* texture = new osg::Texture2D;
|
|
||||||
texture->setTextureSize(tex_width, tex_height);
|
|
||||||
texture->setInternalFormat(GL_RGB);
|
|
||||||
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
|
|
||||||
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
|
|
||||||
texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
|
|
||||||
texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
|
|
||||||
texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
|
||||||
|
|
||||||
// set up the render to texture camera.
|
|
||||||
{
|
|
||||||
|
|
||||||
// create the camera
|
|
||||||
osg::Camera* camera = new osg::Camera;
|
|
||||||
|
|
||||||
camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
|
||||||
|
|
||||||
// set viewport
|
|
||||||
camera->setViewport(0,0,tex_width,tex_height);
|
|
||||||
|
|
||||||
// set the camera to render before the main camera.
|
|
||||||
camera->setRenderOrder(osg::Camera::PRE_RENDER);
|
|
||||||
|
|
||||||
// tell the camera to use OpenGL frame buffer object where supported.
|
|
||||||
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
|
||||||
|
|
||||||
// attach the texture and use it as the color buffer.
|
|
||||||
camera->attach(osg::Camera::COLOR_BUFFER, texture);
|
|
||||||
|
|
||||||
// add subgraph to render
|
|
||||||
camera->addChild(shadower);
|
|
||||||
|
|
||||||
osg::StateSet* stateset = camera->getOrCreateStateSet();
|
|
||||||
|
|
||||||
// make the material black for a shadow.
|
|
||||||
osg::Material* material = new osg::Material;
|
|
||||||
material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
|
|
||||||
material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
|
|
||||||
material->setEmission(osg::Material::FRONT_AND_BACK,ambientLightColor);
|
|
||||||
material->setShininess(osg::Material::FRONT_AND_BACK,0.0f);
|
|
||||||
stateset->setAttribute(material,osg::StateAttribute::OVERRIDE);
|
|
||||||
|
|
||||||
group->addChild(camera);
|
|
||||||
|
|
||||||
// create the texgen node to project the tex coords onto the subgraph
|
|
||||||
osg::TexGenNode* texgenNode = new osg::TexGenNode;
|
|
||||||
texgenNode->setTextureUnit(unit);
|
|
||||||
group->addChild(texgenNode);
|
|
||||||
|
|
||||||
// set an update callback to keep moving the camera and tex gen in the right direction.
|
|
||||||
group->setUpdateCallback(new UpdateCameraAndTexGenCallback(lightPosition, camera, texgenNode));
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the shadowed subgraph so that it uses the texture and tex gen settings.
|
|
||||||
{
|
|
||||||
osg::StateSet* stateset = shadowed->getOrCreateStateSet();
|
|
||||||
stateset->setTextureAttributeAndModes(unit,texture,osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureMode(unit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureMode(unit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureMode(unit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureMode(unit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// set hud to render shadow texture, just for interest
|
|
||||||
{
|
|
||||||
osg::Geode* geode = new osg::Geode;
|
|
||||||
osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(0,0,0),osg::Vec3(100.0,0.0,0.0),osg::Vec3(0.0,100.0,0.0));
|
|
||||||
geom->getOrCreateStateSet()->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
|
||||||
geom->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
|
|
||||||
geode->addDrawable(geom);
|
|
||||||
|
|
||||||
osg::Camera* camera = new osg::Camera;
|
|
||||||
|
|
||||||
// set the projection matrix
|
|
||||||
camera->setProjectionMatrix(osg::Matrix::ortho2D(0,100,0,100));
|
|
||||||
|
|
||||||
// set the view matrix
|
|
||||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
|
||||||
camera->setViewMatrix(osg::Matrix::identity());
|
|
||||||
|
|
||||||
camera->setViewport(50,50,100,100);
|
|
||||||
|
|
||||||
// only clear the depth buffer
|
|
||||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
// draw subgraph after main camera view.
|
|
||||||
camera->setRenderOrder(osg::Camera::POST_RENDER);
|
|
||||||
|
|
||||||
camera->addChild(geode);
|
|
||||||
|
|
||||||
group->addChild(camera);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/* -*-c++-*-
|
|
||||||
*
|
|
||||||
* OpenSceneGraph example, osgshadowtexture.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CREATESHADOWEDSCENE_H
|
|
||||||
#define CREATESHADOWEDSCENE_H
|
|
||||||
|
|
||||||
#include <osg/Node>
|
|
||||||
#include <osg/Vec3>
|
|
||||||
|
|
||||||
// function to create a lightsource which contain a shadower and showed subgraph,
|
|
||||||
// the showadowed subgrph has a cull callback to fire off a pre render to texture
|
|
||||||
// of the shadowed subgraph.
|
|
||||||
extern osg::Group* createShadowedScene(osg::Node* shadower,osg::Node* shadowed,const osg::Vec3& lightPosition,float radius,unsigned int textureUnit=1);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,274 +0,0 @@
|
|||||||
/* OpenSceneGraph example, osgshadowtexture.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <osg/Notify>
|
|
||||||
#include <osg/MatrixTransform>
|
|
||||||
#include <osg/ShapeDrawable>
|
|
||||||
#include <osg/PositionAttitudeTransform>
|
|
||||||
#include <osg/Geometry>
|
|
||||||
#include <osg/Texture2D>
|
|
||||||
#include <osg/Geode>
|
|
||||||
|
|
||||||
#include <osgUtil/Optimizer>
|
|
||||||
|
|
||||||
#include <osgDB/Registry>
|
|
||||||
#include <osgDB/ReadFile>
|
|
||||||
|
|
||||||
#include <osgViewer/Viewer>
|
|
||||||
|
|
||||||
#include <osgShadow/ShadowedScene>
|
|
||||||
#include <osgShadow/ShadowVolume>
|
|
||||||
#include <osgShadow/ShadowTexture>
|
|
||||||
#include <osgShadow/ShadowMap>
|
|
||||||
|
|
||||||
// include the call which creates the shadowed subgraph.
|
|
||||||
#include "CreateShadowedScene.h"
|
|
||||||
|
|
||||||
|
|
||||||
// for the grid data..
|
|
||||||
#include "../osghangglide/terrain_coords.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
|
|
||||||
{
|
|
||||||
// set up the animation path
|
|
||||||
osg::AnimationPath* animationPath = new osg::AnimationPath;
|
|
||||||
animationPath->setLoopMode(osg::AnimationPath::LOOP);
|
|
||||||
|
|
||||||
int numSamples = 40;
|
|
||||||
float yaw = 0.0f;
|
|
||||||
float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f);
|
|
||||||
float roll = osg::inDegrees(30.0f);
|
|
||||||
|
|
||||||
double time=0.0f;
|
|
||||||
double time_delta = looptime/(double)numSamples;
|
|
||||||
for(int i=0;i<numSamples;++i)
|
|
||||||
{
|
|
||||||
osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
|
|
||||||
osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0)));
|
|
||||||
|
|
||||||
animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
|
|
||||||
|
|
||||||
yaw += yaw_delta;
|
|
||||||
time += time_delta;
|
|
||||||
|
|
||||||
}
|
|
||||||
return animationPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::Node* createBase(const osg::Vec3& center,float radius)
|
|
||||||
{
|
|
||||||
|
|
||||||
osg::Geode* geode = new osg::Geode;
|
|
||||||
|
|
||||||
// set up the texture of the base.
|
|
||||||
osg::StateSet* stateset = new osg::StateSet();
|
|
||||||
osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
osg::Texture2D* texture = new osg::Texture2D;
|
|
||||||
texture->setImage(image);
|
|
||||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
geode->setStateSet( stateset );
|
|
||||||
|
|
||||||
|
|
||||||
osg::HeightField* grid = new osg::HeightField;
|
|
||||||
grid->allocate(38,39);
|
|
||||||
grid->setOrigin(center+osg::Vec3(-radius,-radius,0.0f));
|
|
||||||
grid->setXInterval(radius*2.0f/(float)(38-1));
|
|
||||||
grid->setYInterval(radius*2.0f/(float)(39-1));
|
|
||||||
|
|
||||||
float minHeight = FLT_MAX;
|
|
||||||
float maxHeight = -FLT_MAX;
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int r;
|
|
||||||
for(r=0;r<39;++r)
|
|
||||||
{
|
|
||||||
for(unsigned int c=0;c<38;++c)
|
|
||||||
{
|
|
||||||
float h = vertex[r+c*39][2];
|
|
||||||
if (h>maxHeight) maxHeight=h;
|
|
||||||
if (h<minHeight) minHeight=h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float hieghtScale = radius*0.5f/(maxHeight-minHeight);
|
|
||||||
float hieghtOffset = -(minHeight+maxHeight)*0.5f;
|
|
||||||
|
|
||||||
for(r=0;r<39;++r)
|
|
||||||
{
|
|
||||||
for(unsigned int c=0;c<38;++c)
|
|
||||||
{
|
|
||||||
float h = vertex[r+c*39][2];
|
|
||||||
grid->setHeight(c,r,(h+hieghtOffset)*hieghtScale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
geode->addDrawable(new osg::ShapeDrawable(grid));
|
|
||||||
|
|
||||||
osg::Group* group = new osg::Group;
|
|
||||||
group->addChild(geode);
|
|
||||||
|
|
||||||
return group;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::Node* createMovingModel(const osg::Vec3& center, float radius)
|
|
||||||
{
|
|
||||||
float animationLength = 10.0f;
|
|
||||||
|
|
||||||
osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength);
|
|
||||||
|
|
||||||
osg::Group* model = new osg::Group;
|
|
||||||
|
|
||||||
osg::Node* cessna = osgDB::readNodeFile("cessna.osg");
|
|
||||||
if (cessna)
|
|
||||||
{
|
|
||||||
const osg::BoundingSphere& bs = cessna->getBound();
|
|
||||||
|
|
||||||
float size = radius/bs.radius()*0.3f;
|
|
||||||
osg::MatrixTransform* positioned = new osg::MatrixTransform;
|
|
||||||
positioned->setDataVariance(osg::Object::STATIC);
|
|
||||||
positioned->setMatrix(osg::Matrix::translate(-bs.center())*
|
|
||||||
osg::Matrix::scale(size,size,size)*
|
|
||||||
osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,2.0f));
|
|
||||||
|
|
||||||
positioned->addChild(cessna);
|
|
||||||
|
|
||||||
osg::MatrixTransform* xform = new osg::MatrixTransform;
|
|
||||||
xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
|
|
||||||
xform->addChild(positioned);
|
|
||||||
|
|
||||||
model->addChild(xform);
|
|
||||||
}
|
|
||||||
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
osg::Node* createModel(osg::ArgumentParser& arguments)
|
|
||||||
{
|
|
||||||
osg::Vec3 center(0.0f,0.0f,0.0f);
|
|
||||||
float radius = 100.0f;
|
|
||||||
osg::Vec3 lightPosition(center+osg::Vec3(0.0f,0.0f,radius));
|
|
||||||
|
|
||||||
// the shadower model
|
|
||||||
osg::Node* shadower = createMovingModel(center,radius*0.5f);
|
|
||||||
|
|
||||||
// the shadowed model
|
|
||||||
osg::Node* shadowed = createBase(center-osg::Vec3(0.0f,0.0f,radius*0.25),radius);
|
|
||||||
|
|
||||||
if (arguments.read("--sv"))
|
|
||||||
{
|
|
||||||
// hint to tell viewer to request stencil buffer when setting up windows
|
|
||||||
osg::DisplaySettings::instance()->setMinimumNumStencilBits(8);
|
|
||||||
|
|
||||||
osgShadow::ShadowedScene* shadowedScene = new osgShadow::ShadowedScene;
|
|
||||||
|
|
||||||
osg::ref_ptr<osgShadow::ShadowVolume> shadowVolume = new osgShadow::ShadowVolume;
|
|
||||||
shadowedScene->setShadowTechnique(shadowVolume.get());
|
|
||||||
shadowVolume->setDynamicShadowVolumes(true);
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::LightSource> ls = new osg::LightSource;
|
|
||||||
ls->getLight()->setPosition(osg::Vec4(lightPosition,1.0));
|
|
||||||
|
|
||||||
shadowedScene->addChild(shadower);
|
|
||||||
shadowedScene->addChild(shadowed);
|
|
||||||
shadowedScene->addChild(ls.get());
|
|
||||||
|
|
||||||
return shadowedScene;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (arguments.read("--st"))
|
|
||||||
{
|
|
||||||
|
|
||||||
osgShadow::ShadowedScene* shadowedScene = new osgShadow::ShadowedScene;
|
|
||||||
|
|
||||||
osg::ref_ptr<osgShadow::ShadowTexture> shadowTexture = new osgShadow::ShadowTexture;
|
|
||||||
shadowedScene->setShadowTechnique(shadowTexture.get());
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::LightSource> ls = new osg::LightSource;
|
|
||||||
ls->getLight()->setPosition(osg::Vec4(lightPosition,1.0));
|
|
||||||
|
|
||||||
shadowedScene->setReceivesShadowTraversalMask(0x1);
|
|
||||||
shadowed->setNodeMask(shadowedScene->getReceivesShadowTraversalMask());
|
|
||||||
|
|
||||||
shadowedScene->setCastsShadowTraversalMask(0x2);
|
|
||||||
shadower->setNodeMask(shadowedScene->getCastsShadowTraversalMask());
|
|
||||||
|
|
||||||
shadowedScene->addChild(shadower);
|
|
||||||
shadowedScene->addChild(shadowed);
|
|
||||||
shadowedScene->addChild(ls.get());
|
|
||||||
|
|
||||||
return shadowedScene;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (arguments.read("--sm"))
|
|
||||||
{
|
|
||||||
|
|
||||||
osgShadow::ShadowedScene* shadowedScene = new osgShadow::ShadowedScene;
|
|
||||||
|
|
||||||
osg::ref_ptr<osgShadow::ShadowMap> shadowMap = new osgShadow::ShadowMap;
|
|
||||||
shadowedScene->setShadowTechnique(shadowMap.get());
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::LightSource> ls = new osg::LightSource;
|
|
||||||
ls->getLight()->setPosition(osg::Vec4(lightPosition,1.0));
|
|
||||||
|
|
||||||
shadowedScene->setReceivesShadowTraversalMask(0x1);
|
|
||||||
shadowed->setNodeMask(shadowedScene->getReceivesShadowTraversalMask());
|
|
||||||
|
|
||||||
shadowedScene->setCastsShadowTraversalMask(0x2);
|
|
||||||
shadower->setNodeMask(shadowedScene->getCastsShadowTraversalMask());
|
|
||||||
|
|
||||||
shadowedScene->addChild(shadower);
|
|
||||||
shadowedScene->addChild(shadowed);
|
|
||||||
shadowedScene->addChild(ls.get());
|
|
||||||
|
|
||||||
return shadowedScene;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// combine the models together to create one which has the shadower and the shadowed with the required callback.
|
|
||||||
osg::Group* root = createShadowedScene(shadower,shadowed,lightPosition,radius/100.0f,1);
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
|
||||||
{
|
|
||||||
osg::ArgumentParser arguments(&argc,argv);
|
|
||||||
|
|
||||||
// construct the viewer.
|
|
||||||
osgViewer::Viewer viewer;
|
|
||||||
|
|
||||||
// pass the model to the viewer.
|
|
||||||
viewer.setSceneData( createModel(arguments) );
|
|
||||||
|
|
||||||
viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
|
||||||
|
|
||||||
return viewer.run();
|
|
||||||
}
|
|
@ -33,9 +33,6 @@ osgclip
|
|||||||
echo osgcubemap
|
echo osgcubemap
|
||||||
osgcubemap
|
osgcubemap
|
||||||
|
|
||||||
echo osgdepthshadow
|
|
||||||
osgdepthshadow
|
|
||||||
|
|
||||||
echo osgdistortion
|
echo osgdistortion
|
||||||
osgdistortion
|
osgdistortion
|
||||||
|
|
||||||
@ -144,12 +141,18 @@ osgviewer glsl_mandelbrot.osg
|
|||||||
echo osgviewer glsl_julia.osg
|
echo osgviewer glsl_julia.osg
|
||||||
osgviewer glsl_julia.osg
|
osgviewer glsl_julia.osg
|
||||||
|
|
||||||
echo osgshadowtexture
|
|
||||||
osgshadowtexture cessna.osg
|
|
||||||
|
|
||||||
echo osgshape
|
echo osgshape
|
||||||
osgshape
|
osgshape
|
||||||
|
|
||||||
|
echo osgshadow -3 --sm
|
||||||
|
osgshadow -3 --sm
|
||||||
|
|
||||||
|
echo osgshadow -2 --st
|
||||||
|
osgshadow -2 --st
|
||||||
|
|
||||||
|
echo osgshadow -3 --ssm
|
||||||
|
osgshadow -3 --ssm
|
||||||
|
|
||||||
echo osgsimplifier
|
echo osgsimplifier
|
||||||
osgsimplifier --ratio 0.1 cessna.osg
|
osgsimplifier --ratio 0.1 cessna.osg
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user