1. Almacenamiento de Imágenes en Memoria
Para capturar los datos del fotograma actual, se implementa una clase derivada de osg::Camera::DrawCallback. Esta clase se ejecuta después del dibujado de cada fotograma y almacena la información de los píxeles en un objeto osg::Image.
class FrameGrabber : public osg::Camera::DrawCallback
{
public:
FrameGrabber(osg::Image* imageBuffer) : buffer(imageBuffer) {}
FrameGrabber() : buffer(new osg::Image) {}
virtual void operator()(const osg::Camera& camera) const
{
if (!camera.getViewport()) return;
unsigned int imgWidth = camera.getViewport()->width();
unsigned int imgHeight = camera.getViewport()->height();
buffer->allocateImage(imgWidth, imgHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE);
buffer->readPixels(0, 0, imgWidth, imgHeight, GL_RGBA, GL_UNSIGNED_BYTE);
}
osg::Image* getStoredImage() const { return buffer.get(); }
private:
osg::ref_ptr<osg::Image> buffer;
};
2. Evento de Captura y Guardado en Archivo
Se crea un manejador de eventos GUI para detectar la pulsación de teclas y activar el guardado de la imagen capturada. Al presionar la tecla 's', se escribe el contenido almacenado en un archivo de imagen.
class ScreenshotHandler : public osgGA::GUIEventHandler
{
public:
ScreenshotHandler(FrameGrabber* grabber) : captureTarget(grabber), fileCounter(0) {}
bool handle(const osgGA::GUIEventAdapter& event, osgGA::GUIActionAdapter& action)
{
osgViewer::View* currentView = dynamic_cast<osgViewer::View*>(&action);
if (!currentView) return false;
if (event.getEventType() == osgGA::GUIEventAdapter::KEYUP)
{
if (event.getKey() == 's' || event.getKey() == 'S')
{
std::string filename = "capture_" + std::to_string(++fileCounter) + ".png";
osgDB::writeImageFile(*captureTarget->getStoredImage(), filename);
return true;
}
}
return false;
}
private:
FrameGrabber* captureTarget;
unsigned int fileCounter;
};
3. Integración en la Aplicación
Los componentes se configuran durante la inicialización del visor. El callback de captura se asocia a la cámara, y el manejador de eventos se añade al visor para reaccionar a las interacciones del usuario.
// Instanciar componentes
osg::ref_ptr<FrameGrabber> grabber = new FrameGrabber();
osg::ref_ptr<ScreenshotHandler> handler = new ScreenshotHandler(grabber.get());
// Configurar visor
viewer->getCamera()->setFinalDrawCallback(grabber);
viewer->addEventHandler(handler);
viewer->setSceneData(rootNode);