Hi all,
> > Maybe OSG should integrate
> >
> > http://www.mesa3d.org/brianp/TR.html
In my personal SDL-based viewer I've implemented a simple function that
takes arbitrary-size snapshots. With some tweaks to remove dependency on the
host class you should be able to use it in your application:
bool osgSDL::Viewer::exportSnapshot(const std::string &filename, int width,
int height, bool savetiles)
{
if (viewports_.empty())
return false;
Viewport* vp = viewports_.front().get();
osgUtil::SceneView* sv = vp->getSceneView();
if (!sv)
return false;
double left, right, bottom, top, zNear, zFar;
sv->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar);
double ar = width / static_cast<double>(height);
double target_frustum_h = top - bottom;
double target_frustum_w = ar * target_frustum_h;
double target_left = -target_frustum_w * 0.5;
double target_right = target_frustum_w * 0.5;
double target_bottom = -target_frustum_h * 0.5;
double target_top = target_frustum_h * 0.5;
int vpwidth = vp->getWidth() * getWidth();
int vpheight = vp->getHeight() * getHeight();
double newbottom = target_bottom;
double newtop = newbottom + (target_top - target_bottom) * vpheight /
height;
double newfrustum_h = newtop - newbottom;
int t = 0;
int s = 0;
typedef std::vector<osg::ref_ptr<osg::Image> > Image_list;
Image_list images;
while (newbottom < target_top)
{
double frame_height = vpheight;
if (newtop > target_top)
frame_height = height % vpheight;
double newleft = target_left;
double newright = newleft + (target_right - target_left) * vpwidth /
width;
double newfrustum_w = newright - newleft;
s = 0;
while (newleft < target_right)
{
double frame_width = vpwidth;
if (newright > target_right)
frame_width = width % vpwidth;
sv->setProjectionMatrixAsFrustum(newleft, newright, newbottom, newtop,
zNear, zFar);
cull(sv);
draw(sv);
std::ostringstream oss;
oss << osgDB::getNameLessExtension(filename) << "_" << s << "_" << t <<
"." << osgDB::getFileExtension(filename);
osg::ref_ptr<osg::Image> img = new osg::Image;
images.push_back(img);
img->readPixels(0, 0, frame_width, frame_height, GL_RGBA,
GL_UNSIGNED_BYTE);
if (savetiles)
{
if (!osgDB::writeImageFile(*img.get(), oss.str()))
{
std::cerr << "Error writing " << oss.str() << "\n";
return false;
}
}
newleft += newfrustum_w;
newright += newfrustum_w;
++s;
}
newbottom += newfrustum_h;
newtop += newfrustum_h;
++t;
}
osg::ref_ptr<osg::Image> mosaic = new osg::Image;
mosaic->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
for (int i=0; i<t; ++i)
{
int yo = vpheight * i;
for (int j=0; j<s; ++j)
{
int xo = vpwidth * j;
mosaic->copySubImage(xo, yo, 0, images.at(j+i*s).get());
}
}
if (!osgDB::writeImageFile(*mosaic.get(), filename))
{
std::cerr << "Error writing mosaic " << filename << "\n";
return false;
}
return true;
}
Cheers,
Marco
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/