diff --git a/include/osg/SampleMaski b/include/osg/SampleMaski new file mode 100644 index 000000000..dee17bcf5 --- /dev/null +++ b/include/osg/SampleMaski @@ -0,0 +1,95 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * 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 + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library 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. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSG_SAMPLEMASKI +#define OSG_SAMPLEMASKI 1 + +#include + +namespace osg { + +/** + * osg::SampleMaski does nothing if OpenGL 3.2 or ARB_texture_multisample are not available. +*/ +class OSG_EXPORT SampleMaski : public StateAttribute +{ + public : + + SampleMaski(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + SampleMaski(const SampleMaski& sampleMaski,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_StateAttribute(osg, SampleMaski, SAMPLEMASKI) + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ + virtual int compare(const StateAttribute& sa) const; + + inline void setMask(unsigned int mask, unsigned int maskNumber = 0u ) { _sampleMask[maskNumber] = mask; } + + inline unsigned int getMask(unsigned int maskNumber = 0u) const { return _sampleMask[maskNumber]; } + + virtual void apply(State& state) const; + + public: + + /** Extensions class which encapsulates the querying of extensions and + * associated function pointers, and provide convenience wrappers to + * check for the extensions or use the associated functions. + */ + class OSG_EXPORT Extensions : public osg::Referenced + { + public: + Extensions(unsigned int contextID); + + Extensions(const Extensions& rhs); + + void lowestCommonDenominator(const Extensions& rhs); + + void setupGLExtensions(unsigned int contextID); + + bool isOpenGL32upported() const { return _isOpenGL32upported; } + bool isTextureMultisampleSupported() const { return _isTextureMultisampleSupported; } + bool isSampleMaskiSupported() const { return _isSampleMaskiSupported; } + + void glSampleMaski(GLuint maskNumber, GLbitfield mask) const; + + protected: + + ~Extensions() {} + + bool _isOpenGL32upported; + bool _isTextureMultisampleSupported; + bool _isSampleMaskiSupported; + + typedef void (GL_APIENTRY * SampleMaski) ( GLuint maskNumber, GLbitfield mask ); + + SampleMaski _glSampleMaski; + }; + + static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized); + + static void setExtensions(unsigned int contextID,Extensions* extensions); + + + protected: + + virtual ~SampleMaski(); + +//For now support only up to 64 bit mask; + unsigned int _sampleMask[2]; +}; + +} + +#endif diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index 32b4cb6cd..e8c155d42 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -164,6 +164,7 @@ class OSG_EXPORT StateAttribute : public Object PROGRAM, CLAMPCOLOR, HINT, + SAMPLEMASKI, /// osgFX namespace VALIDATOR, diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 7e9fb6738..944e67ccb 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -134,6 +134,7 @@ SET(TARGET_H ${HEADER_PATH}/Referenced ${HEADER_PATH}/ref_ptr ${HEADER_PATH}/RenderInfo + ${HEADER_PATH}/SampleMaski ${HEADER_PATH}/Scissor ${HEADER_PATH}/Sequence ${HEADER_PATH}/ShadeModel @@ -305,6 +306,7 @@ SET(TARGET_SRC ProxyNode.cpp Quat.cpp Referenced.cpp + SampleMaski.cpp Scissor.cpp Sequence.cpp ShadeModel.cpp diff --git a/src/osg/SampleMaski.cpp b/src/osg/SampleMaski.cpp new file mode 100644 index 000000000..cc40292cc --- /dev/null +++ b/src/osg/SampleMaski.cpp @@ -0,0 +1,143 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * 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 + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library 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. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include +#include +#include + +using namespace osg; + + +SampleMaski::SampleMaski() +{ + _sampleMask[0u] = ~0u; + _sampleMask[1u] = ~0u; +} + +SampleMaski::SampleMaski(const SampleMaski& sampleMaski,const CopyOp& copyop): + StateAttribute(sampleMaski,copyop) +{ + _sampleMask[0u] = sampleMaski._sampleMask[0u]; + _sampleMask[1u] = sampleMaski._sampleMask[1u]; +} + +SampleMaski::~SampleMaski() +{ +} + +int SampleMaski::compare(const StateAttribute& sa) const +{ + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Parameter macros below. + COMPARE_StateAttribute_Types(SampleMaski,sa) + + COMPARE_StateAttribute_Parameter(_sampleMask[0u]) + COMPARE_StateAttribute_Parameter(_sampleMask[1u]) + + return 0; // passed all the above comparison macros, must be equal. +} + +void SampleMaski::apply(State& state) const +{ + // get "per-context" extensions + const unsigned int contextID = state.getContextID(); + const Extensions* extensions = getExtensions(contextID,true); + + if ( (extensions->isTextureMultisampleSupported()) || (extensions->isOpenGL32upported()) || (extensions->isSampleMaskiSupported()) ) + { + extensions->glSampleMaski(0u, _sampleMask[0u]); +//For now we use only 32-bit Sample mask +// extensions->glSampleMaski(1u, _sampleMask[1u]); + return; + } + + OSG_WARN << "SampleMaski failed as the required graphics capabilities were\n" + " not found (contextID " << contextID << "). OpenGL 3.2 or \n" + " ARB_texture_multisample extension is required." << std::endl; +} + + +typedef buffered_value< ref_ptr > BufferedExtensions; +static BufferedExtensions s_extensions; + +SampleMaski::Extensions* SampleMaski::getExtensions(unsigned int contextID,bool createIfNotInitalized) +{ + if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions(contextID); + return s_extensions[contextID].get(); +} + +void SampleMaski::setExtensions(unsigned int contextID,Extensions* extensions) +{ + s_extensions[contextID] = extensions; +} + +SampleMaski::Extensions::Extensions(unsigned int contextID) +{ + setupGLExtensions(contextID); +} + +SampleMaski::Extensions::Extensions(const Extensions& rhs): + Referenced() +{ + _isTextureMultisampleSupported = rhs._isTextureMultisampleSupported; + _isOpenGL32upported = rhs._isOpenGL32upported; + _isSampleMaskiSupported = rhs._isSampleMaskiSupported; + _glSampleMaski = rhs._glSampleMaski; +} + + +void SampleMaski::Extensions::lowestCommonDenominator(const Extensions& rhs) +{ + if (!rhs._isTextureMultisampleSupported) _isTextureMultisampleSupported = false; + if (!rhs._isOpenGL32upported) _isOpenGL32upported = false; + if (!rhs._isSampleMaskiSupported) _isSampleMaskiSupported = false; + + if (!rhs._glSampleMaski) _glSampleMaski = NULL; +} + +void SampleMaski::Extensions::setupGLExtensions(unsigned int contextID) +{ + // extension support + _isTextureMultisampleSupported = isGLExtensionSupported(contextID, "GL_ARB_texture_multisample"); + _isOpenGL32upported = getGLVersionNumber() >= 3.2; + + // function pointers + setGLExtensionFuncPtr(_glSampleMaski, "glSampleMaski"); + + + // protect against buggy drivers (maybe not necessary) + if (!_glSampleMaski) _isSampleMaskiSupported = false; + + // notify + if( _isOpenGL32upported ) + { + OSG_INFO << "SampleMaski is going to use OpenGL 3.2 API (contextID " << contextID << ")." << std::endl; + } + else if( _isTextureMultisampleSupported ) + { + OSG_INFO << "SampleMaski is going to use GL_ARB_texture_multisample extension (contextID " << contextID << ")." << std::endl; + } + else + { + OSG_INFO << "SampleMaski did not found required graphics capabilities\n" + " (contextID " << contextID << "). OpenGL 3.2 or \n" + " GL_ARB_texture_multisample extension is required." << std::endl; + } +} + +void SampleMaski::Extensions::glSampleMaski(GLuint maskNumber, GLbitfield mask) const +{ + _glSampleMaski(maskNumber, mask); +} + diff --git a/src/osgWrappers/serializers/osg/SampleMaski.cpp b/src/osgWrappers/serializers/osg/SampleMaski.cpp new file mode 100644 index 000000000..fee1923fc --- /dev/null +++ b/src/osgWrappers/serializers/osg/SampleMaski.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +static bool checkMasks( const osg::SampleMaski& ) +{ + return true; +} + +static bool readMasks( osgDB::InputStream& is, osg::SampleMaski& attr ) +{ + if ( is.getFileVersion() > 96 ) + { + unsigned int mask0, mask1; + is >> mask0 >> mask1; + attr.setMask( mask0, 0 ); + attr.setMask( mask1, 1 ); + } + return true; +} + +static bool writeMasks( osgDB::OutputStream& os, const osg::SampleMaski& attr ) +{ + os << attr.getMask( 0u ) << attr.getMask( 1u ) << std::endl; + return true; +} + +REGISTER_OBJECT_WRAPPER( SampleMaski, + new osg::SampleMaski, + osg::SampleMaski, + "osg::Object osg::StateAttribute osg::SampleMaski" ) +{ + ADD_USER_SERIALIZER( Masks ); // +}