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