Merge branch 'master' into shader_pipeline

This commit is contained in:
Robert Osfield 2018-01-03 12:34:01 +00:00
commit e3d438d80f
8 changed files with 83 additions and 111 deletions

View File

@ -20,6 +20,7 @@
// This example can work only if GL version is 4.3 or greater
#include <osg/Texture2D>
#include <osg/BindImageTexture>
#include <osg/ComputeDispatch>
#include <osg/Geode>
#include <osgDB/ReadFile>
@ -52,7 +53,9 @@ int main( int argc, char** argv )
tex2D->setInternalFormat( GL_R32F );
tex2D->setSourceFormat( GL_RED );
tex2D->setSourceType( GL_FLOAT );
tex2D->bindToImageUnit( 0, osg::Texture::WRITE_ONLY ); // So we can use 'image2D' in the compute shader
// So we can use 'image2D' in the compute shader
osg::ref_ptr<osg::BindImageTexture> imagbinding = new osg::BindImageTexture(0, tex2D, osg::BindImageTexture::WRITE_ONLY, GL_R32F);
// The compute shader can't work with other kinds of shaders
// It also requires the work group numbers. Setting them to 0 will disable the compute shader
@ -75,7 +78,7 @@ int main( int argc, char** argv )
quad->addDrawable( geom );
quad->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
quad->getOrCreateStateSet()->setTextureAttributeAndModes( 0, tex2D.get() );
quad->getOrCreateStateSet()->setAttributeAndModes(imagbinding.get());
// Create the scene graph and start the viewer
osg::ref_ptr<osg::Group> scene = new osg::Group;
scene->addChild( sourceNode );

View File

@ -151,6 +151,7 @@
#include <osg/Image>
#include <osg/Texture>
#include <osg/TextureBuffer>
#include <osg/BindImageTexture>
#include <osg/BufferIndexBinding>
#include <osg/ComputeBoundsVisitor>
#include <osg/LightSource>
@ -321,9 +322,9 @@ struct IndirectTarget
{
indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands.get());
indirectCommandTextureBuffer->setInternalFormat( GL_R32I );
indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE);
indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false);
indirectCommandImageBinding=new osg::BindImageTexture(index, indirectCommandTextureBuffer, osg::BindImageTexture::READ_WRITE, GL_R32I);
// add proper primitivesets to geometryAggregators
if( !useMultiDrawArraysIndirect ) // use glDrawArraysIndirect()
@ -365,7 +366,8 @@ struct IndirectTarget
instanceTarget = new osg::TextureBuffer(instanceTargetImage);
instanceTarget->setInternalFormat( internalFormat );
instanceTarget->bindToImageUnit(OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, osg::Texture::READ_WRITE);
instanceTargetimagebinding = new osg::BindImageTexture(OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, instanceTarget, osg::BindImageTexture::READ_WRITE, internalFormat);
}
@ -374,6 +376,7 @@ struct IndirectTarget
std::string uniformName = uniformNamePrefix + char( '0' + index );
osg::Uniform* uniform = new osg::Uniform(uniformName.c_str(), (int)index );
stateset->addUniform( uniform );
stateset->setAttribute(indirectCommandImageBinding);
stateset->setTextureAttribute( index, indirectCommandTextureBuffer.get() );
@ -389,6 +392,8 @@ struct IndirectTarget
osg::Uniform* uniform = new osg::Uniform(uniformName.c_str(), (int)(OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index) );
stateset->addUniform( uniform );
stateset->setAttribute(instanceTargetimagebinding);
stateset->setTextureAttribute( OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, instanceTarget.get() );
}
@ -400,9 +405,11 @@ struct IndirectTarget
osg::ref_ptr< osg::DefaultIndirectCommandDrawArrays > indirectCommands;
osg::ref_ptr<osg::TextureBuffer> indirectCommandTextureBuffer;
osg::ref_ptr<osg::BindImageTexture> indirectCommandImageBinding;
osg::ref_ptr< AggregateGeometryVisitor > geometryAggregator;
osg::ref_ptr<osg::Program> drawProgram;
osg::ref_ptr< osg::TextureBuffer > instanceTarget;
osg::ref_ptr<osg::BindImageTexture> instanceTargetimagebinding;
unsigned int maxTargetQuantity;
};
@ -1713,4 +1720,3 @@ int main( int argc, char **argv )
return viewer.run();
}

View File

@ -10,7 +10,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
/// author: Julien Valentin 2017 (mp3butcher@hotmail.com)
/// author: Julien Valentin 2017 (mp3butcher@hotmail.com)
#ifndef _GLImageUnitBinding_H
#define _GLImageUnitBinding_H
@ -29,7 +29,7 @@ namespace osg
class OSG_EXPORT BindImageTexture : public osg::StateAttribute {
public:
/** Type of access that will be performed on the texture image. */
enum ImageAccess
enum Access
{
NOT_USED = 0,
READ_ONLY = GL_READ_ONLY_ARB,
@ -40,7 +40,7 @@ class OSG_EXPORT BindImageTexture : public osg::StateAttribute {
BindImageTexture(
GLuint imageunit = 0,
osg::Texture* target = 0,
ImageAccess access = READ_ONLY,
Access access = READ_ONLY,
GLenum format = GL_RGBA8,
int level = 0,
bool layered = GL_FALSE,
@ -67,27 +67,27 @@ class OSG_EXPORT BindImageTexture : public osg::StateAttribute {
META_StateAttribute(osg,BindImageTexture, BINDIMAGETEXTURE)
void setImageUnit(GLuint i) { _imageunit=i; }
GLuint getImageUnit() const { return _imageunit; }
inline void setImageUnit(GLuint i) { _imageunit=i; }
inline GLuint getImageUnit() const { return _imageunit; }
void setLevel(GLint i) { _level=i; }
GLint getLevel() const { return _level; }
inline void setLevel(GLint i) { _level=i; }
inline GLint getLevel() const { return _level; }
void setIsLayered(GLboolean i) { _layered=i; }
GLboolean getIsLayered() const { return _layered; }
inline void setIsLayered(GLboolean i) { _layered=i; }
inline GLboolean getIsLayered() const { return _layered; }
void setLayer(GLint i) { _layer=i; }
GLint getLayer() const { return _layer; }
inline void setLayer(GLint i) { _layer=i; }
inline GLint getLayer() const { return _layer; }
void setAccess(ImageAccess i) { _access=i; }
GLenum getAccess()const { return _access; }
inline void setAccess(Access i) { _access=i; }
inline Access getAccess() const { return _access; }
void setFormat(GLenum i) { _format=i; }
GLenum getFormat()const { return _format; }
inline void setFormat(GLenum i) { _format=i; }
inline GLenum getFormat() const { return _format; }
void setTexture(osg::Texture* target) { _target=target; }
osg::Texture* getTexture() { return _target.get();}
const osg::Texture* getTexture() const { return _target.get();}
inline void setTexture(osg::Texture* target) { _target=target; }
inline osg::Texture* getTexture() { return _target.get();}
inline const osg::Texture* getTexture() const { return _target.get();}
virtual void apply(osg::State&state) const;
@ -102,11 +102,10 @@ class OSG_EXPORT BindImageTexture : public osg::StateAttribute {
GLint _level;
GLboolean _layered;
GLint _layer;
GLenum _access;
Access _access;
GLenum _format;
};
}
#endif

View File

@ -676,38 +676,6 @@ class OSG_EXPORT Texture : public osg::TextureAttribute
* min filter is used. */
void allocateMipmapLevels();
/** Encapsulates texture image load/store attributes */
struct ImageAttachment
{
GLuint unit;
GLint level;
GLboolean layered;
GLint layer;
GLenum access;
GLenum format;
ImageAttachment()
: unit(0), level(0), layered(GL_FALSE), layer(0), access(0), format(0) {}
};
/** Type of access that will be performed on the texture image. */
enum ImageAccess
{
NOT_USED = 0,
READ_ONLY = GL_READ_ONLY_ARB,
WRITE_ONLY = GL_WRITE_ONLY_ARB,
READ_WRITE = GL_READ_WRITE_ARB
};
/** Bind texture to an image unit (available only if GL version is 4.2 or greater)
* The format parameter for the image unit need not exactly match the texture internal format,
* but if it is set to 0, the texture internal format will be used.
* See http://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt */
void bindToImageUnit(unsigned int unit, GLenum access, GLenum format=0, int level=0, bool layered=false, int layer=0);
ImageAttachment& getImageAttachment() { return _imageAttachment; }
const ImageAttachment& getImageAttachment() const { return _imageAttachment; }
/** Sets GL_TEXTURE_COMPARE_MODE_ARB to GL_COMPARE_R_TO_TEXTURE_ARB
* See http://oss.sgi.com/projects/ogl-sample/registry/ARB/shadow.txt. */
void setShadowComparison(bool flag) { _use_shadow_comparison = flag; }
@ -890,8 +858,6 @@ class OSG_EXPORT Texture : public osg::TextureAttribute
ShadowTextureMode _shadow_texture_mode;
float _shadow_ambient;
ImageAttachment _imageAttachment;
public:
struct OSG_EXPORT TextureProfile

View File

@ -1384,16 +1384,6 @@ void Texture::setMaxAnisotropy(float anis)
}
}
void Texture::bindToImageUnit(unsigned int unit, GLenum access, GLenum format, int level, bool layered, int layer)
{
_imageAttachment.unit = unit;
_imageAttachment.level = level;
_imageAttachment.layered = layered ? GL_TRUE : GL_FALSE;
_imageAttachment.layer = layer;
_imageAttachment.access = access;
_imageAttachment.format = format;
dirtyTextureParameters();
}
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
void Texture::dirtyTextureObject()
@ -1997,19 +1987,6 @@ void Texture::applyTexParameters(GLenum target, State& state) const
}
}
// Apply image load/store attributes
if (extensions->isBindImageTextureSupported() && _imageAttachment.access!=0)
{
TextureObject* tobj = getTextureObject(contextID);
if (tobj)
{
extensions->glBindImageTexture(
_imageAttachment.unit, tobj->id(), _imageAttachment.level,
_imageAttachment.layered, _imageAttachment.layer, _imageAttachment.access,
_imageAttachment.format!=0 ? _imageAttachment.format : _internalFormat);
}
}
getTextureParameterDirty(state.getContextID()) = false;
}

View File

@ -160,7 +160,6 @@ void TextureBuffer::apply(State& state) const
#endif
if (textureObject)
{
const GLExtensions* extensions = state.get<GLExtensions>();
if(_bufferData.valid() &&_modifiedCount[contextID]!=_bufferData->getModifiedCount() )
{
_modifiedCount[contextID]=_bufferData->getModifiedCount() ;
@ -178,18 +177,6 @@ void TextureBuffer::apply(State& state) const
}
textureObject->bind(state);
if( getTextureParameterDirty(contextID) )
{
if( extensions->isBindImageTextureSupported() && _imageAttachment.access!=0 )
{
extensions->glBindImageTexture(
_imageAttachment.unit, textureObject->id(), _imageAttachment.level,
_imageAttachment.layered, _imageAttachment.layer, _imageAttachment.access,
_imageAttachment.format!=0 ? _imageAttachment.format : _internalFormat);
}
getTextureParameterDirty(state.getContextID()) = false;
}
}
else if (_bufferData.valid() &&_bufferData->getBufferObject() )//&& _bufferObject->getNumBufferData()>0 )
{
@ -205,13 +192,6 @@ void TextureBuffer::apply(State& state) const
textureObject->_profile._internalFormat=_internalFormat;
textureObject->bind(state);
if ( extensions->isBindImageTextureSupported() && _imageAttachment.access!=0 )
{
extensions->glBindImageTexture(
_imageAttachment.unit, textureObject->id(), _imageAttachment.level,
_imageAttachment.layered, _imageAttachment.layer, _imageAttachment.access,
_imageAttachment.format!=0 ? _imageAttachment.format : _internalFormat);
}
getTextureParameterDirty(state.getContextID()) = false;
computeInternalFormat();
@ -239,4 +219,3 @@ void TextureBuffer::computeInternalFormat() const
if (getImage() ) computeInternalFormatWithImage(*getImage());
else computeInternalFormatType();
}

View File

@ -0,0 +1,30 @@
#include <osg/BindImageTexture>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
#define ADD_GLBOOL_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, GLboolean >( \
#PROP, ((int)(DEF)), &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_BOOL )
REGISTER_OBJECT_WRAPPER( BindImageTexture,
new osg::BindImageTexture,
osg::BindImageTexture,
"osg::Object osg::StateAttribute osg::BindImageTexture" )
{
ADD_OBJECT_SERIALIZER( Texture, osg::Texture, NULL);
ADD_UINT_SERIALIZER(ImageUnit,0);
ADD_GLINT_SERIALIZER(Level,0);
ADD_GLBOOL_SERIALIZER(IsLayered,GL_FALSE);
ADD_GLINT_SERIALIZER(Layer,0);
BEGIN_ENUM_SERIALIZER( Access, NOT_USED );
ADD_ENUM_VALUE( NOT_USED );
ADD_ENUM_VALUE( READ_ONLY );
ADD_ENUM_VALUE( WRITE_ONLY );
ADD_ENUM_VALUE( READ_WRITE );
END_ENUM_SERIALIZER();
ADD_GLENUM_SERIALIZER(Format,GLenum,GL_RGBA8);
}

View File

@ -73,22 +73,31 @@ static bool writeInternalFormat( osgDB::OutputStream& os, const osg::Texture& te
// _imageAttachment
static bool checkImageAttachment( const osg::Texture& attr )
{
return attr.getImageAttachment().access!=0;
return false;
}
struct DummyImageAttachment
{
DummyImageAttachment(): unit(0), level(0), layered(GL_FALSE), layer(0), access(0), format(0){}
GLuint unit;
GLint level;
GLboolean layered;
GLint layer;
GLenum access;
GLenum format;
};
static bool readImageAttachment( osgDB::InputStream& is, osg::Texture& attr )
{
osg::Texture::ImageAttachment attachment;
DummyImageAttachment attachment;
is >> attachment.unit >> attachment.level >> attachment.layered
>> attachment.layer >> attachment.access >> attachment.format;
attr.bindToImageUnit( attachment.unit, attachment.access, attachment.format,
attachment.level, attachment.layered!=GL_FALSE, attachment.layer );
return true;
}
static bool writeImageAttachment( osgDB::OutputStream& os, const osg::Texture& attr )
{
const osg::Texture::ImageAttachment& attachment = attr.getImageAttachment();
DummyImageAttachment attachment;
os << attachment.unit << attachment.level << attachment.layered
<< attachment.layer << attachment.access << attachment.format << std::endl;
return true;
@ -248,9 +257,12 @@ REGISTER_OBJECT_WRAPPER( Texture,
UPDATE_TO_VERSION_SCOPED( 95 )
ADD_USER_SERIALIZER( ImageAttachment ); // _imageAttachment
}
{
UPDATE_TO_VERSION_SCOPED( 98 )
{
UPDATE_TO_VERSION_SCOPED( 153 )
REMOVE_SERIALIZER( ImageAttachment );
}
{
UPDATE_TO_VERSION_SCOPED( 98 )
ADD_USER_SERIALIZER( Swizzle ); // _swizzle
}
}