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