Ported all the render to texture examples across to using the new osg::CameraNode.
Added support for texture cube maps in FBO + CameraNode.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/PolygonOffset>
|
||||
#include <osg/CullFace>
|
||||
#include <osg/TexEnvCombine>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Light>
|
||||
#include <osg/LightSource>
|
||||
@@ -17,18 +17,12 @@
|
||||
#include <osg/Material>
|
||||
|
||||
#include <osgUtil/TransformCallback>
|
||||
#include <osgUtil/RenderToTextureStage>
|
||||
|
||||
#include <osg/CameraNode>
|
||||
#include <osg/TexGenNode>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
const int depth_texture_height = 512;
|
||||
const int depth_texture_width = 512;
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
@@ -91,152 +85,8 @@ LightTransformCallback::operator()(Node* node, NodeVisitor* 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(1.1f);
|
||||
polygon_offset->setUnits(4.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::FRONT);
|
||||
_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()->getStage();
|
||||
|
||||
// set up the background color and clear mask.
|
||||
rtts->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
rtts->setColorMask(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->getRenderGraphList().size()==0 && rtts->getRenderBinList().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()->getStage()->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> _create_lights()
|
||||
{
|
||||
ref_ptr<MatrixTransform> transform_0 = new MatrixTransform;
|
||||
|
||||
@@ -256,6 +106,7 @@ ref_ptr<MatrixTransform> _create_lights(ref_ptr<StateSet> root_stateset)
|
||||
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);
|
||||
@@ -265,11 +116,11 @@ ref_ptr<MatrixTransform> _create_lights(ref_ptr<StateSet> root_stateset)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -336,72 +187,220 @@ ref_ptr<Group> _create_scene()
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
||||
class UpdateCameraAndTexGenCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
UpdateCameraAndTexGenCallback(osg::MatrixTransform* light_transform, osg::CameraNode* cameraNode, osg::TexGenNode* texgenNode):
|
||||
_light_transform(light_transform),
|
||||
_cameraNode(cameraNode),
|
||||
_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<_cameraNode->getNumChildren(); ++i)
|
||||
{
|
||||
bs.expandBy(_cameraNode->getChild(i)->getBound());
|
||||
}
|
||||
|
||||
if (!bs.valid())
|
||||
{
|
||||
osg::notify(osg::WARN) << "bb invalid"<<_cameraNode.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;
|
||||
|
||||
float top = (bs.radius()/centerDistance)*znear;
|
||||
float right = top;
|
||||
|
||||
_cameraNode->setReferenceFrame(osg::CameraNode::ABSOLUTE_RF);
|
||||
_cameraNode->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
|
||||
_cameraNode->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 = _cameraNode->getViewMatrix() *
|
||||
_cameraNode->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::CameraNode> _cameraNode;
|
||||
osg::ref_ptr<osg::TexGenNode> _texgenNode;
|
||||
|
||||
};
|
||||
|
||||
|
||||
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::CameraNode* camera = new osg::CameraNode;
|
||||
|
||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
||||
camera->setComputeNearFarMode(osg::CameraNode::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);
|
||||
|
||||
ref_ptr<PolygonOffset> polygon_offset = new PolygonOffset;
|
||||
polygon_offset->setFactor(1.1f);
|
||||
polygon_offset->setUnits(4.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::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::CameraNode::PRE_RENDER);
|
||||
|
||||
// tell the camera to use OpenGL frame buffer object where supported.
|
||||
camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT);
|
||||
|
||||
// attach the texture and use it as the color buffer.
|
||||
camera->attach(osg::CameraNode::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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
// 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 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");
|
||||
|
||||
// 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());
|
||||
// construct the viewer.
|
||||
osgProducer::Viewer viewer(arguments);
|
||||
|
||||
// if user request help write it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
// 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;
|
||||
arguments.getApplicationUsage()->write(std::cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// any option left unread are converted into errors to write out later.
|
||||
arguments.reportRemainingOptionsAsUnrecognized();
|
||||
// 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())
|
||||
// report any errors if they have occured when parsing the program aguments.
|
||||
if (arguments.errors())
|
||||
{
|
||||
arguments.writeErrorMessages(std::cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ref_ptr<MatrixTransform> scene = new MatrixTransform;
|
||||
scene->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(125.0),1.0,0.0,0.0));
|
||||
|
||||
ref_ptr<Group> shadowed_scene = _create_scene();
|
||||
if (!shadowed_scene.valid()) return 1;
|
||||
scene->addChild(shadowed_scene.get());
|
||||
ref_ptr<MatrixTransform> scene = new MatrixTransform;
|
||||
scene->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(125.0),1.0,0.0,0.0));
|
||||
|
||||
ref_ptr<MatrixTransform> light_transform = _create_lights(scene->getOrCreateStateSet());
|
||||
if (!scene.valid()) return 1;
|
||||
scene->addChild(light_transform.get());
|
||||
ref_ptr<Group> shadowed_scene = _create_scene();
|
||||
if (!shadowed_scene.valid()) return 1;
|
||||
|
||||
ref_ptr<Texture2D> texture = new Texture2D;
|
||||
texture->setInternalFormat(GL_DEPTH_COMPONENT);
|
||||
texture->setShadowComparison(true);
|
||||
texture->setShadowTextureMode(Texture::LUMINANCE);
|
||||
ref_ptr<MatrixTransform> light_transform = _create_lights();
|
||||
if (!light_transform.valid()) return 1;
|
||||
|
||||
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);
|
||||
ref_ptr<Group> shadowedScene = createShadowedScene(shadowed_scene.get(),light_transform.get(),0);
|
||||
|
||||
scene->setCullCallback(new RenderToTextureCallback(shadowed_scene.get(), texture.get(), light_transform.get(), tex_gen.get()));
|
||||
scene->addChild(shadowedScene.get());
|
||||
|
||||
// add model to viewer.
|
||||
viewer.setSceneData(scene.get());
|
||||
viewer.setSceneData(scene.get());
|
||||
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
while (!viewer.done())
|
||||
while (!viewer.done())
|
||||
{
|
||||
// wait for all cull and draw threads to complete.
|
||||
viewer.sync();
|
||||
@@ -414,8 +413,8 @@ int main(int argc, char** argv)
|
||||
viewer.frame();
|
||||
}
|
||||
|
||||
// wait for all cull and draw threads to complete before exit.
|
||||
viewer.sync();
|
||||
// wait for all cull and draw threads to complete before exit.
|
||||
viewer.sync();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
osg::Node* createDistortionSubgraph(osg::Node* subgraph)
|
||||
osg::Node* createDistortionSubgraph(osg::Node* subgraph, const osg::Vec4& clearColour)
|
||||
{
|
||||
osg::Group* distortionNode = new osg::Group;
|
||||
|
||||
@@ -42,6 +42,10 @@ osg::Node* createDistortionSubgraph(osg::Node* subgraph)
|
||||
{
|
||||
osg::CameraNode* camera = new osg::CameraNode;
|
||||
|
||||
// set clear the color and depth buffer
|
||||
camera->setClearColor(clearColour);
|
||||
camera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// just inherit the main cameras view
|
||||
camera->setReferenceFrame(osg::Transform::RELATIVE_RF);
|
||||
camera->setProjectionMatrix(osg::Matrixd::identity());
|
||||
@@ -49,7 +53,6 @@ osg::Node* createDistortionSubgraph(osg::Node* subgraph)
|
||||
|
||||
// set viewport
|
||||
camera->setViewport(0,0,tex_width,tex_height);
|
||||
camera->getOrCreateStateSet()->setAttribute(camera->getViewport());
|
||||
|
||||
// set the camera to render before the main camera.
|
||||
camera->setRenderOrder(osg::CameraNode::PRE_RENDER);
|
||||
@@ -219,7 +222,7 @@ int main( int argc, char **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::Node* distortionNode = createDistortionSubgraph(loadedModel);
|
||||
osg::Node* distortionNode = createDistortionSubgraph(loadedModel, viewer.getClearColor());
|
||||
|
||||
// add model to the viewer.
|
||||
viewer.setSceneData( distortionNode );
|
||||
|
||||
@@ -76,7 +76,6 @@ void build_world(osg::Group *root)
|
||||
camera->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f));
|
||||
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
camera->setViewport(0, 0, width, height);
|
||||
camera->getOrCreateStateSet()->setAttribute(camera->getViewport());
|
||||
|
||||
// set the camera to render before the main camera.
|
||||
camera->setRenderOrder(osg::CameraNode::PRE_RENDER);
|
||||
|
||||
@@ -1028,8 +1028,8 @@ osg::Node* ForestTechniqueManager::createScene(unsigned int numTreesToCreates)
|
||||
osg::Program* program = new osg::Program;
|
||||
stateset->setAttribute(program);
|
||||
|
||||
osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource);
|
||||
program->addShader(vertex_shader);
|
||||
//osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource);
|
||||
//program->addShader(vertex_shader);
|
||||
|
||||
osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource);
|
||||
program->addShader(fragment_shader);
|
||||
|
||||
@@ -23,38 +23,43 @@
|
||||
#include <osg/PolygonOffset>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/CameraNode>
|
||||
#include <osg/FrontFace>
|
||||
|
||||
#include <osgText/Text>
|
||||
|
||||
|
||||
osg::Node* createRearView(osg::Node* subgraph)
|
||||
osg::Node* createRearView(osg::Node* subgraph, const osg::Vec4& clearColour)
|
||||
{
|
||||
|
||||
osg::CameraNode* camera = new osg::CameraNode;
|
||||
|
||||
// set the projection matrix
|
||||
camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
|
||||
|
||||
// set the viewport
|
||||
camera->setViewport(420,800,400,200);
|
||||
|
||||
camera->getOrCreateStateSet()->setAttribute(camera->getViewport());
|
||||
|
||||
|
||||
// set the view matrix
|
||||
camera->setCullingActive(false);
|
||||
camera->setReferenceFrame(osg::Transform::RELATIVE_RF);
|
||||
camera->setTransformOrder(osg::CameraNode::POST_MULTIPLE);
|
||||
camera->setProjectionMatrix(osg::Matrixd::identity());
|
||||
|
||||
camera->setProjectionMatrix(osg::Matrixd::scale(-1.0f,1.0f,1.0f));
|
||||
camera->setViewMatrix(osg::Matrixd::rotate(osg::inDegrees(180.0f),0.0f,1.0f,0.0f));
|
||||
|
||||
// only clear the depth buffer
|
||||
// set clear the color and depth buffer
|
||||
camera->setClearColor(clearColour);
|
||||
camera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// draw subgraph after main camera view.
|
||||
camera->setRenderOrder(osg::CameraNode::POST_RENDER);
|
||||
|
||||
// add the subgraph to draw.
|
||||
camera->addChild(subgraph);
|
||||
|
||||
// switch of back face culling as we've swapped over the projection matrix making back faces become front faces.
|
||||
#if 1
|
||||
camera->getOrCreateStateSet()->setAttribute(new osg::FrontFace(osg::FrontFace::CLOCKWISE));
|
||||
#else
|
||||
camera->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
|
||||
#endif
|
||||
|
||||
return camera;
|
||||
}
|
||||
|
||||
@@ -103,7 +108,7 @@ int main( int argc, char **argv )
|
||||
|
||||
// add the HUD subgraph.
|
||||
if (scene.valid()) group->addChild(scene.get());
|
||||
group->addChild(createRearView(scene.get()));
|
||||
group->addChild(createRearView(scene.get(), viewer.getClearColor()));
|
||||
|
||||
// set the scene to render
|
||||
viewer.setSceneData(group.get());
|
||||
|
||||
@@ -122,6 +122,9 @@ int main( int argc, char **argv )
|
||||
// get details on keyboard and mouse bindings used by the viewer.
|
||||
viewer.getUsage(*arguments.getApplicationUsage());
|
||||
|
||||
bool shader = false;
|
||||
while (arguments.read("--shader")) shader = true;
|
||||
|
||||
// if user request help write it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
{
|
||||
@@ -196,6 +199,42 @@ int main( int argc, char **argv )
|
||||
// register the handler for modifying the point size
|
||||
viewer.getEventHandlerList().push_front(new KeyboardEventHandler(viewer.getGlobalStateSet()));
|
||||
|
||||
|
||||
if (shader)
|
||||
{
|
||||
osg::StateSet* stateset = loadedModel->getOrCreateStateSet();
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// vertex shader using just Vec4 coefficients
|
||||
char vertexShaderSource[] =
|
||||
"void main(void) \n"
|
||||
"{ \n"
|
||||
"\n"
|
||||
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
|
||||
"}\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// fragment shader
|
||||
//
|
||||
char fragmentShaderSource[] =
|
||||
"void main(void) \n"
|
||||
"{ \n"
|
||||
" gl_FragColor = gl_Color; \n"
|
||||
"}\n";
|
||||
|
||||
|
||||
osg::Program* program = new osg::Program;
|
||||
stateset->setAttribute(program);
|
||||
|
||||
osg::Shader* vertex_shader = new osg::Shader(osg::Shader::VERTEX, vertexShaderSource);
|
||||
program->addShader(vertex_shader);
|
||||
|
||||
//osg::Shader* fragment_shader = new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSource);
|
||||
//program->addShader(fragment_shader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
|
||||
@@ -213,13 +213,11 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph)
|
||||
|
||||
// set view
|
||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
camera->setViewMatrixAsLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));
|
||||
camera->setViewMatrixAsLookAt(bs.center()-osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));
|
||||
|
||||
// set viewport
|
||||
camera->setViewport(0,0,tex_width,tex_height);
|
||||
|
||||
camera->getOrCreateStateSet()->setAttribute(camera->getViewport());
|
||||
|
||||
// set the camera to render before the main camera.
|
||||
camera->setRenderOrder(osg::CameraNode::PRE_RENDER);
|
||||
|
||||
|
||||
@@ -1,420 +1,282 @@
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/Group>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Quat>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/TextureCubeMap>
|
||||
#include <osg/TexGen>
|
||||
#include <osg/TexMat>
|
||||
#include <osg/TexEnvCombine>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
#include <osg/MatrixTransform>
|
||||
|
||||
#include <osgUtil/RenderToTextureStage>
|
||||
#include <osgUtil/Optimizer>
|
||||
#include <osgUtil/TransformCallback>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgGA/FlightManipulator>
|
||||
#include <osgGA/DriveManipulator>
|
||||
|
||||
#include <osgProducer/Viewer>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#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/TextureCubeMap>
|
||||
#include <osg/TexMat>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Light>
|
||||
#include <osg/LightSource>
|
||||
#include <osg/PolygonOffset>
|
||||
#include <osg/CullFace>
|
||||
#include <osg/Material>
|
||||
#include <osg/RefNodePath>
|
||||
|
||||
#define UPDATE_ONE_IMAGE_PER_FRAME 1
|
||||
#include <osgUtil/TransformCallback>
|
||||
|
||||
#include <osg/CameraNode>
|
||||
#include <osg/TexGenNode>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
class PrerenderAppCallback : public osg::NodeCallback
|
||||
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(-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;
|
||||
}
|
||||
|
||||
osg::RefNodePath createReflector()
|
||||
{
|
||||
ref_ptr<Group> scene = new Group;
|
||||
ref_ptr<Geode> geode_1 = new Geode;
|
||||
scene->addChild(geode_1.get());
|
||||
|
||||
const float radius = 0.8f;
|
||||
ref_ptr<TessellationHints> hints = new TessellationHints;
|
||||
hints->setDetailRatio(2.0f);
|
||||
ref_ptr<ShapeDrawable> shape = new ShapeDrawable(new Sphere(Vec3(0.0f, 0.0f, 0.0f), radius * 1.5f), hints.get());
|
||||
shape->setColor(Vec4(0.8f, 0.8f, 0.8f, 1.0f));
|
||||
geode_1->addDrawable(shape.get());
|
||||
|
||||
osg::RefNodePath refNodeList;
|
||||
refNodeList.push_back(scene.get());
|
||||
refNodeList.push_back(geode_1.get());
|
||||
|
||||
return refNodeList;
|
||||
}
|
||||
|
||||
class UpdateCameraAndTexGenCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
PrerenderAppCallback(osg::Node* subgraph):
|
||||
_subgraph(subgraph) {}
|
||||
typedef std::vector< osg::ref_ptr<osg::CameraNode> > CameraList;
|
||||
|
||||
UpdateCameraAndTexGenCallback(osg::RefNodePath& reflectorNodePath, CameraList& cameraNodes):
|
||||
_reflectorNodePath(reflectorNodePath),
|
||||
_cameraNodes(cameraNodes)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
// traverse the subgraph to update any nodes.
|
||||
if (_subgraph.valid()) _subgraph->accept(*nv);
|
||||
|
||||
// must traverse the Node's subgraph
|
||||
// first update subgraph to make sure objects are all moved into postion
|
||||
traverse(node,nv);
|
||||
|
||||
// compute the position of the center of the reflector subgraph
|
||||
osg::Matrixd matrix = osg::computeLocalToWorld(_reflectorNodePath);
|
||||
osg::BoundingSphere bs = _reflectorNodePath.back()->getBound();
|
||||
osg::Vec3 position = bs.center() * matrix;
|
||||
|
||||
typedef std::pair<osg::Vec3, osg::Vec3> ImageData;
|
||||
const ImageData id[] =
|
||||
{
|
||||
ImageData( osg::Vec3( 1, 0, 0), osg::Vec3( 0, -1, 0) ), // +X
|
||||
ImageData( osg::Vec3(-1, 0, 0), osg::Vec3( 0, -1, 0) ), // -X
|
||||
ImageData( osg::Vec3( 0, 1, 0), osg::Vec3( 0, 0, 1) ), // +Y
|
||||
ImageData( osg::Vec3( 0, -1, 0), osg::Vec3( 0, 0, -1) ), // -Y
|
||||
ImageData( osg::Vec3( 0, 0, 1), osg::Vec3( 0, -1, 0) ), // +Z
|
||||
ImageData( osg::Vec3( 0, 0, -1), osg::Vec3( 0, -1, 0) ) // -Z
|
||||
};
|
||||
|
||||
for(unsigned int i=0;
|
||||
i<6 && i<_cameraNodes.size();
|
||||
++i)
|
||||
{
|
||||
_cameraNodes[i]->setReferenceFrame(osg::CameraNode::ABSOLUTE_RF);
|
||||
_cameraNodes[i]->setProjectionMatrixAsFrustum(-1.0,1.0,-1.0,1.0,1.0,10000.0);
|
||||
_cameraNodes[i]->setViewMatrixAsLookAt(position,position+id[i].first,id[i].second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> _subgraph;
|
||||
protected:
|
||||
|
||||
virtual ~UpdateCameraAndTexGenCallback() {}
|
||||
|
||||
osg::RefNodePath _reflectorNodePath;
|
||||
CameraList _cameraNodes;
|
||||
};
|
||||
|
||||
|
||||
class PrerenderCullCallback : public osg::NodeCallback
|
||||
class TexMatCullCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
PrerenderCullCallback(osg::Node* subgraph, osg::TextureCubeMap* cubemap, osg::TexMat* texmat):
|
||||
_subgraph(subgraph),
|
||||
_cubemap(cubemap),
|
||||
TexMatCullCallback(osg::TexMat* texmat):
|
||||
_texmat(texmat)
|
||||
{
|
||||
_updateCubemapFace = 0;
|
||||
_clearColor = osg::Vec4(1,1,1,1);
|
||||
_localState[0] = new osg::StateSet;
|
||||
_localState[1] = new osg::StateSet;
|
||||
_localState[2] = new osg::StateSet;
|
||||
_localState[3] = new osg::StateSet;
|
||||
_localState[4] = new osg::StateSet;
|
||||
_localState[5] = new osg::StateSet;
|
||||
}
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
// Reset this counter to zero, otherwise it wont do the while loop down below.
|
||||
// And the cubemap will never update the newer frames.
|
||||
if (_updateCubemapFace > 5)
|
||||
_updateCubemapFace = 0;
|
||||
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
|
||||
if (cv && _cubemap.valid() && _subgraph.valid())
|
||||
{
|
||||
const osg::Vec4 clearColArray[] =
|
||||
{
|
||||
osg::Vec4(0, 0, 1, 1), // +X
|
||||
osg::Vec4(1, 0.7f, 0, 1), // -X
|
||||
osg::Vec4(0, 1, 1, 1), // +Y
|
||||
osg::Vec4(1, 1, 0, 1), // -Y
|
||||
osg::Vec4(1, 0, 0, 1), // +Z
|
||||
osg::Vec4(0, 1, 0, 1) // -Z
|
||||
};
|
||||
|
||||
osg::Quat q;
|
||||
cv->getModelViewMatrix().get(q);
|
||||
const osg::Matrix C = osg::Matrix::rotate( q.inverse() );
|
||||
_texmat->setMatrix(C);
|
||||
|
||||
#if UPDATE_ONE_IMAGE_PER_FRAME
|
||||
if ((_updateCubemapFace >= 0) && (_updateCubemapFace <= 5))
|
||||
{
|
||||
_clearColor = clearColArray[_updateCubemapFace];
|
||||
doPreRender(*node, *cv, _updateCubemapFace++);
|
||||
}
|
||||
#else
|
||||
while (_updateCubemapFace<6)
|
||||
{
|
||||
_clearColor = clearColArray[_updateCubemapFace];
|
||||
doPreRender(*node, *cv, _updateCubemapFace++);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// must traverse the subgraph
|
||||
// first update subgraph to make sure objects are all moved into postion
|
||||
traverse(node,nv);
|
||||
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
|
||||
if (cv)
|
||||
{
|
||||
osg::Quat quat;
|
||||
cv->getModelViewMatrix().get(quat);
|
||||
_texmat->setMatrix(osg::Matrix::rotate(quat.inverse()));
|
||||
}
|
||||
}
|
||||
|
||||
void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv, const int nFace);
|
||||
|
||||
struct ImageData
|
||||
{
|
||||
ImageData(const osg::Vec3& dir, const osg::Vec3& up) : _dir(dir), _up(up) {}
|
||||
osg::Vec3 _dir;
|
||||
osg::Vec3 _up;
|
||||
};
|
||||
|
||||
osg::ref_ptr<osg::Node> _subgraph;
|
||||
osg::ref_ptr<osg::TextureCubeMap> _cubemap;
|
||||
osg::ref_ptr<osg::StateSet> _localState[6];
|
||||
osg::ref_ptr<osg::TexMat> _texmat;
|
||||
osg::Vec4 _clearColor;
|
||||
int _updateCubemapFace;
|
||||
protected:
|
||||
|
||||
osg::ref_ptr<TexMat> _texmat;
|
||||
};
|
||||
|
||||
|
||||
void PrerenderCullCallback::doPreRender(osg::Node& /*node*/, osgUtil::CullVisitor& cv, const int nFace)
|
||||
osg::Group* createShadowedScene(osg::Node* reflectedSubgraph, osg::RefNodePath reflectorNodePath, unsigned int unit, const osg::Vec4& clearColor)
|
||||
{
|
||||
const ImageData id[] =
|
||||
|
||||
osg::Group* group = new osg::Group;
|
||||
|
||||
unsigned int tex_width = 512;
|
||||
unsigned int tex_height = 512;
|
||||
|
||||
osg::TextureCubeMap* texture = new osg::TextureCubeMap;
|
||||
texture->setTextureSize(tex_width, tex_height);
|
||||
|
||||
texture->setInternalFormat(GL_RGB);
|
||||
texture->setFilter(osg::TextureCubeMap::MIN_FILTER,osg::TextureCubeMap::LINEAR);
|
||||
texture->setFilter(osg::TextureCubeMap::MAG_FILTER,osg::TextureCubeMap::LINEAR);
|
||||
|
||||
// set up the render to texture cameras.
|
||||
UpdateCameraAndTexGenCallback::CameraList cameraNodes;
|
||||
for(unsigned int i=0; i<6; ++i)
|
||||
{
|
||||
ImageData( osg::Vec3( 1, 0, 0), osg::Vec3( 0, -1, 0) ), // +X
|
||||
ImageData( osg::Vec3(-1, 0, 0), osg::Vec3( 0, -1, 0) ), // -X
|
||||
ImageData( osg::Vec3( 0, 1, 0), osg::Vec3( 0, 0, 1) ), // +Y
|
||||
ImageData( osg::Vec3( 0, -1, 0), osg::Vec3( 0, 0, -1) ), // -Y
|
||||
ImageData( osg::Vec3( 0, 0, 1), osg::Vec3( 0, -1, 0) ), // +Z
|
||||
ImageData( osg::Vec3( 0, 0, -1), osg::Vec3( 0, -1, 0) ) // -Z
|
||||
};
|
||||
|
||||
osg::Image* image = _cubemap->getImage((osg::TextureCubeMap::Face)nFace);
|
||||
osg::Vec3 dir = id[nFace]._dir;
|
||||
osg::Vec3 up = id[nFace]._up;
|
||||
// create the camera
|
||||
osg::CameraNode* camera = new osg::CameraNode;
|
||||
|
||||
const osg::BoundingSphere& bs = _subgraph->getBound();
|
||||
if (!bs.valid())
|
||||
{
|
||||
osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()<<std::endl;
|
||||
return;
|
||||
}
|
||||
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
camera->setClearColor(clearColor);
|
||||
|
||||
// create the render to texture stage.
|
||||
osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage;
|
||||
// set viewport
|
||||
camera->setViewport(0,0,tex_width,tex_height);
|
||||
|
||||
// set up lighting.
|
||||
// currently ignore lights in the scene graph itself..
|
||||
// will do later.
|
||||
osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage();
|
||||
// set the camera to render before the main camera.
|
||||
camera->setRenderOrder(osg::CameraNode::PRE_RENDER);
|
||||
|
||||
// set up the background color and clear mask.
|
||||
rtts->setClearColor(_clearColor);
|
||||
// tell the camera to use OpenGL frame buffer object where supported.
|
||||
camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT);
|
||||
|
||||
// ABJ: use default (color+depth)
|
||||
rtts->setClearMask(previous_stage->getClearMask());
|
||||
// attach the texture and use it as the color buffer.
|
||||
camera->attach(osg::CameraNode::COLOR_BUFFER, texture, 0, i);
|
||||
|
||||
// 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();
|
||||
|
||||
// set the current renderbin to be the newly created stage.
|
||||
cv.setCurrentRenderBin(rtts.get());
|
||||
|
||||
|
||||
float znear = 1.0f*bs.radius();
|
||||
float zfar = 3.0f*bs.radius();
|
||||
// add subgraph to render
|
||||
camera->addChild(reflectedSubgraph);
|
||||
|
||||
znear *= 0.9f;
|
||||
zfar *= 1.1f;
|
||||
|
||||
// set up projection.
|
||||
const double fovy = 90.0;
|
||||
const double aspectRatio = 1.0;
|
||||
osg::RefMatrix* projection = new osg::RefMatrix;
|
||||
projection->makePerspective(fovy, aspectRatio, znear, zfar);
|
||||
|
||||
cv.pushProjectionMatrix(projection);
|
||||
|
||||
osg::RefMatrix* matrix = new osg::RefMatrix;
|
||||
osg::Vec3 eye = bs.center(); eye.z() = 0.0f;
|
||||
osg::Vec3 center = eye + dir;
|
||||
matrix->makeLookAt(eye, center, up);
|
||||
|
||||
cv.pushModelViewMatrix(matrix);
|
||||
|
||||
cv.pushStateSet(_localState[nFace].get());
|
||||
|
||||
{
|
||||
// traverse the subgraph
|
||||
_subgraph->accept(cv);
|
||||
group->addChild(camera);
|
||||
|
||||
cameraNodes.push_back(camera);
|
||||
}
|
||||
|
||||
// create the texgen node to project the tex coords onto the subgraph
|
||||
osg::TexGenNode* texgenNode = new osg::TexGenNode;
|
||||
texgenNode->getTexGen()->setMode(osg::TexGen::REFLECTION_MAP);
|
||||
texgenNode->setTextureUnit(unit);
|
||||
group->addChild(texgenNode);
|
||||
|
||||
cv.popStateSet();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
cv.popModelViewMatrix();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
cv.popProjectionMatrix();
|
||||
|
||||
// restore the previous renderbin.
|
||||
cv.setCurrentRenderBin(previousRenderBin);
|
||||
|
||||
if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0)
|
||||
// set the reflected subgraph so that it uses the texture and tex gen settings.
|
||||
{
|
||||
// getting to this point means that all the subgraph has been
|
||||
// culled by small feature culling or is beyond LOD ranges.
|
||||
return;
|
||||
osg::Node* reflectorNode = reflectorNodePath.front().get();
|
||||
group->addChild(reflectorNode);
|
||||
|
||||
osg::StateSet* stateset = reflectorNode->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::TexMat* texmat = new osg::TexMat;
|
||||
stateset->setTextureAttributeAndModes(unit,texmat,osg::StateAttribute::ON);
|
||||
|
||||
reflectorNode->setCullCallback(new TexMatCullCallback(texmat));
|
||||
}
|
||||
|
||||
int height = 512;
|
||||
int width = 512;
|
||||
|
||||
const osg::Viewport& viewport = *cv.getViewport();
|
||||
|
||||
// offset the impostor viewport from the center of the main window
|
||||
// viewport as often the edges of the viewport might be obscured by
|
||||
// other windows, which can cause image/reading writing problems.
|
||||
int center_x = viewport.x()+viewport.width()/2;
|
||||
int center_y = viewport.y()+viewport.height()/2;
|
||||
|
||||
osg::Viewport* new_viewport = new osg::Viewport;
|
||||
new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height);
|
||||
rtts->setViewport(new_viewport);
|
||||
|
||||
_localState[nFace]->setAttribute(new_viewport);
|
||||
// add the reflector scene to draw just as normal
|
||||
group->addChild(reflectedSubgraph);
|
||||
|
||||
// set an update callback to keep moving the camera and tex gen in the right direction.
|
||||
group->setUpdateCallback(new UpdateCameraAndTexGenCallback(reflectorNodePath, cameraNodes));
|
||||
|
||||
// and the render to texture stage to the current stages
|
||||
// dependancy list.
|
||||
cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get());
|
||||
|
||||
// if one exist attach image to the RenderToTextureStage.
|
||||
// if (image.valid()) rtts->setImage(_image.get());
|
||||
if (image) rtts->setImage(image);
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
osg::Drawable* makeGeometry()
|
||||
{
|
||||
const float radius = 20;
|
||||
return new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius));
|
||||
}
|
||||
|
||||
osg::Node* createPreRenderSubGraph(osg::Node* subgraph)
|
||||
{
|
||||
if (!subgraph) return 0;
|
||||
|
||||
// create the quad to visualize.
|
||||
osg::Drawable* geom = makeGeometry();
|
||||
geom->setSupportsDisplayList(false);
|
||||
|
||||
// new we need to add the texture to the Drawable, we do so by creating a
|
||||
// StateSet to contain the Texture StateAttribute.
|
||||
osg::StateSet* stateset = new osg::StateSet;
|
||||
|
||||
osg::TextureCubeMap* cubemap = new osg::TextureCubeMap;
|
||||
|
||||
// set up the textures
|
||||
osg::Image* imagePosX = new osg::Image;
|
||||
osg::Image* imageNegX = new osg::Image;
|
||||
osg::Image* imagePosY = new osg::Image;
|
||||
osg::Image* imageNegY = new osg::Image;
|
||||
osg::Image* imagePosZ = new osg::Image;
|
||||
osg::Image* imageNegZ = new osg::Image;
|
||||
|
||||
imagePosX->setInternalTextureFormat(GL_RGB);
|
||||
imageNegX->setInternalTextureFormat(GL_RGB);
|
||||
imagePosY->setInternalTextureFormat(GL_RGB);
|
||||
imageNegY->setInternalTextureFormat(GL_RGB);
|
||||
imagePosZ->setInternalTextureFormat(GL_RGB);
|
||||
imageNegZ->setInternalTextureFormat(GL_RGB);
|
||||
|
||||
cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
|
||||
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);
|
||||
cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
|
||||
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);
|
||||
cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);
|
||||
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);
|
||||
|
||||
cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);
|
||||
cubemap->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
|
||||
cubemap->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
|
||||
stateset->setTextureAttributeAndModes(0, cubemap, osg::StateAttribute::ON);
|
||||
|
||||
osg::TexGen *texgen = new osg::TexGen;
|
||||
texgen->setMode(osg::TexGen::REFLECTION_MAP);
|
||||
stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON);
|
||||
|
||||
osg::TexMat* texmat = new osg::TexMat;
|
||||
stateset->setTextureAttribute(0, texmat);
|
||||
|
||||
stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
|
||||
|
||||
geom->setStateSet(stateset);
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(geom);
|
||||
|
||||
// Geodes can't have cull callback so create extra Group to attach cullcallback.
|
||||
osg::Group* parent = new osg::Group;
|
||||
|
||||
parent->setUpdateCallback(new PrerenderAppCallback(subgraph));
|
||||
|
||||
parent->setCullCallback(new PrerenderCullCallback(subgraph, cubemap, texmat));
|
||||
|
||||
parent->addChild(geode);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
struct DrawableCullCallback : public osg::Drawable::CullCallback
|
||||
{
|
||||
DrawableCullCallback(osg::TexMat* texmat) : _texmat(texmat)
|
||||
{}
|
||||
|
||||
virtual bool cull(osg::NodeVisitor* nv, osg::Drawable* /*drawable*/, osg::State* /*state*/) const
|
||||
{
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
|
||||
if (cv)
|
||||
{
|
||||
osg::Quat q;
|
||||
cv->getModelViewMatrix().get(q);
|
||||
const osg::Matrix C = osg::Matrix::rotate( q.inverse() );
|
||||
_texmat->setMatrix(C);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mutable osg::ref_ptr<osg::TexMat> _texmat;
|
||||
};
|
||||
|
||||
osg::Node* createReferenceSphere()
|
||||
{
|
||||
const float radius = 10;
|
||||
osg::Drawable* sphere = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius));
|
||||
|
||||
osg::StateSet* stateset = new osg::StateSet;
|
||||
sphere->setStateSet(stateset);
|
||||
|
||||
osg::TextureCubeMap* cubemap = new osg::TextureCubeMap;
|
||||
#define CUBEMAP_FILENAME(face) "Cubemap_axis/" #face ".png"
|
||||
|
||||
osg::Image* imagePosX = osgDB::readImageFile(CUBEMAP_FILENAME(posx));
|
||||
osg::Image* imageNegX = osgDB::readImageFile(CUBEMAP_FILENAME(negx));
|
||||
osg::Image* imagePosY = osgDB::readImageFile(CUBEMAP_FILENAME(posy));
|
||||
osg::Image* imageNegY = osgDB::readImageFile(CUBEMAP_FILENAME(negy));
|
||||
osg::Image* imagePosZ = osgDB::readImageFile(CUBEMAP_FILENAME(posz));
|
||||
osg::Image* imageNegZ = osgDB::readImageFile(CUBEMAP_FILENAME(negz));
|
||||
|
||||
if (imagePosX && imageNegX && imagePosY && imageNegY && imagePosZ && imageNegZ)
|
||||
{
|
||||
cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
|
||||
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);
|
||||
cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
|
||||
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);
|
||||
cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);
|
||||
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);
|
||||
|
||||
cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);
|
||||
cubemap->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
|
||||
cubemap->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
|
||||
stateset->setTextureAttributeAndModes(0, cubemap, osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
osg::TexGen *texgen = new osg::TexGen;
|
||||
texgen->setMode(osg::TexGen::REFLECTION_MAP);
|
||||
stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON);
|
||||
|
||||
osg::TexMat* texmat = new osg::TexMat;
|
||||
stateset->setTextureAttribute(0, texmat);
|
||||
|
||||
stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
|
||||
|
||||
|
||||
sphere->setCullCallback(new DrawableCullCallback(texmat));
|
||||
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
geode->addDrawable(sphere);
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// use an ArgumentParser object to manage the program arguments.
|
||||
osg::ArgumentParser arguments(&argc,argv);
|
||||
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 pre rendering of scene to a texture, and then apply this texture to geometry.");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
||||
|
||||
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);
|
||||
|
||||
@@ -422,7 +284,7 @@ int main( int argc, char **argv )
|
||||
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
|
||||
|
||||
// get details on keyboard and mouse bindings used by the viewer.
|
||||
viewer.getUsage(*arguments.getApplicationUsage());
|
||||
viewer.getUsage(*arguments. getApplicationUsage());
|
||||
|
||||
// if user request help write it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
@@ -437,72 +299,36 @@ int main( int argc, char **argv )
|
||||
// report any errors if they have occured when parsing the program aguments.
|
||||
if (arguments.errors())
|
||||
{
|
||||
arguments.writeErrorMessages(std::cout);
|
||||
return 1;
|
||||
arguments.writeErrorMessages(std::cout);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
if (arguments.argc()<=1)
|
||||
{
|
||||
arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
osg::Group* rootNode = new osg::Group();
|
||||
|
||||
#if 1
|
||||
osg::Node* sky = osgDB::readNodeFile("skydome.osg");
|
||||
ref_ptr<MatrixTransform> scene = new MatrixTransform;
|
||||
scene->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(125.0),1.0,0.0,0.0));
|
||||
|
||||
// Proof of concept to see if the skydome really rotates and that the cubemap gets updated.
|
||||
// create a transform to spin the model.
|
||||
|
||||
osg::MatrixTransform* loadedModelTransform = new osg::MatrixTransform;
|
||||
loadedModelTransform->addChild(sky);
|
||||
ref_ptr<Group> reflectedSubgraph = _create_scene();
|
||||
if (!reflectedSubgraph.valid()) return 1;
|
||||
|
||||
osg::NodeCallback* nc = new osgUtil::TransformCallback(loadedModelTransform->getBound().center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(5.0f));
|
||||
loadedModelTransform->setUpdateCallback(nc);
|
||||
ref_ptr<Group> reflectedScene = createShadowedScene(reflectedSubgraph.get(),createReflector(),0, viewer.getClearColor());
|
||||
|
||||
// osg::Group* rootNode = new osg::Group();
|
||||
// rootNode->addChild(loadedModelTransform);
|
||||
// rootNode->addChild(createPreRenderSubGraph(loadedModelTransform));
|
||||
scene->addChild(reflectedScene.get());
|
||||
|
||||
|
||||
if (loadedModelTransform)
|
||||
{
|
||||
rootNode->addChild(createPreRenderSubGraph(loadedModelTransform));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
osg::PositionAttitudeTransform* pat = new osg::PositionAttitudeTransform;
|
||||
pat->setPosition(osg::Vec3(0,0,50));
|
||||
pat->addChild(createReferenceSphere());
|
||||
rootNode->addChild(pat);
|
||||
#endif
|
||||
|
||||
// load the nodes from the commandline arguments.
|
||||
osg::Node* loadedModel = osgDB::readNodeFiles(arguments);
|
||||
if (loadedModel)
|
||||
rootNode->addChild(loadedModel);
|
||||
|
||||
// add model to the viewer.
|
||||
viewer.setSceneData( rootNode );
|
||||
viewer.setSceneData(scene.get());
|
||||
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
while( !viewer.done() )
|
||||
while (!viewer.done())
|
||||
{
|
||||
// wait for all cull and draw threads to complete.
|
||||
viewer.sync();
|
||||
// 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();
|
||||
// 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();
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
viewer.frame();
|
||||
}
|
||||
|
||||
// wait for all cull and draw threads to complete before exit.
|
||||
@@ -510,4 +336,3 @@ int main( int argc, char **argv )
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,6 @@ osg::Group* createShadowedScene(osg::Node* shadower,osg::Node* shadowed,const os
|
||||
|
||||
// set viewport
|
||||
camera->setViewport(0,0,tex_width,tex_height);
|
||||
camera->getOrCreateStateSet()->setAttribute(camera->getViewport());
|
||||
|
||||
// set the camera to render before the main camera.
|
||||
camera->setRenderOrder(osg::CameraNode::PRE_RENDER);
|
||||
@@ -190,7 +189,6 @@ osg::Group* createShadowedScene(osg::Node* shadower,osg::Node* shadowed,const os
|
||||
camera->setViewMatrix(osg::Matrix::identity());
|
||||
|
||||
camera->setViewport(50,50,100,100);
|
||||
camera->getOrCreateStateSet()->setAttribute(camera->getViewport());
|
||||
|
||||
// only clear the depth buffer
|
||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <osg/Transform>
|
||||
#include <osg/Viewport>
|
||||
#include <osg/ColorMask>
|
||||
#include <osg/CullSettings>
|
||||
#include <osg/Texture>
|
||||
#include <osg/Image>
|
||||
@@ -37,32 +38,45 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
META_Node(osg, CameraNode);
|
||||
|
||||
|
||||
/** Sets the clear color. */
|
||||
inline void setClearColor(const Vec4& color) { _clearColor = color; }
|
||||
|
||||
/** Set the viewport of the scene view to use specified osg::Viewport. */
|
||||
void setViewport(osg::Viewport* viewport)
|
||||
{
|
||||
_viewport = viewport;
|
||||
}
|
||||
/** Returns the clear color. */
|
||||
inline const Vec4& getClearColor() const { return _clearColor; }
|
||||
|
||||
/** Set the clear mask used in glClear(..).
|
||||
* Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
|
||||
inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
|
||||
|
||||
/** Set the viewport of the scene view to specified dimensions. */
|
||||
void setViewport(int x,int y,int width,int height)
|
||||
{
|
||||
if (!_viewport) _viewport = new osg::Viewport;
|
||||
_viewport->setViewport(x,y,width,height);
|
||||
}
|
||||
/** Get the clear mask.*/
|
||||
inline GLbitfield getClearMask() const { return _clearMask; }
|
||||
|
||||
|
||||
/** Set the color mask of the camera to use specified osg::ColorMask. */
|
||||
void setColorMask(osg::ColorMask* colorMask);
|
||||
|
||||
/** Set the color mask of the camera to specified values. */
|
||||
void setColorMask(bool red, bool green, bool blue, bool alpha);
|
||||
|
||||
/** Get the const ColorMask. */
|
||||
const ColorMask* getColorMask() const { return _colorMask.get(); }
|
||||
|
||||
/** Get the ColorMask. */
|
||||
ColorMask* getColorMask() { return _colorMask.get(); }
|
||||
|
||||
|
||||
/** Set the viewport of the camera to use specified osg::Viewport. */
|
||||
void setViewport(osg::Viewport* viewport);
|
||||
|
||||
/** Set the viewport of the camera to specified dimensions. */
|
||||
void setViewport(int x,int y,int width,int height);
|
||||
|
||||
/** Get the const viewport. */
|
||||
const Viewport* getViewport() const { return _viewport.get(); }
|
||||
|
||||
/** Get the viewport. */
|
||||
Viewport* getViewport() { return _viewport.get(); }
|
||||
|
||||
/** Get the viewport of the scene view. */
|
||||
void getViewport(int& x,int& y,int& width,int& height) const
|
||||
{
|
||||
if (_viewport.valid()) _viewport->getViewport(x,y,width,height);
|
||||
}
|
||||
|
||||
|
||||
enum TransformOrder
|
||||
{
|
||||
@@ -149,22 +163,6 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
/** Get the inverse view matrix.*/
|
||||
Matrixd getInverseViewMatrix() const;
|
||||
|
||||
|
||||
|
||||
/** Sets the clear color. */
|
||||
inline void setClearColor(const Vec4& color) { _clearColor = color; }
|
||||
|
||||
/** Returns the clear color. */
|
||||
inline const Vec4& getClearColor() const { return _clearColor; }
|
||||
|
||||
/** Set the clear mask used in glClear(..).
|
||||
* Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
|
||||
inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
|
||||
|
||||
/** Get the clear mask.*/
|
||||
inline GLbitfield getClearMask() const { return _clearMask; }
|
||||
|
||||
|
||||
|
||||
enum RenderOrder
|
||||
{
|
||||
@@ -276,6 +274,7 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings
|
||||
|
||||
Vec4 _clearColor;
|
||||
GLbitfield _clearMask;
|
||||
ref_ptr<ColorMask> _colorMask;
|
||||
ref_ptr<Viewport> _viewport;
|
||||
|
||||
TransformOrder _transformOrder;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <osg/GL>
|
||||
#include <osg/Texture>
|
||||
#include <osg/buffered_value>
|
||||
#include <osg/CameraNode>
|
||||
|
||||
#ifndef GL_EXT_framebuffer_object
|
||||
#define GL_EXT_framebuffer_object 1
|
||||
@@ -256,6 +257,7 @@ namespace osg
|
||||
explicit FrameBufferAttachment(Texture3D* target, int zoffset, int level = 0);
|
||||
explicit FrameBufferAttachment(TextureCubeMap* target, int face, int level = 0);
|
||||
explicit FrameBufferAttachment(TextureRectangle* target);
|
||||
explicit FrameBufferAttachment(CameraNode::Attachment& attachment);
|
||||
|
||||
~FrameBufferAttachment();
|
||||
|
||||
|
||||
@@ -25,7 +25,12 @@ class OSG_EXPORT FrontFace : public StateAttribute
|
||||
{
|
||||
public :
|
||||
|
||||
FrontFace();
|
||||
enum Mode {
|
||||
CLOCKWISE = GL_CW,
|
||||
COUNTER_CLOCKWISE = GL_CCW
|
||||
};
|
||||
|
||||
FrontFace(Mode face=COUNTER_CLOCKWISE);
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||
FrontFace(const FrontFace& ff,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
@@ -46,11 +51,6 @@ class OSG_EXPORT FrontFace : public StateAttribute
|
||||
|
||||
return 0; // passed all the above comparison macro's, must be equal.
|
||||
}
|
||||
|
||||
enum Mode {
|
||||
CLOCKWISE = GL_CW,
|
||||
COUNTER_CLOCKWISE = GL_CCW
|
||||
};
|
||||
|
||||
inline void setMode(Mode mode) { _mode = mode; }
|
||||
inline Mode getMode() const { return _mode; }
|
||||
|
||||
@@ -105,6 +105,12 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
|
||||
/** Get the clear color.*/
|
||||
int getClearStencil() const { return _clearStencil; }
|
||||
|
||||
void setInheritedRenderStageLightingMatrix(const osg::Matrix& matrix) { _inheritedRenderStageLightingMatrix = matrix; }
|
||||
const osg::Matrix& getInheritedRenderStageLightingMatrix() const { return _inheritedRenderStageLightingMatrix; }
|
||||
|
||||
void setInheritedRenderStageLighting(RenderStageLighting* rsl) { _inheritedRenderStageLighting = rsl; }
|
||||
RenderStageLighting* getInheritedRenderStageLighting() { return _inheritedRenderStageLighting.get(); }
|
||||
|
||||
void setRenderStageLighting(RenderStageLighting* rsl) { _renderStageLighting = rsl; }
|
||||
|
||||
RenderStageLighting* getRenderStageLighting() const
|
||||
@@ -159,6 +165,8 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
|
||||
double _clearDepth;
|
||||
int _clearStencil;
|
||||
|
||||
mutable osg::Matrix _inheritedRenderStageLightingMatrix;
|
||||
mutable osg::ref_ptr<RenderStageLighting> _inheritedRenderStageLighting;
|
||||
mutable osg::ref_ptr<RenderStageLighting> _renderStageLighting;
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class OSGUTIL_EXPORT RenderStageLighting : public osg::Object
|
||||
_texAttrListMap[textureUnit].push_back(AttrMatrixPair(attr,matrix));
|
||||
}
|
||||
|
||||
virtual void draw(osg::State& state,RenderLeaf*& previous);
|
||||
virtual void draw(osg::State& state,RenderLeaf*& previous, const osg::Matrix* postMultMatrix = 0);
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ CameraNode::CameraNode():
|
||||
_renderOrder(POST_RENDER),
|
||||
_renderTargetImplementation(FRAME_BUFFER)
|
||||
{
|
||||
setStateSet(new StateSet);
|
||||
}
|
||||
|
||||
CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop):
|
||||
@@ -30,6 +31,7 @@ CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop):
|
||||
CullSettings(camera),
|
||||
_clearColor(camera._clearColor),
|
||||
_clearMask(camera._clearMask),
|
||||
_colorMask(camera._colorMask),
|
||||
_viewport(camera._viewport),
|
||||
_transformOrder(camera._transformOrder),
|
||||
_projectionMatrix(camera._projectionMatrix),
|
||||
@@ -37,8 +39,7 @@ CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop):
|
||||
_renderOrder(camera._renderOrder),
|
||||
_renderTargetImplementation(camera._renderTargetImplementation),
|
||||
_bufferAttachmentMap(camera._bufferAttachmentMap)
|
||||
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +47,54 @@ CameraNode::~CameraNode()
|
||||
{
|
||||
}
|
||||
|
||||
void CameraNode::setColorMask(osg::ColorMask* colorMask)
|
||||
{
|
||||
if (_colorMask == colorMask) return;
|
||||
|
||||
osg::StateSet* stateset = getOrCreateStateSet();
|
||||
if (_colorMask.valid() && stateset)
|
||||
{
|
||||
stateset->removeAttribute(_colorMask.get());
|
||||
}
|
||||
|
||||
_colorMask = colorMask;
|
||||
|
||||
if (_colorMask.valid() && stateset)
|
||||
{
|
||||
stateset->setAttribute(_colorMask.get());
|
||||
}
|
||||
}
|
||||
|
||||
void CameraNode::setColorMask(bool red, bool green, bool blue, bool alpha)
|
||||
{
|
||||
if (!_colorMask) setColorMask(new osg::ColorMask);
|
||||
if (_colorMask.valid()) _colorMask->setMask(red,green,blue,alpha);
|
||||
}
|
||||
|
||||
void CameraNode::setViewport(osg::Viewport* viewport)
|
||||
{
|
||||
if (_viewport == viewport) return;
|
||||
|
||||
osg::StateSet* stateset = getOrCreateStateSet();
|
||||
if (_viewport.valid() && stateset)
|
||||
{
|
||||
stateset->removeAttribute(_viewport.get());
|
||||
}
|
||||
|
||||
_viewport = viewport;
|
||||
|
||||
if (_viewport.valid() && stateset)
|
||||
{
|
||||
stateset->setAttribute(_viewport.get());
|
||||
}
|
||||
}
|
||||
|
||||
void CameraNode::setViewport(int x,int y,int width,int height)
|
||||
{
|
||||
if (!_viewport) setViewport(new osg::Viewport);
|
||||
if (_viewport.valid()) _viewport->setViewport(x,y,width,height);
|
||||
}
|
||||
|
||||
Matrixd CameraNode::getInverseViewMatrix() const
|
||||
{
|
||||
Matrixd inverse;
|
||||
|
||||
@@ -211,6 +211,55 @@ FrameBufferAttachment::FrameBufferAttachment(TextureRectangle* target)
|
||||
_ximpl->textureTarget = target;
|
||||
}
|
||||
|
||||
FrameBufferAttachment::FrameBufferAttachment(CameraNode::Attachment& attachment)
|
||||
{
|
||||
osg::Texture* texture = attachment._texture.get();
|
||||
osg::Texture1D* texture1D = dynamic_cast<osg::Texture1D*>(texture);
|
||||
if (texture1D)
|
||||
{
|
||||
_ximpl = new Pimpl(Pimpl::TEXTURE1D, attachment._level);
|
||||
_ximpl->textureTarget = texture1D;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(texture);
|
||||
if (texture2D)
|
||||
{
|
||||
_ximpl = new Pimpl(Pimpl::TEXTURE2D, attachment._level);
|
||||
_ximpl->textureTarget = texture2D;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::Texture3D* texture3D = dynamic_cast<osg::Texture3D*>(texture);
|
||||
if (texture3D)
|
||||
{
|
||||
_ximpl = new Pimpl(Pimpl::TEXTURE3D, attachment._level);
|
||||
_ximpl->textureTarget = texture3D;
|
||||
_ximpl->zoffset = attachment._face;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::TextureCubeMap* textureCubeMap = dynamic_cast<osg::TextureCubeMap*>(texture);
|
||||
if (textureCubeMap)
|
||||
{
|
||||
_ximpl = new Pimpl(Pimpl::TEXTURECUBE, attachment._level);
|
||||
_ximpl->textureTarget = textureCubeMap;
|
||||
_ximpl->cubeMapFace = attachment._face;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::TextureRectangle* textureRectangle = dynamic_cast<osg::TextureRectangle*>(texture);
|
||||
if (textureRectangle)
|
||||
{
|
||||
_ximpl = new Pimpl(Pimpl::TEXTURERECT);
|
||||
_ximpl->textureTarget = textureRectangle;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::notify(osg::WARN)<<"Error: FrameBufferAttachment::FrameBufferAttachment(CameraNode::Attachment&) passed an unrecognised Texture type."<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
FrameBufferAttachment::~FrameBufferAttachment()
|
||||
{
|
||||
delete _ximpl;
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
FrontFace::FrontFace()
|
||||
FrontFace::FrontFace(Mode face)
|
||||
{
|
||||
_mode = COUNTER_CLOCKWISE;
|
||||
_mode = face;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -90,9 +90,6 @@ void TexGen::apply(State&) const
|
||||
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
|
||||
|
||||
// note, R & Q will be disabled so R&Q settings won't
|
||||
// have an effect, see above comment in enable(). RO.
|
||||
|
||||
}
|
||||
else if (_mode == EYE_LINEAR)
|
||||
{
|
||||
@@ -106,9 +103,6 @@ void TexGen::apply(State&) const
|
||||
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
|
||||
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
|
||||
|
||||
// note, R & Q will be disabled so R&Q settings won't
|
||||
// have an effect, see above comment in enable(). RO.
|
||||
|
||||
}
|
||||
else if (_mode == NORMAL_MAP)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <osg/Image>
|
||||
#include <osg/State>
|
||||
#include <osg/TextureCubeMap>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osg/GLU>
|
||||
|
||||
@@ -302,6 +303,26 @@ void TextureCubeMap::apply(State& state) const
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_internalFormat!=0) )
|
||||
{
|
||||
_textureObjectBuffer[contextID] = textureObject = generateTextureObject(
|
||||
contextID,GL_TEXTURE_CUBE_MAP,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0);
|
||||
|
||||
textureObject->bind();
|
||||
|
||||
applyTexParameters(GL_TEXTURE_CUBE_MAP,state);
|
||||
|
||||
for (int n=0; n<6; n++)
|
||||
{
|
||||
// no image present, but dimensions at set so less create the texture
|
||||
glTexImage2D( faceTarget[n], 0, _internalFormat,
|
||||
_textureWidth, _textureHeight, _borderWidth,
|
||||
_internalFormat,
|
||||
GL_UNSIGNED_BYTE,
|
||||
0);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1036,6 +1036,7 @@ void CullVisitor::apply(osg::CameraNode& camera)
|
||||
StateSet* node_state = camera.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
osg::RefMatrix& originalModelView = getModelViewMatrix();
|
||||
|
||||
if (camera.getReferenceFrame()==osg::Transform::ABSOLUTE_RF)
|
||||
{
|
||||
@@ -1078,17 +1079,28 @@ void CullVisitor::apply(osg::CameraNode& camera)
|
||||
// will do later.
|
||||
osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage();
|
||||
|
||||
// set the compute near far mode.
|
||||
ComputeNearFarMode saved_compute_near_far_mode = getComputeNearFarMode();
|
||||
setComputeNearFarMode( camera.getComputeNearFarMode());
|
||||
|
||||
// set up the background color and clear mask.
|
||||
rtts->setClearColor(camera.getClearColor());
|
||||
rtts->setClearMask(camera.getClearMask());
|
||||
|
||||
osg::Viewport* viewport = camera.getViewport()!=0 ? camera.getViewport() : previous_stage->getViewport();
|
||||
|
||||
// set the color mask.
|
||||
osg::ColorMask* colorMask = camera.getColorMask()!=0 ? camera.getColorMask() : previous_stage->getColorMask();
|
||||
rtts->setColorMask(colorMask);
|
||||
|
||||
// set up the viewport.
|
||||
osg::Viewport* viewport = camera.getViewport()!=0 ? camera.getViewport() : previous_stage->getViewport();
|
||||
rtts->setViewport( viewport );
|
||||
|
||||
// set up to charge the same RenderStageLighting is the parent previous stage.
|
||||
//rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
|
||||
osg::Matrix inhertiedMVtolocalMV;
|
||||
inhertiedMVtolocalMV.invert(originalModelView);
|
||||
inhertiedMVtolocalMV.postMult(getModelViewMatrix());
|
||||
rtts->setInheritedRenderStageLightingMatrix(inhertiedMVtolocalMV);
|
||||
rtts->setInheritedRenderStageLighting(previous_stage->getRenderStageLighting());
|
||||
|
||||
// record the render bin, to be restored after creation
|
||||
// of the render to text
|
||||
@@ -1106,6 +1118,10 @@ void CullVisitor::apply(osg::CameraNode& camera)
|
||||
|
||||
// restore the previous renderbin.
|
||||
setCurrentRenderBin(previousRenderBin);
|
||||
|
||||
// restore the previous compute near far mode
|
||||
setComputeNearFarMode(saved_compute_near_far_mode);
|
||||
|
||||
|
||||
if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0)
|
||||
{
|
||||
@@ -1156,9 +1172,49 @@ void CullVisitor::apply(osg::CameraNode& camera)
|
||||
fbo = new osg::FrameBufferObject;
|
||||
rtts->setFrameBufferObject(fbo.get());
|
||||
|
||||
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(tex));
|
||||
fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_DEPTH_COMPONENT24)));
|
||||
bool colorAttached = false;
|
||||
bool depthAttached = false;
|
||||
bool stencilAttached = false;
|
||||
for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin();
|
||||
itr != bufferAttachements.end();
|
||||
++itr)
|
||||
{
|
||||
|
||||
osg::CameraNode::BufferComponent buffer = itr->first;
|
||||
osg::CameraNode::Attachment& attachment = itr->second;
|
||||
switch(buffer)
|
||||
{
|
||||
case(osg::CameraNode::DEPTH_BUFFER):
|
||||
{
|
||||
fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment));
|
||||
depthAttached = true;
|
||||
break;
|
||||
}
|
||||
case(osg::CameraNode::STENCIL_BUFFER):
|
||||
{
|
||||
fbo->setAttachment(GL_STENCIL_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment));
|
||||
stencilAttached = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(attachment));
|
||||
colorAttached = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!depthAttached)
|
||||
{
|
||||
fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_DEPTH_COMPONENT24)));
|
||||
}
|
||||
|
||||
if (!colorAttached)
|
||||
{
|
||||
fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_RGB)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,8 +177,17 @@ void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous)
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
// apply the lights.
|
||||
if (_renderStageLighting.valid()) _renderStageLighting->draw(state,previous);
|
||||
// apply the positional state.
|
||||
if (_inheritedRenderStageLighting.valid())
|
||||
{
|
||||
_inheritedRenderStageLighting->draw(state, previous, &_inheritedRenderStageLightingMatrix);
|
||||
}
|
||||
|
||||
// apply the positional state.
|
||||
if (_renderStageLighting.valid())
|
||||
{
|
||||
_renderStageLighting->draw(state, previous, 0);
|
||||
}
|
||||
|
||||
// draw the children and local.
|
||||
RenderBin::drawImplementation(state,previous);
|
||||
|
||||
@@ -32,7 +32,7 @@ void RenderStageLighting::reset()
|
||||
_texAttrListMap.clear();
|
||||
}
|
||||
|
||||
void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous)
|
||||
void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous, const osg::Matrix* postMultMatrix)
|
||||
{
|
||||
|
||||
if (previous)
|
||||
@@ -47,7 +47,18 @@ void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous)
|
||||
litr!=_attrList.end();
|
||||
++litr)
|
||||
{
|
||||
state.applyModelViewMatrix((*litr).second.get());
|
||||
if (postMultMatrix)
|
||||
{
|
||||
if ((*litr).second.valid())
|
||||
state.applyModelViewMatrix(new osg::RefMatrix( (*((*litr).second)) * (*postMultMatrix)));
|
||||
else
|
||||
state.applyModelViewMatrix(new osg::RefMatrix( *postMultMatrix));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
state.applyModelViewMatrix((*litr).second.get());
|
||||
}
|
||||
|
||||
// apply the light source.
|
||||
litr->first->apply(state);
|
||||
@@ -71,7 +82,17 @@ void RenderStageLighting::draw(osg::State& state,RenderLeaf*& previous)
|
||||
litr!=attrList.end();
|
||||
++litr)
|
||||
{
|
||||
state.applyModelViewMatrix((*litr).second.get());
|
||||
if (postMultMatrix)
|
||||
{
|
||||
if ((*litr).second.valid())
|
||||
state.applyModelViewMatrix(new osg::RefMatrix( (*((*litr).second)) * (*postMultMatrix)));
|
||||
else
|
||||
state.applyModelViewMatrix(new osg::RefMatrix( *postMultMatrix));
|
||||
}
|
||||
else
|
||||
{
|
||||
state.applyModelViewMatrix((*litr).second.get());
|
||||
}
|
||||
|
||||
// apply the light source.
|
||||
litr->first->apply(state);
|
||||
|
||||
@@ -60,8 +60,11 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
}
|
||||
|
||||
if (_image.valid())
|
||||
{
|
||||
_image->readPixels(_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height(),_imageReadPixelFormat,_imageReadPixelDataType);
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (fbo_supported)
|
||||
{
|
||||
fbo_ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
Reference in New Issue
Block a user