diff --git a/include/osg/FrameBufferObject b/include/osg/FrameBufferObject index 4843b78d2..cbbfbf311 100644 --- a/include/osg/FrameBufferObject +++ b/include/osg/FrameBufferObject @@ -345,6 +345,7 @@ namespace osg **************************************************************************/ class Texture1D; class Texture2D; + class Texture2DMultisample; class Texture3D; class Texture2DArray; class TextureCubeMap; @@ -359,6 +360,7 @@ namespace osg explicit FrameBufferAttachment(RenderBuffer* target); explicit FrameBufferAttachment(Texture1D* target, int level = 0); explicit FrameBufferAttachment(Texture2D* target, int level = 0); + explicit FrameBufferAttachment(Texture2DMultisample* target, int level = 0); explicit FrameBufferAttachment(Texture3D* target, int zoffset, int level = 0); explicit FrameBufferAttachment(Texture2DArray* target, int layer, int level = 0); explicit FrameBufferAttachment(TextureCubeMap* target, int face, int level = 0); diff --git a/include/osg/Texture b/include/osg/Texture index a2128e832..943ab7fd0 100644 --- a/include/osg/Texture +++ b/include/osg/Texture @@ -222,6 +222,10 @@ #define GL_TEXTURE_DEPTH 0x8071 #endif +#ifndef GL_TEXTURE_2D_MULTISAMPLE + #define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#endif + // Integer teture extension as in http://www.opengl.org/registry/specs/EXT/texture_integer.txt #ifndef GL_EXT_texture_integer #define GL_RGBA32UI_EXT 0x8D70 @@ -619,7 +623,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute void setTextureFilterAnisotropicSupported(bool flag) { _isTextureFilterAnisotropicSupported=flag; } bool isTextureFilterAnisotropicSupported() const { return _isTextureFilterAnisotropicSupported; } - + void setTextureCompressionARBSupported(bool flag) { _isTextureCompressionARBSupported=flag; } bool isTextureCompressionARBSupported() const { return _isTextureCompressionARBSupported; } @@ -638,6 +642,9 @@ class OSG_EXPORT Texture : public osg::StateAttribute void setGenerateMipMapSupported(bool flag) { _isGenerateMipMapSupported=flag; } bool isGenerateMipMapSupported() const { return _isGenerateMipMapSupported; } + void setTextureMultisampledSupported(bool flag) { _isTextureMultisampledSupported=flag; } + bool isTextureMultisampledSupported() const { return _isTextureMultisampledSupported; } + void setShadowSupported(bool flag) { _isShadowSupported = flag; } bool isShadowSupported() const { return _isShadowSupported; } @@ -683,6 +690,11 @@ class OSG_EXPORT Texture : public osg::StateAttribute _glGetCompressedTexImage(target, level, data); } + void glTexImage2DMultisample(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) const + { + _glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); + } + void glTexParameterIiv(GLenum target, GLenum pname, const GLint* data) const { _glTexParameterIiv(target, pname, data); @@ -696,16 +708,18 @@ class OSG_EXPORT Texture : public osg::StateAttribute protected: ~Extensions() {} - + typedef void (APIENTRY * CompressedTexImage2DArbProc) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRY * CompressedTexSubImage2DArbProc) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRY * GetCompressedTexImageArbProc) (GLenum target, GLint level, GLvoid *data); + typedef void (APIENTRY * TexImage2DMultisample)(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); typedef void (APIENTRY * TexParameterIivProc)(GLenum target, GLenum pname, const GLint* data); typedef void (APIENTRY * TexParameterIuivProc)(GLenum target, GLenum pname, const GLuint* data); CompressedTexImage2DArbProc _glCompressedTexImage2D; CompressedTexSubImage2DArbProc _glCompressedTexSubImage2D; GetCompressedTexImageArbProc _glGetCompressedTexImage; + TexImage2DMultisample _glTexImage2DMultisample; TexParameterIivProc _glTexParameterIiv; TexParameterIuivProc _glTexParameterIuiv; @@ -718,6 +732,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute bool _isTextureEdgeClampSupported; bool _isTextureBorderClampSupported; bool _isGenerateMipMapSupported; + bool _isTextureMultisampledSupported; bool _isShadowSupported; bool _isShadowAmbientSupported; bool _isClientStorageSupported; @@ -761,6 +776,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute * unless you're implementing a subload callback. */ void applyTexImage2D_subload(State& state, GLenum target, const Image* image, GLsizei width, GLsizei height, GLint inInternalFormat, GLsizei numMipmapLevels) const; + /** Returned by mipmapBeforeTexImage() to indicate what * mipmapAfterTexImage() should do */ enum GenerateMipmapMode diff --git a/include/osg/Texture2DMultisample b/include/osg/Texture2DMultisample new file mode 100644 index 000000000..fab4af6c9 --- /dev/null +++ b/include/osg/Texture2DMultisample @@ -0,0 +1,95 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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. + * + * Texture2DMultisample codes Copyright (C) 2010 Marcin Hajder + * Thanks to to my company http://www.ai.com.pl for allowing me free this work. +*/ + +#ifndef OSG_TEXTURE2DMS +#define OSG_TEXTURE2DMS 1 + +#include + +namespace osg { + + /** Texture2DMultisample state class which encapsulates OpenGL 2D multisampled texture functionality. + * Multisampled texture were introduced with OpenGL 3.1 and extension GL_ARB_texture_multisample. + * See http://www.opengl.org/registry/specs/ARB/texture_multisample.txt for more info. + */ + +class OSG_EXPORT Texture2DMultisample : public Texture +{ + public : + + Texture2DMultisample(); + + Texture2DMultisample(GLsizei numSamples, GLboolean fixedsamplelocations); + + /** Copy constructor using CopyOp to manage deep vs shallow copy. */ + Texture2DMultisample(const Texture2DMultisample& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_StateAttribute(osg, Texture2DMultisample,TEXTURE); + + /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */ + virtual int compare(const StateAttribute& rhs) const; + + virtual GLenum getTextureTarget() const + { + return GL_TEXTURE_2D_MULTISAMPLE; + } + + /** Sets the texture width and height. If width or height are zero, + * calculate the respective value from the source image size. */ + inline void setTextureSize(int width, int height) const + { + _textureWidth = width; + _textureHeight = height; + } + + inline void setNumSamples( int samples ) { _numSamples = samples; } + + // unnecessary for Texture2DMultisample + virtual void setImage(unsigned int face, Image* image){} + virtual Image* getImage(unsigned int face){return NULL;} + virtual const Image* getImage(unsigned int face) const{return NULL;} + virtual unsigned int getNumImages() const{return 0;} + virtual void allocateMipmap(State& state) const {} + + void setTextureWidth(int width) { _textureWidth=width; } + void setTextureHeight(int height) { _textureHeight=height; } + + virtual int getTextureWidth() const { return _textureWidth; } + virtual int getTextureHeight() const { return _textureHeight; } + virtual int getTextureDepth() const { return 1; } + + /** Bind the texture object. If the texture object hasn't already been + * compiled, create the texture mipmap levels. */ + virtual void apply(State& state) const; + + protected : + + virtual ~Texture2DMultisample(); + + virtual void computeInternalFormat() const; + + /** Subloaded images can have different texture and image sizes. */ + mutable GLsizei _textureWidth, _textureHeight; + + mutable GLsizei _numSamples; + + mutable GLboolean _fixedsamplelocations; + +}; + +} + +#endif diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 7592c53e9..915385907 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -158,6 +158,7 @@ SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/Texture ${HEADER_PATH}/Texture1D ${HEADER_PATH}/Texture2D + ${HEADER_PATH}/Texture2DMultisample ${HEADER_PATH}/Texture2DArray ${HEADER_PATH}/Texture3D ${HEADER_PATH}/TextureCubeMap @@ -317,6 +318,7 @@ ADD_LIBRARY(${LIB_NAME} Texture1D.cpp Texture2DArray.cpp Texture2D.cpp + Texture2DMultisample.cpp Texture3D.cpp Texture.cpp TextureCubeMap.cpp diff --git a/src/osg/FrameBufferObject.cpp b/src/osg/FrameBufferObject.cpp index de8c452b0..404315ba5 100644 --- a/src/osg/FrameBufferObject.cpp +++ b/src/osg/FrameBufferObject.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -287,7 +288,8 @@ struct FrameBufferAttachment::Pimpl TEXTURE3D, TEXTURECUBE, TEXTURERECT, - TEXTURE2DARRAY + TEXTURE2DARRAY, + TEXTURE2DMULTISAMPLE }; TargetType targetType; @@ -344,6 +346,12 @@ FrameBufferAttachment::FrameBufferAttachment(Texture2D* target, int level) _ximpl->textureTarget = target; } +FrameBufferAttachment::FrameBufferAttachment(Texture2DMultisample* target, int level) +{ + _ximpl = new Pimpl(Pimpl::TEXTURE2DMULTISAMPLE, level); + _ximpl->textureTarget = target; +} + FrameBufferAttachment::FrameBufferAttachment(Texture3D* target, int zoffset, int level) { _ximpl = new Pimpl(Pimpl::TEXTURE3D, level); @@ -393,6 +401,14 @@ FrameBufferAttachment::FrameBufferAttachment(Camera::Attachment& attachment) return; } + osg::Texture2DMultisample* texture2DMS = dynamic_cast(texture); + if (texture2DMS) + { + _ximpl = new Pimpl(Pimpl::TEXTURE2DMULTISAMPLE, attachment._level); + _ximpl->textureTarget = texture2DMS; + return; + } + osg::Texture3D* texture3D = dynamic_cast(texture); if (texture3D) { @@ -534,6 +550,9 @@ void FrameBufferAttachment::attach(State &state, GLenum target, GLenum attachmen case Pimpl::TEXTURE2D: ext->glFramebufferTexture2D(target, attachment_point, GL_TEXTURE_2D, tobj->id(), _ximpl->level); break; + case Pimpl::TEXTURE2DMULTISAMPLE: + ext->glFramebufferTexture2D(target, attachment_point, GL_TEXTURE_2D_MULTISAMPLE, tobj->id(), _ximpl->level); + break; case Pimpl::TEXTURE3D: ext->glFramebufferTexture3D(target, attachment_point, GL_TEXTURE_3D, tobj->id(), _ximpl->level, _ximpl->zoffset); break; diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 4b5046c06..a4b473eb2 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -2187,6 +2187,8 @@ Texture::Extensions::Extensions(unsigned int contextID) _isTextureBorderClampSupported = OSG_GL3_FEATURES || isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f); _isGenerateMipMapSupported = builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f); + + _isTextureMultisampledSupported = isGLExtensionSupported(contextID,"GL_ARB_texture_multisample"); _isShadowSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_shadow"); @@ -2251,10 +2253,12 @@ Texture::Extensions::Extensions(unsigned int contextID) setGLExtensionFuncPtr(_glCompressedTexImage2D,"glCompressedTexImage2D","glCompressedTexImage2DARB"); setGLExtensionFuncPtr(_glCompressedTexSubImage2D,"glCompressedTexSubImage2D","glCompressedTexSubImage2DARB"); setGLExtensionFuncPtr(_glGetCompressedTexImage,"glGetCompressedTexImage","glGetCompressedTexImageARB");; + setGLExtensionFuncPtr(_glTexImage2DMultisample, "glTexImage2DMultisample", "glTexImage2DMultisampleARB"); setGLExtensionFuncPtr(_glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB"); setGLExtensionFuncPtr(_glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB"); - + + if (_glTexParameterIiv == NULL) setGLExtensionFuncPtr(_glTexParameterIiv, "glTexParameterIivEXT"); if (_glTexParameterIuiv == NULL) setGLExtensionFuncPtr(_glTexParameterIuiv, "glTexParameterIuivEXT"); diff --git a/src/osg/Texture2DMultisample.cpp b/src/osg/Texture2DMultisample.cpp new file mode 100644 index 000000000..45ccb25dd --- /dev/null +++ b/src/osg/Texture2DMultisample.cpp @@ -0,0 +1,140 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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. + * + * Texture2DMultisample codes Copyright (C) 2010 Marcin Hajder + * Thanks to to my company http://www.ai.com.pl for allowing me free this work. +*/ + +#include +#include +#include +#include + +using namespace osg; + +Texture2DMultisample::Texture2DMultisample(): + _textureWidth(0), + _textureHeight(0), + _numSamples(1), + _fixedsamplelocations(GL_FALSE) +{ +} + +Texture2DMultisample::Texture2DMultisample(GLsizei numSamples, GLboolean fixedsamplelocations): + _textureWidth(0), + _textureHeight(0), + _numSamples(numSamples), + _fixedsamplelocations(fixedsamplelocations) +{ +} + +Texture2DMultisample::Texture2DMultisample(const Texture2DMultisample& text,const CopyOp& copyop): + Texture(text,copyop), + _textureWidth(text._textureWidth), + _textureHeight(text._textureHeight), + _numSamples(text._numSamples), + _fixedsamplelocations(text._fixedsamplelocations) +{ +} + +Texture2DMultisample::~Texture2DMultisample() +{ +} + +int Texture2DMultisample::compare(const StateAttribute& sa) const +{ + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Parameter macro's below. + COMPARE_StateAttribute_Types(Texture2DMultisample,sa) + + + int result = compareTexture(rhs); + if (result!=0) return result; + + // compare each parameter in turn against the rhs. + if (_textureWidth != 0 && rhs._textureWidth != 0) + { + COMPARE_StateAttribute_Parameter(_textureWidth) + } + if (_textureHeight != 0 && rhs._textureHeight != 0) + { + COMPARE_StateAttribute_Parameter(_textureHeight) + } + if (_numSamples != 0 && rhs._numSamples != 0) + { + COMPARE_StateAttribute_Parameter(_numSamples) + } + if (_fixedsamplelocations != 0 && rhs._fixedsamplelocations != 0) + { + COMPARE_StateAttribute_Parameter(_fixedsamplelocations) + } + + + return 0; // passed all the above comparison macro's, must be equal. +} + +void Texture2DMultisample::apply(State& state) const +{ + // current OpenGL context. + const unsigned int contextID = state.getContextID(); + const Extensions* extensions = getExtensions(contextID,true); + if (!extensions->isTextureMultisampledSupported()) + { + OSG_INFO<<"Texture2DMultisample not supoorted."<getApplyTime())); + tom->getNumberApplied()++; + + // get the texture object for the current contextID. + TextureObject* textureObject = getTextureObject(contextID); + + if (textureObject) + { + textureObject->bind(); + } + else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_numSamples!=0) ) + { + _textureObjectBuffer[contextID] = textureObject = + generateTextureObject( this, + contextID, + getTextureTarget(), + 1, + _internalFormat, + _textureWidth, + _textureHeight, + 1, + _borderWidth); + + textureObject->bind(); + + extensions->glTexImage2DMultisample( getTextureTarget(), + _numSamples, + _internalFormat, + _textureWidth, + _textureHeight, + _fixedsamplelocations ); + + } + else + { + glBindTexture( getTextureTarget(), 0 ); + } +} + +void Texture2DMultisample::computeInternalFormat() const +{ + computeInternalFormatType(); +} + diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index 15a3e9902..aeb5fcc6f 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -283,6 +284,7 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo) osg::Texture* texture = itr->second._texture.get(); osg::Texture1D* texture1D = 0; osg::Texture2D* texture2D = 0; + osg::Texture2DMultisample* texture2DMS = 0; osg::Texture3D* texture3D = 0; osg::TextureCubeMap* textureCubeMap = 0; osg::TextureRectangle* textureRectangle = 0; @@ -300,6 +302,13 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo) texture2D->setTextureSize(width,height); } } + else if (0 != (texture2DMS = dynamic_cast(texture))) + { + if (texture2DMS->getTextureWidth()==0 || texture2DMS->getTextureHeight()==0) + { + texture2DMS->setTextureSize(width,height); + } + } else if (0 != (texture3D = dynamic_cast(texture))) { if (texture3D->getTextureWidth()==0 || texture3D->getTextureHeight()==0 || texture3D->getTextureDepth()==0 )