I tried it with the blend functions set up properly but I still run into
something. I will include some code:
Code:
//set up fragment color raster
osg::TextureRectangle* colorsRect;
colorsRect = new osg::TextureRectangle;
colorsRect->setTextureSize(screenWidth, screenHeight);
colorsRect->setInternalFormat(GL_RGBA32F_ARB);
colorsRect->setSourceFormat(GL_RGBA);
colorsRect->setSourceType(GL_FLOAT);
colorsRect->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
colorsRect->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
//set up fragment color raster 2 for water
osg::TextureRectangle* waterRect;
waterRect = new osg::TextureRectangle;
waterRect->setTextureSize(screenWidth, screenHeight);
waterRect->setInternalFormat(GL_RGBA32F_ARB);
waterRect->setSourceFormat(GL_RGBA);
waterRect->setSourceType(GL_FLOAT);
waterRect->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
waterRect->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
//create quad that will be rendered on screen
osg::Geometry* polyGeom = new osg::Geometry();
polyGeom->setSupportsDisplayList(false);
osg::Vec3Array* vertices = new osg::Vec3Array;
osg::Vec2Array* texcoords = new osg::Vec2Array;
vertices->push_back(osg::Vec3d(0,0,0));
texcoords->push_back(osg::Vec2(0,0));
vertices->push_back(osg::Vec3d(1,0,0));
texcoords->push_back(osg::Vec2(screenWidth,0));
vertices->push_back(osg::Vec3d(1,1,0));
texcoords->push_back(osg::Vec2(screenWidth,screenHeight));
vertices->push_back(osg::Vec3d(0,1,0));
texcoords->push_back(osg::Vec2(0,screenHeight));
polyGeom->setVertexArray(vertices);
polyGeom->setTexCoordArray(0,texcoords);
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
polyGeom->setColorArray(colors);
polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
polyGeom->addPrimitiveSet(new
osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertices->size()));
osg::Geode* geode = new osg::Geode();
geode->addDrawable(polyGeom);
rootNode->addChild(geode);
osg::StateSet* stateset = new osg::StateSet;
stateset->addUniform(new osg::Uniform("colorsRect", 0));
stateset->addUniform(new osg::Uniform("normalsRect", 1));
stateset->addUniform(new osg::Uniform("positionsRect", 2));
stateset->addUniform(new osg::Uniform("waterRect", 3));
stateset->setTextureAttributeAndModes(0, colorsRect,
osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(1, normalsRect,
osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(2, positionsRect,
osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(3, waterRect,
osg::StateAttribute::ON);
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
polyGeom->setStateSet(stateset);
//set up the scene camera
osg::ref_ptr<osg::Camera> camera = new osg::Camera();
camera->setViewport(new osg::Viewport(0,0,screenWidth,screenHeight));
camera->setProjectionMatrixAsPerspective(30.0, 16.f/9.f, 0.5, 10000);
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//camera->setClearColor(fog->getFogColor());
camera->setClearColor(osg::Vec4(0,0,0,0));
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
camera->addChild(worldNode); //add the world to the world camera
//camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0),
colorsRect, 0, 0, false, 4, 4);
//camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER1),
normalsRect, 0, 0, false, 4, 4);
//camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER2),
positionsRect, 0, 0, false, 4, 4);
camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0),
colorsRect);
camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER1),
normalsRect);
camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER2),
positionsRect);
camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER3),
waterRect);
osg::ref_ptr<osg::BlendFunc> blendFunct = new
osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
camera->getOrCreateStateSet()->setAttributeAndModes(blendFunct,
osg::StateAttribute::ON);
camera->getOrCreateStateSet()->setMode(GL_BLEND,
osg::StateAttribute::ON); //blend
waterNode = new osg::Group;
waterNode->getOrCreateStateSet()->setMode( GL_CULL_FACE,
osg::StateAttribute::OFF);
setupWaterTexture();
waterNode->getOrCreateStateSet()->setAttributeAndModes(shaders.getWaterShader(),
osg::StateAttribute::ON);
osgNode->addChild(waterNode);
osg::ref_ptr<osg::Depth> depth = new osg::Depth;
depth->setWriteMask( false );
waterNode->getOrCreateStateSet()->setAttributeAndModes( depth,
osg::StateAttribute::ON );
waterNode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
//transparancy hint
above the relevant parts of the code...
now the relevant parts of the fragment shaders:
For terrain:
Code:
gl_FragData[0] = texture2D(dirt,gl_TexCoord[0].st) * mix(gl_Color,
vec4(1, 1, 1, 1) , smoothFactor);
gl_FragData[1] = vec4(transpose(gl_NormalMatrix) * normal,0); //save
the world-space normal, cause eye space is too hard or something
gl_FragData[2] = invViewMatrix * eyeVec;
gl_FragData[3] = vec4(0,0,0,0);
for water:
Code:
gl_FragData[0] = vec4(0,0,0,0);
gl_FragData[1] = vec4(0,0,0,0);
gl_FragData[2] = vec4(0,0,0,0);
gl_FragData[3] = vec4(0,1,0,1);
for the final shader:
Code:
vec4 color = vec4(texture2DRect( colorsRect, gl_TexCoord[0].st ).rgb,
1);
vec4 waterColor = texture2DRect( waterRect, gl_TexCoord[0].st );
gl_FragColor=waterColor;
return;
so basically I'm just showing the 4th buffer, which should contain green pixel
where there is water.
now when I start it up, everything is black... but when I change this
gl_FragData[0] = vec4(0,0,0,0); to gl_FragData[0] = vec4(0,0,0,1);, then
suddenly I do see green pixels where there is water.
So changing the alpha value of what I write to buffer 0 seems to effect the
blending in buffer 3... or something like that
So my guess is that in the blending function, the SRC_ALPHA from the FIRST
buffer is always used, even when it's dealing with buffer 2, 3 and 4. or do you
have another explanation?
If I use an extra pass I can get rid of these problems and I will probably do
so to make it easier and more logical, but I'm still curious to what happens
here, and if my guess is correct and if there is a way to 'fix' this. Unless I
did something else wrong, in case I hope you can point out the mistake!
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=57150#57150
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org