From Art Trevs, "Features of the patch are:

- Implementation of integer textures as in EXT_texture_integer

- setBorderColor(Vec4) changed to setBorderColor(Vec4d) to pass double values
as border color. (Probably we have to provide an overloading function to
still support Vec4f ?)

- new method Texture::getInternalFormatType() added. Gives information if the
internal format normalized, float, signed integer or unsigned integer. Can
help people to write better code ;-)

"

Futher changes to this submission by Robert Osfield, changed the dirty mipmap
flag into a buffer_value<> vector to ensure safe handling of multiple contexts.
This commit is contained in:
Robert Osfield
2007-09-11 12:04:58 +00:00
parent 98763cc4c5
commit 5e83ae4821
22 changed files with 807 additions and 48 deletions

View File

@@ -18,6 +18,7 @@
#include <osg/GLU>
#include <osg/Timer>
#include <osg/ApplicationUsage>
#include <osg/FrameBufferObject>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Mutex>
@@ -358,7 +359,8 @@ Texture::Texture():
_use_shadow_comparison(false),
_shadow_compare_func(LEQUAL),
_shadow_texture_mode(LUMINANCE),
_shadow_ambient(0)
_shadow_ambient(0),
_internalFormatType(NORMALIZED)
{
}
@@ -383,7 +385,8 @@ Texture::Texture(const Texture& text,const CopyOp& copyop):
_use_shadow_comparison(text._use_shadow_comparison),
_shadow_compare_func(text._shadow_compare_func),
_shadow_texture_mode(text._shadow_texture_mode),
_shadow_ambient(text._shadow_ambient)
_shadow_ambient(text._shadow_ambient),
_internalFormatType(text._internalFormatType)
{
}
@@ -422,6 +425,8 @@ int Texture::compareTexture(const Texture& rhs) const
COMPARE_StateAttribute_Parameter(_clientStorageHint)
COMPARE_StateAttribute_Parameter(_resizeNonPowerOfTwoHint)
COMPARE_StateAttribute_Parameter(_internalFormatType);
return 0;
}
@@ -492,6 +497,7 @@ void Texture::setMaxAnisotropy(float anis)
}
}
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
void Texture::dirtyTextureObject()
{
@@ -513,10 +519,12 @@ void Texture::takeTextureObjects(Texture::TextureObjectListMap& toblm)
void Texture::dirtyTextureParameters()
{
for(unsigned int i=0;i<_texParametersDirtyList.size();++i)
{
_texParametersDirtyList[i] = 1;
}
_texParametersDirtyList.setAllElementsTo(1);
}
void Texture::allocateMipmapLevels()
{
_texMipmapGenerationDirtyList.setAllElementsTo(1);
}
void Texture::computeInternalFormatWithImage(const osg::Image& image) const
@@ -609,10 +617,88 @@ void Texture::computeInternalFormatWithImage(const osg::Image& image) const
}
_internalFormat = internalFormat;
computeInternalFormatType();
//osg::notify(osg::NOTICE)<<"Internal format="<<std::hex<<internalFormat<<std::dec<<std::endl;
}
void Texture::computeInternalFormatType() const
{
// Here we could also precompute the _sourceFormat if it is not set,
// since it is different for different internal formats
// (i.e. rgba integer texture --> _sourceFormat = GL_RGBA_INTEGER_EXT)
// Should we do this? ( Art, 09. Sept. 2007)
// compute internal format type based on the internal format
switch(_internalFormat)
{
case GL_RGBA32UI_EXT:
case GL_RGBA16UI_EXT:
case GL_RGBA8UI_EXT:
case GL_RGB32UI_EXT:
case GL_RGB16UI_EXT:
case GL_RGB8UI_EXT:
case GL_LUMINANCE32UI_EXT:
case GL_LUMINANCE16UI_EXT:
case GL_LUMINANCE8UI_EXT:
case GL_INTENSITY32UI_EXT:
case GL_INTENSITY16UI_EXT:
case GL_INTENSITY8UI_EXT:
case GL_LUMINANCE_ALPHA32UI_EXT:
case GL_LUMINANCE_ALPHA16UI_EXT:
case GL_LUMINANCE_ALPHA8UI_EXT :
_internalFormatType = UNSIGNED_INTEGER;
break;
case GL_RGBA32I_EXT:
case GL_RGBA16I_EXT:
case GL_RGBA8I_EXT:
case GL_RGB32I_EXT:
case GL_RGB16I_EXT:
case GL_RGB8I_EXT:
case GL_LUMINANCE32I_EXT:
case GL_LUMINANCE16I_EXT:
case GL_LUMINANCE8I_EXT:
case GL_INTENSITY32I_EXT:
case GL_INTENSITY16I_EXT:
case GL_INTENSITY8I_EXT:
case GL_LUMINANCE_ALPHA32I_EXT:
case GL_LUMINANCE_ALPHA16I_EXT:
case GL_LUMINANCE_ALPHA8I_EXT:
_internalFormatType = SIGNED_INTEGER;
break;
case GL_RGBA32F_ARB:
case GL_RGBA16F_ARB:
case GL_RGB32F_ARB:
case GL_RGB16F_ARB:
case GL_LUMINANCE32F_ARB:
case GL_LUMINANCE16F_ARB:
case GL_INTENSITY32F_ARB:
case GL_INTENSITY16F_ARB:
case GL_LUMINANCE_ALPHA32F_ARB:
case GL_LUMINANCE_ALPHA16F_ARB:
_internalFormatType = FLOAT;
break;
default:
_internalFormatType = NORMALIZED;
break;
};
}
bool Texture::isCompressedInternalFormat() const
{
return isCompressedInternalFormat(getInternalFormat());
@@ -703,7 +789,9 @@ void Texture::applyTexParameters(GLenum target, State& state) const
glTexParameteri( target, GL_TEXTURE_MIN_FILTER, _min_filter);
glTexParameteri( target, GL_TEXTURE_MAG_FILTER, _mag_filter);
if (extensions->isTextureFilterAnisotropicSupported())
// Art: I think anisotropic filtering is not supported by the integer textures
if (extensions->isTextureFilterAnisotropicSupported() &&
_internalFormatType != SIGNED_INTEGER && _internalFormatType != UNSIGNED_INTEGER)
{
// note, GL_TEXTURE_MAX_ANISOTROPY_EXT will either be defined
// by gl.h (or via glext.h) or by include/osg/Texture.
@@ -712,10 +800,23 @@ void Texture::applyTexParameters(GLenum target, State& state) const
if (extensions->isTextureBorderClampSupported())
{
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, _borderColor.ptr());
if (_internalFormatType == SIGNED_INTEGER)
{
GLint color[4] = {(GLint)_borderColor.r(), (GLint)_borderColor.g(), (GLint)_borderColor.b(), (GLint)_borderColor.a()};
extensions->glTexParameterIiv(target, GL_TEXTURE_BORDER_COLOR, color);
}else if (_internalFormatType == UNSIGNED_INTEGER)
{
GLuint color[4] = {(GLuint)_borderColor.r(), (GLuint)_borderColor.g(), (GLuint)_borderColor.b(), (GLuint)_borderColor.a()};
extensions->glTexParameterIuiv(target, GL_TEXTURE_BORDER_COLOR, color);
}else{
GLfloat color[4] = {(GLfloat)_borderColor.r(), (GLfloat)_borderColor.g(), (GLfloat)_borderColor.b(), (GLfloat)_borderColor.a()};
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color);
}
}
if (extensions->isShadowSupported() && target == GL_TEXTURE_2D)
// integer texture are not supported by the shadow
if (extensions->isShadowSupported() && target == GL_TEXTURE_2D &&
_internalFormatType != SIGNED_INTEGER && _internalFormatType != UNSIGNED_INTEGER)
{
if (_use_shadow_comparison)
{
@@ -1290,6 +1391,46 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
}
void Texture::generateMipmap(State& state) const
{
const unsigned int contextID = state.getContextID();
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
// if not initialized before, then do nothing
if (textureObject == NULL) return;
_texMipmapGenerationDirtyList[contextID] = 0;
// if internal format does not provide automatic mipmap generation, then do manual allocation
if (_internalFormatType == SIGNED_INTEGER || _internalFormatType == UNSIGNED_INTEGER)
{
allocateMipmap(state);
return;
}
// get fbo extension which provides us with the glGenerateMipmapEXT function
osg::FBOExtensions* fbo_ext = osg::FBOExtensions::instance(state.getContextID(), true);
// check if the function is supported
if (fbo_ext->glGenerateMipmapEXT)
{
textureObject->bind();
fbo_ext->glGenerateMipmapEXT(textureObject->_target);
// inform state that this texture is the current one bound.
state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);
// if the function is not supported, then do manual allocation
}else
{
allocateMipmap(state);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Static map to manage the deletion of texture objects are the right time.
//////////////////////////////////////////////////////////////////////////////////////////////
@@ -1365,6 +1506,8 @@ Texture::Extensions::Extensions(const Extensions& rhs):
_isNonPowerOfTwoTextureMipMappedSupported = rhs._isNonPowerOfTwoTextureMipMappedSupported;
_isNonPowerOfTwoTextureNonMipMappedSupported = rhs._isNonPowerOfTwoTextureNonMipMappedSupported;
_isTextureIntegerEXTSupported = rhs._isTextureIntegerEXTSupported;
}
void Texture::Extensions::lowestCommonDenominator(const Extensions& rhs)
@@ -1395,6 +1538,8 @@ void Texture::Extensions::lowestCommonDenominator(const Extensions& rhs)
if (!rhs._isNonPowerOfTwoTextureMipMappedSupported) _isNonPowerOfTwoTextureMipMappedSupported = false;
if (!rhs._isNonPowerOfTwoTextureNonMipMappedSupported) _isNonPowerOfTwoTextureNonMipMappedSupported = false;
if (!rhs._isTextureIntegerEXTSupported) _isTextureIntegerEXTSupported = false;
}
void Texture::Extensions::setupGLExtensions(unsigned int contextID)
@@ -1438,6 +1583,8 @@ void Texture::Extensions::setupGLExtensions(unsigned int contextID)
_isNonPowerOfTwoTextureMipMappedSupported = _isNonPowerOfTwoTextureNonMipMappedSupported;
_isTextureIntegerEXTSupported = isGLExtensionSupported(contextID, "GL_EXT_texture_integer");
if (rendererString.find("Radeon")!=std::string::npos || rendererString.find("RADEON")!=std::string::npos)
{
_isNonPowerOfTwoTextureMipMappedSupported = false;
@@ -1473,9 +1620,40 @@ void Texture::Extensions::setupGLExtensions(unsigned int contextID)
_numTextureUnits = 1;
}
setGLExtensionFuncPtr(_glCompressedTexImage2D, "glCompressedTexImage2D","glCompressedTexImage2DARB");
setGLExtensionFuncPtr(_glCompressedTexSubImage2D, "glCompressedTexSubImage2D","glCompressedTexSubImage2DARB");
setGLExtensionFuncPtr(_glGetCompressedTexImage, "glGetCompressedTexImage","glGetCompressedTexImageARB");
setGLExtensionFuncPtr(_glCompressedTexImage2D,"glCompressedTexImage2D","glCompressedTexImage2DARB");
setGLExtensionFuncPtr(_glCompressedTexSubImage2D,"glCompressedTexSubImage2D","glCompressedTexSubImage2DARB");
setGLExtensionFuncPtr(_glGetCompressedTexImage,"glGetCompressedTexImage","glGetCompressedTexImageARB");;
setGLExtensionFuncPtr(_glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB");
setGLExtensionFuncPtr(_glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB");
if (_glTexParameterIiv == NULL) setGLExtensionFuncPtr(_glTexParameterIiv, "glTexParameterIivEXT");
if (_glTexParameterIuiv == NULL) setGLExtensionFuncPtr(_glTexParameterIuiv, "glTexParameterIuivEXT");
}
void Texture::Extensions::glTexParameterIiv(GLenum target, GLenum pname, const GLint* data) const
{
if (_glTexParameterIiv)
{
_glTexParameterIiv(target, pname, data);
}
else
{
notify(WARN)<<"Error: glTexParameterIiv not supported by OpenGL driver"<<std::endl;
}
}
void Texture::Extensions::glTexParameterIuiv(GLenum target, GLenum pname, const GLuint* data) const
{
if (_glTexParameterIuiv)
{
_glTexParameterIuiv(target, pname, data);
}
else
{
notify(WARN)<<"Error: glTexParameterIuiv not supported by OpenGL driver"<<std::endl;
}
}
void Texture::Extensions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) const