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