root/OpenSceneGraph/trunk/examples/osgshadowtexture/CreateShadowedScene.cpp @ 5757

Revision 5757, 7.6 kB (checked in by robert, 7 years ago)

Renamed osg::CameraNode? to osg::Camera, cleaned up osg::View.

Added beginnings of new osgViewer::Scene,View,Viewer,CompositeViewer? and GraphicsWindowProxy? files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/Texture2D>
2#include <osg/Material>
3#include <osg/LightSource>
4#include <osg/Geode>
5#include <osg/Geometry>
6#include <osg/ShapeDrawable>
7#include <osg/Camera>
8#include <osg/TexGenNode>
9#include <osg/Notify>
10#include <osg/io_utils>
11
12#include "CreateShadowedScene.h"
13
14using namespace osg;
15
16class UpdateCameraAndTexGenCallback : public osg::NodeCallback
17{
18    public:
19   
20        UpdateCameraAndTexGenCallback(const osg::Vec3& position, osg::Camera* Camera, osg::TexGenNode* texgenNode):
21            _position(position),
22            _Camera(Camera),
23            _texgenNode(texgenNode)
24        {
25        }
26       
27        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
28        {
29            // first update subgraph to make sure objects are all moved into postion
30            traverse(node,nv);
31           
32            // now compute the camera's view and projection matrix to point at the shadower (the camera's children)
33            osg::BoundingSphere bs;
34            for(unsigned int i=0; i<_Camera->getNumChildren(); ++i)
35            {
36                bs.expandBy(_Camera->getChild(i)->getBound());
37            }
38           
39            if (!bs.valid())
40            {
41                osg::notify(osg::WARN) << "bb invalid"<<_Camera.get()<<std::endl;
42                return;
43            }
44
45            float centerDistance = (_position-bs.center()).length();
46
47            float znear = centerDistance-bs.radius();
48            float zfar  = centerDistance+bs.radius();
49            float zNearRatio = 0.001f;
50            if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
51
52            float top   = (bs.radius()/centerDistance)*znear;
53            float right = top;
54
55            _Camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
56            _Camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
57            _Camera->setViewMatrixAsLookAt(_position,bs.center(),osg::Vec3(0.0f,1.0f,0.0f));
58
59            // compute the matrix which takes a vertex from local coords into tex coords
60            // will use this later to specify osg::TexGen..
61            osg::Matrix MVPT = _Camera->getViewMatrix() *
62                               _Camera->getProjectionMatrix() *
63                               osg::Matrix::translate(1.0,1.0,1.0) *
64                               osg::Matrix::scale(0.5f,0.5f,0.5f);
65                               
66            _texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR);
67            _texgenNode->getTexGen()->setPlanesFromMatrix(MVPT);
68
69        }
70       
71    protected:
72   
73        virtual ~UpdateCameraAndTexGenCallback() {}
74       
75        osg::Vec3                     _position;
76        osg::ref_ptr<osg::Camera> _Camera;
77        osg::ref_ptr<osg::TexGenNode> _texgenNode;
78
79};
80
81
82osg::Group* createShadowedScene(osg::Node* shadower,osg::Node* shadowed,const osg::Vec3& lightPosition,float radius,unsigned int unit)
83{
84    osg::Group* group = new osg::Group;
85   
86    // add light source
87    {
88        osg::LightSource* lightSource = new osg::LightSource;
89        lightSource->getLight()->setPosition(osg::Vec4(lightPosition,1.0f));
90        lightSource->getLight()->setLightNum(0);
91
92        group->addChild(lightSource);
93
94        osg::Geode* lightgeode = new osg::Geode;
95        lightgeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
96        lightgeode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(lightPosition,radius)));
97        group->addChild(lightgeode);
98    }
99       
100    osg::Vec4 ambientLightColor(0.2,0.2f,0.2f,1.0f);
101
102    // add the shadower and shadowed.
103    group->addChild(shadower);
104    group->addChild(shadowed);
105
106       
107    unsigned int tex_width = 512;
108    unsigned int tex_height = 512;
109   
110    osg::Texture2D* texture = new osg::Texture2D;
111    texture->setTextureSize(tex_width, tex_height);
112    texture->setInternalFormat(GL_RGB);
113    texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
114    texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
115    texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
116    texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
117    texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
118   
119    // set up the render to texture camera.
120    {
121
122        // create the camera
123        osg::Camera* camera = new osg::Camera;
124
125        camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
126
127        // set viewport
128        camera->setViewport(0,0,tex_width,tex_height);
129
130        // set the camera to render before the main camera.
131        camera->setRenderOrder(osg::Camera::PRE_RENDER);
132
133        // tell the camera to use OpenGL frame buffer object where supported.
134        camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
135
136        // attach the texture and use it as the color buffer.
137        camera->attach(osg::Camera::COLOR_BUFFER, texture);
138
139        // add subgraph to render
140        camera->addChild(shadower);
141       
142        osg::StateSet* stateset = camera->getOrCreateStateSet();
143
144        // make the material black for a shadow.
145        osg::Material* material = new osg::Material;
146        material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
147        material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
148        material->setEmission(osg::Material::FRONT_AND_BACK,ambientLightColor);
149        material->setShininess(osg::Material::FRONT_AND_BACK,0.0f);
150        stateset->setAttribute(material,osg::StateAttribute::OVERRIDE);
151
152        group->addChild(camera);
153       
154        // create the texgen node to project the tex coords onto the subgraph
155        osg::TexGenNode* texgenNode = new osg::TexGenNode;
156        texgenNode->setTextureUnit(unit);
157        group->addChild(texgenNode);
158
159        // set an update callback to keep moving the camera and tex gen in the right direction.
160        group->setUpdateCallback(new UpdateCameraAndTexGenCallback(lightPosition, camera, texgenNode));
161    }
162
163    // set the shadowed subgraph so that it uses the texture and tex gen settings.   
164    {
165        osg::StateSet* stateset = shadowed->getOrCreateStateSet();
166        stateset->setTextureAttributeAndModes(unit,texture,osg::StateAttribute::ON);
167        stateset->setTextureMode(unit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
168        stateset->setTextureMode(unit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
169        stateset->setTextureMode(unit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
170        stateset->setTextureMode(unit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
171    }
172   
173
174    // set hud to render shadow texture, just for interest
175    {
176        osg::Geode* geode = new osg::Geode;
177        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));
178        geom->getOrCreateStateSet()->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
179        geom->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
180        geode->addDrawable(geom);
181       
182        osg::Camera* camera = new osg::Camera;
183
184        // set the projection matrix
185        camera->setProjectionMatrix(osg::Matrix::ortho2D(0,100,0,100));
186
187        // set the view matrix   
188        camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
189        camera->setViewMatrix(osg::Matrix::identity());
190       
191        camera->setViewport(50,50,100,100);
192
193        // only clear the depth buffer
194        camera->setClearMask(GL_DEPTH_BUFFER_BIT);
195
196        // draw subgraph after main camera view.
197        camera->setRenderOrder(osg::Camera::POST_RENDER);
198
199        camera->addChild(geode);
200       
201        group->addChild(camera);
202       
203    }
204   
205    return group;
206}
Note: See TracBrowser for help on using the browser.