Hi all

I want to dynamically connect post processing of my rendered output. But when I 
do so my attach texture simply becomes black. Below is a GUIEventHandler that 
tries to hock a post rendering camera into the pipeline. If I move out the code 
block in the EventHandler to run it before "viewer.run()" everything works as 
expected and the main camera renders nicely to the texture. Is it even possible 
to dynamically connect post effect like this at runtime?


osg::Program* getShader()
{
        osg::Shader* fragObject = new osg::Shader(osg::Shader::FRAGMENT);
        osg::Shader* vertObject = new osg::Shader(osg::Shader::VERTEX);

        fragObject->setShaderSource(
                "uniform sampler2D tex0; \n"
                "\n"
                "void main() \n"
                "{ \n"
                " float dist = 0.02;"
                "       gl_FragColor = texture2D( tex0, gl_TexCoord[0].xy); \n"
                "       gl_FragColor += texture2D( tex0, gl_TexCoord[0].xy + 
vec2(dist,0)); \n"
                "       gl_FragColor += texture2D( tex0, gl_TexCoord[0].xy + 
vec2(-dist,0)); \n"
                "       gl_FragColor += texture2D( tex0, gl_TexCoord[0].xy + 
vec2(0,dist)); \n"
                "       gl_FragColor += texture2D( tex0, gl_TexCoord[0].xy + 
vec2(0,-dist)); \n"
                "       gl_FragColor *= 1.0/5.0;\n"
                "} \n");

        vertObject->setShaderSource(
                "uniform sampler2D tex0; \n"
                "\n"
                "void main()\n"
                "{ \n"
                "       gl_TexCoord[0] = gl_MultiTexCoord0; \n"
                "       gl_Position = ftransform(); \n"
                "} \n");

        osg::Program* programObject = new osg::Program;

        programObject->addShader(fragObject);
        programObject->addShader(vertObject);

        return programObject;
}

osg::Texture* createRenderTexture( int tex_width, int tex_height, bool depth )
{
        // create simple 2D texture
        osg::Texture2D* texture2D = new osg::Texture2D;
        texture2D->setTextureSize(tex_width, tex_height);
        texture2D->setResizeNonPowerOfTwoHint(false);
        texture2D->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
        texture2D->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
        
texture2D->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
        
texture2D->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
        texture2D->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));

        // setup float format
        if (!depth)
        {
                texture2D->setInternalFormat(GL_RGBA16F_ARB);
                texture2D->setSourceFormat(GL_RGBA);
                texture2D->setSourceType(GL_FLOAT);
        }else{
                texture2D->setInternalFormat(GL_DEPTH_COMPONENT);
        }

        return texture2D;
}

osg::Group* createQuad( osg::Texture* pSourceTexture )
{
        osg::Geode *geode = new osg::Geode;
        osg::Geometry *geo = new osg::Geometry;

        osg::ref_ptr<osg::Program> program = getShader();

        float scale = 0.25f;

        osg::Vec3Array *vx = new osg::Vec3Array;
        vx->push_back(osg::Vec3( 1.0, 0, -1.0) * scale);
        vx->push_back(osg::Vec3(-1.0, 0, -1.0) * scale);
        vx->push_back(osg::Vec3(-1.0, 0,  1.0) * scale);
        vx->push_back(osg::Vec3( 1.0, 0,  1.0) * scale);
        geo->setVertexArray(vx);

        osg::Vec3Array *nx = new osg::Vec3Array;
        nx->push_back(osg::Vec3(0, -1, 0));
        geo->setNormalArray(nx);
        geo->setNormalBinding(osg::Geometry::BIND_OVERALL);

        // Set texture coordinates
        osg::Vec2Array *tx = new osg::Vec2Array;
        tx->push_back(osg::Vec2(0, 0));
        tx->push_back(osg::Vec2(1, 0));
        tx->push_back(osg::Vec2(1, 1));
        tx->push_back(osg::Vec2(0, 1));
        geo->setTexCoordArray(0, tx);
        geo->setTexCoordArray(1, tx);

        geo->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));

        geode->getOrCreateStateSet();
        geode->getStateSet()->setTextureAttributeAndModes(0, pSourceTexture);
        geode->getStateSet()->addUniform(new osg::Uniform("tex0", 0));

        geode->getStateSet()->setAttributeAndModes(
                program,
                osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

        geode->addDrawable(geo);
        osg::Group* group = new osg::Group;
        group->addChild(geode);
        return group;
}


        class postSwitch :public osgGA::GUIEventHandler
        {
        public:
                postSwitch(osg::Camera* camera):
                        _cam(camera)
                {};

                /** Handle events, return true if handled, false otherwise. */
                virtual bool handle(const osgGA::GUIEventAdapter& 
ea,osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv)
                {
                        if (ea.getKey() == 'k')
                        {

                                //std::cout << arguments.getApplicationName() 
<<": No data loaded" << std::endl;
                                //return 1;

                                osg::Camera* sceneCamera = _cam.get();
                                sceneCamera->setViewMatrixAsLookAt(osg::Vec3(0, 
-1, 0), osg::Vec3(0, 0, 0), osg::Vec3(0, 0, 1));
                                
sceneCamera->setProjectionMatrixAsPerspective(45,1,1,200);

                                const osg::Viewport* pViewport = 
sceneCamera->getViewport();
                                int x = pViewport->x();
                                int y = pViewport->y();
                                unsigned int width = pViewport->width()/2;
                                unsigned int height = pViewport->height()/2;

                                sceneCamera->setViewport(0,0,512,512);

                                osg::Camera* rttCam = new osg::Camera();
                                rttCam->setName("RTT Project Camera");
                                rttCam->setClearColor(osg::Vec4f(0.2f, 1.0f, 
0.2f, 1.0f));
                                rttCam->setViewport(x, y, width, height);
                                
rttCam->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);
                                rttCam->setViewMatrixAsLookAt(osg::Vec3(0, -1, 
0), osg::Vec3(0, 0, 0), osg::Vec3(0, 0, 1));
                                
rttCam->setProjectionMatrixAsPerspective(45,1,1,200);
                                //rttCam->setClearMask(GL_COLOR_BUFFER_BIT | 
GL_DEPTH_BUFFER_BIT);

                                
//rttCam->setGraphicsContext(sceneCamera->getGraphicsContext());
                                
rttCam->setRenderOrder(osg::Camera::RenderOrder::POST_RENDER);

                                // set the view matrix   
                                
rttCam->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                                rttCam->setAllowEventFocus(false);

                                osg::Texture* pTex = createRenderTexture( 512, 
512, false );
                                osg::Node* pQuad = createQuad(pTex);
                                osg::Group* pGroup = new osg::Group;
                                pGroup->addChild(pQuad);

                                
sceneCamera->attach(osg::Camera::COLOR_BUFFER,pTex);

                                rttCam->addChild(pGroup);
                                sceneCamera->addChild(rttCam);
                                return true;
                        }
                        return false;
                }

                osg::ref_ptr<osg::Camera> _cam;

        }; 

Best Regards RagnarHammarqvist
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to