Texture.hh 10.3 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
#include <ACGL/ACGL.hh>

11
#include <ACGL/Base/Macros.hh>
Robert Menzel's avatar
Robert Menzel committed
12
13
#include <ACGL/OpenGL/GL.hh>
#include <ACGL/OpenGL/Tools.hh>
Robert Menzel's avatar
Robert Menzel committed
14
15
16
#include <ACGL/Math/Math.hh>

#include <vector>
Robert Menzel's avatar
Robert Menzel committed
17
#include <tr1/memory>
Robert Menzel's avatar
Robert Menzel committed
18
19

namespace ACGL{
Robert Menzel's avatar
Robert Menzel committed
20
namespace OpenGL{
Robert Menzel's avatar
Robert Menzel committed
21
22
23

class Texture
{
24
    ACGL_NOT_COPYABLE(Texture)
Robert Menzel's avatar
Robert Menzel committed
25
26
27
28
29

    // ========================================================================================================= \/
    // ============================================================================================ CONSTRUCTORS \/
    // ========================================================================================================= \/
public:
30
31
32
33
34
    //!
    /*!
        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
35
    :   mContext(0),
36
        mTarget(_target),
Robert Menzel's avatar
Robert Menzel committed
37
38
39
        mWidth(0),
        mHeight(0),
        mDepth(0),
40
41
42
43
44
        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
45
46
    {
        glGenTextures(1, &mContext);
47
48
49
        if (openGLCriticalErrorOccured() ) {
            ACGL::Utils::error() << "could not generate texture!" << std::endl;
        }
Robert Menzel's avatar
Robert Menzel committed
50
51
52
53
54
55
56
57
58
59
60
61
62
    }

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

    // ==================================================================================================== \/
    // ============================================================================================ GETTERS \/
    // ==================================================================================================== \/
public:
    inline GLuint  getContext        (void) const { return mContext;        }
63
    inline GLenum  getTarget         (void) const { return mTarget;         }
Robert Menzel's avatar
Robert Menzel committed
64
65
66
67
68
69
    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;           }
70
71
    inline GLint   getMinFilter      (void) const { return mMinFilter;      }
    inline GLint   getMagFilter      (void) const { return mMagFilter;      }
Robert Menzel's avatar
Robert Menzel committed
72
73
74
75
76
77
78
79
80
81

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

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

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

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    //! 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
129
        GLsizei _width,
130
131
        GLsizei _height,
        GLsizei _depth)
Robert Menzel's avatar
Robert Menzel committed
132
133
134
135
136
137
138
139
140
141
    {
        mWidth = _width;
        mHeight = _height;
        mDepth = _depth;
        if(mWidth > 0 && mHeight > 0 && mDepth > 0)
        {
            //3D
        }
        else if(mWidth > 0 && mHeight > 0)
        {
142
            setImageData2D(_pData);
Robert Menzel's avatar
Robert Menzel committed
143
144
145
146
147
148
149
        }
        else if(mWidth > 0)
        {
            //1D
        }
    }

150
151
152
    //! Set texture data for 1D, 2D or 3D textures
    inline void setImageData(
        const GLvoid* _pData,
Robert Menzel's avatar
Robert Menzel committed
153
        GLsizei _width,
154
155
156
157
158
        GLsizei _height,
        GLsizei _depth,
        GLenum _internalFormat,
        GLenum _format,
        GLenum _type)
Robert Menzel's avatar
Robert Menzel committed
159
160
161
    {
        mWidth = _width;
        mHeight = _height;
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        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
    inline void setImageData2D(const GLvoid* _pData = NULL)
    {
183
        glBindTexture(mTarget, mContext);
Robert Menzel's avatar
Robert Menzel committed
184
185
186
187
188
189
190
191
192
        glTexImage2D(
            mTarget,
            0,
            mInternalFormat,
            mWidth,
            mHeight,
            0,//no border
            mFormat,
            mType,
193
194
195
196
            _pData);
        if (openGLCriticalErrorOccured() ) {
            ACGL::Utils::error() << "could not generate texture!d" << std::endl;
        }
Robert Menzel's avatar
Robert Menzel committed
197
198
    }

199
    //! Set texture data
200
201
202
203
    inline void setImageData2D(
        const GLvoid* _pData,
        GLsizei _width,
        GLsizei _height)
Robert Menzel's avatar
Robert Menzel committed
204
    {
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
        mWidth = _width;
        mHeight = _height;
        glBindTexture(mTarget, mContext);
        glTexImage2D(
            mTarget,
            0,
            mInternalFormat,
            mWidth,
            mHeight,
            0,//no border
            mFormat,
            mType,
            _pData);
    }

    //! Set texture data
221
222
223
224
225
226
227
    inline void setImageData2D(
        const GLvoid* _pData,
        GLsizei _width,
        GLsizei _height,
        GLenum _internalFormat,
        GLenum _format,
        GLenum _type)
228
    {
229
230
231
232
233
        mWidth = _width;
        mHeight = _height;
        mInternalFormat = _internalFormat;
        mFormat = _format;
        mType = _type;
234
        glBindTexture(mTarget, mContext);
Robert Menzel's avatar
Robert Menzel committed
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
        glTexImage2D(
            mTarget,
            0,
            mInternalFormat,
            mWidth,
            mHeight,
            0,//no border
            mFormat,
            mType,
            _pData);
    }

    //! 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.
251
        Note: The function is not const, because it changes the corresponding GPU data
Robert Menzel's avatar
Robert Menzel committed
252
     */
253
    inline void setImageDataMipMap2D(
Robert Menzel's avatar
Robert Menzel committed
254
        const GLvoid* _pData,
255
256
257
        GLint         _mipmapLevel,
        GLsizei       _width = 0,
        GLsizei       _height = 0)
Robert Menzel's avatar
Robert Menzel committed
258
    {
259
        glBindTexture(mTarget, mContext);
Robert Menzel's avatar
Robert Menzel committed
260
261
262
263
        glTexImage2D(
            mTarget,
            _mipmapLevel,
            mInternalFormat,
264
265
            _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
266
267
268
269
270
            0,//no border
            mFormat,
            mType,
            _pData);
    }
271

272
    //! Set data for specific area within the 2D texture
273
    //! Note: The function is not const, because it changes the corresponding GPU data
274
    inline void setSubImageData2D(
275
276
277
278
279
280
            const GLvoid* _pData,
            int _x,
            int _y,
            int _width,
            int _height)
    {
281
        glBindTexture(mTarget, mContext);
282
283
284
285
286
287
288
289
        glTexSubImage2D(
            mTarget,
            0,
            _x,
            _y,
            _width,
            _height,
            mFormat,
290
291
292
293
294
            mType,
            _pData);
    }

    //! Set data for specific area within the 3D texture
295
    //! Note: The function is not const, because it changes the corresponding GPU data
296
    inline void setSubImageData3D(
297
298
299
300
301
302
303
304
            const GLvoid* _pData,
            int _x,
            int _y,
            int _z,
            int _width,
            int _height,
            int _depth)
    {
305
        glBindTexture(mTarget, mContext);
306
307
308
309
310
311
312
313
314
315
316
        glTexSubImage3D(
            mTarget,
            0,
            _x,
            _y,
            _z,
            _width,
            _height,
            _depth,
            mFormat,
            mType,
317
318
            _pData);
    }
Robert Menzel's avatar
Robert Menzel committed
319
    
320
321
322
    //! 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
323
    {
324
        glBindTexture(mTarget, mContext);
Robert Menzel's avatar
Robert Menzel committed
325
326
        glEnable(mTarget);
        glGenerateMipmap(mTarget);
327
        openGLRareError();
Robert Menzel's avatar
Robert Menzel committed
328
329
330
331
332
333
334
    } 

    // =================================================================================================== \/
    // ============================================================================================ FIELDS \/
    // =================================================================================================== \/
private:
    GLuint  mContext;
335
    GLenum  mTarget;
Robert Menzel's avatar
Robert Menzel committed
336
337
338
339
340
341
    GLsizei mWidth;
    GLsizei mHeight;
    GLsizei mDepth;
    GLenum  mInternalFormat;
    GLenum  mFormat;
    GLenum  mType;
342
343
    GLint   mMinFilter;
    GLint   mMagFilter;
Robert Menzel's avatar
Robert Menzel committed
344
345
};

346
347
ACGL_SHARED_TYPEDEF(Texture)

Robert Menzel's avatar
Robert Menzel committed
348
349

} // OpenGL
Robert Menzel's avatar
Robert Menzel committed
350
351
} // ACGL

352
#endif // ACGL_OPENGL_OBJECTS_TEXTURE_HH