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 Opensg-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensg-users