Hi,

I would like to write the output/buffer of fragment shader to texture (RTT) as 
I wish (e.g. all red), however this result is depending of the model's shapes 
visible in the scene. How can I proceed with this correctly?

Follow below my minimal source code and the results.

Thanks in advance!

Expected: 
[Image: http://forum.openscenegraph.org/files/expected_964.jpg ] 

Current: 
[Image: http://forum.openscenegraph.org/files/current_875.jpg ] 


Code:
#include <osg/TextureRectangle>
#include <osg/Group>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/PolygonMode>
#include <osg/Texture>
#include <osg/Camera>
#include <osgText/Text>

static const char *mrtVertSource = {
    "#version 130\n"
    "out vec3 worldNormal;\n"
    "void main(void)\n"
    "{\n"
    "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
    "   worldNormal = normalize(gl_NormalMatrix * gl_Normal);\n"
    "   gl_TexCoord[0] = gl_MultiTexCoord0;\n"
    "}\n"};

static const char *mrtFragSource = {
    "#version 130\n"
    "in vec3 worldNormal;\n"
    "void main(void)\n"
    "{\n"
    "   gl_FragData[0] = vec4(worldNormal, 0.0);\n"
    "}\n"};

osg::Geode *createScreenQuad(float width, float height, float scale = 1.0f)
{
    osg::Geometry *geom = osg::createTexturedQuadGeometry(
        osg::Vec3(), osg::Vec3(width, 0.0f, 0.0f), osg::Vec3(0.0f, height, 
0.0f),
        0.0f, 0.0f, width * scale, height * scale);
    osg::ref_ptr<osg::Geode> quad = new osg::Geode;
    quad->addDrawable(geom);

    int values = osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED;
    quad->getOrCreateStateSet()->setAttribute(
        new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, 
osg::PolygonMode::FILL), values);
    quad->getOrCreateStateSet()->setMode(GL_LIGHTING, values);
    return quad.release();
}

osg::Camera *createRTTCamera(osg::Camera::BufferComponent buffer, osg::Texture 
*tex)
{
    osg::ref_ptr<osg::Camera> camera = new osg::Camera;
    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, tex->getTextureWidth(), tex->getTextureHeight());
    camera->attach(buffer, tex);

    return camera.release();
}

osg::Camera *createHUDCamera(double left, double right, double bottom, double 
top)
{
    osg::ref_ptr<osg::Camera> camera = new osg::Camera;
    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
    camera->setRenderOrder(osg::Camera::POST_RENDER);
    camera->setAllowEventFocus(false);
    camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top));
    camera->getOrCreateStateSet()->setMode(GL_LIGHTING, 
osg::StateAttribute::OFF);
    return camera.release();
}

osg::TextureRectangle *createFloatTexture(uint w, uint h)
{
    osg::ref_ptr<osg::TextureRectangle> tex2D = new osg::TextureRectangle;
    tex2D->setTextureSize(w, h);
    tex2D->setInternalFormat(GL_RGB32F_ARB);
    tex2D->setSourceFormat(GL_RGBA);
    tex2D->setSourceType(GL_FLOAT);
    tex2D->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
    tex2D->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
    return tex2D.release();
}

int main(int argc, char **argv)
{
    osg::ref_ptr<osg::Node> scene = 
osgDB::readNodeFile("/home/romulo/Tools/OpenSceneGraph-Data/cow.osg");

    unsigned int w = 800, h = 800;
    osg::Texture *normalTex = createFloatTexture(w, h);

    osg::ref_ptr<osg::Camera> rttCamera = 
createRTTCamera(osg::Camera::COLOR_BUFFER0, normalTex);
    rttCamera->addChild(scene.get());

    osg::ref_ptr<osg::Program> program = new osg::Program;
    program->addShader(new osg::Shader(osg::Shader::VERTEX, mrtVertSource));
    program->addShader(new osg::Shader(osg::Shader::FRAGMENT, mrtFragSource));
    rttCamera->getOrCreateStateSet()->setAttributeAndModes(program.get(), 
osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
    rttCamera->getOrCreateStateSet()->addUniform(new osg::Uniform("defaultTex", 
0));

    osg::ref_ptr<osg::Camera> hudCamera = createHUDCamera(0.0, 1.0, 0.0, 1.0);
    hudCamera->addChild(createScreenQuad(1.f, 1.0f, w));
    hudCamera->getOrCreateStateSet()->setTextureAttributeAndModes(0, normalTex);

    osg::ref_ptr<osg::Group> root = new osg::Group;
    root->addChild(rttCamera.get());
    root->addChild(hudCamera.get());
    root->addChild(scene.get());

    osgViewer::Viewer viewer;
    viewer.setUpViewInWindow(0, 0, w, h);
    viewer.setSceneData(root.get());
    return viewer.run();
}




Rômulo

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



_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to