Skip to content

Instantly share code, notes, and snippets.

@jasonbeverage
Created December 15, 2015 20:50
Show Gist options
  • Save jasonbeverage/de0e5b2038686214decb to your computer and use it in GitHub Desktop.
Save jasonbeverage/de0e5b2038686214decb to your computer and use it in GitHub Desktop.
Simple openscenegraph capture camera example
/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
* Copyright 2015 Pelican Mapping
* http://osgearth.org
*
* osgEarth is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <osg/Notify>
#include <osg/Depth>
#include <osg/LineWidth>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TrackballManipulator>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgEarth/OverlayDecorator>
#include <osgEarth/MapNode>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ExampleResources>
#include <osgEarthUtil/Controls>
#include <osgEarthSymbology/Color>
#define LC "[viewer] "
using namespace osgEarth::Util;
using namespace osgEarth::Util::Controls;
using namespace osgEarth::Symbology;
osg::Node* makeQuad(osg::Texture* texture)
{
osg::Geode* geode = new osg::Geode;
osg::Geometry* geometry = new osg::Geometry;
osg::Vec3Array* verts = new osg::Vec3Array();
verts->push_back(osg::Vec3(0.0, 0.0, 0.0));
verts->push_back(osg::Vec3(texture->getTextureWidth(), 0.0, 0.0));
verts->push_back(osg::Vec3(texture->getTextureWidth(), texture->getTextureHeight(), 0.0));
verts->push_back(osg::Vec3(0.0, texture->getTextureHeight(), 0.0));
geometry->setVertexArray( verts );
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back( osg::Vec4(1.0, 1.0, 1.0, 1.0));
geometry->setColorArray( colors );
geometry->setColorBinding( osg::Geometry::BIND_OVERALL );
osg::Vec2Array* texCoords = new osg::Vec2Array();
geometry->setTexCoordArray(0, texCoords );
texCoords->push_back( osg::Vec2f(0.0, 0.0));
texCoords->push_back( osg::Vec2f(1.0, 0.0));
texCoords->push_back( osg::Vec2f(1.0, 1.0));
texCoords->push_back( osg::Vec2f(0.0, 1.0));
geometry->addPrimitiveSet( new osg::DrawArrays(GL_QUADS, 0, 4));
geode->addDrawable( geometry );
geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture );
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
return geode;
}
osg::Camera* createCaptureCamera(osg::Node* node, osg::Texture2D* texture)
{
osg::Camera* camera = new osg::Camera;
// set up the background color and clear mask.
camera->setClearColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set up projection.
//camera->setProjectionMatrix(osg::Matrix::ortho2D(0,slide->getWidth(),0,slide->getHeight()));
// set view
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
// set viewport
camera->setViewport(0,0,texture->getTextureWidth(),texture->getTextureHeight());
// set the camera to render before the main camera.
camera->setRenderOrder(osg::Camera::PRE_RENDER);
// tell the camera to use OpenGL frame buffer object where supported.
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
// attach the texture and use it as the color buffer.
/*
camera->attach(osg::Camera::COLOR_BUFFER, texture,
0, 0, false, 0, 0 );
*/
camera->attach( osg::Camera::COLOR_BUFFER, texture, 0, 0, false );
camera->addChild( node );
return camera;
}
int
main(int argc, char** argv)
{
osg::ArgumentParser arguments(&argc,argv);
osgViewer::CompositeViewer viewer(arguments);
viewer.setThreadingModel( osgViewer::CompositeViewer::SingleThreaded );
// query the screen size.
osg::GraphicsContext::ScreenIdentifier si;
si.readDISPLAY();
if ( si.displayNum < 0 ) si.displayNum = 0;
osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
unsigned int b = 50;
unsigned int width = 1920/4;
unsigned int height = 1080/4;
osgViewer::View* mainView = new osgViewer::View();
mainView->getCamera()->setNearFarRatio(0.00002);
EarthManipulator* em = new EarthManipulator();
em->getSettings()->setMinMaxPitch(-90, 0);
mainView->setCameraManipulator( em );
mainView->setUpViewInWindow( b, b, width, height);
viewer.addView( mainView );
osgViewer::View* overlayView = new osgViewer::View();
overlayView->getCamera()->setNearFarRatio(0.00002);
overlayView->setCameraManipulator( new osgGA::TrackballManipulator() );
overlayView->setUpViewInWindow( b + 1920/4, b, width, height);
overlayView->addEventHandler(new osgGA::StateSetManipulator(overlayView->getCamera()->getOrCreateStateSet()));
viewer.addView( overlayView );
std::string pathfile;
double animationSpeed = 1.0;
if (arguments.read("-p", pathfile))
{
mainView->setCameraManipulator( new osgGA::AnimationPathManipulator(pathfile) );
}
osg::Node* node = MapNodeHelper().load( arguments, mainView );
if ( node )
{
mainView->setSceneData( node );
osg::Texture2D* texture = new osg::Texture2D();
//texture->setImage(osgDB::readImageFile("C:/Temp/flat.png"));
texture->setResizeNonPowerOfTwoHint( false );
texture->setTextureSize( 1920, 1080 );
texture->setInternalFormat(GL_RGBA);
texture->setSourceFormat( GL_RGBA );
texture->setSourceType( GL_UNSIGNED_BYTE );
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture::LINEAR);
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture::LINEAR);
/*
texture->setTextureSize( _slide->getWidth(), _slide->getHeight());
texture->setInternalFormat(GL_RGBA);
texture->setSourceFormat( GL_RGBA );
texture->setSourceType( GL_UNSIGNED_BYTE );
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture::NEAREST);
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture::NEAREST);
*/
osg::Camera* captureCamera = createCaptureCamera( node, texture );
osg::Group* overlayGroup = new osg::Group;
overlayGroup->addChild(captureCamera);
overlayGroup->addChild( makeQuad( texture ) );
overlayGroup->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
overlayView->setSceneData(overlayGroup);
while (!viewer.done())
{
captureCamera->setProjectionMatrix( mainView->getCamera()->getProjectionMatrix() );
captureCamera->setViewMatrix(mainView->getCamera()->getViewMatrix());
viewer.frame();
}
return 0;
}
else return -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment