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

Reply via email to