[osg-users] What is the reason for using a texture image that is black on the basis of the osgmultiplerendertargets?

OpenSceneGraph Users osg-users at lists.openscenegraph.org
Mon Jun 22 19:18:57 PDT 2020


/* OpenSceneGraph example, osgmultiplerendertargets.
*
*  Permission is hereby granted, free of charge, to any person obtaining a 
copy
*  of this software and associated documentation files (the "Software"), to 
deal
*  in the Software without restriction, including without limitation the 
rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/

#include <osg/GLExtensions>
#include <osg/Node>
#include <osg/Geometry>
#include <osg/Notify>
#include <osg/MatrixTransform>
#include <osg/Texture2D>
#include <osg/TextureRectangle>
#include <osg/ColorMask>
#include <osg/Material>
#include <osg/Capability>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

#include <iostream>
#include <stdio.h>

#define NUM_TEXTURES 1

// The quad geometry is used by the render to texture camera to generate 
multiple textures.
osg::Group* createRTTQuad(unsigned int tex_width, unsigned int tex_height, 
bool useHDR)
{
    osg::Group *top_group = new osg::Group;

    osg::ref_ptr<osg::Geode> quad_geode = new osg::Geode;

    osg::ref_ptr<osg::Vec3Array> quad_coords = new osg::Vec3Array; // 
vertex coords
    // counter-clockwise
    quad_coords->push_back(osg::Vec3d(0, 0, -1));
    quad_coords->push_back(osg::Vec3d(1, 0, -1));
    quad_coords->push_back(osg::Vec3d(1, 1, -1));
    quad_coords->push_back(osg::Vec3d(0, 1, -1));

    osg::ref_ptr<osg::Vec2Array> quad_tcoords = new osg::Vec2Array; // 
texture coords
    quad_tcoords->push_back(osg::Vec2(0, 0));
    quad_tcoords->push_back(osg::Vec2(tex_width, 0));
    quad_tcoords->push_back(osg::Vec2(tex_width, tex_height));
    quad_tcoords->push_back(osg::Vec2(0, tex_height));

    osg::ref_ptr<osg::Geometry> quad_geom = new osg::Geometry;
    osg::ref_ptr<osg::DrawArrays> quad_da = new 
osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4);

    quad_geom->setVertexArray(quad_coords.get());
    quad_geom->setTexCoordArray(0, quad_tcoords.get());
    quad_geom->addPrimitiveSet(quad_da.get());

    osg::StateSet *stateset = quad_geom->getOrCreateStateSet();
    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);

    stateset->addUniform(new osg::Uniform("width", (int)tex_width));

    // Attach shader, glFragData is used to create data for multiple render 
targets
static const char *shaderSource = {
"uniform int width;"
"uniform sampler2D tex; \n"
"void main(void)\n"
"{\n"
"    gl_FragData[0] = texture2D( tex, gl_TexCoord[0].st);\n"
"}\n"
};

osg::ref_ptr<osg::Shader> fshader = new osg::Shader(osg::Shader::FRAGMENT, 
shaderSource);
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(fshader.get());
stateset->setAttributeAndModes(program.get(), osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE);

osg::ref_ptr<osg::Image> image = osgDB::readImageFile("Images/man.jpg");
osg::Texture2D * texture1 = new osg::Texture2D;
texture1->setDataVariance(osg::Object::DYNAMIC); // protect from being 
optimized away as static state.
texture1->setImage(image);
stateset->setTextureAttributeAndModes(0, texture1, osg::StateAttribute::ON);

stateset->addUniform(new osg::Uniform("tex", 0));

    quad_geode->addDrawable(quad_geom.get());

    top_group->addChild(quad_geode.get());

    return top_group;
}

// Here a scene consisting of a single quad is created. This scene is 
viewed by the screen camera.
// The quad is textured using a shader and the multiple textures generated 
in the RTT stage.
osg::Node* createScene(osg::Node* cam_subgraph, unsigned int tex_width, 
unsigned int tex_height, bool useHDR, bool useImage, bool useMultiSample)
{
    if (!cam_subgraph) return 0;

    // create a group to contain the quad and the pre render camera.
    osg::Group* parent = new osg::Group;

    // textures to render to and to use for texturing of the final quad
    osg::TextureRectangle* textureRect = new osg::TextureRectangle;
textureRect = new osg::TextureRectangle;
textureRect->setTextureSize(tex_width, tex_height);
textureRect->setInternalFormat(GL_RGBA);
textureRect->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
textureRect->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);


    // first create the geometry of the quad
    {
        osg::Geometry* polyGeom = new osg::Geometry();

        polyGeom->setSupportsDisplayList(false);

        osg::Vec3Array* vertices = new osg::Vec3Array;
        osg::Vec2Array* texcoords = new osg::Vec2Array;

        vertices->push_back(osg::Vec3d(0,0,0));
        texcoords->push_back(osg::Vec2(0,0));

        vertices->push_back(osg::Vec3d(1,0,0));
        texcoords->push_back(osg::Vec2(tex_width,0));

        vertices->push_back(osg::Vec3d(1,0,1));
        texcoords->push_back(osg::Vec2(tex_width,tex_height));

        vertices->push_back(osg::Vec3d(0,0,1));
        texcoords->push_back(osg::Vec2(0,tex_height));

        polyGeom->setVertexArray(vertices);
        polyGeom->setTexCoordArray(0,texcoords);

        polyGeom->addPrimitiveSet(new 
osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertices->size()));

        // now we need to add the textures (generated by RTT) to the 
Drawable.
        osg::StateSet* stateset = new osg::StateSet;
stateset->setTextureAttributeAndModes(0, textureRect, 
osg::StateAttribute::ON);

        polyGeom->setStateSet(stateset);

static const char *shaderSource = {
"uniform sampler2DRect textureID0;\n"
"void main(void)\n"
"{\n"
"    gl_FragData[0] = vec4(texture2DRect( textureID0, gl_TexCoord[0].st 
).rgb, 1);  \n"
"}\n"
};

osg::ref_ptr<osg::Shader> fshader = new osg::Shader(osg::Shader::FRAGMENT, 
shaderSource);
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(fshader.get());
stateset->setAttributeAndModes(program.get(), osg::StateAttribute::ON | 
osg::StateAttribute::OVERRIDE);

        stateset->addUniform(new osg::Uniform("textureID0", 0));

        //stateset->setDataVariance(osg::Object::DYNAMIC);

        osg::Geode* geode = new osg::Geode();
        geode->addDrawable(polyGeom);

        parent->addChild(geode);
    }

    // now create the camera to do the multiple render to texture
    {
        osg::Camera* camera = new osg::Camera;

        // set up the background color and clear mask.
        camera->setClearColor(osg::Vec4(1.0f,0.0f,1.0f,1.0f));
        camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // the camera is going to look at our input quad
        camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1,0,1));
        camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
        camera->setViewMatrix(osg::Matrix::identity());

        // set viewport
        camera->setViewport(0, 0, tex_width, tex_height);

        // set the camera to render before the main camera.
        camera->setRenderOrder(osg::Camera::PRE_RENDER);

        // tell the camera to use OpenGL frame buffer objects
        
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);

        // attach the textures to use
camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), 
textureRect, 0, 0, false, 4, 4);

osg::Image* image = new osg::Image;
image->allocateImage(tex_width, tex_height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
// attach the image so its copied on each frame.
camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), 
image);

// push back the image to the texture
textureRect->setImage(0, image);
        // add the subgraph to render
        camera->addChild(cam_subgraph);

        parent->addChild(camera);
    }

    return parent;
}

int main( int argc, char **argv )
{
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    // construct the viewer.
    osgViewer::Viewer viewer(arguments);

    unsigned tex_width  = 512;
    unsigned tex_height = 512;

    osg::Group* subGraph = createRTTQuad(tex_width, tex_height, false);

    osg::Group* rootNode = new osg::Group();
    rootNode->addChild(createScene(subGraph, tex_width, tex_height, false, 
false, false));

    // add model to the viewer.
    viewer.setSceneData( rootNode );

    return viewer.run();
}



-- 
You received this message because you are subscribed to the Google Groups "OpenSceneGraph Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osg-users+unsubscribe at googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osg-users/f454e071-42a4-4a70-87d3-06ef15f69f10o%40googlegroups.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20200622/86e3226f/attachment.html>


More information about the osg-users mailing list