Hello,
I submitted this to osg-submissions, and thought osg-users may find this
useful.
PROBLEM
Need to add border around overlay window such as a rear view window.
SOLUTION
Created border decorator.
DETAILS
OSG version 1.2.
This was a simple modification to osgmultiplecameras example, but could
easily be modified for osg 2.0. (I am just not there yet).
The example attaches another camera node that pre renders under the
overlayed window.
I believe this is something that people are looking for.
LIMITATIONS
This example does not show how you could create non-rectangular overlays
such as circular mirrors. To do this you would need to create a
render-to-texture camera that renders to a circular drawable, and then
blends. An example of how to do this would combine osgprerender and osghud.
CONCLUSION
I'd appreciate if anybody could integrate this with osg1.2, and especially
if someone could modify it to be useful with the current osg version.
If someone can't get to it, I'm sure I will once I upgrade to 2.0.
Thanks.
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osgProducer/Viewer>
#include <osg/Material>
#include <osg/Geode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/Projection>
#include <osg/PolygonOffset>
#include <osg/MatrixTransform>
#include <osg/CameraNode>
#include <osg/FrontFace>
#include <osgText/Text>
class borderDecorator
{
public:
borderDecorator(osg::CameraNode* camera, unsigned int borderSize);
~borderDecorator(void){}
const osg::Vec4& GetColor(void) const{return
_borderCamera->getClearColor();}
void SetColor(const osg::Vec4& value);
protected:
unsigned int _borderSize;
osg::CameraNode* _camera;
osg::CameraNode* _borderCamera;
private:
void UpdateBorder(void);
};
borderDecorator::borderDecorator(osg::CameraNode* camera, unsigned int
borderSize)
{
_camera = camera;
_borderSize=borderSize;
_borderCamera = new osg::CameraNode();
// set the view matrix
_borderCamera->setCullingActive(false);
_borderCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
// set clear the color and depth buffer
SetColor(osg::Vec4(0.0,0.0,0.0,1.0));
_borderCamera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// draw subgraph after main camera view.
_borderCamera->setRenderOrder(osg::CameraNode::PRE_RENDER);
UpdateBorder();
_camera->addChild( _borderCamera );
}
void borderDecorator::SetColor(const osg::Vec4& value)
{
_borderCamera->setClearColor(value);
}
void borderDecorator::UpdateBorder(void)
{
int borderSizeHalf=_borderSize/2;
int x=_camera->getViewport()->x()-borderSizeHalf;
int y=_camera->getViewport()->y()-borderSizeHalf;
int width=_camera->getViewport()->width()+_borderSize;
int height=_camera->getViewport()->height()+_borderSize;
// set the viewport
_borderCamera->setViewport(x,y,width,height);
}
osg::Node* createRearView(osg::Node* subgraph, const osg::Vec4& clearColour)
{
osg::CameraNode* camera = new osg::CameraNode;
// set the viewport
camera->setViewport(10,10,400,200);
// set the view matrix
camera->setCullingActive(false);
camera->setReferenceFrame(osg::Transform::RELATIVE_RF);
camera->setTransformOrder(osg::CameraNode::POST_MULTIPLY);
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));
// 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.
camera->getOrCreateStateSet()->setAttribute(new
osg::FrontFace(osg::FrontFace::CLOCKWISE));
unsigned int borderSize=20;
borderDecorator decorator(camera, borderSize);
decorator.SetColor(osg::Vec4(1.0,0.0,0.0,1.0));
return camera;
}
int main( int argc, char **argv )
{
// use an ArgumentParser object to manage the program arguments.
osg::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 how to do Head Up Displays.");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+"
[options] [filename] ...");
arguments.getApplicationUsage()->addCommandLineOption("-h or
--help","Display this information");
// construct the viewer.
osgProducer::Viewer viewer(arguments);
// set up the value with sensible default event handlers.
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
// get details on keyboard and mouse bindings used by the viewer.
viewer.getUsage(*arguments.getApplicationUsage());
// if user request help write it out to cout.
if (arguments.read("-h") || arguments.read("--help"))
{
arguments.getApplicationUsage()->write(std::cout);
return 1;
}
// any option left unread are converted into errors to write out later.
arguments.reportRemainingOptionsAsUnrecognized();
// report any errors if they have occured when parsing the program aguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}
// read the scene from the list of file specified commandline args.
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
osg::ref_ptr<osg::Group> group = new osg::Group;
// add the HUD subgraph.
if (scene.valid()) group->addChild(scene.get());
osg::Vec4 colour = viewer.getClearColor();
colour.r() *= 0.5f;
colour.g() *= 0.5f;
colour.b() *= 0.5f;
// note tone down the normal back ground colour to make it obvious that
there is a seperate camera inserted.
group->addChild(createRearView(scene.get(), colour));
// set the scene to render
viewer.setSceneData(group.get());
// create the windows and run the threads.
viewer.realize();
while( !viewer.done() )
{
// wait for all cull and draw threads to complete.
viewer.sync();
// update the scene by traversing it with the the update visitor which
will
// call all node update callbacks and animations.
viewer.update();
// fire off the cull and draw traversals of the scene.
viewer.frame();
}
// wait for all cull and draw threads to complete.
viewer.sync();
// run a clean up frame to delete all OpenGL objects.
viewer.cleanup_frame();
// wait for all the clean up frame to complete.
viewer.sync();
return 0;
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org