Народ,
Я изучал FBO, RTT и MRT, чтобы включить эту функцию в свое приложение, однако я столкнулся с некоторыми проблемами / сомнениями, я не нашел ответов / советов во время поиска.Ниже следует описание моего сценария.Буду благодарен, если кто-нибудь сможет мне помочь.
Что я хочу сделать?
- Присоединить две текстуры рендеринга (для буферов цвета и глубины) кта же камера;
- Отображение только цветового буфера в камере пост-рендеринга;
- Считывание изображений из глубины и цветового буфера в финальном обратном вызове отрисовки;
- Запись собранных плавающих изображенийна диске.
Что я получил до сих пор?
- Разрешить рендеринг для буферов цвета или глубины отдельно, но не одновременно на одной и той же камере;
- Отображение цветового буфера в камере пост-рендеринга;
- Считывание буфера цвета или глубины в финальном обратном вызове отрисовки;
- Запись собранного изображения (цвет или глубина) на диске - только изображениякак GL_UNSIGNED_BYTE.Представлена следующая ошибка:
Ошибка записи файла ./Test-depth.png: Предупреждение: Ошибка записи в "./Test-depth.png".
Какие есть сомнения?(помощь!)
- Как правильно отобразить обе текстуры (буфер цвета и глубины) в одной камере?
- Как правильно прочитать буферы глубины и цветав окончательном обратном вызове отрисовки?
- Почему во время записи изображения на диск ошибка отображается только для изображений как GL_FLOAT, а не для GL_UNSIGNED_BYTE?
- Прикреплена ли текстура рендеринга к osg :: Geodeобязательно или необязательно в этом процессе?Нужно ли создавать два osg :: Geode (по одному для каждого буфера) или только один osg :: Geode для обоих?
Пожалуйста, посмотрите мой текущий исходный код (что я делаюздесь не так?):
// OSG includes
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer>
#include <osg/Camera>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Texture2D>
struct SnapImage : public osg::Camera::DrawCallback {
SnapImage(osg::GraphicsContext* gc) {
_image = new osg::Image;
_depth = new osg::Image;
if (gc->getTraits()) {
int width = gc->getTraits()->width;
int height = gc->getTraits()->height;
_image->allocateImage(width, height, 1, GL_RGBA, GL_FLOAT);
_depth->allocateImage(width, height, 1, GL_DEPTH_COMPONENT, GL_FLOAT);
}
}
virtual void operator () (osg::RenderInfo& renderInfo) const {
osg::Camera* camera = renderInfo.getCurrentCamera();
osg::GraphicsContext* gc = camera->getGraphicsContext();
if (gc->getTraits() && _image.valid()) {
int width = gc->getTraits()->width;
int height = gc->getTraits()->height;
_image->readPixels(0, 0, width, height, GL_RGBA, GL_FLOAT);
_depth->readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT);
osgDB::writeImageFile(*_image, "./Test-color.png");
osgDB::writeImageFile(*_depth, "./Test-depth.png");
}
}
osg::ref_ptr<osg::Image> _image;
osg::ref_ptr<osg::Image> _depth;
};
osg::Camera* setupMRTCamera( osg::ref_ptr<osg::Camera> camera, std::vector<osg::Texture2D*>& attachedTextures, int w, int h ) {
camera->setClearColor( osg::Vec4() );
camera->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
camera->setRenderOrder( osg::Camera::PRE_RENDER );
camera->setViewport( 0, 0, w, h );
osg::Texture2D* tex = new osg::Texture2D;
tex->setTextureSize( w, h );
tex->setSourceType( GL_FLOAT );
tex->setSourceFormat( GL_RGBA );
tex->setInternalFormat( GL_RGBA32F_ARB );
tex->setResizeNonPowerOfTwoHint( false );
tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
attachedTextures.push_back( tex );
camera->attach( osg::Camera::COLOR_BUFFER, tex );
tex = new osg::Texture2D;
tex->setTextureSize( w, h );
tex->setSourceType( GL_FLOAT );
tex->setSourceFormat( GL_DEPTH_COMPONENT );
tex->setInternalFormat( GL_DEPTH_COMPONENT32 );
tex->setResizeNonPowerOfTwoHint( false );
attachedTextures.push_back( tex );
camera->attach( osg::Camera::DEPTH_BUFFER, tex );
return camera.release();
}
int main() {
osg::ref_ptr< osg::Group > root( new osg::Group );
root->addChild( osgDB::readNodeFile( "cow.osg" ) );
unsigned int winW = 800;
unsigned int winH = 600;
osgViewer::Viewer viewer;
viewer.setUpViewInWindow( 0, 0, winW, winH );
viewer.setSceneData( root.get() );
viewer.realize();
// setup MRT camera
std::vector<osg::Texture2D*> attachedTextures;
osg::Camera* mrtCamera ( viewer.getCamera() );
setupMRTCamera( mrtCamera, attachedTextures, winW, winH );
// set RTT textures to quad
osg::Geode* geode( new osg::Geode );
geode->addDrawable( osg::createTexturedQuadGeometry(
osg::Vec3(-1,-1,0), osg::Vec3(2.0,0.0,0.0), osg::Vec3(0.0,2.0,0.0)) );
geode->getOrCreateStateSet()->setTextureAttributeAndModes( 0, attachedTextures[0] );
geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
geode->getOrCreateStateSet()->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
// configure postRenderCamera to draw fullscreen textured quad
osg::Camera* postRenderCamera( new osg::Camera );
postRenderCamera->setClearMask( 0 );
postRenderCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER, osg::Camera::FRAME_BUFFER );
postRenderCamera->setReferenceFrame( osg::Camera::ABSOLUTE_RF );
postRenderCamera->setRenderOrder( osg::Camera::POST_RENDER );
postRenderCamera->setViewMatrix( osg::Matrixd::identity() );
postRenderCamera->setProjectionMatrix( osg::Matrixd::identity() );
postRenderCamera->addChild( geode );
root->addChild(postRenderCamera);
// setup the callback
SnapImage* finalDrawCallback = new SnapImage(viewer.getCamera()->getGraphicsContext());
mrtCamera->setFinalDrawCallback(finalDrawCallback);
return (viewer.run());
}
Заранее спасибо,
Rômulo Cerqueira