Skip to content

Commit

Permalink
From David Callu, "Here an update of osg::Uniform :
Browse files Browse the repository at this point in the history
- add non square matrix
- add double
- add all uniform type available in OpenGL 4.2
- backward compatibility for Matrixd to set/get an float uniform matrix
- update of IVE / Wrapper ReadWriter

implementation of AtomicCounterBuffer based on BufferIndexBinding

add example that use AtomicCounterBuffer and show rendering order of fragments,
original idea from geeks3d.com."
  • Loading branch information
robertosfield committed Mar 29, 2012
1 parent 32f31fb commit ef9d865
Show file tree
Hide file tree
Showing 16 changed files with 2,935 additions and 401 deletions.
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ IF(DYNAMIC_OPENSCENEGRAPH)
ADD_SUBDIRECTORY(osg2cpp)
ADD_SUBDIRECTORY(osganalysis)
ADD_SUBDIRECTORY(osganimate)
ADD_SUBDIRECTORY(osgatomiccounter)
ADD_SUBDIRECTORY(osgautocapture)
ADD_SUBDIRECTORY(osgautotransform)
ADD_SUBDIRECTORY(osgbillboard)
Expand Down
4 changes: 4 additions & 0 deletions examples/osgatomiccounter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SET(TARGET_SRC osgatomiccounter.cpp)

#### end var setup ###
SETUP_EXAMPLE(osgatomiccounter)
238 changes: 238 additions & 0 deletions examples/osgatomiccounter/osgatomiccounter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2012-2012 David Callu
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commercial and non commercial applications,
* as long as this copyright notice is maintained.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

#include <osg/BufferIndexBinding>
#include <osg/BufferObject>
#include <osg/Camera>
#include <osg/Program>

#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>

#include <iostream>


class AdaptNumPixelUniform : public osg::Camera::DrawCallback
{
public:
AdaptNumPixelUniform()
{
_atomicCounterArray = new osg::UIntArray;
_atomicCounterArray->push_back(0);
}

virtual void operator () (osg::RenderInfo& renderInfo) const
{
_acbb->readData(*renderInfo.getState(), *_atomicCounterArray);
unsigned int numPixel = osg::maximum(1u, _atomicCounterArray->front());

if ((renderInfo.getView()->getFrameStamp()->getFrameNumber() % 10) == 0)
{
OSG_INFO << "osgatomiccounter : draw " << numPixel << " pixels." << std::endl;
}

_invNumPixelUniform->set( 1.0f / static_cast<float>(numPixel) );
}

osg::ref_ptr<osg::Uniform> _invNumPixelUniform;
osg::ref_ptr<osg::UIntArray> _atomicCounterArray;
osg::ref_ptr<osg::AtomicCounterBufferBinding> _acbb;
};


osg::Program * createProgram()
{

std::stringstream vp;
vp << "#version 420 compatibility\n"
<< "\n"
<< "void main(void)\n"
<< "{\n"
<< " gl_Position = ftransform();\n"
<< "}\n";
osg::Shader * vpShader = new osg::Shader( osg::Shader::VERTEX, vp.str() );



std::stringstream fp;
fp << "#version 420 compatibility\n"
<< "\n"
<< "layout(binding = 0) uniform atomic_uint acRed;\n"
<< "layout(binding = 0, offset = 4) uniform atomic_uint acGreen;\n"
<< "layout(binding = 2) uniform atomic_uint acBlue;\n"
<< "\n"
<< "uniform float invNumPixel;\n"
<< "\n"
<< "void main(void)\n"
<< "{\n"
<< " float r = float(atomicCounterIncrement(acRed)) * invNumPixel;\n"
<< " float g = float(atomicCounterIncrement(acGreen)) * invNumPixel;\n"
<< " float b = float(atomicCounterIncrement(acBlue)) * invNumPixel;\n"
<< " gl_FragColor = vec4(r, g, b, 1.0);\n"
<< "}\n"
<< "\n";
osg::Shader * fpShader = new osg::Shader( osg::Shader::FRAGMENT, fp.str() );

osg::Program * program = new osg::Program;
program->addShader(vpShader);
program->addShader(fpShader);

return program;
}

class ResetAtomicCounter : public osg::StateAttributeCallback
{
public:
virtual void operator () (osg::StateAttribute* sa, osg::NodeVisitor*)
{
osg::AtomicCounterBufferBinding * acbb = dynamic_cast<osg::AtomicCounterBufferBinding *>(sa);
if (acbb)
{
osg::AtomicCounterBufferObject * acbo = dynamic_cast<osg::AtomicCounterBufferObject*>(acbb->getBufferObject());
if (acbo && acbo->getBufferData(0))
{
acbo->getBufferData(0)->dirty();
}
}
}
};


int main(int argc, char** argv)
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);

arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is a simple example which show draw order of pixel.");
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");

osgViewer::Viewer viewer(arguments);

unsigned int helpType = 0;
if ((helpType = arguments.readHelpType()))
{
arguments.getApplicationUsage()->write(std::cout, helpType);
return 1;
}

// report any errors if they have occurred when parsing the program arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}

// set up the camera manipulators.
viewer.setCameraManipulator( new osgGA::TrackballManipulator() );

// add the state manipulator
viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

// add the thread model handler
viewer.addEventHandler(new osgViewer::ThreadingHandler);

// add the window size toggle handler
viewer.addEventHandler(new osgViewer::WindowSizeHandler);

// add the stats handler
viewer.addEventHandler(new osgViewer::StatsHandler);

// add the help handler
viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));

// add the screen capture handler
viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);

// load the data
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
if (!loadedModel)
{
osg::Geometry * quad = osg::createTexturedQuadGeometry(osg::Vec3f(-2.0f, 0.0f, -2.0f),
osg::Vec3f(2.0f, 0.0f, 0.0f),
osg::Vec3f(0.0f, 0.0f, 2.0f) );

osg::Geode * geode = new osg::Geode;
geode->addDrawable(quad);
loadedModel = geode;
}

// any option left unread are converted into errors to write out later.
arguments.reportRemainingOptionsAsUnrecognized();

// report any errors if they have occurred when parsing the program arguments.
if (arguments.errors())
{
arguments.writeErrorMessages(std::cout);
return 1;
}


osg::StateSet * ss = loadedModel->asGeode()->getDrawable(0)->getOrCreateStateSet();
ss->setAttributeAndModes( createProgram(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED );

ss = loadedModel->getOrCreateStateSet();
osg::ref_ptr<osg::UIntArray> atomicCounterArrayRedAndGreen = new osg::UIntArray;
atomicCounterArrayRedAndGreen->push_back(0);
atomicCounterArrayRedAndGreen->push_back(0);

osg::ref_ptr<osg::UIntArray> atomicCounterArrayBlue = new osg::UIntArray;
atomicCounterArrayBlue->push_back(0);

osg::ref_ptr<osg::AtomicCounterBufferObject> acboRedAndGreen = new osg::AtomicCounterBufferObject;
acboRedAndGreen->setUsage(GL_STREAM_COPY);
atomicCounterArrayRedAndGreen->setBufferObject(acboRedAndGreen.get());

osg::ref_ptr<osg::AtomicCounterBufferObject> acboBlue = new osg::AtomicCounterBufferObject;
acboBlue->setUsage(GL_STREAM_COPY);
atomicCounterArrayBlue->setBufferObject(acboBlue.get());

osg::ref_ptr<osg::AtomicCounterBufferBinding> acbbRedAndGreen = new osg::AtomicCounterBufferBinding(0, acboRedAndGreen.get(), 0, sizeof(GLuint)*3);
ss->setAttributeAndModes(acbbRedAndGreen.get());

osg::ref_ptr<osg::AtomicCounterBufferBinding> acbbBlue = new osg::AtomicCounterBufferBinding(2, acboBlue.get(), 0, sizeof(GLuint));
ss->setAttributeAndModes(acbbBlue.get());

acbbRedAndGreen->setUpdateCallback(new ResetAtomicCounter);
acbbBlue->setUpdateCallback(new ResetAtomicCounter);

osg::ref_ptr<osg::Uniform> invNumPixelUniform = new osg::Uniform("invNumPixel", 1.0f/(800.0f*600.0f));
ss->addUniform( invNumPixelUniform.get() );

AdaptNumPixelUniform * drawCallback = new AdaptNumPixelUniform;
drawCallback->_invNumPixelUniform = invNumPixelUniform;
drawCallback->_acbb = acbbBlue;

viewer.getCamera()->setFinalDrawCallback(drawCallback);

// optimize the scene graph, remove redundant nodes and state etc.
osgUtil::Optimizer optimizer;
optimizer.optimize(loadedModel.get());

viewer.setSceneData( loadedModel.get() );

viewer.realize();

return viewer.run();

}
37 changes: 36 additions & 1 deletion include/osg/BufferIndexBinding
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
* Copyright (C) 2010 Tim Moore
* Copyright (C) 2012 David Callu
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
Expand All @@ -15,6 +16,7 @@
#ifndef OSG_BUFFERINDEXBINDING
#define OSG_BUFFERINDEXBINDING 1

#include <osg/Array>
#include <osg/Export>
#include <osg/BufferObject>
#include <osg/StateAttribute>
Expand All @@ -23,6 +25,7 @@
#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
#endif


namespace osg {

class State;
Expand Down Expand Up @@ -129,6 +132,38 @@ class OSG_EXPORT TransformFeedbackBufferBinding : public BufferIndexBinding
return 0;
}
};
}

/** StateAttribute for binding a atomic counter buffer index target.
*/
class OSG_EXPORT AtomicCounterBufferBinding : public BufferIndexBinding
{
public:
AtomicCounterBufferBinding(GLuint index=0);
/** Create a binding for a atomic counter buffer index target.
* @param index the index target
* @param bo associated buffer object
* @param offset offset into buffer object
* @param size size of data in buffer object
*/
AtomicCounterBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, GLsizeiptr size);
AtomicCounterBufferBinding(const AtomicCounterBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_StateAttribute(osg, AtomicCounterBufferBinding, ATOMICCOUNTERBUFFERBINDING);

void readData(osg::State & state, osg::UIntArray & uintArray) const;

virtual int compare(const StateAttribute& bb) const
{
COMPARE_StateAttribute_Types(AtomicCounterBufferBinding, bb)

COMPARE_StateAttribute_Parameter(_target)
COMPARE_StateAttribute_Parameter(_index)
COMPARE_StateAttribute_Parameter(_bufferObject)
COMPARE_StateAttribute_Parameter(_offset)
COMPARE_StateAttribute_Parameter(_size)
return 0;
}
};

} // namespace osg

#endif
12 changes: 12 additions & 0 deletions include/osg/BufferObject
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
* Copyright (C) 2012 David Callu
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
Expand Down Expand Up @@ -829,6 +830,17 @@ class OSG_EXPORT UniformBufferObject : public BufferObject
virtual ~UniformBufferObject();
};

class OSG_EXPORT AtomicCounterBufferObject : public BufferObject
{
public:
AtomicCounterBufferObject();
AtomicCounterBufferObject(const AtomicCounterBufferObject& ubo, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_Object(osg, AtomicCounterBufferObject);

protected:
virtual ~AtomicCounterBufferObject();
};

inline void GLBufferObject::bindBuffer()
{
_extensions->glBindBuffer(_profile._target,_glObjectID);
Expand Down
Loading

0 comments on commit ef9d865

Please sign in to comment.