Commit 81399d36 authored by Robert Menzel's avatar Robert Menzel

side-effect free sampling parameter setting and getting

parent 98b64e11
......@@ -35,13 +35,6 @@ namespace OpenGL{
* The TextureBase class holds the methods to define 2 & 3, the Images (incl. getter and setter)
* vary between different texture types, so subclasses will take care if that.
*
* Note that changing the sampler mode might bind this texture to the currently active texture unit
* (but don't rely on it as this 'side effect' might get removed later on).
*
* Multiple states, e.g. the sampling mode gets stored in a texture as getting this infos back from
* GL is not trivial (at least if the currently bound texture should not change).
*
* WARNING: All setter bind the texture to the currently active texture unit!
*/
class TextureBase
{
......@@ -62,17 +55,7 @@ public:
mHeight(1),
mDepth(1),
mInternalFormat(GL_RGBA),
mType(GL_UNSIGNED_BYTE),
mMinFilter(GL_NEAREST_MIPMAP_LINEAR),
mMagFilter(GL_LINEAR),
mWrapS(GL_REPEAT),
mWrapT(GL_REPEAT),
mWrapR(GL_REPEAT),
mMinLod(-1000),
mMaxLod(1000),
mLodBias(0.0f),
mCompareMode(GL_NONE),
mCompareFunc(GL_LEQUAL)
mType(GL_UNSIGNED_BYTE)
{
glGenTextures(1, &mObjectName);
if (openGLCriticalErrorOccured() ) {
......@@ -97,20 +80,18 @@ public:
inline GLsizei getDepth (void) const { return mDepth; }
inline GLenum getInternalFormat (void) const { return mInternalFormat; }
inline GLenum getType (void) const { return mType; }
inline GLint getMinFilter (void) const { return mMinFilter; }
inline GLint getMagFilter (void) const { return mMagFilter; }
inline GLint getMinLOD (void) const { return mMinLod; }
inline GLint getMaxLOD (void) const { return mMaxLod; }
inline GLfloat getLODBias (void) const { return mLodBias; }
inline GLenum getCompareMode (void) const { return mCompareMode; }
inline GLenum getCompareFunc (void) const { return mCompareFunc; }
#ifndef ACGL_OPENGLES_VERSION_20
inline GLenum getWrapS (void) const { return mWrapS; }
inline GLenum getWrapT (void) const { return mWrapT; }
inline GLenum getWrapR (void) const { return mWrapR; }
#endif // ACGL_OPENGLES_VERSION_20
inline GLint getMinFilter (void) const { return getParameterI(GL_TEXTURE_MIN_FILTER); }
inline GLint getMagFilter (void) const { return getParameterI(GL_TEXTURE_MAG_FILTER); }
inline GLint getMinLOD (void) const { return getParameterI(GL_TEXTURE_MIN_LOD); }
inline GLint getMaxLOD (void) const { return getParameterI(GL_TEXTURE_MAX_LOD); }
inline GLfloat getLODBias (void) const { return getParameterF(GL_TEXTURE_LOD_BIAS); }
inline GLenum getCompareMode (void) const { return (GLenum) getParameterI(GL_TEXTURE_COMPARE_MODE); }
inline GLenum getCompareFunc (void) const { return (GLenum) getParameterI(GL_TEXTURE_COMPARE_FUNC); }
#ifndef ACGL_OPENGLES_VERSION_20
inline GLenum getWrapS (void) const { return (GLenum) getParameterI(GL_TEXTURE_WRAP_S); }
inline GLenum getWrapT (void) const { return (GLenum) getParameterI(GL_TEXTURE_WRAP_T); }
inline GLenum getWrapR (void) const { return (GLenum) getParameterI(GL_TEXTURE_WRAP_R); }
#endif // ACGL_OPENGLES_VERSION_20
inline glm::uvec3 getSize (void) const { return glm::uvec3( mWidth, mHeight, mDepth ); }
// ===================================================================================================== \/
......@@ -132,23 +113,11 @@ public:
openGLRareError();
}
//! Note, side-effect: The function will bind this texture!
inline void setMinFilter(GLint _value)
{
mMinFilter = _value;
glBindTexture(mTarget, mObjectName);
glTexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, mMinFilter);
openGLRareError();
}
//! sets the minification filter
void setMinFilter(GLint _value = GL_NEAREST_MIPMAP_LINEAR );
//! Note, side-effect: The function will bind this texture!
inline void setMagFilter(GLint _value)
{
mMagFilter = _value;
glBindTexture(mTarget, mObjectName);
glTexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, mMagFilter);
openGLRareError();
}
//! sets the magnification filter
void setMagFilter(GLint _value = GL_LINEAR);
#ifndef ACGL_OPENGLES_VERSION_20
void setWrapS( GLenum _wrapS = GL_REPEAT );
......@@ -178,7 +147,6 @@ public:
void setAnisotropicFilter( GLfloat _sampleCount );
//! Generate mipmaps from the current base texture (i.e. the texture from level 0)
//! Note: The function is not const, because it changes the corresponding GPU data
void generateMipmaps(void);
// =================================================================================================== \/
......@@ -195,17 +163,13 @@ protected:
GLenum mInternalFormat;
GLenum mType;
// sampling parameters:
GLint mMinFilter;
GLint mMagFilter;
GLenum mWrapS;
GLenum mWrapT;
GLenum mWrapR;
GLint mMinLod;
GLint mMaxLod;
GLfloat mLodBias;
GLenum mCompareMode;
GLenum mCompareFunc;
// Checks what texture is currently bound at the texture target used by this texture
// to be later used to restore that texture (to be side effect free). Then binds this texture.
GLuint bindAndGetOldTexture() const;
// generic get parameter functions:
GLfloat getParameterF( GLenum _name ) const;
GLint getParameterI( GLenum _name ) const;
};
ACGL_SMARTPOINTER_TYPEDEFS(TextureBase)
......
......@@ -9,84 +9,91 @@
using namespace ACGL::OpenGL;
void TextureBase::setMinFilter(GLint _value)
{
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, _value);
glBindTexture(mTarget, prevTexture);
}
void TextureBase::setMagFilter(GLint _value)
{
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, _value);
glBindTexture(mTarget, prevTexture);
}
#ifndef ACGL_OPENGLES_VERSION_20
void TextureBase::setWrapS( GLenum _wrapS )
{
glBindTexture(mTarget, mObjectName);
mWrapS = _wrapS;
glTexParameteri(mTarget, GL_TEXTURE_WRAP_S, mWrapS);
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri(mTarget, GL_TEXTURE_WRAP_S, _wrapS);
glBindTexture(mTarget, prevTexture);
}
void TextureBase::setWrapT( GLenum _wrapT )
{
glBindTexture(mTarget, mObjectName);
mWrapT = _wrapT;
glTexParameteri(mTarget, GL_TEXTURE_WRAP_T, mWrapT);
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri(mTarget, GL_TEXTURE_WRAP_T, _wrapT);
glBindTexture(mTarget, prevTexture);
}
void TextureBase::setWrapR( GLenum _wrapR )
{
glBindTexture(mTarget, mObjectName);
mWrapR = _wrapR;
glTexParameteri(mTarget, GL_TEXTURE_WRAP_R, mWrapR);
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri(mTarget, GL_TEXTURE_WRAP_R, _wrapR);
glBindTexture(mTarget, prevTexture);
}
void TextureBase::setWrap( GLenum _wrapS, GLenum _wrapT, GLenum _wrapR )
{
glBindTexture(mTarget, mObjectName);
mWrapS = _wrapS;
glTexParameteri(mTarget, GL_TEXTURE_WRAP_S, mWrapS);
setWrapS(_wrapS);
if(_wrapT != 0)
{
mWrapT = _wrapT;
glTexParameteri(mTarget, GL_TEXTURE_WRAP_T, mWrapT);
setWrapT(_wrapT);
}
if(_wrapR != 0)
{
mWrapR = _wrapR;
glTexParameteri(mTarget, GL_TEXTURE_WRAP_R, mWrapR);
setWrapR(_wrapR);
}
openGLRareError();
}
#endif // ACGL_OPENGLES_VERSION_20
void TextureBase::setMinLOD( GLint _lod )
{
glBindTexture(mTarget, mObjectName);
mMinLod = _lod;
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri( mTarget, GL_TEXTURE_MIN_LOD, _lod);
glBindTexture(mTarget, prevTexture);
}
void TextureBase::setMaxLOD( GLint _lod )
{
glBindTexture(mTarget, mObjectName);
mMaxLod = _lod;
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri( mTarget, GL_TEXTURE_MAX_LOD, _lod);
glBindTexture(mTarget, prevTexture);
}
void TextureBase::setLODBias( GLfloat _bias )
{
glBindTexture(mTarget, mObjectName);
mLodBias = _bias;
GLuint prevTexture = bindAndGetOldTexture();
glTexParameterf( mTarget, GL_TEXTURE_LOD_BIAS, _bias);
glBindTexture(mTarget, prevTexture);
}
void TextureBase::setCompareMode( GLenum _mode )
{
glBindTexture(mTarget, mObjectName);
mCompareMode = _mode;
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri( mTarget, GL_TEXTURE_COMPARE_MODE, _mode);
glBindTexture(mTarget, prevTexture);
}
void TextureBase::setCompareFunc( GLenum _func )
{
glBindTexture(mTarget, mObjectName);
mCompareFunc = _func;
GLuint prevTexture = bindAndGetOldTexture();
glTexParameteri( mTarget, GL_TEXTURE_COMPARE_FUNC, _func);
glBindTexture(mTarget, prevTexture);
}
......@@ -94,10 +101,13 @@ void TextureBase::setAnisotropicFilter( GLfloat _sampleCount )
{
if ( ACGL_EXT_texture_filter_anisotrophic() ) {
// anisotrophic filtering is supported:
GLuint prevTexture = bindAndGetOldTexture();
_sampleCount = std::max( _sampleCount, 1.0f );
_sampleCount = std::min( _sampleCount, ACGL_MAX_TEXTURE_MAX_ANISOTROPY );
glBindTexture( mTarget, mObjectName );
glTexParameterf( mTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, _sampleCount );
glBindTexture(mTarget, prevTexture);
openGLRareError();
} else
{
......@@ -112,7 +122,8 @@ void TextureBase::setAnisotropicFilter( GLfloat _sampleCount )
void TextureBase::generateMipmaps(void)
{
glBindTexture(mTarget, mObjectName);
GLuint prevTexture = bindAndGetOldTexture();
#if (!defined ACGL_OPENGL_PROFILE_CORE)
// on some ATI systems texturing has to be enabled to generate MipMaps
// this is not needed by the spec an deprecated on core profiles (generates
......@@ -126,9 +137,53 @@ void TextureBase::generateMipmaps(void)
#else
glGenerateMipmap(mTarget);
#endif
glBindTexture(mTarget, prevTexture);
openGLRareError();
}
GLint TextureBase::getParameterI( GLenum _name ) const
{
GLuint prevTexture = bindAndGetOldTexture();
GLint param;
glGetTexParameteriv( mTarget, _name, &param );
glBindTexture(mTarget, prevTexture);
return param;
}
GLfloat TextureBase::getParameterF( GLenum _name ) const
{
GLuint prevTexture = bindAndGetOldTexture();
GLfloat param;
glGetTexParameterfv( mTarget, _name, &param );
glBindTexture(mTarget, prevTexture);
return param;
}
GLuint TextureBase::bindAndGetOldTexture() const
{
GLint prevTexture = 0;
if (mTarget == GL_TEXTURE_1D) glGetIntegerv(GL_TEXTURE_BINDING_1D, &prevTexture);
else if(mTarget == GL_TEXTURE_2D) glGetIntegerv(GL_TEXTURE_BINDING_2D, &prevTexture);
else if(mTarget == GL_TEXTURE_3D) glGetIntegerv(GL_TEXTURE_BINDING_3D, &prevTexture);
else if(mTarget == GL_TEXTURE_1D_ARRAY) glGetIntegerv(GL_TEXTURE_BINDING_1D_ARRAY, &prevTexture);
else if(mTarget == GL_TEXTURE_2D_ARRAY) glGetIntegerv(GL_TEXTURE_BINDING_2D_ARRAY, &prevTexture);
else if(mTarget == GL_TEXTURE_RECTANGLE) glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE, &prevTexture);
else if(mTarget == GL_TEXTURE_2D_MULTISAMPLE) glGetIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &prevTexture);
else if(mTarget == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) glGetIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, &prevTexture);
else if(mTarget == GL_TEXTURE_BINDING_CUBE_MAP) glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &prevTexture);
else if(mTarget == GL_TEXTURE_BINDING_CUBE_MAP_ARRAY) glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, &prevTexture);
else if(mTarget == GL_TEXTURE_BINDING_BUFFER) glGetIntegerv(GL_TEXTURE_BINDING_BUFFER, &prevTexture);
else {
ACGL::Utils::error() << "Unknown texture target, will create sideeffecs as old bound texture can not get restored!" << std::endl;
}
glBindTexture(mTarget, mObjectName);
return (GLuint) prevTexture;
}
//////////////////////////////////////////////////////////////////////////
//
// old Texture class:
......@@ -138,19 +193,10 @@ SharedTextureData Texture::getImageData(GLint _lod, GLenum _type) const
{
if(_type == GL_INVALID_ENUM) _type = mType;
// remember the previously bound texture
GLint prevTexture;
// remember the previously bound texture and bind this one
GLuint prevTexture = bindAndGetOldTexture();
if (mTarget == GL_TEXTURE_1D) glGetIntegerv(GL_TEXTURE_BINDING_1D, &prevTexture);
else if(mTarget == GL_TEXTURE_2D) glGetIntegerv(GL_TEXTURE_BINDING_2D, &prevTexture);
else if(mTarget == GL_TEXTURE_3D) glGetIntegerv(GL_TEXTURE_BINDING_3D, &prevTexture);
else if(mTarget == GL_TEXTURE_1D_ARRAY) glGetIntegerv(GL_TEXTURE_BINDING_1D_ARRAY, &prevTexture);
else if(mTarget == GL_TEXTURE_2D_ARRAY) glGetIntegerv(GL_TEXTURE_BINDING_2D_ARRAY, &prevTexture);
else if(mTarget == GL_TEXTURE_RECTANGLE) glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE, &prevTexture);
else if(mTarget == GL_TEXTURE_2D_MULTISAMPLE) glGetIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &prevTexture);
else if(mTarget == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) glGetIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, &prevTexture);
// determine the required buffer size to hold the requested LOD level
bind();
GLint width, height, depth;
glGetTexLevelParameteriv(mTarget, _lod, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(mTarget, _lod, GL_TEXTURE_HEIGHT, &height);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment