Texture.cc 7.86 KB
Newer Older
1 2 3 4 5
/***********************************************************************
 * Copyright 2011-2012 Computer Graphics Group RWTH Aachen University. *
 * All rights reserved.                                                *
 * Distributed under the terms of the MIT License (see LICENSE.TXT).   *
 **********************************************************************/
Robert Menzel's avatar
Robert Menzel committed
6

Robert Menzel's avatar
Robert Menzel committed
7
#include <ACGL/OpenGL/Objects/Texture.hh>
8
#include <ACGL/OpenGL/glloaders/extensions.hh> // for anisotrophic filtering
Robert Menzel's avatar
Robert Menzel committed
9

Robert Menzel's avatar
Robert Menzel committed
10
using namespace ACGL::OpenGL;
Robert Menzel's avatar
Robert Menzel committed
11

12 13 14 15 16 17 18 19 20 21 22 23 24 25
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);
}

26
#ifndef ACGL_OPENGLES_VERSION_20
Robert Menzel's avatar
Robert Menzel committed
27
void TextureBase::setWrapS( GLenum _wrapS )
28
{
29 30 31
    GLuint prevTexture = bindAndGetOldTexture();
    glTexParameteri(mTarget, GL_TEXTURE_WRAP_S, _wrapS);
    glBindTexture(mTarget, prevTexture);
32 33
}

Robert Menzel's avatar
Robert Menzel committed
34
void TextureBase::setWrapT( GLenum _wrapT )
35
{
36 37 38
    GLuint prevTexture = bindAndGetOldTexture();
    glTexParameteri(mTarget, GL_TEXTURE_WRAP_T, _wrapT);
    glBindTexture(mTarget, prevTexture);
39 40
}

Robert Menzel's avatar
Robert Menzel committed
41
void TextureBase::setWrapR( GLenum _wrapR )
42
{
43 44 45
    GLuint prevTexture = bindAndGetOldTexture();
    glTexParameteri(mTarget, GL_TEXTURE_WRAP_R, _wrapR);
    glBindTexture(mTarget, prevTexture);
46 47
}

Robert Menzel's avatar
Robert Menzel committed
48
void TextureBase::setWrap( GLenum _wrapS, GLenum _wrapT, GLenum _wrapR )
Robert Menzel's avatar
Robert Menzel committed
49
{
50
    setWrapS(_wrapS);
Robert Menzel's avatar
Robert Menzel committed
51 52 53

    if(_wrapT != 0)
    {
54
        setWrapT(_wrapT);
Robert Menzel's avatar
Robert Menzel committed
55 56 57 58
    }

    if(_wrapR != 0)
    {
59
        setWrapR(_wrapR);
Robert Menzel's avatar
Robert Menzel committed
60 61
    }
}
62
#endif // ACGL_OPENGLES_VERSION_20
Robert Menzel's avatar
Robert Menzel committed
63

64 65
void TextureBase::setMinLOD(  GLint _lod )
{
66
    GLuint prevTexture = bindAndGetOldTexture();
67
    glTexParameteri( mTarget, GL_TEXTURE_MIN_LOD, _lod);
68
    glBindTexture(mTarget, prevTexture);
69 70 71 72
}

void TextureBase::setMaxLOD(  GLint _lod )
{
73
    GLuint prevTexture = bindAndGetOldTexture();
74
    glTexParameteri( mTarget, GL_TEXTURE_MAX_LOD, _lod);
75
    glBindTexture(mTarget, prevTexture);
76 77 78 79
}

void TextureBase::setLODBias( GLfloat _bias )
{
80
    GLuint prevTexture = bindAndGetOldTexture();
81
    glTexParameterf( mTarget, GL_TEXTURE_LOD_BIAS, _bias);
82
    glBindTexture(mTarget, prevTexture);
83 84 85 86
}

void TextureBase::setCompareMode( GLenum _mode )
{
87
    GLuint prevTexture = bindAndGetOldTexture();
88
    glTexParameteri( mTarget, GL_TEXTURE_COMPARE_MODE, _mode);
89
    glBindTexture(mTarget, prevTexture);
90 91 92 93
}

void TextureBase::setCompareFunc( GLenum _func )
{
94
    GLuint prevTexture = bindAndGetOldTexture();
95
    glTexParameteri( mTarget, GL_TEXTURE_COMPARE_FUNC, _func);
96
    glBindTexture(mTarget, prevTexture);
97 98 99
}


Robert Menzel's avatar
Robert Menzel committed
100
void TextureBase::setAnisotropicFilter( GLfloat _sampleCount )
Robert Menzel's avatar
Robert Menzel committed
101
{
102
    if ( ACGL_EXT_texture_filter_anisotrophic() ) {
Robert Menzel's avatar
Robert Menzel committed
103
        // anisotrophic filtering is supported:
104 105
        GLuint prevTexture = bindAndGetOldTexture();

106 107
        _sampleCount = std::max( _sampleCount, 1.0f );
        _sampleCount = std::min( _sampleCount, ACGL_MAX_TEXTURE_MAX_ANISOTROPY );
Robert Menzel's avatar
Robert Menzel committed
108
        glTexParameterf( mTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, _sampleCount );
109 110

        glBindTexture(mTarget, prevTexture);
Robert Menzel's avatar
Robert Menzel committed
111 112 113
        openGLRareError();
    } else
    {
Robert Menzel's avatar
Robert Menzel committed
114 115 116 117 118 119
        if (_sampleCount != 1.0f ) {
            // anisotropic filtering will just increase the image quality, so this is just
            // a warning and no error, 1 sample is equal to no anisotrophic filtering, so ignore
            // that case entirely!
            ACGL::Utils::warning() << "Anisotropic filtering is not supported, ignored" << std::endl;
        }
Robert Menzel's avatar
Robert Menzel committed
120 121
    }
}
Janis Born's avatar
Janis Born committed
122

Robert Menzel's avatar
Robert Menzel committed
123 124
void TextureBase::generateMipmaps(void)
{
125 126
    GLuint prevTexture = bindAndGetOldTexture();

Robert Menzel's avatar
Robert Menzel committed
127 128 129 130 131 132 133 134 135 136 137 138 139
#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
    // an error on MacOS X Lion)
    glEnable(mTarget);
    openGLRareError();
#endif
#ifdef ACGL_OPENGL_VERSION_21
    // OpenGL 2 way to generate MipMaps
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
#else
    glGenerateMipmap(mTarget);
#endif
140 141

    glBindTexture(mTarget, prevTexture);
Robert Menzel's avatar
Robert Menzel committed
142 143 144
    openGLRareError();
}

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
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;
}

Robert Menzel's avatar
Robert Menzel committed
187 188 189 190
//////////////////////////////////////////////////////////////////////////
//
// old Texture class:

191
#ifndef ACGL_OPENGLES_VERSION_20
192
SharedTextureData Texture::getImageData(GLint _lod, GLenum _type) const
Janis Born's avatar
Janis Born committed
193
{
194
    if(_type == GL_INVALID_ENUM) _type = mType;
Janis Born's avatar
Janis Born committed
195

196 197
    // remember the previously bound texture and bind this one
    GLuint prevTexture = bindAndGetOldTexture();
198
    
Janis Born's avatar
Janis Born committed
199 200
    // determine the required buffer size to hold the requested LOD level
    GLint width, height, depth;
201
    glGetTexLevelParameteriv(mTarget, _lod, GL_TEXTURE_WIDTH,  &width);
Janis Born's avatar
Janis Born committed
202
    glGetTexLevelParameteriv(mTarget, _lod, GL_TEXTURE_HEIGHT, &height);
203
    glGetTexLevelParameteriv(mTarget, _lod, GL_TEXTURE_DEPTH,  &depth);
Janis Born's avatar
Janis Born committed
204 205

    // fetch the image data
206 207 208 209
    int channels = 4;
    if (mFormat == GL_RGB) channels = 3; // TODO: check the other channel types

    GLubyte* imageData = new GLubyte[width * height * getGLTypeSize(_type) * channels];
210
    glGetTexImage(mTarget, _lod, mFormat, _type, (GLvoid*)imageData);
Janis Born's avatar
Janis Born committed
211

212 213 214
    // revert to the previously bound texture
    glBindTexture(mTarget, prevTexture);

Janis Born's avatar
Janis Born committed
215 216 217 218 219 220
    // store the image data and meta information in a TextureData object
    SharedTextureData dataObject = SharedTextureData(new TextureData());
    dataObject->setWidth(width);
    dataObject->setHeight(height);
    dataObject->setDepth(depth);
    dataObject->setType(_type);
221
    dataObject->setFormat(mFormat);
Janis Born's avatar
Janis Born committed
222 223 224 225
    dataObject->setData(imageData); // dataObject will take care of freeing imageData

    return dataObject;
}
226
#endif // ES 2.0