OpenSceneGraph Forum Forum Index OpenSceneGraph Forum
Official forum which mirrors the existent OSG mailing lists. Messages posted here are forwarded to the mailing list and vice versa.
 
   FAQFAQ    SearchSearch    MemberlistMemberlist    RulesRules    UsergroupsUsergroups    RegisterRegister 
 Mail2Forum SettingsMail2Forum Settings  ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
   AlbumAlbum  OpenSceneGraph IRC ChatOpenSceneGraph IRC Chat   SmartFeedSmartFeed 

Problems with MRT


 
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> General
View previous topic :: View next topic  
Author Message
romulogcerqueira
User


Joined: 11 Jun 2015
Posts: 57
Location: Brazil

PostPosted: Sat May 12, 2018 4:46 pm    Post subject:
Problems with MRT
Reply with quote

Folks,

I have studied about FBO, RTT and MRT to include this feature in my application, however I faced with some problems/doubts I did not find answers/tips during my search. Follows below the description of my scenario. I´ll be grateful if anyone can help me.

What I want to do?
- Attach two render textures (for color and depth buffers) to the same camera;
- Display only the color buffer in the post render camera;
- Read images from depth and color buffer in a final draw callback;
- Write collected float images in disk.

What have I got so far?
- Allow rendering for color or depth buffers separately, but not both on the same camera;
- Display the color buffer in the post render camera;
- Read color or depth buffer in the final draw callback;
- Write collected image (color or depth) in disk - only images as GL_UNSIGNED_BYTE. The following error is presented:
Error writing file ./Test-depth.png: Warning: Error in writing to "./Test-depth.png".

What are the doubts? (help!)
- How can I properly render both textures (color and depth buffer) in the same camera?
- How can I properly read both depth and color buffers in the final draw callback?
- During image writing in disk, why the error is presented only for images as GL_FLOAT, not for GL_UNSIGNED_BYTE?
- Is the render texture attached to an osg::Geode mandatory or optional in this process? Do I need to create two osg::Geode (one for each buffers), or only one osg::Geode for both?

Please take a look in my current source code (what am I doing wrong here?):

Code:
// 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());
}


Thanks in advance,

Rômulo Cerqueira
Back to top
View user's profile Send private message
romulogcerqueira
User


Joined: 11 Jun 2015
Posts: 57
Location: Brazil

PostPosted: Mon May 14, 2018 12:29 pm    Post subject:
Reply with quote

Folks!

Any tips here?

Thanks in advance,

Rômulo
Back to top
View user's profile Send private message
mp3butcher (Julien Valentin)
Appreciator


Joined: 17 Feb 2010
Posts: 462
Location: France

PostPosted: Mon May 14, 2018 1:24 pm    Post subject:
Reply with quote

I never used float texture for depth RTT perhaps you should stay with classic integer textures....

romulogcerqueira wrote:
Folks!

Any tips here?

Thanks in advance,

Rômulo

_________________
Twirling twirling twirling toward freedom
Back to top
View user's profile Send private message Visit poster's website
romulogcerqueira
User


Joined: 11 Jun 2015
Posts: 57
Location: Brazil

PostPosted: Tue May 15, 2018 11:26 pm    Post subject:
Reply with quote

Hi,

just updating my progress:

What have I got so far?
[ ✓ ] Allow rendering for color or depth buffers on the same camera;
[ ✓ ] Display only the color buffer in the post render camera;
[ ✓ ] Read color or depth buffer in the final draw callback;
[ ✗ ] Write collected image (color or depth) in disk - only images as GL_UNSIGNED_BYTE, instead of GL_FLOAT.

I changed the buffer reader in my callback (readImageFromCurrentTexture() instead of readPixels()), however I still got problems when I render floating textures...

Follows my current code. Any suggestions here?

Code:
// 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, osg::Texture2D* tex1, osg::Texture2D* tex2 ) {
        if (gc->getTraits()) {
            _texColor = tex1;
            _texDepth = tex2;
        }
    }

    virtual void operator () (osg::RenderInfo& renderInfo) const {
        // color buffer
        renderInfo.getState()->applyTextureAttribute(0, _texColor);
        osg::ref_ptr<osg::Image> mColor = new osg::Image();
        mColor->readImageFromCurrentTexture(renderInfo.getContextID(), true, _texColor->getSourceType());
        osgDB::ReaderWriter::WriteResult wrColor = osgDB::Registry::instance()->writeImage(*mColor, "./Test-color.png", NULL);
        if (!wrColor.success()) {
            osg::notify(osg::WARN) << "Color image: failed! (" << wrColor.message() << ")" << std::endl;
        }

        // depth buffer
        renderInfo.getState()->applyTextureAttribute(0, _texDepth);
        osg::ref_ptr<osg::Image> mDepth = new osg::Image();
        mDepth->readImageFromCurrentTexture(renderInfo.getContextID(), true, _texDepth->getSourceType());
        osgDB::ReaderWriter::WriteResult wrDepth = osgDB::Registry::instance()->writeImage(*mDepth, "./Test-depth.png", NULL);
        if (!wrDepth.success()) {
            osg::notify(osg::WARN) << "Depth image: failed! (" << wrDepth.message() << ")" << std::endl;
        }
    }
    osg::ref_ptr<osg::Texture2D> _texColor;
    osg::ref_ptr<osg::Texture2D> _texDepth;
};

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, 0 );
    camera->setViewport( 0, 0, w, h );

    osg::Texture2D* tex = new osg::Texture2D;
    tex->setTextureSize( w, h );
    tex->setInternalFormat( GL_RGB );
    tex->setSourceFormat( GL_RGBA );
    tex->setSourceType( GL_UNSIGNED_BYTE );
    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->setSourceFormat(GL_DEPTH_COMPONENT);
    tex->setInternalFormat(GL_DEPTH_COMPONENT);
    tex->setSourceType(GL_UNSIGNED_BYTE);
    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( "/home/romulo/Tools/OpenSceneGraph-Data/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(), attachedTextures[0], attachedTextures[1]);
    mrtCamera->setFinalDrawCallback(finalDrawCallback);

    return (viewer.run());
}

...

Thank you!

Cheers,
Rômulo
Back to top
View user's profile Send private message
SMesserschmidt (Sebastian Messerschmidt)
Forum Moderator


Joined: 10 Sep 2013
Posts: 822

PostPosted: Wed May 16, 2018 6:22 am    Post subject:
Problems with MRT
Reply with quote

Hi Romulo,

Have you debugged into the writeImage functionality of the png-plugin?
Have you tried using tiff etc.?

I suspect that either the read-back image is either empty or has the
wrong image format, so the plugin cannot write it. Not all formats that
you can use for images can be written by the plugins.

Cheers
Sebastian

Quote:
Hi,

just updating my progress:

What have I got so far?
[ ✓ ] Allow rendering for color or depth buffers on the same camera;
[ ✓ ] Display only the color buffer in the post render camera;
[ ✓ ] Read color or depth buffer in the final draw callback;
[ ✗ ] Write collected image (color or depth) in disk - only images as GL_UNSIGNED_BYTE, instead of GL_FLOAT.

I changed the buffer reader in my callback (readImageFromCurrentTexture() instead of readPixels()), however I still got problems when I render floating textures...

This is my current code:


Code:
// 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, osg::Texture2D* tex1, osg::Texture2D* tex2 ) {
if (gc->getTraits()) {
_texColor = tex1;
_texDepth = tex2;
}
}

virtual void operator () (osg::RenderInfo& renderInfo) const {
// color buffer
renderInfo.getState()->applyTextureAttribute(0, _texColor);
osg::ref_ptr<osg::Image> mColor = new osg::Image();
mColor->readImageFromCurrentTexture(renderInfo.getContextID(), true, GL_UNSIGNED_BYTE);
osgDB::ReaderWriter::WriteResult wrColor = osgDB::Registry::instance()->writeImage(*mColor, "./Test-color.png", NULL);
if (!wrColor.success()) {
osg::notify(osg::WARN) << "Color image: failed! (" << wrColor.message() << ")" << std::endl;
}

// depth buffer
renderInfo.getState()->applyTextureAttribute(0, _texDepth);
osg::ref_ptr<osg::Image> mDepth = new osg::Image();
mDepth->readImageFromCurrentTexture(renderInfo.getContextID(), true, GL_UNSIGNED_BYTE);
osgDB::ReaderWriter::WriteResult wrDepth = osgDB::Registry::instance()->writeImage(*mDepth, "./Test-depth.png", NULL);
if (!wrDepth.success()) {
osg::notify(osg::WARN) << "Depth image: failed! (" << wrDepth.message() << ")" << std::endl;
}
}
osg::ref_ptr<osg::Texture2D> _texColor;
osg::ref_ptr<osg::Texture2D> _texDepth;
};

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, 0 );
camera->setViewport( 0, 0, w, h );

osg::Texture2D* tex = new osg::Texture2D;
tex->setTextureSize( w, h );
tex->setInternalFormat( GL_RGB );
tex->setSourceFormat( GL_RGBA );
tex->setSourceType( GL_UNSIGNED_BYTE );
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->setSourceFormat(GL_DEPTH_COMPONENT);
tex->setInternalFormat(GL_DEPTH_COMPONENT);
tex->setSourceType(GL_UNSIGNED_BYTE);
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( "/home/romulo/Tools/OpenSceneGraph-Data/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(), attachedTextures[0], attachedTextures[1]);
mrtCamera->setFinalDrawCallback(finalDrawCallback);

return (viewer.run());
}



...

Thank you!

Cheers,
Rômulo[/code][/i]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=73644#73644









------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
romulogcerqueira
User


Joined: 11 Jun 2015
Posts: 57
Location: Brazil

PostPosted: Fri May 18, 2018 8:34 am    Post subject:
Reply with quote

Hi Sebastian and Julien,

thanks for your comments. I tried your suggestions without success, even output image in different formats (BMP, PNG, TIFF...). It is funny, because I can handle the image data as GL_FLOAT, but the image is only properly written in disk as UNSIGNED_BYTE.

At this moment, this process is not more necessary to me, however a work around can help more people.

Thank you!

Cheers,
Rômulo
Back to top
View user's profile Send private message
robertosfield
OSG Project Lead


Joined: 18 Mar 2009
Posts: 12027

PostPosted: Fri May 18, 2018 10:06 am    Post subject:
Problems with MRT
Reply with quote

Hi Rômulo,

On 18 May 2018 at 09:34, Rômulo Cerqueira <> wrote:
Quote:
thanks for your comments. I tried your suggestions without success, even output image in different formats (BMP, PNG, TIFF...). It is funny, because I can handle the image data as GL_FLOAT, but the image is only properly written in disk as UNSIGNED_BYTE.

I'm not the original author of the plugins you are trying to use so
can't provide any quick answers, like yourself I have to read the code
and look up the 3rd party libraries/formats to find out whether it
possible for them to support writing data out in floats.

It might be that the plugins you are trying to use might be able to
support float output but the plugins don't yet implement it. Like all
parts of the OSG things get developed when users need features that
don't yet exist so it might be the case here. So I'd recommend just
diving into the plugin code and see what is happening for your data,
you have you data and application so best placed to do this.

Cheers,
Robert.


------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
mp3butcher (Julien Valentin)
Appreciator


Joined: 17 Feb 2010
Posts: 462
Location: France

PostPosted: Sun May 20, 2018 9:44 pm    Post subject:
Reply with quote

Hi
Are you sure read back images are those expected?
output im->data(0...image.size) in the standard output in order to be sure your result are good
If it's not the case add code to control where it fails:
1 rendering color or depth buffers to textures
2 display result textures on quads to see if it what u expect
3 Read color or depth buffer in the final draw callback (output readback on console)
4 Write images (color or depth) to disk

Once you've done it you'll know where is the problem (i don't believe it comes from plugin...)

(And again, rtt COLOR_BUFFERX to float texture works like a charm but I'm not sure you can read back those integer buffers to float textures)

Hope it helps
Cheers

Perhaps you should add step in your example in order to diagnose where your issue is
romulogcerqueira wrote:
Hi,

just updating my progress:

What have I got so far?
[ ✓ ] Allow rendering for color or depth buffers on the same camera;
[ ✓ ] Display only the color buffer in the post render camera;
[ ✓ ] Read color or depth buffer in the final draw callback;
[ ✗ ] Write collected image (color or depth) in disk - only images as GL_UNSIGNED_BYTE, instead of GL_FLOAT.

I changed the buffer reader in my callback (readImageFromCurrentTexture() instead of readPixels()), however I still got problems when I render floating textures...

Follows my current code. Any suggestions here?

Code:
// 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, osg::Texture2D* tex1, osg::Texture2D* tex2 ) {
        if (gc->getTraits()) {
            _texColor = tex1;
            _texDepth = tex2;
        }
    }

    virtual void operator () (osg::RenderInfo& renderInfo) const {
        // color buffer
        renderInfo.getState()->applyTextureAttribute(0, _texColor);
        osg::ref_ptr<osg::Image> mColor = new osg::Image();
        mColor->readImageFromCurrentTexture(renderInfo.getContextID(), true, _texColor->getSourceType());
        osgDB::ReaderWriter::WriteResult wrColor = osgDB::Registry::instance()->writeImage(*mColor, "./Test-color.png", NULL);
        if (!wrColor.success()) {
            osg::notify(osg::WARN) << "Color image: failed! (" << wrColor.message() << ")" << std::endl;
        }

        // depth buffer
        renderInfo.getState()->applyTextureAttribute(0, _texDepth);
        osg::ref_ptr<osg::Image> mDepth = new osg::Image();
        mDepth->readImageFromCurrentTexture(renderInfo.getContextID(), true, _texDepth->getSourceType());
        osgDB::ReaderWriter::WriteResult wrDepth = osgDB::Registry::instance()->writeImage(*mDepth, "./Test-depth.png", NULL);
        if (!wrDepth.success()) {
            osg::notify(osg::WARN) << "Depth image: failed! (" << wrDepth.message() << ")" << std::endl;
        }
    }
    osg::ref_ptr<osg::Texture2D> _texColor;
    osg::ref_ptr<osg::Texture2D> _texDepth;
};

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, 0 );
    camera->setViewport( 0, 0, w, h );

    osg::Texture2D* tex = new osg::Texture2D;
    tex->setTextureSize( w, h );
    tex->setInternalFormat( GL_RGB );
    tex->setSourceFormat( GL_RGBA );
    tex->setSourceType( GL_UNSIGNED_BYTE );
    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->setSourceFormat(GL_DEPTH_COMPONENT);
    tex->setInternalFormat(GL_DEPTH_COMPONENT);
    tex->setSourceType(GL_UNSIGNED_BYTE);
    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( "/home/romulo/Tools/OpenSceneGraph-Data/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(), attachedTextures[0], attachedTextures[1]);
    mrtCamera->setFinalDrawCallback(finalDrawCallback);

    return (viewer.run());
}

...

Thank you!

Cheers,
Rômulo

_________________
Twirling twirling twirling toward freedom
Back to top
View user's profile Send private message Visit poster's website
romulogcerqueira
User


Joined: 11 Jun 2015
Posts: 57
Location: Brazil

PostPosted: Mon May 21, 2018 11:48 pm    Post subject:
Reply with quote

Hi Robert and mp3butcher,

thanks for all comments. I tried the mp3butcher`s suggestion (save the rendered image data to txt) without errors. Please see my current source code and outputs.

Code:
// OSG includes
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Camera>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Texture2D>

#include <fstream>
#include <iterator>
#include <string>
#include <vector>

struct SnapImage : public osg::Camera::DrawCallback {
    SnapImage(osg::GraphicsContext* gc, osg::Texture2D* tex ) {
        if (gc->getTraits()) {
            _texColor = tex;
        }
    }

    virtual void operator () (osg::RenderInfo& renderInfo) const {
        // color buffer
        renderInfo.getState()->applyTextureAttribute(0, _texColor);
        osg::ref_ptr<osg::Image> mColor = new osg::Image();
        mColor->readImageFromCurrentTexture(renderInfo.getContextID(), true, GL_FLOAT);
        mColor->setInternalTextureFormat( GL_RGBA32F_ARB );

        float* data = (float*) mColor->data();
        std::vector<float> vec = std::vector<float>(data, data + (mColor->s() * mColor->t()));

        std::ofstream fout("vector.txt");
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<float>(fout, "\n"));
    }
    osg::ref_ptr<osg::Texture2D> _texColor;
};

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, 0 );
    camera->setViewport( 0, 0, w, h );

    osg::Texture2D* tex = new osg::Texture2D;
    tex->setTextureSize( w, h );
    tex->setInternalFormat( GL_RGBA32F_ARB );
    tex->setSourceFormat( GL_RGBA );
    tex->setSourceType( GL_FLOAT );
    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 );

    return camera.release();
}


int main() {
    osg::ref_ptr< osg::Group > root( new osg::Group );
    root->addChild( osgDB::readNodeFile( "/cow.osg" ) );
    unsigned int winW = 300;
    unsigned int winH = 200;

    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->addChild( geode );
    root->addChild(postRenderCamera);

    // setup the callback
    SnapImage* finalDrawCallback = new SnapImage(viewer.getCamera()->getGraphicsContext(), attachedTextures[0]);
    mrtCamera->setFinalDrawCallback(finalDrawCallback);

    return (viewer.run());
}


...

Thank you!

Cheers,
Rômulo
Back to top
View user's profile Send private message
mp3butcher (Julien Valentin)
Appreciator


Joined: 17 Feb 2010
Posts: 462
Location: France

PostPosted: Wed May 23, 2018 12:38 pm    Post subject:
Reply with quote

Hi
don't use float texture if you want to output classic image format such as jpg,png,bmp.. (AFAIK these are all integer images...)
Cheers

romulogcerqueira wrote:
Hi Robert and mp3butcher,

thanks for all comments. I tried the mp3butcher`s suggestion (save the rendered image data to txt) without errors. Please see my current source code and outputs.

Code:
// OSG includes
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Camera>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Texture2D>

#include <fstream>
#include <iterator>
#include <string>
#include <vector>

struct SnapImage : public osg::Camera::DrawCallback {
    SnapImage(osg::GraphicsContext* gc, osg::Texture2D* tex ) {
        if (gc->getTraits()) {
            _texColor = tex;
        }
    }

    virtual void operator () (osg::RenderInfo& renderInfo) const {
        // color buffer
        renderInfo.getState()->applyTextureAttribute(0, _texColor);
        osg::ref_ptr<osg::Image> mColor = new osg::Image();
        mColor->readImageFromCurrentTexture(renderInfo.getContextID(), true, GL_FLOAT);
        mColor->setInternalTextureFormat( GL_RGBA32F_ARB );

        float* data = (float*) mColor->data();
        std::vector<float> vec = std::vector<float>(data, data + (mColor->s() * mColor->t()));

        std::ofstream fout("vector.txt");
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<float>(fout, "\n"));
    }
    osg::ref_ptr<osg::Texture2D> _texColor;
};

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, 0 );
    camera->setViewport( 0, 0, w, h );

    osg::Texture2D* tex = new osg::Texture2D;
    tex->setTextureSize( w, h );
    tex->setInternalFormat( GL_RGBA32F_ARB );
    tex->setSourceFormat( GL_RGBA );
    tex->setSourceType( GL_FLOAT );
    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 );

    return camera.release();
}


int main() {
    osg::ref_ptr< osg::Group > root( new osg::Group );
    root->addChild( osgDB::readNodeFile( "/cow.osg" ) );
    unsigned int winW = 300;
    unsigned int winH = 200;

    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->addChild( geode );
    root->addChild(postRenderCamera);

    // setup the callback
    SnapImage* finalDrawCallback = new SnapImage(viewer.getCamera()->getGraphicsContext(), attachedTextures[0]);
    mrtCamera->setFinalDrawCallback(finalDrawCallback);

    return (viewer.run());
}


...

Thank you!

Cheers,
Rômulo

_________________
Twirling twirling twirling toward freedom
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> General All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum

Similar Topics
Topic Author Forum Replies Posted
No new posts osglight demo problems with Intel gra... eventhorizon5 General 2 Mon Jul 09, 2018 8:52 pm View latest post
No new posts Memory problems in Windows/Visual Studio markja General 6 Thu Apr 19, 2018 3:20 pm View latest post
No new posts Problems with osgText::Text internal ... brianh General 3 Tue Mar 20, 2018 10:45 am View latest post
No new posts Undocking WIN32 causes problems adrianj General 0 Sat Mar 10, 2018 4:16 am View latest post
No new posts wide aspect ratio causing problems wi... exedor General 1 Tue Dec 26, 2017 10:18 pm View latest post


Board Security Anti Bot Question MOD - phpBB MOD against Spam Bots
Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP