Merge branch 'master' into shader_pipeline
This commit is contained in:
commit
e3d438d80f
@ -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 );
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
30
src/osgWrappers/serializers/osg/BindImageTexture.cpp
Normal file
30
src/osgWrappers/serializers/osg/BindImageTexture.cpp
Normal 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);
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user