Hi Andrea,

First of all there several errors.
The first one is where you assign the texture as input to your stateset:

for making this work you should write this:

       secondStateset->addUniform(new osg::Uniform("previousTexture",0));
secondStateset->setTextureAttributeAndModes(0,previousTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); Note the first line using the value 0 to bind the sampler to the same texture unit (0)

Secondly, for your test you are using a model without texture coordinates. This of course will not work if you want to use the gl_TexCoord attributes.
So try with another model if you need them.

Another problem was with your 2nd pass vertex/fragemt shader:
Either you'll have to use the built-in gl_TexCoord and write to in the vertex shader, or u have to use your varying "texture_coordinate" In your example you are writing the varying "texture_coordinate" in your vertex shader and reading the built-in (which you don't write to) in the fragment shader.

The result is surely not what you expected, but at least it is somehow projecting the result of the first frame to your model. I've taken the freedom to modify your shader a bit, but you'll still have to re-project the fragments to get the correct result if I understood you correctly.

I'm still wondering what you are trying to achieve exactly.

If there are further question, you can contact me directly via email


Attached you'll find the fixed sources:
<code>

#include <osg/Program>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgDB/FileUtils>
#include <osg/io_utils>
#include <osg/Texture2D>
#include <osg/Group>
#include <osg/Matrix>
#include <osg/MatrixTransform>
#include <osg/PolygonMode>

//////////////////////////////////////////////////////////////////
// Vertex shader pass 0 : Color
//
 char vertexShaderSourcePass_0[] =
       "varying vec4 COLOR;\n"
       "\n"
       "varying vec2 texcoord;\n"
       "\n"
       "void main(void)\n"
       "{\n"
       "    COLOR = gl_Color;\n"
       "    gl_Position = ftransform();\n"
       "}\n";

//////////////////////////////////////////////////////////////////
// fragment shader pass 0 : Color
//
    char fragmentShaderSourcePass_0[] =
        "varying vec4 COLOR; \n"
        "\n"
        "void main(void) \n"
        "{\n"
        "vec4 newcolor = COLOR;\n"
        "COLOR.r = newcolor.b/2;\n"
        "COLOR.g = newcolor.r/3;\n"
        "COLOR.b = newcolor.g + 0.1;\n"
        "    gl_FragColor =  COLOR; \n"
        "}\n";

//////////////////////////////////////////////////////////////////
// Vertex shader pass 1 : TWIST
//
     char vertexShaderSourcePass_1[] =
       "uniform float time;\n"
       "uniform float height;\n"
       "uniform float angle_deg_max;\n"
       "\n"
       "varying vec2 texture_coordinate;\n"
       "varying vec4  normal, lightDir[3], eyeVec;\n"
       "\n"
       "vec4 DoTwist( vec4 pos, float t )\n"
       "{\n"
       "    float st = sin(t);\n"
       "    float ct = cos(t);\n"
       "    vec4 new_pos;\n"
       "\n"
       "    new_pos.x = pos.x*ct - pos.z*st;\n"
       "    new_pos.z = pos.x*st + pos.z*ct;\n"
       "    new_pos.y = pos.y;\n"
       "    new_pos.w = pos.w;\n"
        "    return( new_pos );\n"
       "}\n"

       " void main()\n"
       "{ \n"
       "  float angle_deg = angle_deg_max*sin(time);\n"
       "  float angle_rad = angle_deg * 3.14159 / 180.0;\n"
       "  float ang = (height*0.5 + gl_Vertex.y)/height * angle_rad;\n"
       " vec4 twistedPosition = DoTwist(gl_Vertex, ang);\n"
       " // vec4 twistedNormal = DoTwist(vec4(gl_Normal, ang);\n"
       " gl_Position = gl_ModelViewProjectionMatrix * twistedPosition;\n"
       " vec3 vVertex = vec3(gl_ModelViewMatrix * twistedPosition);\n"
" // lightDir[0] = vec3(gl_LightSource[0].position.xyz - vVertex);\n" " // lightDir[1] = vec3(gl_LightSource[1].position.xyz - vVertex);\n" " // lightDir[2] = vec3(gl_LightSource[2].position.xyz - vVertex);\n"
       " // eyeVec = -vVertex;\n"
       "  // normal = gl_NormalMatrix * twistedNormal.xyz;\n"
       "  gl_TexCoord[0] = gl_MultiTexCoord0;\n"
       "   texture_coordinate = vec2(gl_MultiTexCoord0);\n"
       " //gl_Position = ftransform();\n"
       "}\n";

//////////////////////////////////////////////////////////////////
    // fragment shader pass 1 : TWIST
    //
    char fragmentShaderSourcePass_1[] =
        "uniform sampler2D previousTexture; \n"
        "varying vec2 texture_coordinate;\n"
        "\n"
        "void main(void) \n"
        "{\n"
" vec4 somecolor = texture2D(previousTexture, gl_FragCoord.xy / vec2(1024.0,512.0));\n"
        "  gl_FragColor = somecolor; \n"
        "}\n";

/*!
* \fn osg::Camera* createHUDCamera( double left, double right, double bottom, double top ) * \brief Create an HUD Camera (as Post Render). Contains the result of the shader multiple pass
*  this code coming from openscenegraph 3 cookbook
*/
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();
    }

/*!
* \fn osg::Geode* createScreenQuad( float width, float height, float scale=1.0f)
* \brief Create screen Quad for the HUD Camera
* this code coming from openscenegraph 3 cookbook
*/
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();
    }


/*!
* \fn  void ApplyHUDCamera(osg::Texture2D *image, osg::Group* root)
* \brief Visualiza the HUD CAMERA Result
*
*/
void ApplyHUDCamera(osg::Texture2D *image, osg::Group* root)
{
    std::cout << "APPLY HUD" << std::endl;
    {
        osg::ref_ptr<osg::Camera> mHudCamera;
        mHudCamera =  createHUDCamera(0.0, 1.0, 0.0, 1.0);
        mHudCamera->addChild( createScreenQuad(1.0f, 1.0f));
osg::ref_ptr<osg::StateSet> mStateset = mHudCamera->getOrCreateStateSet();
        mStateset->setTextureAttributeAndModes( 0, image );
        root->addChild(mHudCamera.get());
    }
    return;
}


/*!
* \fn osg::Texture2D* SingleTexturePass(osg::Group* root,osg::Node* viewnode,osg::Vec4 clearColor, int windowWidth, int windowHeight) * \brief Process the first shader effect. Use a PRE RENDER Camera and fills the FBO with the result of the first shader (test_Pass_0)
*/
osg::Texture2D* SingleTexturePass(osg::Group* root,osg::Node* viewnode,osg::Vec4 clearColor, int windowWidth, int windowHeight)
{
    std::cout << "FIRST PASS" << std::endl;

    osg::ref_ptr<osg::Texture2D> firstTexture = new osg::Texture2D;
    firstTexture->setTextureSize(windowWidth, windowHeight);
    firstTexture->setInternalFormat(GL_RGBA);
firstTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
firstTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
firstTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
firstTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
//firstTexture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));

    // set up the render to color texture camera.
    {
       osg::ref_ptr<osg::Camera> firstCamera = new osg::Camera;
       firstCamera->setName("FirstCamera");
       // firstCamera->setClearColor(clearColor);
       firstCamera->setViewport(0,0,windowWidth,windowHeight);
       //firstCamera->setClearStencil(0);
       //firstCamera->setClearDepth(0.0);
//firstCamera->setClearAccum(osg::Vec4(1.0,1.0,1.0,1.0));
//firstCamera->setClearMask(GL_COLOR_BUFFER_BIT); // | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//firstCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
//firstCamera->setCullingMode(osg::Camera::VIEW_FRUSTUM_SIDES_CULLING);
       //colorCamera->setViewport(the_viewport.get());
       //colorCamera->setProjectionMatrix(proj_matrix);
       //colorCamera->setViewMatrix(view_matrix);

       firstCamera->setRenderOrder(osg::Camera::PRE_RENDER,0);
firstCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
firstCamera->attach(osg::Camera::COLOR_BUFFER,firstTexture.get());
       firstCamera->addChild(viewnode);

osg::ref_ptr<osg::StateSet> firstStateset = firstCamera->getOrCreateStateSet(); //viewnode//
       osg::Program* firstProgram=new osg::Program();
firstProgram->addShader(new osg::Shader(osg::Shader::VERTEX, vertexShaderSourcePass_0)); firstProgram->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSourcePass_0));
       /*
osg::Shader* vertexShader = osgDB::readShaderFile(osg::Shader::VERTEX, "\\shaders\\shaders\\testMultipass\\test_Pass_0.vert");
       osg::Program* firstProgram=new osg::Program();
       if (!vertexShader)
       {
            std::cout << " No vertex Shader Loaded." << std::endl;
            return 0;
        }
       else
       {
std::cout << " Vertex Shader Loaded : test_Pass_0.vert " << std::endl;
       }
osg::Shader* fragShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders\\shaders\\testMultipass\\test_Pass_0.frag");
        if (!fragShader)
        {
            std::cout << " No fragment Shader Loaded." << std::endl;
            return 0;
        }
        else
        {
std::cout << " fragment Shader Loaded : test_Pass_0.frag " << std::endl;
        }
        firstProgram->addShader(vertexShader);
        firstProgram->addShader(fragShader);
        */
        firstStateset->setAttributeAndModes(firstProgram);
        root->addChild(firstCamera.get());
    }
  return firstTexture.get();
}



/*!
* \fn osg::Texture2D* DoubleTexturePass(osg::Group* root,osg::Node* viewnode,osg::Vec4 clearColor, int windowWidth, int windowHeight) * \brief Call the SingleTexturePass; Process the second shader effect. Use a PRE RENDER Camera and fills the FBO with the result of the second shader (test_Pass_1)
*/
osg::Texture2D* DoubleTexturePass(osg::Group* root,osg::Node* viewnode,osg::Vec4 clearColor, int windowWidth, int windowHeight)
{
osg::Texture2D* previousTexture=SingleTexturePass(root,viewnode,clearColor, windowWidth, windowHeight);

    std::cout << "Second PASS" << std::endl;

    osg::ref_ptr<osg::Texture2D> secondTexture = new osg::Texture2D;
    secondTexture->setTextureSize(windowWidth, windowHeight);
    secondTexture->setInternalFormat(GL_RGBA);
secondTexture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
secondTexture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
secondTexture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
secondTexture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);

    // set up the render to normal and depth texture camera.
    {
       osg::ref_ptr<osg::Camera> secondCamera = new osg::Camera;
       secondCamera->setName("SecondCamera");
       //secondCamera->setClearColor(clearColor);
       secondCamera->setViewport(0,0,windowWidth,windowHeight);
       secondCamera->setRenderOrder(osg::Camera::PRE_RENDER,0);
secondCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
secondCamera->attach(osg::Camera::COLOR_BUFFER,secondTexture.get());
       secondCamera->addChild(viewnode);
       secondCamera->setClearColor(osg::Vec4(0,0,0,1));

osg::ref_ptr<osg::StateSet> secondStateset = secondCamera->getOrCreateStateSet(); //viewnode

       osg::Timer_t startTick = osg::Timer::instance()->tick();

float fTime = 0.5; //(float) osg::Timer::instance()->getSecondsPerTick();

       float angle_deg_max = 15.0;

       float height = 5.0;

       secondStateset->addUniform(new osg::Uniform("height",height));
       secondStateset->addUniform(new osg::Uniform("time",fTime));
secondStateset->addUniform(new osg::Uniform("angle_deg_max",angle_deg_max));
       secondStateset->addUniform(new osg::Uniform("previousTexture",0));
secondStateset->setTextureAttributeAndModes(0,previousTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);

       osg::Program* secondProgram=new osg::Program();
secondProgram->addShader(new osg::Shader(osg::Shader::VERTEX, vertexShaderSourcePass_1)); secondProgram->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragmentShaderSourcePass_1));

       /*
osg::Shader* vertexShader2 = osgDB::readShaderFile(osg::Shader::VERTEX, "\\shaders\\shaders\\testMultipass\\test_Pass_1.vert");
       osg::Program* secondProgram=new osg::Program();
       if (!vertexShader2)
       {
            std::cout << " No vertex Shader Loaded." << std::endl;
            return 0;
        }
           else
        {
std::cout << " Vertex Shader Loaded : test_Pass_1.vert " << std::endl;
        }

osg::Shader* fragShader2 = osgDB::readShaderFile(osg::Shader::FRAGMENT, "shaders\\shaders\\testMultipass\\test_Pass_1.frag");
        if (!fragShader2)
        {
            std::cout << " No fragment Shader Loaded." << std::endl;
            return 0;
        }
        else
        {
std::cout << " fragment Shader Loaded : test_Pass_1.frag " << std::endl;
        }

        secondProgram->addShader(vertexShader2);
        secondProgram->addShader(fragShader2);
        */
        secondStateset->setAttributeAndModes(secondProgram);

        root->addChild(secondCamera.get());
    }

    return secondTexture.get();
}



int main( int argc, char** argv )
{
    osg::ArgumentParser arguments( &argc, argv );
     osg::ref_ptr<osg::Program> program =new osg::Program;
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Group> mainRoot = new osg::Group;
    osg::ref_ptr<osg::Node> root;
    osg::Matrix rootMatrix;
    rootMatrix.setTrans(0.0,0.0,0.0);
    osg::ref_ptr<osg::MatrixTransform> myNode=new osg::MatrixTransform();
    myNode->setMatrix(rootMatrix);
    root= osgDB::readNodeFile("mp40.osgt");
    if (!root.valid())
        {
            std::cout << "Error during model loading." << std::endl;
            return NULL;
        }
    myNode->addChild(root.get());

    // SINGLE PASS : WORKS
// osg::Texture2D* finalTexture=SingleTexturePass(mainRoot.get(),myNode.get(),osg::Vec4(0.3,0.4,0.5,1.0), 1024, 512);

// MULTIPLE PASS : DOESN'T WORK. Comment next line and uncomment the previous to see the single pass. osg::Texture2D* finalTexture=DoubleTexturePass(mainRoot.get(),myNode.get(),osg::Vec4(0.3,0.4,0.5,1.0), 1024, 512);

    ApplyHUDCamera(finalTexture,mainRoot.get());

    viewer.setSceneData(mainRoot.get() );

    viewer.setUpViewInWindow( 100, 100, 1124, 612 );
    viewer.run();
    return 0;
}


</code>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to