Texture.hh 10 KB
Newer Older
Robert Menzel's avatar
Robert Menzel committed
1
2
3
4
5
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University         //
// All rights reserved.                                                       //
////////////////////////////////////////////////////////////////////////////////

6
7
#ifndef ACGL_OPENGL_OBJECTS_TEXTURE_HH
#define ACGL_OPENGL_OBJECTS_TEXTURE_HH
Robert Menzel's avatar
Robert Menzel committed
8

Robert Menzel's avatar
Robert Menzel committed
9
10
11
12
13
/*
 * A Texture wrapps the OpenGL texture. To fill these with data from image files a
 * matching TextureControllerFile* is needed.
 */

Robert Menzel's avatar
Robert Menzel committed
14
15
#include <ACGL/ACGL.hh>

16
#include <ACGL/Base/Macros.hh>
Robert Menzel's avatar
Robert Menzel committed
17
18
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Tools.hh>
Robert Menzel's avatar
Robert Menzel committed
19
20
21
#include <ACGL/Math/Math.hh>

#include <vector>
Robert Menzel's avatar
Robert Menzel committed
22
#include <tr1/memory>
Robert Menzel's avatar
Robert Menzel committed
23
24

namespace ACGL{
Robert Menzel's avatar
Robert Menzel committed
25
namespace OpenGL{
Robert Menzel's avatar
Robert Menzel committed
26
27
28

class Texture
{
29
    ACGL_NOT_COPYABLE(Texture)
Robert Menzel's avatar
Robert Menzel committed
30
31
32
33
34

    // ========================================================================================================= \/
    // ============================================================================================ CONSTRUCTORS \/
    // ========================================================================================================= \/
public:
35
36
37
38
39
    //!
    /*!
        Default texture parameters taken from: http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml
     */
    Texture(GLenum _target)
Robert Menzel's avatar
Robert Menzel committed
40
    :   mContext(0),
41
        mTarget(_target),
Robert Menzel's avatar
Robert Menzel committed
42
43
44
        mWidth(0),
        mHeight(0),
        mDepth(0),
45
46
47
48
49
        mInternalFormat(GL_RGBA),
        mFormat(GL_RGBA),
        mType(GL_UNSIGNED_BYTE),
        mMinFilter(GL_NEAREST_MIPMAP_LINEAR),
        mMagFilter(GL_LINEAR)
Robert Menzel's avatar
Robert Menzel committed
50
51
    {
        glGenTextures(1, &mContext);
52
53
54
        if (openGLCriticalErrorOccured() ) {
            ACGL::Utils::error() << "could not generate texture!" << std::endl;
        }
Robert Menzel's avatar
Robert Menzel committed
55
56
57
58
59
60
61
62
63
64
65
66
67
    }

    virtual ~Texture(void)
    {
        // context 0 will get ignored by OpenGL
        glDeleteTextures(1, &mContext);
    }

    // ==================================================================================================== \/
    // ============================================================================================ GETTERS \/
    // ==================================================================================================== \/
public:
    inline GLuint  getContext        (void) const { return mContext;        }
68
    inline GLenum  getTarget         (void) const { return mTarget;         }
Robert Menzel's avatar
Robert Menzel committed
69
70
71
72
73
74
    inline GLsizei getWidth          (void) const { return mWidth;          }
    inline GLsizei getHeight         (void) const { return mHeight;         }
    inline GLsizei getDepth          (void) const { return mDepth;          }
    inline GLenum  getInternalFormat (void) const { return mInternalFormat; }
    inline GLenum  getFormat         (void) const { return mFormat;         }
    inline GLenum  getType           (void) const { return mType;           }
75
76
    inline GLint   getMinFilter      (void) const { return mMinFilter;      }
    inline GLint   getMagFilter      (void) const { return mMagFilter;      }
Robert Menzel's avatar
Robert Menzel committed
77
78
79
80
81
82
83
84
85
86

    // ===================================================================================================== \/
    // ============================================================================================ WRAPPERS \/
    // ===================================================================================================== \/
public:
    //! Activate texture unit and bind this texture.
    inline void bind(GLenum _textureUnit) const
    {
        glActiveTexture(GL_TEXTURE0 + _textureUnit);
        glBindTexture(mTarget, mContext);
87
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
88
89
90
91
92
93
    }
    
    //! Bind this texture.
    inline void bind(void) const
    {
        glBindTexture(mTarget, mContext);
94
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
95
96
    }

97
    //! Note: The function is not const, because it changes the corresponding GPU data
98
    inline void setMinFilter(GLint _value)
Robert Menzel's avatar
Robert Menzel committed
99
    {
100
        mMinFilter = _value;
101
        glBindTexture(mTarget, mContext);
102
        glTexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, mMinFilter);
103
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
104
105
    }

106
    //! Note: The function is not const, because it changes the corresponding GPU data
107
    inline void setMagFilter(GLint _value)
Robert Menzel's avatar
Robert Menzel committed
108
    {
109
        mMagFilter = _value;
110
        glBindTexture(mTarget, mContext);
111
        glTexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, mMagFilter);
112
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
113
114
    }

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    //! Set texture data for 1D, 2D or 3D textures
    inline void setImageData(const GLvoid* _pData = NULL)
    {
        if(mWidth > 0 && mHeight > 0 && mDepth > 0)
        {
            //3D
        }
        else if(mWidth > 0 && mHeight > 0)
        {
            setImageData2D(_pData);
        }
        else if(mWidth > 0)
        {
            //1D
        }
    }
    //! Set texture data for 1D, 2D or 3D textures
    inline void setImageData(
        const GLvoid* _pData,
Robert Menzel's avatar
Robert Menzel committed
134
        GLsizei _width,
135
136
        GLsizei _height,
        GLsizei _depth)
Robert Menzel's avatar
Robert Menzel committed
137
138
139
140
141
142
143
144
145
146
    {
        mWidth = _width;
        mHeight = _height;
        mDepth = _depth;
        if(mWidth > 0 && mHeight > 0 && mDepth > 0)
        {
            //3D
        }
        else if(mWidth > 0 && mHeight > 0)
        {
147
            setImageData2D(_pData);
Robert Menzel's avatar
Robert Menzel committed
148
149
150
151
152
153
154
        }
        else if(mWidth > 0)
        {
            //1D
        }
    }

155
156
157
    //! Set texture data for 1D, 2D or 3D textures
    inline void setImageData(
        const GLvoid* _pData,
Robert Menzel's avatar
Robert Menzel committed
158
        GLsizei _width,
159
160
161
162
163
        GLsizei _height,
        GLsizei _depth,
        GLenum _internalFormat,
        GLenum _format,
        GLenum _type)
Robert Menzel's avatar
Robert Menzel committed
164
165
166
    {
        mWidth = _width;
        mHeight = _height;
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
        mDepth = _depth;
        mInternalFormat = _internalFormat;
        mFormat = _format;
        mType = _type;
        if(mWidth > 0 && mHeight > 0 && mDepth > 0)
        {
            //3D
        }
        else if(mWidth > 0 && mHeight > 0)
        {
            setImageData2D(_pData);
        }
        else if(mWidth > 0)
        {
            //1D
        }
    }

    //! Set texture data
186
187
188
189
190
191
192
    inline void setImageData2D(
        const GLvoid* _pData,
        GLsizei _width,
        GLsizei _height,
        GLenum  _internalFormat,
        GLenum  _format,
        GLenum  _type)
193
    {
194
195
196
197
        mInternalFormat = _internalFormat;
        mFormat         = _format;
        mType           = _type;
        setImageData2D( _pData, _width, _height );
Robert Menzel's avatar
Robert Menzel committed
198
199
    }

200
    //! Set texture data
201
202
203
204
    inline void setImageData2D(
        const GLvoid* _pData,
        GLsizei _width,
        GLsizei _height)
Robert Menzel's avatar
Robert Menzel committed
205
    {
206
        mWidth  = _width;
207
        mHeight = _height;
208
        setImageData2D( _pData );
209
210
211
    }

    //! Set texture data
212
    inline void setImageData2D(const GLvoid* _pData = NULL)
213
214
    {
        glBindTexture(mTarget, mContext);
Robert Menzel's avatar
Robert Menzel committed
215
216
217
218
219
220
221
222
223
224
        glTexImage2D(
            mTarget,
            0,
            mInternalFormat,
            mWidth,
            mHeight,
            0,//no border
            mFormat,
            mType,
            _pData);
225
226
227
        if (openGLCriticalErrorOccured() ) {
            ACGL::Utils::error() << "could not generate texture!d" << std::endl;
        }
Robert Menzel's avatar
Robert Menzel committed
228
229
230
231
232
233
    }

    //! Set texture data for some mipmap level.
    /*!
        If you upload a texture for a higher mipmap level, the function will automatically determine
        its size calculating (w,h)/2^level where w and h are the width and height of the base texture.
234
        Note: The function is not const, because it changes the corresponding GPU data
Robert Menzel's avatar
Robert Menzel committed
235
     */
236
    inline void setImageDataMipMap2D(
Robert Menzel's avatar
Robert Menzel committed
237
        const GLvoid* _pData,
238
239
240
        GLint         _mipmapLevel,
        GLsizei       _width = 0,
        GLsizei       _height = 0)
Robert Menzel's avatar
Robert Menzel committed
241
    {
242
        glBindTexture(mTarget, mContext);
Robert Menzel's avatar
Robert Menzel committed
243
244
245
246
        glTexImage2D(
            mTarget,
            _mipmapLevel,
            mInternalFormat,
247
248
            _width > 0 ? _width : mWidth  / GLsizei(Math::Functions::pow(2.0f, float(_mipmapLevel))),
            _height > 0 ? _height : mHeight / GLsizei(Math::Functions::pow(2.0f, float(_mipmapLevel))),
Robert Menzel's avatar
Robert Menzel committed
249
250
251
252
253
            0,//no border
            mFormat,
            mType,
            _pData);
    }
254

255
    //! Set data for specific area within the 2D texture
256
    //! Note: The function is not const, because it changes the corresponding GPU data
257
    inline void setSubImageData2D(
258
259
260
261
262
263
            const GLvoid* _pData,
            int _x,
            int _y,
            int _width,
            int _height)
    {
264
        glBindTexture(mTarget, mContext);
265
266
267
268
269
270
271
272
        glTexSubImage2D(
            mTarget,
            0,
            _x,
            _y,
            _width,
            _height,
            mFormat,
273
274
275
276
277
            mType,
            _pData);
    }

    //! Set data for specific area within the 3D texture
278
    //! Note: The function is not const, because it changes the corresponding GPU data
279
    inline void setSubImageData3D(
280
281
282
283
284
285
286
287
            const GLvoid* _pData,
            int _x,
            int _y,
            int _z,
            int _width,
            int _height,
            int _depth)
    {
288
        glBindTexture(mTarget, mContext);
289
290
291
292
293
294
295
296
297
298
299
        glTexSubImage3D(
            mTarget,
            0,
            _x,
            _y,
            _z,
            _width,
            _height,
            _depth,
            mFormat,
            mType,
300
301
            _pData);
    }
Robert Menzel's avatar
Robert Menzel committed
302
    
303
304
305
    //! 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)
Robert Menzel's avatar
Robert Menzel committed
306
    {
307
        glBindTexture(mTarget, mContext);
Robert Menzel's avatar
Robert Menzel committed
308
309
        glEnable(mTarget);
        glGenerateMipmap(mTarget);
310
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
311
312
313
314
315
316
317
    } 

    // =================================================================================================== \/
    // ============================================================================================ FIELDS \/
    // =================================================================================================== \/
private:
    GLuint  mContext;
318
    GLenum  mTarget;
Robert Menzel's avatar
Robert Menzel committed
319
320
321
322
323
324
    GLsizei mWidth;
    GLsizei mHeight;
    GLsizei mDepth;
    GLenum  mInternalFormat;
    GLenum  mFormat;
    GLenum  mType;
325
326
    GLint   mMinFilter;
    GLint   mMagFilter;
Robert Menzel's avatar
Robert Menzel committed
327
328
};

329
330
ACGL_SHARED_TYPEDEF(Texture)

Robert Menzel's avatar
Robert Menzel committed
331
332

} // OpenGL
Robert Menzel's avatar
Robert Menzel committed
333
334
} // ACGL

335
#endif // ACGL_OPENGL_OBJECTS_TEXTURE_HH