Hi Sebastian,
here you can find a minimal compileable example :


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_TexCoord[0].xy);\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);
     
           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",osg::Uniform::SAMPLER_2D));
           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("cessna.osg"); 
        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;
}





Thank you!

Cheers,
Andrea[/code]

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





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

Reply via email to