Hello,
I've cleaned my previous version of transformFeedBack example in order to use
TransformFeedbackBufferBinding and a DrawCallback
Code:
/* OpenSceneGraph example, osgtransformfeedback
*
* 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.
*/
/* file: examples/osgtransformfeedback/osgtransformfeedback.cpp
* author: Julien Valentin 2013-10-01
* copyright: (C) 2013
* license: OpenSceneGraph Public License (OSGPL)
*
* A demo of GLSL geometry shaders using OSG transform feedback
*
*/
/* OpenSceneGraph example, osgtransformfeedback
*
* 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.
*/
/* file: examples/osgtransformfeedback/osgtransformfeedback.cpp
* author: Julien Valentin 2013-10-01
* copyright: (C) 2013
* license: OpenSceneGraph Public License (OSGPL)
*
* A demo of GLSL geometry shaders using OSG transform feedback
*
*/
#include <osg/GL2Extensions>
#include <osg/Notify>
#include <osg/ref_ptr>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Point>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Program>
#include <osg/Shader>
#include <osg/BlendFunc>
#include <osg/Uniform>
#include <osgViewer/Viewer>
#include <osg/BufferIndexBinding>
#include <osgDB/WriteFile>
#include <iostream>
///////////////////////////////////////////////////////////////////////////
class SineAnimation: public osg::UniformCallback
{
public:
SineAnimation( float rate = 1.0f, float scale = 1.0f, float offset = 0.0f )
:
_rate(rate), _scale(scale), _offset(offset)
{}
void operator()( osg::Uniform* uniform, osg::NodeVisitor* nv )
{
float angle = _rate * nv->getFrameStamp()->getSimulationTime();
float value = sinf( angle ) * _scale + _offset;
uniform->set( value );
}
private:
const float _rate;
const float _scale;
const float _offset;
};
//////////////////////////////////////////////////////////////////////////////////////
namespace osg
{
class OSG_EXPORT TransformFeedBackDrawCallback: public Drawable::DrawCallback
{
protected:
std::vector<osg::ref_ptr<osg::TransformFeedbackBufferBinding> > _tfbbs;
GLuint _index;
public:
TransformFeedBackDrawCallback():Drawable::DrawCallback()
{
_type=0;
}
TransformFeedBackDrawCallback(const Drawable::DrawCallback&dc,const
CopyOp&co);
/** Get the primitive type of the feedback.
*/
GLenum getFeedBackType() const
{
return _type;
}
void setFeedBackType(GLenum e)
{
_type=e;
}
void addTransformFeedbackBufferBinding(osg::TransformFeedbackBufferBinding
* tfbb);
void
removeTransformFeedbackBufferBinding(osg::TransformFeedbackBufferBinding *
tfbb);
osg::TransformFeedbackBufferBinding
*getTransformFeedbackBufferBinding(const unsigned int &i)const
{
return _tfbbs[i];
}
unsigned int getNumTransformFeedbackBufferBindings()const
{
return _tfbbs.size();
}
META_Object(osg,TransformFeedBackDrawCallback);
/** do TransformFeedback draw code.*/
virtual void drawImplementation(osg::RenderInfo& renderInfo,const
osg::Drawable* drawable ) const;
};
TransformFeedBackDrawCallback:: TransformFeedBackDrawCallback(const
Drawable::DrawCallback&dc,const CopyOp&co):osg::Drawable::DrawCallback(dc,co)
{
}
void
TransformFeedBackDrawCallback::addTransformFeedbackBufferBinding(osg::TransformFeedbackBufferBinding
* tfbb)
{
if(tfbb)_tfbbs.push_back(tfbb);
}
void
TransformFeedBackDrawCallback::removeTransformFeedbackBufferBinding(osg::TransformFeedbackBufferBinding
* tfbb)
{
for(std::vector<osg::ref_ptr<osg::TransformFeedbackBufferBinding>
>::iterator i=_tfbbs.begin(); i!=_tfbbs.end(); i++)
{
if((*i).get()==tfbb)
{
_tfbbs.erase(i);
return;
}
}
}
/** do TransformFeedback draw code.*/
void TransformFeedBackDrawCallback::drawImplementation(osg::RenderInfo&
renderInfo,const osg::Drawable* drawable ) const
{
osg::GLExtensions* ext = renderInfo.getState()->get<osg::GLExtensions>();
///required?
for(std::vector<osg::ref_ptr<osg::TransformFeedbackBufferBinding>
>::const_iterator i=_tfbbs.begin(); i!=_tfbbs.end(); i++)
{
(*i)->apply(*renderInfo.getState());
}
glEnable(GL_RASTERIZER_DISCARD);
ext->glBeginTransformFeedback(_type);
drawable->drawImplementation(renderInfo);
ext->glEndTransformFeedback();
glDisable(GL_RASTERIZER_DISCARD);
///unbind all TransformFeedbackBufferBindingS
ext->glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
}
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
static const char* RendervertSource =
{
"#version 120\n"
"varying vec4 v_color;\n"
"void main(void)\n"
"{\n"
" v_color = gl_Vertex;\n"
" gl_Position = gl_ModelViewProjectionMatrix *(gl_Vertex);\n"
"}\n"
};
static const char* vertSource =
{
"#version 120\n"
"#extension GL_EXT_geometry_shader4 : enable\n"
"varying out vec4 v_color;\n"
"void main(void)\n"
"{\n"
" gl_Position = (gl_Vertex);\n"
" v_color = gl_Vertex;\n"
"}\n"
};
static const char* geomSource =
{
"#version 120\n"
"#extension GL_EXT_geometry_shader4 : enable\n"
"uniform float u_anim1;\n"
" varying in vec4 v_color[];\n"
" varying vec4 out1;\n"
"void main(void)\n"
"{\n"
" vec4 v =vec4( gl_PositionIn[0].xyz,1);\n"
" out1 = v + vec4(u_anim1,0.,0.,0.);// gl_Position = v +
vec4(u_anim1,0.,0.,0.); \n"
" EmitVertex();\n"
" EndPrimitive();\n"
" out1 = v - vec4(u_anim1,0.,0.,0.); // gl_Position = v -
vec4(u_anim1,0.,0.,0.); \n"
" EmitVertex();\n"
" EndPrimitive();\n"
"\n"
" out1= v + vec4(0.,1.0-u_anim1,0.,0.);// gl_Position = v +
vec4(0.,1.0-u_anim1,0.,0.); \n"
" EmitVertex();\n"
" EndPrimitive();\n"
" out1 = v - vec4(0.,1.0-u_anim1,0.,0.); //gl_Position = v -
vec4(0.,1.0-u_anim1,0.,0.); \n"
" EmitVertex();\n"
" EndPrimitive();\n"
"}\n"
};
static const char* fragSource =
{
"#version 120\n"
"#extension GL_EXT_geometry_shader4 : enable\n"
"varying vec4 v_color_out;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = vec4(1,0,0,1);//v_color_out;\n"
"}\n"
};
osg::Program* createGeneratorShader()
{
osg::Program* pgm = new osg::Program;
pgm->setName( "osg transformfeedback generator demo" );
pgm->addShader( new osg::Shader( osg::Shader::VERTEX, vertSource ) );
///setup Transform FeedBack program
pgm->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, 4 );
pgm->setParameter( GL_GEOMETRY_INPUT_TYPE_EXT, GL_POINTS );
pgm->setParameter( GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_POINTS );
pgm->addShader( new osg::Shader( osg::Shader::GEOMETRY, geomSource ) );
pgm->addTransformFeedBackVarying(std::string("out1"));
pgm->setTransformFeedBackMode(GL_INTERLEAVED_ATTRIBS);
return pgm;
}
osg::Program* createRenderShader()
{
osg::Program* pgm = new osg::Program;
pgm->setName( "osg transformfeedback renderer demo" );
pgm->addShader( new osg::Shader( osg::Shader::VERTEX, RendervertSource )
);
pgm->addShader( new osg::Shader( osg::Shader::FRAGMENT, fragSource ) );
return pgm;
}
int main( int , char** )
{
osg::Geode* root( new osg::Geode );
osg::ref_ptr<osg::Geometry > somePointsGenerator = new osg::Geometry();
somePointsGenerator->setName("SomePointsGenerator");
{
somePointsGenerator->setUseVertexBufferObjects(true);
somePointsGenerator->setUseDisplayList(false);
osg::StateSet* sset = somePointsGenerator->getOrCreateStateSet();
sset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
osg::ref_ptr<osg::Vec4Array> vAry = new osg::Vec4Array;
vAry->push_back( osg::Vec4(0,0,0,1) );
vAry->push_back( osg::Vec4(0,1,0,1) );
vAry->push_back( osg::Vec4(1,0,0,1) );
vAry->push_back( osg::Vec4(1,1,0,1 ));
somePointsGenerator->addPrimitiveSet( new osg::DrawArrays( GL_POINTS,
0, vAry->size() ) );
somePointsGenerator->setVertexArray( vAry );
osg::ref_ptr<osg::Program> _program=createGeneratorShader() ;
sset->setAttribute(_program );
// a generic cyclic animation value
osg::Uniform* u_anim1( new osg::Uniform( "u_anim1", 0.9f ) );
u_anim1->setUpdateCallback( new SineAnimation( 4, 0.5, 0.5 ) );
sset->addUniform( u_anim1 );
}
osg::ref_ptr<osg::Geometry > somePointsRenderer = new osg::Geometry();
somePointsRenderer->setName("SomePointsRenderer");
{
int
numprimgen=somePointsGenerator->getVertexArray()->getNumElements()*4;
somePointsRenderer->setUseVertexBufferObjects(true);
somePointsRenderer->setUseDisplayList(false);
osg::ref_ptr<osg::Vec4Array> vAry2 = new osg::Vec4Array;
vAry2->resize(numprimgen);
somePointsRenderer-> setVertexArray(vAry2);
somePointsRenderer-> addPrimitiveSet( new osg::DrawArrays( GL_LINES,
0,numprimgen));
osg::StateSet* sset = somePointsRenderer-> getOrCreateStateSet();
sset->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
sset->setAttribute( createRenderShader() );
}
{
///setup Transform FeedBack callback
osg::TransformFeedBackDrawCallback *tfcb=new
osg::TransformFeedBackDrawCallback();
osg::TransformFeedbackBufferBinding *tfbb=new
osg::TransformFeedbackBufferBinding ();
tfbb->setBufferObject(somePointsRenderer->getVertexArray()->getVertexBufferObject());
somePointsRenderer->getOrCreateVertexBufferObject();
tfbb->setSize(somePointsRenderer->getVertexArray()->getTotalDataSize());
somePointsGenerator->getStateSet()->setAttribute(tfbb);
tfcb->setType(GL_POINTS);
tfcb->addTransformFeedbackBufferBinding(tfbb);
somePointsGenerator->setDrawCallback(tfcb);
}
root->addChild(somePointsGenerator);
root->addChild(somePointsRenderer);
///ensure draw sequence
somePointsGenerator->getStateSet()->setRenderBinDetails(0,"RenderBin");
somePointsRenderer->getStateSet()->setRenderBinDetails(1,"RenderBin");
osgViewer::Viewer viewer;
viewer.setSceneData( root );
return viewer.run();
}
I've also do some stuff to serialize it but it requires:
-the TransformFeedbackDrawCallback to be integrated somewhere in OSG
(..in osg/Drawable?)
-a osg::BufferObject,osg::UniforBufferBinding class serializers
Does it seams you reasonable?
If so I'll post my work on it...
[/code]
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=67104#67104
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org