Hello Marcus,
once again, thank you for sharing your code. Basically it is working. I only
have to problems:
1. I use a gradient background in my scene but it is not tiled at all. I
will have to investigate what is really happening...
2. The Image class does allocate a continous buffer for the whole image at
once. This does not scale very well and leads rather fast to memory
exhaustion. A better solution would be to write the tile data in a stream
like manner. Or a special image class which does hold its buffer on disk
instead of the main memory.
3. The image generation process is visible to the end user. This is an
application specific problem. I would have to create a separate 'printing'
window which is not visible to the application user.
I did not know about the TileCameraDecorator class and its application.
OpenSG does really have a lot to offer. Problem is often to uncover the
hidden treasures.
Best,
Johannes
P.S.: The code in OpenSG 2.0 folded with my own style and frame...
_views is just a vector of 'view' objects which are wrappers around
the OpenSG ViewPort and some other viewport relevant stuff.
osg::ImageTransitPtr CompositeViewer::getHiResScreenShot(
osg::UInt32 width,
osg::UInt32 height)
{
ImageUnrecPtr output_image = Image::create();
output_image->set(Image::OSG_RGBA_PF, width, height);
if (!_views.empty()) {
ImageUnrecPtr grab_image = Image::create();
GrabForegroundUnrecPtr grabber = GrabForeground::create();
grabber->setImage(grab_image);
grabber->setActive(true);
grabber->setAutoResize(false);
size_t num_views = _views.size();
std::vector<TileCameraDecoratorUnrecPtr> decorators;
decorators.resize(num_views);
for (size_t i = 0; i < num_views; ++i) {
Viewport* vp = _views[i]->getPort();
TileCameraDecoratorUnrecPtr decorator =
TileCameraDecorator::create();
decorator->setFullSize(width, height);
decorator->setDecoratee(vp->getCamera());
decorators[i] = decorator;
vp->setCamera(decorator);
}
_views.back()->getPort()->editMFForegrounds()->push_back(grabber);
UInt32 maxWidth = _win->getWidth();
UInt32 maxHeight = _win->getHeight();
for (UInt32 xPos = 0; xPos < width; xPos += maxWidth)
{
UInt32 xSize = std::min(maxWidth, width - xPos);
for (UInt32 yPos = 0; yPos < height; yPos += maxHeight)
{
UInt32 ySize = std::min(maxHeight, height - yPos);
for (size_t i = 0; i < num_views; ++i) {
Viewport* vp = _views[i]->getPort();
// coords > 1 are interpreted as pixels
vp->setSize(0, 0, xSize, ySize);
TileCameraDecorator* decorator = decorators[i];
decorator->setSize( xPos / float(width),
yPos / float(height),
(xPos + xSize) / float(width),
(yPos + ySize) / float(height) );
grab_image->set(output_image->getPixelFormat(), xSize,
ySize);
}
_win->render(_action);
output_image->setSubData(xPos, yPos, 0, xSize, ySize, 1,
grabber->getImage()->getData());
}
}
//
// restore window
//
for (size_t i = 0; i < num_views; ++i) {
Viewport* vp = _views[i]->getPort();
vp->setCamera(decorators[i]->getDecoratee());
vp->setSize(0, 0, 1, 1);
}
_views.back()->getPort()->removeObjFromForegrounds(grabber);
}
return ImageTransitPtr(output_image);
}
------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the
lucky parental unit. See the prize list and enter to win:
http://p.sf.net/sfu/thinkgeek-promo
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users