Created
March 23, 2021 00:50
-
-
Save hkusoft/fa78c4a11b6eb25e38bcb6519eeccba3 to your computer and use it in GitHub Desktop.
OsgSnapshotHelper by David Kou
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include "OsgSnapshotHelper.h" | |
OsgSnapshotHelper::OsgSnapshotHelper(osgViewer::Viewer* pView) | |
{ | |
pViewer = pView; | |
// Install custom renderer | |
osg::ref_ptr<CustomRenderer> customRenderer = new CustomRenderer(pViewer->getCamera()); | |
pViewer->getCamera()->setRenderer(customRenderer.get()); | |
////Important | |
//pViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); | |
// Do cull and draw to render the scene correctly | |
customRenderer->setCullOnly(false); | |
} | |
void OsgSnapshotHelper::Capture(std::string fileName) | |
{ | |
if (pViewer) | |
{ | |
// Add the WindowCaptureCallback now that we have full resolution | |
GLenum buffer = pViewer->getCamera()->getGraphicsContext()->getTraits()->doubleBuffer ? GL_BACK : GL_FRONT; | |
pViewer->getCamera()->setFinalDrawCallback(new WindowCaptureCallback(buffer, fileName)); | |
pViewer->renderingTraversals(); | |
pViewer->getCamera()->setFinalDrawCallback(NULL); | |
} | |
} | |
OsgSnapshotHelper::~OsgSnapshotHelper() | |
{ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <osg/ArgumentParser> | |
#include <osg/CoordinateSystemNode> | |
#include <osg/Matrix> | |
#include <osg/NodeVisitor> | |
#include <osgUtil/IntersectionVisitor> | |
#include <osgUtil/GLObjectsVisitor> | |
#include <osgDB/ReadFile> | |
#include <osgDB/WriteFile> | |
#include <osgGA/DriveManipulator> | |
#include <osgGA/FlightManipulator> | |
#include <osgGA/KeySwitchMatrixManipulator> | |
#include <osgGA/TerrainManipulator> | |
#include <osgGA/TrackballManipulator> | |
#include <osgTerrain/Terrain> | |
#include <osgTerrain/GeometryTechnique> | |
#include <osgViewer/Viewer> | |
#include <osgViewer/ViewerEventHandlers> | |
#include <osgViewer/Renderer> | |
#include <iostream> | |
#include <sstream> | |
class OsgSnapshotHelper | |
{ | |
/** Capture the frame buffer and write image to disk*/ | |
class WindowCaptureCallback : public osg::Camera::DrawCallback | |
{ | |
public: | |
WindowCaptureCallback(GLenum readBuffer, const std::string& name) : | |
_readBuffer(readBuffer), | |
_fileName(name) | |
{ | |
_image = new osg::Image; | |
} | |
virtual void operator () (osg::RenderInfo& renderInfo) const | |
{ | |
#if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) | |
glReadBuffer(_readBuffer); | |
#else | |
osg::notify(osg::NOTICE) << "Error: GLES unable to do glReadBuffer" << std::endl; | |
#endif | |
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); | |
osg::GraphicsContext* gc = renderInfo.getState()->getGraphicsContext(); | |
if (gc->getTraits()) | |
{ | |
GLenum pixelFormat; | |
if (gc->getTraits()->alpha) | |
pixelFormat = GL_RGBA; | |
else | |
pixelFormat = GL_RGB; | |
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) | |
if (pixelFormat == GL_RGB) | |
{ | |
GLint value = 0; | |
#ifndef GL_IMPLEMENTATION_COLOR_READ_FORMAT | |
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B | |
#endif | |
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &value); | |
if (value != GL_RGB || | |
value != GL_UNSIGNED_BYTE) | |
{ | |
pixelFormat = GL_RGBA;//always supported | |
} | |
} | |
#endif | |
int width = gc->getTraits()->width; | |
int height = gc->getTraits()->height; | |
std::cout << "Capture: size=" << width << "x" << height << ", format=" << (pixelFormat == GL_RGBA ? "GL_RGBA" : "GL_RGB") << std::endl; | |
_image->readPixels(0, 0, width, height, pixelFormat, GL_UNSIGNED_BYTE); | |
} | |
if (!_fileName.empty()) | |
{ | |
std::cout << "Writing to: " << _fileName << std::endl; | |
osgDB::writeImageFile(*_image, _fileName); | |
} | |
} | |
protected: | |
GLenum _readBuffer; | |
std::string _fileName; | |
osg::ref_ptr<osg::Image> _image; | |
mutable OpenThreads::Mutex _mutex; | |
}; | |
/** Do Culling only while loading PagedLODs*/ | |
class CustomRenderer : public osgViewer::Renderer | |
{ | |
public: | |
CustomRenderer(osg::Camera* camera) | |
: osgViewer::Renderer(camera), | |
_cullOnly(true) | |
{ | |
} | |
/** Set flag to omit drawing in renderingTraversals */ | |
void setCullOnly(bool on) { _cullOnly = on; } | |
virtual void operator () (osg::GraphicsContext* /*context*/) | |
{ | |
if (_graphicsThreadDoesCull) | |
{ | |
if (_cullOnly) | |
cull(); | |
else | |
cull_draw(); | |
} | |
} | |
virtual void cull() | |
{ | |
osgUtil::SceneView* sceneView = _sceneView[0].get(); | |
if (!sceneView || _done) return; | |
updateSceneView(sceneView); | |
osgViewer::View* view = dynamic_cast<osgViewer::View*>(_camera->getView()); | |
if (view) sceneView->setFusionDistance(view->getFusionDistanceMode(), view->getFusionDistanceValue()); | |
sceneView->inheritCullSettings(*(sceneView->getCamera())); | |
sceneView->cull(); | |
} | |
bool _cullOnly; | |
}; | |
public: | |
OsgSnapshotHelper(osgViewer::Viewer* pView); | |
void Capture(std::string fileName); | |
~OsgSnapshotHelper(); | |
protected: | |
osgViewer::Viewer* pViewer; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please STAR ⭐ this gist if you find it helpful!