FinalDrawCallback( osg::Camera* camera ) { const osg::Viewport* viewport = camera->getViewport(); osg::Viewport::value_type width = viewport->width(); osg::Viewport::value_type height = viewport->height(); cout << "viewport w/h: " << width << " " << height << endl; depthbufferimg = new osg::Image; depthbufferimg->allocateImage(width, height, 1, GL_DEPTH_COMPONENT, GL_FLOAT); colorbufferimg = new osg::Image; colorbufferimg->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE); camera->attach(osg::Camera::DEPTH_BUFFER, depthbufferimg.get(), 0, 0); camera->attach(osg::Camera::COLOR_BUFFER, colorbufferimg.get(), 0, 0); done = false; }
osg::Matrix vpb::MyDataSet::getImageSection(vips::VImage &in,const osg::Vec2 minT, const osg::Vec2 maxT,int origX,int origY,osg::Vec4 &texsize,const osg::Matrix &toTex,osg::ref_ptr<osg::Image> &image,osg::Vec4 &ratio,int level){ double downsampleFactor=pow(2,level); double downsampleRatio=1.0/downsampleFactor; // std::cout<< minT << " " << maxT<<std::endl; // printf("%f %f\n",downsampleRatio,downsampleRatio); int x=(int)std::max((int)floor(minT.x()),0); int y=(int)std::max((int)floor(minT.y()),0); int xMax=(int)std::min((int)ceil(maxT.x()),origX); int yMax=(int)std::min((int)ceil(maxT.y()),origY); int xRange=(xMax-x); int yRange=(yMax-y); //printf("X:%d -- %d Y:%d -- %d ",x,xMax,y,yMax); //Need bias of 1.0 or will round down double maxSide=std::max(osg::Image::computeNearestPowerOfTwo(xRange,1.0),osg::Image::computeNearestPowerOfTwo(yRange,1.0)); osg::Vec2 subSize=osg::Vec2(maxSide,maxSide); if(downsampleRatio*maxSide < 1.0){ printf("Clipping %f %f to",downsampleRatio,downsampleFactor); downsampleRatio=1.0/maxSide; downsampleFactor=maxSide; printf("%f %f\n",downsampleRatio,downsampleFactor); } texsize[0]=origX; texsize[1]=origY; texsize[2]=subSize.x(); texsize[3]=subSize.y(); osg::Vec2 downsampleSize(subSize.x(),subSize.y()); downsampleSize.x()*=downsampleRatio; downsampleSize.y()*=downsampleRatio; // printf("Range %d %d\n",xRange,yRange); // printf("%f %f %f %f\n",subSize.x(),subSize.y(),downsampleSize.x(),downsampleSize.y()); image = new osg::Image; image->allocateImage(downsampleSize.x(),downsampleSize.y(), 1, GL_RGB,GL_UNSIGNED_BYTE); if(image->data() == 0 ){ fprintf(stderr,"Failed to allocate\n"); exit(-1); } { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_imageMutex); vips::VImage osgImage(image->data(),downsampleSize.x(),downsampleSize.y(),3,vips::VImage::FMTUCHAR); in.extract_area(x,y,xRange,yRange).embed(1,0,0,subSize.x(),subSize.y()).shrink(downsampleFactor,downsampleFactor).write(osgImage); } ratio=osg::Vec4(x,y,subSize.x(),subSize.y()); //osg::Vec2 f(xRange-subSize.x(),yRange-subSize.y()); //std::cout << f<<std::endl; return toTex; }
/* The main entry */ int render(osg::Node *scene,osg::ref_ptr<osg::Image> &image,osg::GraphicsContext &gc,osg::Matrix &toScreen,const osg::Vec4 &sizes) { // Poster arguments bool activeMode = false; bool outputPoster = true; assert(sizes[2]== sizes[3]); int tileWidth = sizes[0], tileHeight = sizes[1]; int posterWidth = sizes[2], posterHeight = sizes[3]; std::string posterName = "poster.bmp", extName = "bmp"; osg::Vec4 bgColor(0.2f, 0.2f, 0.6f, 1.0f); osg::Camera::RenderTargetImplementation renderImplementation = osg::Camera::FRAME_BUFFER_OBJECT; // Camera settings for inactive screenshot osg::Vec3d latLongHeight( 50.0, 10.0, 2000.0 ); osg::Vec3d hpr( 0.0, 0.0, 0.0 ); const osg::BoundingSphere &bs=scene->getBound(); osg::Vec3d eye(bs.center()+osg::Vec3(0,0,3.5*bs.radius())); osg::ComputeBoundsVisitor cbbv(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); scene->traverse(cbbv); osg::BoundingBox bb = cbbv.getBoundingBox(); if ( !scene ) { std::cout << "No data loaded" << std::endl; return 1; } // Create camera for rendering tiles offscreen. FrameBuffer is recommended because it requires less memory. osg::ref_ptr<osg::Camera> camera = new osg::Camera; camera->setClearColor( bgColor ); camera->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF ); camera->setRenderOrder( osg::Camera::PRE_RENDER ); camera->setRenderTargetImplementation( renderImplementation ); camera->setViewport( 0, 0, tileWidth, tileHeight ); camera->addChild( scene ); // Set the printer osg::ref_ptr<PosterPrinter> printer = new PosterPrinter; printer->setTileSize( tileWidth, tileHeight ); printer->setPosterSize( posterWidth, posterHeight ); printer->setCamera( camera.get() ); if ( outputPoster ) { image = new osg::Image; image->allocateImage( posterWidth, posterHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE ); printer->setFinalPoster( image.get() ); printer->setOutputPosterName( posterName ); } #if 0 // While recording sub-images of the poster, the scene will always be traversed twice, from its two // parent node: root and camera. Sometimes this may not be so comfortable. // To prevent this behaviour, we can use a switch node to enable one parent and disable the other. // However, the solution also needs to be used with care, as the window will go blank while taking // snapshots and recover later. osg::ref_ptr<osg::Switch> root = new osg::Switch; root->addChild( scene, true ); root->addChild( camera.get(), false ); #else osg::ref_ptr<osg::Group> root = new osg::Group; root->addChild( scene ); root->addChild( camera.get() ); #endif osgViewer::Viewer viewer; viewer.setSceneData( root.get() ); viewer.getDatabasePager()->setDoPreCompile( false ); viewer.getCamera()->setGraphicsContext(&gc); if ( renderImplementation==osg::Camera::FRAME_BUFFER ) { // FRAME_BUFFER requires the window resolution equal or greater than the to-be-copied size viewer.setUpViewInWindow( 200, 200, tileWidth, tileHeight ); } else { // We want to see the console output, so just render in a window // viewer.setUpViewInWindow( 200, 200, tileWidth, tileHeight ); viewer.getCamera()->setViewport(new osg::Viewport(0,0,tileWidth,tileHeight)); } if ( activeMode ) { //viewer.addEventHandler( new PrintPosterHandler(printer.get()) ); viewer.addEventHandler( new osgViewer::StatsHandler ); viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); viewer.setCameraManipulator( new osgGA::TrackballManipulator ); viewer.run(); } else { osg::Camera* camera = viewer.getCamera(); computeViewMatrix( camera, eye, hpr ); osg::Vec3 centeredMin,centeredMax; centeredMin=(bb._min-bb.center()); centeredMax=(bb._max-bb.center()); // camera->setProjectionMatrixAsOrtho2D(-bs.radius(),bs.radius(),-bs.radius(),bs.radius()); camera->setProjectionMatrixAsOrtho2D(centeredMin[0],centeredMax[0],centeredMin[1],centeredMax[1]); toScreen=getToScreenMatrix(camera,osg::Vec2(posterWidth,posterHeight)); osg::ref_ptr<CustomRenderer> renderer = new CustomRenderer( camera ); camera->setRenderer( renderer.get() ); viewer.setThreadingModel( osgViewer::Viewer::SingleThreaded ); // Realize and initiate the first PagedLOD request viewer.realize(); viewer.frame(); printer->init( camera ); while ( !printer->done() ) { viewer.advance(); // Keep updating and culling until full level of detail is reached renderer->setCullOnly( true ); while ( viewer.getDatabasePager()->getRequestsInProgress() ) { viewer.updateTraversal(); viewer.renderingTraversals(); } renderer->setCullOnly( false ); printer->frame( viewer.getFrameStamp(), viewer.getSceneData() ); viewer.renderingTraversals(); } } return 0; }