Hello Andrea,

I didn't go through every line of code of your example, as it is far from being minimal. Maybe I'll dig into it later on - but it would be best if you'd assemble a minimal compileable example. Also I'd suggest trying to do some minimal debugging, i.e. don't try to do everything at once. Instead try to debug-out the render2texture from the first pass in your HUD to see what is going on.

cheers
Sebastian


Hi Sebastian,
tahnk you for your suggestions. I have taken some days to study your solutions 
and to apply them to my osg application. It seem that something is going on, 
but i still get some doubts and some errors.
In the following code, i simulate the use of two shader on the same 3D object 
(cessna.osg) using two PRE_RENDER camera : the first shader (test_Pass_0) 
change the object's color, the second shader (test_Pass_1) should apply a twist 
deformation on the same 3D Object.
Finally, i use the HUD camera to visualize the final effect ( a twisted and 
colored cessna).

So, briefly :
I use the PRE_RENDER CAMERA (first Camera) to fill the frame buffer with a 
texture (first texture) coming from the first shader.
A second PRE_RENDER CAMERA (second Camera), applies on the same object a twist 
deformation (with the vertex shader) and this second camera uses the first 
texture to get the color for the second shader (fragment shader). The
second camera fills the FBO for the next camera (HUD camera).

My doubt is : Is this approach correct?

The error is : "Warning: detected OpenGL error 'invalid value' at After 
Renderer::compile"
I get this error after the test_Pass_1.frag. What i see is the cessna.osg 
twisted, but completely black (it seems that the test_pass_1.frag doesn't see
the correct sampler2D input (previousTexture) coming from the first shader 
(test_Pass_0.frag). (I report a snapshot about the this result).


First i report the osg code.

Code for HUD CAMERA : the image input means the result of the test_Pass_0 shader


Code:


// 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();
     }

// this code coming from openscenegraph 3 cookbook
  osg::Geode* createScreenQuad( float width, float height, float scale )
     {
         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();
     }


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;
}




The following code, applies the first shader effect : simply, change object's 
color


Code:

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();
firstStateset->addUniform(new osg::Uniform("fVal",0.5f),osg::StateAttribute::ON);

        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();
}





SingleTexturePass returns a texture that can be used by another shader.

The DoubleTexturePass, calls the singleTexturePass first, and then uses the 
result as input for the second shader :


Code:



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,1);
        
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::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();
}







In the main, i use :


Code:


int main( int argc, char** argv )
{
....

osg::Texture2D* 
finalTexture=DoubleTexturePass(main_root.get(),myNode,osg::Vec4(0.3,0.4,0.5,1.0),
 1024, 512);

ApplyHUDCamera(finalTexture,main_root.get());

...
}





About the shaders, i use the following code :

PASS0: vertex and shader : only color


Code:

// test_pass_0.vert

varying vec4 COLOR;
void main()
{
COLOR = gl_Color;
  gl_Position = ftransform();
}

// test_pass_0.frag
varying vec4 COLOR;
void main()
{
   vec4 newcolor = COLOR;
   COLOR.r = newcolor.b/2;
   COLOR.g = newcolor.r/3;
   COLOR.b = newcolor.g;
   gl_FragColor = COLOR;
}





PASS1: vertex and shader : Twist


Code:


//test_Pass_1.vert

uniform float time;
uniform float height;
uniform float angle_deg_max;

varying vec2 texture_coordinate;
varying vec4  normal, lightDir[3], eyeVec;
vec4 DoTwist( vec4 pos, float t )
{
     float st = sin(t);
     float ct = cos(t);
     vec4 new_pos;
new_pos.x = pos.x*ct - pos.z*st;
     new_pos.z = pos.x*st + pos.z*ct;
new_pos.y = pos.y;
     new_pos.w = pos.w;

     return( new_pos );
}
void main()
{
   float angle_deg = angle_deg_max*sin(time);
   float angle_rad = angle_deg * 3.14159 / 180.0;
float ang = (height*0.5 + gl_Vertex.y)/height * angle_rad; vec4 twistedPosition = DoTwist(gl_Vertex, ang);
   // vec4 twistedNormal = DoTwist(vec4(gl_Normal, ang);

   gl_Position = gl_ModelViewProjectionMatrix * twistedPosition;
vec3 vVertex = vec3(gl_ModelViewMatrix * twistedPosition); // lightDir[0] = vec3(gl_LightSource[0].position.xyz - vVertex);
  // lightDir[1] = vec3(gl_LightSource[1].position.xyz - vVertex);
  // lightDir[2] = vec3(gl_LightSource[2].position.xyz - vVertex);
  // eyeVec = -vVertex;
// normal = gl_NormalMatrix * twistedNormal.xyz; //gl_TexCoord[0] = gl_MultiTexCoord0; texture_coordinate = vec2(gl_MultiTexCoord0); //gl_Position = ftransform();
}

//test_Pass_1.frag

uniform sampler2D previousTexture;
varying vec2 texture_coordinate;

void main()
{
   vec4 somecolor = texture2D(previousTexture, gl_TexCoord[0].xy);
   gl_FragColor =  somecolor;
}








Thank you!

Cheers,
Andrea

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





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

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

Reply via email to