From Marcin Hajder, "This submission contains Texture2DMultisample osg implementation.
Texture2DMultismaple as name suggests provides means to directly access subsamples of rendered FBO target. (GLSL 1.5 texelFetch call). Recently I was working on deferred renderer with OSG, during that I noticed there is no support for multisampled textures (GL_ARB_texture_multisample extension). After consultations with Paul Martz and Wojtek Lewandowski I added Texture2DMultisample class and made few necessary changes around osg::FrameBufferObject, osg::Texture and osgUtil::RenderStage classes." and from follow email: "Fixed. According to ARB_texture_multisample extension specification multisample textures don't need TexParameters since they can only be fetched with texelFetch."
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
95
include/osg/Texture2DMultisample
Normal file
95
include/osg/Texture2DMultisample
Normal file
@@ -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 <osg/Texture>
|
||||
|
||||
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
|
||||
@@ -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
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/Texture1D>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/Texture2DMultisample>
|
||||
#include <osg/Texture3D>
|
||||
#include <osg/Texture2DArray>
|
||||
#include <osg/TextureCubeMap>
|
||||
@@ -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<osg::Texture2DMultisample*>(texture);
|
||||
if (texture2DMS)
|
||||
{
|
||||
_ximpl = new Pimpl(Pimpl::TEXTURE2DMULTISAMPLE, attachment._level);
|
||||
_ximpl->textureTarget = texture2DMS;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::Texture3D* texture3D = dynamic_cast<osg::Texture3D*>(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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
140
src/osg/Texture2DMultisample.cpp
Normal file
140
src/osg/Texture2DMultisample.cpp
Normal file
@@ -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 <osg/GLExtensions>
|
||||
#include <osg/Texture2DMultisample>
|
||||
#include <osg/State>
|
||||
#include <osg/Notify>
|
||||
|
||||
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."<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
|
||||
ElapsedTime elapsedTime(&(tom->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();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <osg/Notify>
|
||||
#include <osg/Texture1D>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/Texture2DMultisample>
|
||||
#include <osg/Texture3D>
|
||||
#include <osg/TextureRectangle>
|
||||
#include <osg/TextureCubeMap>
|
||||
@@ -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<osg::Texture2DMultisample*>(texture)))
|
||||
{
|
||||
if (texture2DMS->getTextureWidth()==0 || texture2DMS->getTextureHeight()==0)
|
||||
{
|
||||
texture2DMS->setTextureSize(width,height);
|
||||
}
|
||||
}
|
||||
else if (0 != (texture3D = dynamic_cast<osg::Texture3D*>(texture)))
|
||||
{
|
||||
if (texture3D->getTextureWidth()==0 || texture3D->getTextureHeight()==0 || texture3D->getTextureDepth()==0 )
|
||||
|
||||
Reference in New Issue
Block a user