Hi I try to implement cellular automata clouds on OSG and have some problem
1) I can’t use (or don’t know) ping-pong rendering technique as described here
http://www.m3xbox.com/GPU_blog/?m=200712
Because when I attach 2 textures to camera FBO in rendering loop camera render
to 2 FBO but I need to change dynamically which draw buffer I need to draw/
I’ve red about RenderStage but how to control it is unclear for me. I’ve make a
workaround that create another camera that render FBO texture to another FBO
texture that can I attach in 1 stage to calculate cellular automata.
2) I’d like to do RTT rendering not in every frame. But As I understand OSG
create rendercashe to strore rendering order how can I dynamically attach and
remove camera from rendering order?
See my example. If anyone is interested in my program I can share.
Thanx in advance
Roman
/* OpenSceneGraph example, osgmultiplerendertargets.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <osg/GLExtensions>
#include <osg/Node>
#include <osg/Geometry>
#include <osg/Notify>
#include <osg/MatrixTransform>
#include <osg/Texture2D>
#include <osg/TextureRectangle>
#include <osg/ColorMask>
#include <osg/Material>
#include <osg/ClampColor>
#include <osgDB/ReadFile>
#include <osgDB/FileUtils>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgViewer/Viewer>
#include <iostream>
float random(float min,float max) { return min +
(max-min)*(float)rand()/(float)RAND_MAX; }
osgViewer::Viewer viewer;
osg::ref_ptr<osg::Texture2D> LTexture0 = new osg::Texture2D;
osg::ref_ptr<osg::Texture2D> LTexture1 = new osg::Texture2D;
osg::ref_ptr<osg::Texture2D> LTexture2 = new osg::Texture2D;
osg::ref_ptr<osg::Texture2D> LTexture3 = new osg::Texture2D;
osg::Texture2D* noise_tex= new osg::Texture2D;
osg::Texture2D* elipsoid_tex= new osg::Texture2D;
osg::ref_ptr<osg::Camera> cellCamera = new osg::Camera;
osg::ref_ptr<osg::Camera> cellCamera1 = new osg::Camera;
osg::ref_ptr<osg::Camera> cellCamera2 = new osg::Camera;
osg::ref_ptr<osg::Camera> finalCamera = new osg::Camera;
static bool seq = true;
osg::Uniform* inputtex = new osg::Uniform("inputtex",0);
osg::Uniform* outputtex = new osg::Uniform("outputtex",1);
osg::Uniform* fNoiseOffsetExtX = new osg::Uniform("fNoiseOffsetExtX",0.02f);
osg::Uniform* fNoiseOffsetExtY = new osg::Uniform("fNoiseOffsetExtY",0.02f);
osg::Uniform* fNoiseOffsetHumX = new osg::Uniform("fNoiseOffsetHumX",0.02f);
osg::Uniform* fNoiseOffsetHumY = new osg::Uniform("fNoiseOffsetHumY",0.02f);
osg::Uniform* fNoiseOffsetActX = new osg::Uniform("fNoiseOffsetActX",0.02f);
osg::Uniform* fNoiseOffsetActY = new osg::Uniform("fNoiseOffsetActY",0.02f);
class UniformVarying : public osg::Uniform::Callback
{
public:
virtual void operator () (osg::Uniform* uniform, osg::NodeVisitor* nv)
{
const osg::FrameStamp* fs = nv->getFrameStamp();
double simulationTime = fs->getSimulationTime();
if (_firstCall)
{
_firstCall = false;
_startTime = simulationTime;
}
_time = simulationTime-_startTime;
uniform->set(_time);
_startTime = simulationTime;
// std::cout<<_time<<std::endl;
fNoiseOffsetActX->set(random(0,0.5));
fNoiseOffsetActY->set(random(0,0.5));
fNoiseOffsetHumX->set(random(0,0.5));
fNoiseOffsetHumY->set(random(0,0.5));
fNoiseOffsetExtX->set(random(0,0.5));
fNoiseOffsetExtY->set(random(0,0.5));
osg::ref_ptr<osg::StateSet> cellstateset1
=cellCamera->getOrCreateStateSet();
osg::ref_ptr<osg::StateSet> cellstateset2
=cellCamera2->getOrCreateStateSet();
osg::ref_ptr<osg::StateSet> finalstateset1
=finalCamera->getOrCreateStateSet();
if(seq)
{
inputtex->set(0);
outputtex->set(1);
//
cellstateset2->setTextureAttributeAndModes(0,LTexture1.get(),osg::StateAttribute::ON);
//
finalstateset1->setTextureAttributeAndModes(0,LTexture1.get(),osg::StateAttribute::ON);
// std::cout<<"seq"<<std::endl;
}
else
{
inputtex->set(1);
outputtex->set(0);
//cellstateset2->setTextureAttributeAndModes(0,LTexture0.get(),osg::StateAttribute::ON);
//
finalstateset1->setTextureAttributeAndModes(0,LTexture0.get(),osg::StateAttribute::ON);
///std::cout<<"!seq"<<std::endl;
}
seq=!seq;
}
bool _firstCall;
float _startTime;
float _time;
};
int main( int argc, char **argv )
{
osg::Group* rootNode = new osg::Group();
float g_ViewportWidth=1024;
float g_ViewportHeight=512;
viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
viewer.setUpViewInWindow(10,10,g_ViewportWidth,g_ViewportHeight);
/* float tex_width = 2048;
float tex_height = 1024;
int tex_segment_width=512;
int tex_segment_height=128;
*/
float tex_width = 1024;
float tex_height = 512;
int tex_segment_width=256;
int tex_segment_height=64;
osg::Group* root = new osg::Group();
osg::Image* image = osgDB::readImageFile("1.rgb");
noise_tex->setImage(image);
noise_tex->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::MIRROR);
noise_tex->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::MIRROR);
osg::Image* image2 = osgDB::readImageFile("elipsoid.rgb");
elipsoid_tex->setImage(image2);
elipsoid_tex->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT);
elipsoid_tex->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT);
/* osg::Image* image3 = osgDB::readImageFile("1.rgb");
LTexture2->setImage(image3);
LTexture2->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::MIRROR);
LTexture2->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::MIRROR);
*/
LTexture0->setTextureSize(tex_width, tex_height);
LTexture0->setInternalFormat(GL_RGBA);
/* LTexture0->setInternalFormat(GL_RGBA16F_ARB);
LTexture0->setSourceFormat(GL_RGBA);
LTexture0->setSourceType(GL_FLOAT);
*/
LTexture0->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
LTexture0->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
LTexture1->setTextureSize(tex_width, tex_height);
LTexture1->setInternalFormat(GL_RGBA);
/* LTexture1->setInternalFormat(GL_RGBA16F_ARB);
LTexture1->setSourceFormat(GL_RGBA);
LTexture1->setSourceType(GL_FLOAT);
*/
LTexture1->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
LTexture1->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
LTexture2->setTextureSize(tex_width, tex_height);
LTexture2->setInternalFormat(GL_RGBA16F_ARB);
LTexture2->setSourceFormat(GL_RGBA);
LTexture2->setSourceType(GL_FLOAT);
LTexture2->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::NEAREST);
LTexture2->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST);
osg::ref_ptr<osg::Geode> geode_cell = new osg::Geode;
osg::ref_ptr<osg::Geometry> geom_cell
=osg::createTexturedQuadGeometry(osg::Vec3(0,0,-1),osg::Vec3(tex_width,0.0,-1.0),osg::Vec3(0.0,tex_height,-1.0));
geom_cell->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
geode_cell->addDrawable(geom_cell.get());
cellCamera->setName("cellCamera");
cellCamera->setClearColor(osg::Vec4f(0.0f,0.0f,0.0f,1.0f));
cellCamera->setProjectionMatrix(osg::Matrix::ortho2D(0,tex_width,0,tex_height));
cellCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
cellCamera->setViewMatrix(osg::Matrix::identity());
cellCamera->setViewport(0,0,tex_width,tex_height);
cellCamera->setRenderOrder(osg::Camera::PRE_RENDER);
cellCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
cellCamera->attach(osg::Camera::COLOR_BUFFER0,LTexture0.get());
cellCamera->addChild(geode_cell.get());
osg::ref_ptr<osg::StateSet> cellstateset
=cellCamera->getOrCreateStateSet();
cellstateset->setTextureAttributeAndModes(0,LTexture1.get(),osg::StateAttribute::ON);
cellstateset->setTextureAttributeAndModes(1,noise_tex,osg::StateAttribute::ON);
cellstateset->setTextureAttributeAndModes(2,elipsoid_tex,osg::StateAttribute::ON);
// cellstateset->setAttribute(clamp,
osg::StateAttribute::ON);
root->addChild(cellCamera.get());
osg::Program* cellprg = new osg::Program;
cellstateset->setAttribute(cellprg);
std::string VertexShaderFile =
osgDB::findDataFile("cell_vp.glsl");
std::string FragmentShaderFile =
osgDB::findDataFile("cell_fp.glsl");
cellprg->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX,VertexShaderFile));
cellprg->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT,
FragmentShaderFile));
cellstateset->addUniform(new
osg::Uniform("Cell_tex", 0));
cellstateset->addUniform(new
osg::Uniform("Noise_tex", 1));
cellstateset->addUniform(new
osg::Uniform("Elipsoid_tex", 2));
cellstateset->addUniform(new
osg::Uniform("fWidth", tex_width));
cellstateset->addUniform(new
osg::Uniform("fHeight", tex_height));
cellstateset->addUniform(new
osg::Uniform("fSegmentWidth", tex_segment_width));
cellstateset->addUniform(new
osg::Uniform("fSegmentHeight", tex_segment_height));
cellstateset->addUniform(new
osg::Uniform("fOffsetX1", 1/tex_width));
cellstateset->addUniform(new
osg::Uniform("fOffsetZ1", 1/tex_height));
cellstateset->addUniform(new
osg::Uniform("fOffsetX2", 2/tex_width));
cellstateset->addUniform(new
osg::Uniform("fOffsetZ2", 2/tex_height));
cellstateset->addUniform(fNoiseOffsetExtX);
cellstateset->addUniform(fNoiseOffsetExtY);
cellstateset->addUniform(fNoiseOffsetHumX);
cellstateset->addUniform(fNoiseOffsetHumY);
cellstateset->addUniform(fNoiseOffsetActX);
cellstateset->addUniform(fNoiseOffsetActY);
osg::Uniform* dtime = new
osg::Uniform("dtime",0.02f);
cellstateset->addUniform(dtime);
cellstateset->addUniform(inputtex);
cellstateset->addUniform(outputtex);
dtime->setUpdateCallback(new UniformVarying);
dtime->setDataVariance(osg::Object::DYNAMIC);
outputtex->setDataVariance(osg::Object::DYNAMIC);
cellstateset->setDataVariance(osg::Object::DYNAMIC);
osg::ref_ptr<osg::Geode> geode_cell1 = new
osg::Geode;
osg::ref_ptr<osg::Geometry> geom_cell1
=osg::createTexturedQuadGeometry(osg::Vec3(0,0,-1),osg::Vec3(tex_width,0.0,-1.0),osg::Vec3(0.0,tex_height,-1.0));
geom_cell1->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
geode_cell1->addDrawable(geom_cell1.get());
cellCamera1->setName("cellCamera");
cellCamera1->setClearColor(osg::Vec4f(0.0f,0.0f,0.0f,1.0f));
cellCamera1->setProjectionMatrix(osg::Matrix::ortho2D(0,tex_width,0,tex_height));
cellCamera1->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
cellCamera1->setViewMatrix(osg::Matrix::identity());
cellCamera1->setViewport(0,0,tex_width,tex_height);
cellCamera1->setRenderOrder(osg::Camera::POST_RENDER,10);
cellCamera1->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
cellCamera1->attach(osg::Camera::COLOR_BUFFER0,LTexture1.get());
cellCamera1->addChild(geode_cell1.get());
osg::ref_ptr<osg::StateSet> cellstateset1
=cellCamera1->getOrCreateStateSet();
cellstateset1->setTextureAttributeAndModes(0,LTexture0.get(),osg::StateAttribute::ON);
root->addChild(cellCamera1.get());
osg::ref_ptr<osg::Geode> geode_cell2 = new osg::Geode;
osg::ref_ptr<osg::Geometry> geom_cell2
=osg::createTexturedQuadGeometry(osg::Vec3(0,0,-1),osg::Vec3(tex_width,0.0,-1.0),osg::Vec3(0.0,tex_height,-1.0));
geom_cell2->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
geode_cell2->addDrawable(geom_cell2.get());
cellCamera2->setName("cellCamera");
cellCamera2->setClearColor(osg::Vec4f(0.0f,0.0f,0.0f,1.0f));
cellCamera2->setProjectionMatrix(osg::Matrix::ortho2D(0,tex_width,0,tex_height));
cellCamera2->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
cellCamera2->setViewMatrix(osg::Matrix::identity());
cellCamera2->setViewport(0,0,tex_width,tex_height);
cellCamera2->setRenderOrder(osg::Camera::POST_RENDER,11);
cellCamera2->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
cellCamera2->attach(osg::Camera::COLOR_BUFFER0,LTexture2.get());
cellCamera2->addChild(geode_cell2.get());
osg::ref_ptr<osg::StateSet> cellstateset2
=cellCamera2->getOrCreateStateSet();
cellstateset2->setTextureAttributeAndModes(0,LTexture1.get(),osg::StateAttribute::ON);
osg::Program* cellprg2 = new osg::Program;
cellstateset2->setAttribute(cellprg2);
std::string VertexShaderFile2 =
osgDB::findDataFile("cell_vp.glsl");
std::string FragmentShaderFile2 =
osgDB::findDataFile("cell_fp_2.glsl");
cellprg2->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX,VertexShaderFile2));
cellprg2->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT,
FragmentShaderFile2));
cellstateset2->addUniform(new
osg::Uniform("Cell_tex", 0));
root->addChild(cellCamera2.get());
osg::ref_ptr<osg::Geode> geode_final = new osg::Geode;
osg::ref_ptr<osg::Geometry> geom_final
=osg::createTexturedQuadGeometry(osg::Vec3(0,0,-1),osg::Vec3(g_ViewportWidth,0.0,-1.0),osg::Vec3(0.0,g_ViewportHeight,-1.0));
geom_final->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
geode_final->addDrawable(geom_final.get());
finalCamera->setName("finalCamera");
finalCamera->setClearColor(osg::Vec4f(0.0f,0.0f,0.0f,1.0f));
finalCamera->setProjectionMatrix(osg::Matrix::ortho2D(0,g_ViewportWidth,0,g_ViewportHeight));
finalCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
finalCamera->setViewMatrix(osg::Matrix::identity());
finalCamera->setViewport(0,0,g_ViewportWidth,g_ViewportHeight);
finalCamera->setRenderOrder(osg::Camera::POST_RENDER,12);
finalCamera->addChild(geode_final.get());
osg::ref_ptr<osg::StateSet> finalstateset
=finalCamera->getOrCreateStateSet();
finalstateset->setTextureAttributeAndModes(0,LTexture2.get(),osg::StateAttribute::ON);
osg::Program* finalprg = new
osg::Program;
finalstateset->setAttribute(finalprg);
std::string VertexShaderFile1 =
osgDB::findDataFile("cell_vp.glsl");
std::string FragmentShaderFile1 =
osgDB::findDataFile("cell_fp_viewer.glsl");
finalprg->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX,VertexShaderFile1));
finalprg->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT,
FragmentShaderFile1));
finalstateset->addUniform(new
osg::Uniform("Cell_tex", 0));
//finalstateset->setTextureAttributeAndModes(0,noise_tex,osg::StateAttribute::ON);
// finalstateset->setAttribute(clamp,
osg::StateAttribute::ON);
finalstateset->setDataVariance(osg::Object::DYNAMIC);
root->addChild(finalCamera.get());
viewer.setSceneData( root );
return viewer.run();
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org