root/OpenSceneGraph/trunk/src/osg/Texture2DArray.cpp @ 10606

Revision 10606, 24.4 kB (checked in by robert, 5 years ago)

Fixed the TextureObject?'s + GLBufferObject reassignment to a new set.

Disabled the unref after apply for a Texture classes when the texture pool is enabled

Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13#include <osg/GLExtensions>
14#include <osg/Texture2DArray>
15#include <osg/State>
16#include <osg/ImageSequence>
17#include <osg/Notify>
18
19#include <string.h>
20
21
22using namespace osg;
23
24Texture2DArray::Texture2DArray():
25            _textureWidth(0),
26            _textureHeight(0),
27            _textureDepth(0),
28            _numMipmapLevels(0)
29{
30}
31
32Texture2DArray::Texture2DArray(const Texture2DArray& text,const CopyOp& copyop):
33            Texture(text,copyop),
34            _textureWidth(text._textureWidth),
35            _textureHeight(text._textureHeight),
36            _textureDepth(text._textureDepth),
37            _numMipmapLevels(text._numMipmapLevels),
38            _subloadCallback(text._subloadCallback)
39{
40    // copy all images by iterating through all of them
41    for (int i=0; i < text._textureDepth; i++)
42    {
43        _images.push_back(copyop(text._images[i].get()));
44        _modifiedCount.push_back(ImageModifiedCount());
45    }
46}
47
48Texture2DArray::~Texture2DArray()
49{
50}
51
52int Texture2DArray::compare(const StateAttribute& sa) const
53{
54    // check the types are equal and then create the rhs variable
55    // used by the COMPARE_StateAttribute_Parameter macro's below.
56    COMPARE_StateAttribute_Types(Texture2DArray,sa)
57
58    bool noImages = true;
59    for (int n=0; n < _textureDepth; n++)
60    {
61        if (noImages && _images[n].valid()) noImages = false;
62        if (noImages && rhs._images[n].valid()) noImages = false;
63   
64        if (_images[n]!=rhs._images[n]) // smart pointer comparison.
65        {
66            if (_images[n].valid())
67            {
68                if (rhs._images[n].valid())
69                {
70                    int result = _images[n]->compare(*rhs._images[n]);
71                    if (result!=0) return result;
72                }
73                else
74                {
75                    return 1; // valid lhs._image is greater than null.
76                }
77            }
78            else if (rhs._images[n].valid())
79            {
80                return -1; // valid rhs._image is greater than null.
81            }
82        }
83    }
84
85   
86    if (noImages)
87    {
88        int result = compareTextureObjects(rhs);
89        if (result!=0) return result;
90    }
91
92    int result = compareTexture(rhs);
93    if (result!=0) return result;
94
95    // compare each parameter in turn against the rhs.
96    COMPARE_StateAttribute_Parameter(_textureWidth)
97    COMPARE_StateAttribute_Parameter(_textureHeight)
98    COMPARE_StateAttribute_Parameter(_textureDepth)
99    COMPARE_StateAttribute_Parameter(_subloadCallback)
100
101    return 0; // passed all the above comparison macro's, must be equal.
102}
103
104void Texture2DArray::setImage(unsigned int layer, Image* image)
105{
106    // check if the layer exceeds the texture depth
107    if (static_cast<int>(layer) >= _textureDepth)
108    {
109        // print warning and do nothing
110        notify(WARN)<<"Warning: Texture2DArray::setImage(..) failed, the given layer number is bigger then the size of the texture array."<<std::endl;
111        return;
112    }
113   
114    if (_images[layer] == image) return;
115
116    unsigned numImageSequencesBefore = 0;
117    for (unsigned int i=0; i<getNumImages(); ++i)
118    {
119        osg::ImageSequence* is = dynamic_cast<osg::ImageSequence*>(_images[i].get());
120        if (is) ++numImageSequencesBefore;
121    }
122
123    // set image
124    _images[layer] = image;
125   _modifiedCount[layer].setAllElementsTo(0);
126
127    // find out if we need to reset the update callback to handle the animation of ImageSequence
128    unsigned numImageSequencesAfter = 0;
129    for (unsigned int i=0; i<getNumImages(); ++i)
130    {
131        osg::ImageSequence* is = dynamic_cast<osg::ImageSequence*>(_images[i].get());
132        if (is) ++numImageSequencesAfter;
133    }
134
135    if (numImageSequencesBefore>0)
136    {
137        if (numImageSequencesAfter==0)
138        {
139            setUpdateCallback(0);
140            setDataVariance(osg::Object::STATIC);
141        }
142    }
143    else if (numImageSequencesAfter>0)
144    {
145        setUpdateCallback(new ImageSequence::UpdateCallback());
146        setDataVariance(osg::Object::DYNAMIC);
147    }
148}
149 
150void Texture2DArray::setTextureSize(int width, int height, int depth)
151{
152    // set dimensions
153    _textureWidth = width;
154    _textureHeight = height;
155    setTextureDepth(depth);
156}
157
158void Texture2DArray::setTextureDepth(int depth)
159{   
160    // if we decrease the number of layers, then delete non-used
161    if (depth < _textureDepth)
162    {
163        _images.resize(depth);
164        _modifiedCount.resize(depth);
165    }
166   
167    // if we increase the array, then add new empty elements
168    if (depth > _textureDepth)
169    {
170        _images.resize(depth, ref_ptr<Image>(0));
171        _modifiedCount.resize(depth, ImageModifiedCount());
172    }
173       
174    // resize the texture array
175    _textureDepth = depth;
176}
177
178Image* Texture2DArray::getImage(unsigned int layer)
179{
180    return _images[layer].get();
181}
182
183const Image* Texture2DArray::getImage(unsigned int layer) const
184{
185    return _images[layer].get();
186}
187
188bool Texture2DArray::imagesValid() const
189{
190    if (_textureDepth < 1) return false;
191    for (int n=0; n < _textureDepth; n++)
192    {
193        if (!_images[n].valid() || !_images[n]->data())
194            return false;
195    }
196    return true;
197}
198
199void Texture2DArray::computeInternalFormat() const
200{
201    if (imagesValid()) computeInternalFormatWithImage(*_images[0]);
202    else computeInternalFormatType();
203}
204
205
206void Texture2DArray::apply(State& state) const
207{
208    // get the contextID (user defined ID of 0 upwards) for the
209    // current OpenGL context.
210    const unsigned int contextID = state.getContextID();
211
212    Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID);
213    ElapsedTime elapsedTime(&(tom->getApplyTime()));
214    tom->getNumberApplied()++;
215
216    const Extensions* extensions = getExtensions(contextID,true);
217
218    // if not supported, then return
219    if (!extensions->isTexture2DArraySupported() || !extensions->isTexture3DSupported())
220    {
221        notify(WARN)<<"Warning: Texture2DArray::apply(..) failed, 2D texture arrays are not support by OpenGL driver."<<std::endl;
222        return;
223    }
224   
225    // get the texture object for the current contextID.
226    TextureObject* textureObject = getTextureObject(contextID);
227
228    // if we already have an texture object, then
229    if (textureObject != 0)
230    {
231        // bind texture object
232        textureObject->bind();
233
234        // if texture parameters changed, then reset them
235        if (getTextureParameterDirty(state.getContextID())) applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);
236
237        // if subload is specified, then use it to subload the images to GPU memory
238        if (_subloadCallback.valid())
239        {
240            _subloadCallback->subload(*this,state);
241        }
242        else
243        {
244            // for each image of the texture array do
245            for (GLsizei n=0; n < _textureDepth; n++)
246            {
247                osg::Image* image = _images[n].get();
248               
249                // if image content is modified, then upload it to the GPU memory
250                if (image && getModifiedCount(n,contextID) != image->getModifiedCount())
251                {
252                    applyTexImage2DArray_subload(state, image, _textureWidth, _textureHeight, n, _internalFormat, _numMipmapLevels);
253                    getModifiedCount(n,contextID) = image->getModifiedCount();
254                }
255            }
256        }
257
258    }
259   
260    // there is no texture object, but exists a subload callback, so use it to upload images
261    else if (_subloadCallback.valid())
262    {
263        // generate texture (i.e. glGenTexture) and apply parameters
264        _textureObjectBuffer[contextID] = textureObject = generateTextureObject(this, contextID, GL_TEXTURE_2D_ARRAY_EXT);
265        textureObject->bind();
266        applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT, state);
267        _subloadCallback->load(*this,state);
268    }
269   
270    // nothing before, but we have valid images, so do manual upload and create texture object manually
271    // TODO: we assume _images[0] is valid, however this may not be always the case
272    //       some kind of checking for the first valid image is required (Art, may 2008)
273    else if (imagesValid())
274    {
275        // compute the internal texture format, this set the _internalFormat to an appropriate value.
276        computeInternalFormat();
277
278        // compute the dimensions of the texture.
279        computeRequiredTextureDimensions(state,*_images[0],_textureWidth, _textureHeight, _numMipmapLevels);
280
281        // create texture object
282        textureObject = generateTextureObject(
283                this, contextID,GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
284       
285        // bind texture
286        textureObject->bind();
287        applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT, state);
288
289        // first we need to allocate the texture memory
290        extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
291                     _textureWidth, _textureHeight, _textureDepth,
292                     _borderWidth,
293                     _sourceFormat ? _sourceFormat : _internalFormat,
294                     _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
295                     0);
296
297        // now for each layer we upload it into the memory
298        for (GLsizei n=0; n<_textureDepth; n++)
299        {
300            // if image is valid then upload it to the texture memory
301            osg::Image* image = _images[n].get();
302            if (image)
303            {
304                // now load the image data into the memory, this will also check if image do have valid properties
305                applyTexImage2DArray_subload(state, image, _textureWidth, _textureHeight, n, _internalFormat, _numMipmapLevels);
306                getModifiedCount(n,contextID) = image->getModifiedCount();
307            }
308        }
309        textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
310
311        _textureObjectBuffer[contextID] = textureObject;
312       
313        // no idea what this for ;-)
314        if (state.getMaxTexturePoolSize()==0 && _unrefImageDataAfterApply && areAllTextureObjectsLoaded())
315        {
316            Texture2DArray* non_const_this = const_cast<Texture2DArray*>(this);
317            for (int n=0; n<_textureDepth; n++)
318            {               
319                if (_images[n].valid() && _images[n]->getDataVariance()==STATIC)
320                {
321                    non_const_this->_images[n] = 0;
322                }
323            }
324        }
325       
326    }
327   
328    // No images present, but dimensions are set. So create empty texture
329    else if ( (_textureWidth > 0) && (_textureHeight > 0) && (_textureDepth > 0) && (_internalFormat!=0) )
330    {
331        // generate texture
332        _textureObjectBuffer[contextID] = textureObject = generateTextureObject(
333                this, contextID, GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
334       
335        textureObject->bind();
336        applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);
337       
338        extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
339                     _textureWidth, _textureHeight, _textureDepth,
340                     _borderWidth,
341                     _sourceFormat ? _sourceFormat : _internalFormat,
342                     _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
343                     0);
344       
345    }
346   
347    // nothing before, so just unbind the texture target
348    else
349    {
350        glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, 0 );
351    }
352
353    // if texture object is now valid and we have to allocate mipmap levels, then
354    if (textureObject != 0 && _texMipmapGenerationDirtyList[contextID])
355    {
356        generateMipmap(state);
357    }
358}
359
360void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GLsizei inwidth, GLsizei inheight, GLsizei indepth, GLint inInternalFormat, GLsizei& numMipmapLevels) const
361{
362    // if we don't have a valid image we can't create a texture!
363    if (!imagesValid())
364        return;
365
366    // get the contextID (user defined ID of 0 upwards) for the
367    // current OpenGL context.
368    const unsigned int contextID = state.getContextID();
369    const Extensions* extensions = getExtensions(contextID,true);   
370    const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true);
371    GLenum target = GL_TEXTURE_2D_ARRAY_EXT;
372   
373    // compute the internal texture format, this set the _internalFormat to an appropriate value.
374    computeInternalFormat();
375
376    // select the internalFormat required for the texture.
377    // bool compressed = isCompressedInternalFormat(_internalFormat);
378    bool compressed_image = isCompressedInternalFormat((GLenum)image->getPixelFormat());
379
380    // if the required layer is exceeds the maximum allowed layer sizes
381    if (indepth > extensions->maxLayerCount())
382    {
383        // we give a warning and do nothing
384        notify(WARN)<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) the given layer number exceeds the maximum number of supported layers."<<std::endl;
385        return;       
386    }
387
388    //Rescale if resize hint is set or NPOT not supported or dimensions exceed max size
389    if( _resizeNonPowerOfTwoHint || !texExtensions->isNonPowerOfTwoTextureSupported(_min_filter)
390        || inwidth > extensions->max2DSize()
391        || inheight > extensions->max2DSize())
392        image->ensureValidSizeForTexturing(extensions->max2DSize());
393
394    // image size or format has changed, this is not allowed, hence return
395    if (image->s()!=inwidth ||
396        image->t()!=inheight ||
397        image->getInternalTextureFormat()!=inInternalFormat )
398    {
399        notify(WARN)<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) given image do have wrong dimension or internal format."<<std::endl;
400        return;       
401    }   
402   
403    glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());
404
405    // if no special mipmapping is required, then
406    if( _min_filter == LINEAR || _min_filter == NEAREST )
407    {
408        numMipmapLevels = 1;
409
410        // upload non-compressed image
411        if (!compressed_image)
412        {
413            extensions->glTexSubImage3D( target, 0,
414                                      0, 0, indepth,
415                                      inwidth, inheight, 1,
416                                      (GLenum)image->getPixelFormat(),
417                                      (GLenum)image->getDataType(),
418                                      image->data() );
419        }
420       
421        // if we support compression and image is compressed, then
422        else if (extensions->isCompressedTexImage3DSupported())
423        {
424            // notify(WARN)<<"glCompressedTexImage3D "<<inwidth<<", "<<inheight<<", "<<indepth<<std::endl;
425            numMipmapLevels = 1;
426
427            GLint blockSize, size;
428            getCompressedSize(_internalFormat, inwidth, inheight, 1, blockSize,size);
429
430            extensions->glCompressedTexSubImage3D(target, 0,
431                0, 0, indepth, 
432                inwidth, inheight, 1,
433                (GLenum)image->getPixelFormat(),
434                size,
435                image->data());
436        }
437
438    // we want to use mipmapping, so enable it
439    }else
440    {
441        // image does not provide mipmaps, so we have to create them
442        if(!image->isMipmap())
443        {
444            notify(WARN)<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) automagic mipmap generation is currently not implemented. Check texture's min/mag filters."<<std::endl;
445
446        // the image object does provide mipmaps, so upload the in the certain levels of a layer
447        }else
448        {
449            numMipmapLevels = image->getNumMipmapLevels();
450
451            int width  = image->s();
452            int height = image->t();
453           
454            for( GLsizei k = 0 ; k < numMipmapLevels  && (width || height ) ;k++)
455            {
456
457                if (width == 0)
458                    width = 1;
459                if (height == 0)
460                    height = 1;
461
462                extensions->glTexSubImage3D( target, k, 0, 0, indepth,
463                                          width, height, 1,
464                                          (GLenum)image->getPixelFormat(),
465                                          (GLenum)image->getDataType(),
466                                          image->getMipmapData(k));
467
468                width >>= 1;
469                height >>= 1;
470            }
471        }
472
473    }
474}
475
476
477void Texture2DArray::copyTexSubImage2DArray(State& state, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height )
478{
479    const unsigned int contextID = state.getContextID();
480    const Extensions* extensions = getExtensions(contextID,true);
481
482    // get the texture object for the current contextID.
483    TextureObject* textureObject = getTextureObject(contextID);
484
485    // if texture object is valid
486    if (textureObject != 0)
487    {
488        textureObject->bind();
489
490        applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);
491        extensions->glCopyTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, xoffset,yoffset,zoffset, x, y, width, height);
492
493        // inform state that this texture is the current one bound.
494        state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);
495
496    }
497    else
498    {
499        notify(WARN)<<"Warning: Texture2DArray::copyTexSubImage2DArray(..) failed, cannot not copy to a non existant texture."<<std::endl;
500    }
501}
502
503void Texture2DArray::allocateMipmap(State& state) const
504{
505    const unsigned int contextID = state.getContextID();
506
507    // get the texture object for the current contextID.
508    TextureObject* textureObject = getTextureObject(contextID);
509   
510    if (textureObject && _textureWidth != 0 && _textureHeight != 0 && _textureDepth != 0)
511    {
512        const Extensions* extensions = getExtensions(contextID,true);
513        // const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true);
514       
515        // bind texture
516        textureObject->bind();
517
518        // compute number of mipmap levels
519        int width = _textureWidth;
520        int height = _textureHeight;
521        int numMipmapLevels = Image::computeNumberOfMipmapLevels(width, height);
522
523        // we do not reallocate the level 0, since it was already allocated
524        width >>= 1;
525        height >>= 1;
526       
527        for( GLsizei k = 1; k < numMipmapLevels  && (width || height); k++)
528        {
529            if (width == 0)
530                width = 1;
531            if (height == 0)
532                height = 1;
533
534            extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, k, _internalFormat,
535                     width, height, _textureDepth, _borderWidth,
536                     _sourceFormat ? _sourceFormat : _internalFormat,
537                     _sourceType ? _sourceType : GL_UNSIGNED_BYTE, NULL);
538
539            width >>= 1;
540            height >>= 1;
541        }
542               
543        // inform state that this texture is the current one bound.
544        state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);       
545    }
546}
547
548typedef buffered_value< ref_ptr<Texture2DArray::Extensions> > BufferedExtensions;
549static BufferedExtensions s_extensions;
550
551Texture2DArray::Extensions* Texture2DArray::getExtensions(unsigned int contextID,bool createIfNotInitalized)
552{
553    if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions(contextID);
554    return s_extensions[contextID].get();
555}
556
557void Texture2DArray::setExtensions(unsigned int contextID,Extensions* extensions)
558{
559    s_extensions[contextID] = extensions;
560}
561
562Texture2DArray::Extensions::Extensions(unsigned int contextID)
563{
564    setupGLExtensions(contextID);
565}
566
567Texture2DArray::Extensions::Extensions(const Extensions& rhs):
568    Referenced()
569{
570    _isTexture3DSupported = rhs._isTexture3DSupported;
571    _isTexture2DArraySupported = rhs._isTexture2DArraySupported;
572   
573    _max2DSize = rhs._max2DSize;
574    _maxLayerCount = rhs._maxLayerCount;
575   
576    _glTexImage3D = rhs._glTexImage3D;
577    _glTexSubImage3D = rhs._glTexSubImage3D;
578    _glCopyTexSubImage3D = rhs._glCopyTexSubImage3D;
579    _glCompressedTexImage3D = rhs._glCompressedTexImage3D;
580    _glCompressedTexSubImage3D = rhs._glCompressedTexSubImage3D;;
581}
582
583void Texture2DArray::Extensions::lowestCommonDenominator(const Extensions& rhs)
584{
585    if (!rhs._isTexture3DSupported)                 _isTexture3DSupported = false;
586    if (!rhs._isTexture2DArraySupported)            _isTexture2DArraySupported = false;
587    if (rhs._max2DSize<_max2DSize)                  _max2DSize = rhs._max2DSize;
588    if (rhs._maxLayerCount<_maxLayerCount)          _maxLayerCount = rhs._maxLayerCount;
589
590    if (!rhs._glTexImage3D)                         _glTexImage3D = 0;
591    if (!rhs._glTexSubImage3D)                      _glTexSubImage3D = 0;
592    if (!rhs._glCompressedTexImage3D)               _glTexImage3D = 0;
593    if (!rhs._glCompressedTexSubImage3D)            _glTexSubImage3D = 0;
594    if (!rhs._glCopyTexSubImage3D)                  _glCopyTexSubImage3D = 0;
595}
596
597void Texture2DArray::Extensions::setupGLExtensions(unsigned int contextID)
598{
599    _isTexture3DSupported = isGLExtensionSupported(contextID,"GL_EXT_texture3D");
600    _isTexture2DArraySupported = isGLExtensionSupported(contextID,"GL_EXT_texture_array");
601
602    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_max2DSize);
603    glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &_maxLayerCount);
604
605    setGLExtensionFuncPtr(_glTexImage3D, "glTexImage3D","glTexImage3DEXT");
606    setGLExtensionFuncPtr(_glTexSubImage3D, "glTexSubImage3D","glTexSubImage3DEXT");
607    setGLExtensionFuncPtr(_glCompressedTexImage3D, "glCompressedTexImage3D","glCompressedTexImage3DARB");
608    setGLExtensionFuncPtr(_glCompressedTexSubImage3D, "glCompressedTexSubImage3D","glCompressedTexSubImage3DARB");
609    setGLExtensionFuncPtr(_glCopyTexSubImage3D, "glCopyTexSubImage3D","glCopyTexSubImage3DEXT");
610}
611
612void Texture2DArray::Extensions::glTexImage3D( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) const
613{
614    if (_glTexImage3D)
615    {
616        _glTexImage3D( target, level, internalFormat, width, height, depth, border, format, type, pixels);
617    }
618    else
619    {
620        notify(WARN)<<"Error: glTexImage3D not supported by OpenGL driver"<<std::endl;
621    }
622}
623
624void Texture2DArray::Extensions::glTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) const
625{
626    if (_glTexSubImage3D)
627    {
628        _glTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
629    }
630    else
631    {
632        notify(WARN)<<"Error: glTexSubImage3D not supported by OpenGL driver"<<std::endl;
633    }
634}
635
636void Texture2DArray::Extensions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) const
637{
638    if (_glCompressedTexImage3D)
639    {
640        _glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
641    }
642    else
643    {
644        notify(WARN)<<"Error: glCompressedTexImage3D not supported by OpenGL driver"<<std::endl;
645    }
646}
647
648void Texture2DArray::Extensions::glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ) const
649{
650    if (_glCompressedTexSubImage3D)
651    {
652        _glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
653    }
654    else
655    {
656        notify(WARN)<<"Error: glCompressedTexImage2D not supported by OpenGL driver"<<std::endl;
657    }
658}
659
660void Texture2DArray::Extensions::glCopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) const
661{
662    if (_glCopyTexSubImage3D)
663    {
664        _glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
665    }
666    else
667    {
668        notify(WARN)<<"Error: glCopyTexSubImage3D not supported by OpenGL driver"<<std::endl;
669    }
670}
Note: See TracBrowser for help on using the browser.