root/OpenSceneGraph/trunk/src/osg/Texture3D.cpp @ 10924

Revision 10924, 24.3 kB (checked in by robert, 4 years ago)

Refactored the way that osg::Image/ImageSequence manages the update callback that needs to be attached to Textures to make it possible to use the Image::update() mechansim in other subclasses from osg::Image.
To enable the automatic attachment of the required update callback to call osg::Image::update(..) subclasses from osg::Image will
need to implement the osg::Image::requestUpdateCall() and return true, and implement the osg::Image::update(NodeVisitor?*) method to recieve the update call during the update traversal.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
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/Texture3D>
15#include <osg/State>
16#include <osg/GLU>
17#include <osg/Notify>
18
19#include <string.h>
20
21
22
23using namespace osg;
24
25Texture3D::Texture3D():
26            _textureWidth(0),
27            _textureHeight(0),
28            _textureDepth(0),
29            _numMipmapLevels(0)
30{
31}
32
33
34Texture3D::Texture3D(Image* image):
35            _textureWidth(0),
36            _textureHeight(0),
37            _textureDepth(0),
38            _numMipmapLevels(0)
39{
40    setImage(image);
41}
42
43Texture3D::Texture3D(const Texture3D& text,const CopyOp& copyop):
44            Texture(text,copyop),
45            _image(copyop(text._image.get())),
46            _textureWidth(text._textureWidth),
47            _textureHeight(text._textureHeight),
48            _textureDepth(text._textureDepth),
49            _numMipmapLevels(text._numMipmapLevels),
50            _subloadCallback(text._subloadCallback)
51{
52}
53
54Texture3D::~Texture3D()
55{
56}
57
58int Texture3D::compare(const StateAttribute& sa) const
59{
60    // check the types are equal and then create the rhs variable
61    // used by the COMPARE_StateAttribute_Parameter macro's below.
62    COMPARE_StateAttribute_Types(Texture3D,sa)
63
64    if (_image!=rhs._image) // smart pointer comparison.
65    {
66        if (_image.valid())
67        {
68            if (rhs._image.valid())
69            {
70                int result = _image->compare(*rhs._image);
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._image.valid())
79        {
80            return -1; // valid rhs._image is greater than null.
81        }
82    }
83
84    if (!_image && !rhs._image)
85    {
86        // no image attached to either Texture2D
87        // but could these textures already be downloaded?
88        // check the _textureObjectBuffer to see if they have been
89        // downloaded
90
91        int result = compareTextureObjects(rhs);
92        if (result!=0) return result;
93    }
94
95    int result = compareTexture(rhs);
96    if (result!=0) return result;
97
98    // compare each parameter in turn against the rhs.
99    COMPARE_StateAttribute_Parameter(_textureWidth)
100    COMPARE_StateAttribute_Parameter(_textureHeight)
101    COMPARE_StateAttribute_Parameter(_textureDepth)
102    COMPARE_StateAttribute_Parameter(_subloadCallback)
103
104    return 0; // passed all the above comparison macro's, must be equal.
105}
106
107void Texture3D::setImage(Image* image)
108{
109    if (_image == image) return;
110
111    if (_image.valid() && _image->requiresUpdateCall())
112    {
113        setUpdateCallback(0);
114        setDataVariance(osg::Object::STATIC);
115    }
116
117    // delete old texture objects.
118    dirtyTextureObject();
119
120    _modifiedCount.setAllElementsTo(0);
121
122    _image = image;
123
124    if (_image.valid() && _image->requiresUpdateCall())
125    {
126        setUpdateCallback(new Image::UpdateCallback());
127        setDataVariance(osg::Object::DYNAMIC);
128    }
129}
130
131void Texture3D::computeRequiredTextureDimensions(State& state, const osg::Image& image,GLsizei& inwidth, GLsizei& inheight,GLsizei& indepth, GLsizei& numMipmapLevels) const
132{
133    const unsigned int contextID = state.getContextID();
134    const Extensions* extensions = getExtensions(contextID,true);
135    const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true);
136
137    int width,height,depth;
138
139    if( !_resizeNonPowerOfTwoHint && texExtensions->isNonPowerOfTwoTextureSupported(_min_filter) )
140    {
141        width = image.s();
142        height = image.t();
143        depth = image.r();
144    }
145    else
146    {
147        width = Image::computeNearestPowerOfTwo(image.s()-2*_borderWidth)+2*_borderWidth;
148        height = Image::computeNearestPowerOfTwo(image.t()-2*_borderWidth)+2*_borderWidth;
149        depth = Image::computeNearestPowerOfTwo(image.r()-2*_borderWidth)+2*_borderWidth;
150    }
151
152    // cap the size to what the graphics hardware can handle.
153    if (width>extensions->maxTexture3DSize()) width = extensions->maxTexture3DSize();
154    if (height>extensions->maxTexture3DSize()) height = extensions->maxTexture3DSize();
155    if (depth>extensions->maxTexture3DSize()) depth = extensions->maxTexture3DSize();
156   
157    inwidth = width;
158    inheight = height;
159    indepth = depth;
160   
161    bool useHardwareMipMapGeneration = !image.isMipmap() && _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported();
162
163    if( _min_filter == LINEAR || _min_filter == NEAREST || useHardwareMipMapGeneration )
164    {
165        numMipmapLevels = 1;
166    }
167    else if( image.isMipmap() )
168    {
169        numMipmapLevels = image.getNumMipmapLevels();
170    }
171    else
172    {
173        numMipmapLevels = 0;
174        for( ; (width || height || depth) ;++numMipmapLevels)
175        {
176
177            if (width == 0)
178                width = 1;
179            if (height == 0)
180                height = 1;
181            if (depth == 0)
182                depth = 1;
183
184            width >>= 1;
185            height >>= 1;
186            depth >>= 1;
187        }   
188    }
189}
190
191void Texture3D::apply(State& state) const
192{
193
194    // get the contextID (user defined ID of 0 upwards) for the
195    // current OpenGL context.
196    const unsigned int contextID = state.getContextID();
197
198    Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
199    ElapsedTime elapsedTime(&(tom->getApplyTime()));
200    tom->getNumberApplied()++;
201
202    const Extensions* extensions = getExtensions(contextID,true);
203                                       
204    if (!extensions->isTexture3DSupported())
205    {
206        notify(WARN)<<"Warning: Texture3D::apply(..) failed, 3D texturing is not support by OpenGL driver."<<std::endl;
207        return;
208    }
209
210    // get the texture object for the current contextID.
211    TextureObject* textureObject = getTextureObject(contextID);
212
213    if (textureObject)
214    {
215        if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount())
216        {
217            // compute the internal texture format, this set the _internalFormat to an appropriate value.
218            computeInternalFormat();
219
220            GLsizei new_width, new_height, new_depth, new_numMipmapLevels;
221
222            // compute the dimensions of the texture.
223            computeRequiredTextureDimensions(state, *_image, new_width, new_height, new_depth, new_numMipmapLevels);
224
225            if (!textureObject->match(GL_TEXTURE_3D, new_numMipmapLevels, _internalFormat, new_width, new_height, new_depth, _borderWidth))
226            {
227                Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
228                _textureObjectBuffer[contextID] = 0;
229                textureObject = 0;
230            }
231        }
232    }
233
234    if (textureObject)
235    {
236        // we have a valid image
237        textureObject->bind();
238
239        if (getTextureParameterDirty(state.getContextID())) applyTexParameters(GL_TEXTURE_3D,state);
240
241        if (_subloadCallback.valid())
242        {
243            _subloadCallback->subload(*this,state);
244        }
245        else if (_image.get() && getModifiedCount(contextID) != _image->getModifiedCount())
246        {
247           computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
248
249            applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
250
251            // update the modified count to show that it is upto date.
252            getModifiedCount(contextID) = _image->getModifiedCount();
253        }
254
255    }
256    else if (_subloadCallback.valid())
257    {
258
259        _textureObjectBuffer[contextID] = textureObject = generateTextureObject(this, contextID,GL_TEXTURE_3D);
260
261        textureObject->bind();
262
263        applyTexParameters(GL_TEXTURE_3D,state);
264
265        _subloadCallback->load(*this,state);
266
267        textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
268
269        // in theory the following line is redundent, but in practice
270        // have found that the first frame drawn doesn't apply the textures
271        // unless a second bind is called?!!
272        // perhaps it is the first glBind which is not required...
273        //glBindTexture( GL_TEXTURE_3D, handle );
274
275    }
276    else if (_image.valid() && _image->data())
277    {
278
279        // compute the internal texture format, this set the _internalFormat to an appropriate value.
280        computeInternalFormat();
281
282        // compute the dimensions of the texture.
283        computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
284
285        textureObject = generateTextureObject(this, contextID,GL_TEXTURE_3D);
286
287        textureObject->bind();
288
289
290        applyTexParameters(GL_TEXTURE_3D,state);
291
292        applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
293
294        textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
295
296        // update the modified count to show that it is upto date.
297        getModifiedCount(contextID) = _image->getModifiedCount();
298
299        _textureObjectBuffer[contextID] = textureObject;
300
301        if (state.getMaxTexturePoolSize()==0 && _unrefImageDataAfterApply && areAllTextureObjectsLoaded() && _image->getDataVariance()==STATIC)
302        {
303            Texture3D* non_const_this = const_cast<Texture3D*>(this);
304            non_const_this->_image = 0;
305        }
306
307    }
308    else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_textureDepth!=0) && (_internalFormat!=0) )
309    {
310        _textureObjectBuffer[contextID] = textureObject = generateTextureObject(
311                this, contextID,GL_TEXTURE_3D,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
312       
313        textureObject->bind();
314
315        applyTexParameters(GL_TEXTURE_3D,state);
316
317        // no image present, but dimensions at set so lets create the texture
318        extensions->glTexImage3D( GL_TEXTURE_3D, 0, _internalFormat,
319                     _textureWidth, _textureHeight, _textureDepth,
320                     _borderWidth,
321                     _sourceFormat ? _sourceFormat : _internalFormat,
322                     _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
323                     0);               
324                     
325        if (_readPBuffer.valid())
326        {
327            _readPBuffer->bindPBufferToTexture(GL_FRONT);
328        }
329       
330    }
331    else
332    {
333        glBindTexture( GL_TEXTURE_3D, 0 );
334    }
335   
336    // if texture object is now valid and we have to allocate mipmap levels, then
337    if (textureObject != 0 && _texMipmapGenerationDirtyList[contextID])
338    {
339        generateMipmap(state);
340    }
341}
342
343void Texture3D::computeInternalFormat() const
344{
345    if (_image.valid()) computeInternalFormatWithImage(*_image);
346    else computeInternalFormatType();
347}
348
349void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMipmapLevels) const
350{
351    // if we don't have a valid image we can't create a texture!
352    if (!image || !image->data())
353        return;
354
355    // get the contextID (user defined ID of 0 upwards) for the
356    // current OpenGL context.
357    const unsigned int contextID = state.getContextID();
358    const Extensions* extensions = getExtensions(contextID,true);   
359    const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true);
360
361    // compute the internal texture format, this set the _internalFormat to an appropriate value.
362    computeInternalFormat();
363
364    // select the internalFormat required for the texture.
365    bool compressed = isCompressedInternalFormat(_internalFormat);
366    bool compressed_image = isCompressedInternalFormat((GLenum)image->getPixelFormat());
367
368    if (compressed)
369    {
370        //notify(WARN)<<"Warning::cannot currently use compressed format with 3D textures."<<std::endl;
371        //return;
372    }   
373   
374    //Rescale if resize hint is set or NPOT not supported or dimensions exceed max size
375    if( _resizeNonPowerOfTwoHint || !texExtensions->isNonPowerOfTwoTextureSupported(_min_filter)
376        || inwidth > extensions->maxTexture3DSize()
377        || inheight > extensions->maxTexture3DSize()
378        || indepth > extensions->maxTexture3DSize() )
379        image->ensureValidSizeForTexturing(extensions->maxTexture3DSize());
380
381    glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());
382
383    bool useHardwareMipMapGeneration = !image->isMipmap() && _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported();
384
385    if( _min_filter == LINEAR || _min_filter == NEAREST || useHardwareMipMapGeneration )
386    {
387        bool hardwareMipMapOn = false;
388        if (_min_filter != LINEAR && _min_filter != NEAREST)
389        {
390            if (useHardwareMipMapGeneration) glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
391            hardwareMipMapOn = true;
392        }
393
394        numMipmapLevels = 1;
395
396        if (!compressed_image)
397        {
398            extensions->glTexImage3D( target, 0, _internalFormat,
399                                      inwidth, inheight, indepth,
400                                      _borderWidth,
401                                      (GLenum)image->getPixelFormat(),
402                                      (GLenum)image->getDataType(),
403                                      image->data() );
404        }
405        else if (extensions->isCompressedTexImage3DSupported())
406        {
407            // notify(WARN)<<"glCompressedTexImage3D "<<inwidth<<", "<<inheight<<", "<<indepth<<std::endl;
408            numMipmapLevels = 1;
409
410            GLint blockSize, size;
411            getCompressedSize(_internalFormat, inwidth, inheight, indepth, blockSize,size);
412
413            extensions->glCompressedTexImage3D(target, 0, _internalFormat,
414                inwidth, inheight, indepth,
415                _borderWidth,
416                size,
417                image->data());
418        }
419
420        if (hardwareMipMapOn) glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS,GL_FALSE);
421    }
422    else
423    {
424        if(!image->isMipmap())
425        {
426
427            numMipmapLevels = 1;
428
429            extensions->gluBuild3DMipmaps( target, _internalFormat,
430                                           image->s(),image->t(),image->r(),
431                                           (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(),
432                                           image->data() );
433
434        }
435        else
436        {
437            numMipmapLevels = image->getNumMipmapLevels();
438
439            int width  = image->s();
440            int height = image->t();
441            int depth = image->r();
442
443            for( GLsizei k = 0 ; k < numMipmapLevels  && (width || height || depth) ;k++)
444            {
445
446                if (width == 0)
447                    width = 1;
448                if (height == 0)
449                    height = 1;
450                if (depth == 0)
451                    depth = 1;
452
453                extensions->glTexImage3D( target, k, _internalFormat,
454                                          width, height, depth, _borderWidth,
455                                          (GLenum)image->getPixelFormat(),
456                                          (GLenum)image->getDataType(),
457                                          image->getMipmapData(k));
458
459                width >>= 1;
460                height >>= 1;
461                depth >>= 1;
462            }
463        }
464
465    }
466
467    inwidth  = image->s();
468    inheight = image->t();
469    indepth  = image->r();
470   
471}
472
473void Texture3D::copyTexSubImage3D(State& state, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height )
474{
475    const unsigned int contextID = state.getContextID();
476    const Extensions* extensions = getExtensions(contextID,true);
477
478    // get the texture object for the current contextID.
479    TextureObject* textureObject = getTextureObject(contextID);
480
481    if (textureObject != 0)
482    {
483        textureObject->bind();
484
485        applyTexParameters(GL_TEXTURE_3D,state);
486        extensions->glCopyTexSubImage3D( GL_TEXTURE_3D, 0, xoffset,yoffset,zoffset, x, y, width, height);
487
488        /* Redundant, delete later */
489        //glBindTexture( GL_TEXTURE_3D, handle );
490
491        // inform state that this texture is the current one bound.
492        state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);
493
494    }
495    else
496    {
497        notify(WARN)<<"Warning: Texture3D::copyTexSubImage3D(..) failed, cannot not copy to a non existant texture."<<std::endl;
498    }
499}
500
501void Texture3D::allocateMipmap(State& state) const
502{
503    const unsigned int contextID = state.getContextID();
504
505    // get the texture object for the current contextID.
506    TextureObject* textureObject = getTextureObject(contextID);
507   
508    if (textureObject && _textureWidth != 0 && _textureHeight != 0 && _textureDepth != 0)
509    {
510        const Extensions* extensions = getExtensions(contextID,true);
511   
512        // bind texture
513        textureObject->bind();
514
515        // compute number of mipmap levels
516        int width = _textureWidth;
517        int height = _textureHeight;
518        int depth = _textureDepth;
519        int numMipmapLevels = Image::computeNumberOfMipmapLevels(width, height, depth);
520
521        // we do not reallocate the level 0, since it was already allocated
522        width >>= 1;
523        height >>= 1;
524        depth >>= 1;
525               
526        for( GLsizei k = 1; k < numMipmapLevels  && (width || height || depth); k++)
527        {
528            if (width == 0)
529                width = 1;
530            if (height == 0)
531                height = 1;
532            if (depth == 0)
533                depth = 1;
534
535            extensions->glTexImage3D( GL_TEXTURE_3D, k, _internalFormat,
536                     width, height, depth, _borderWidth,
537                     _sourceFormat ? _sourceFormat : _internalFormat,
538                     _sourceType ? _sourceType : GL_UNSIGNED_BYTE, NULL);
539
540            width >>= 1;
541            height >>= 1;
542            depth >>= 1;
543        }
544               
545        // inform state that this texture is the current one bound.
546        state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);       
547    }
548}
549
550typedef buffered_value< ref_ptr<Texture3D::Extensions> > BufferedExtensions;
551static BufferedExtensions s_extensions;
552
553Texture3D::Extensions* Texture3D::getExtensions(unsigned int contextID,bool createIfNotInitalized)
554{
555    if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions(contextID);
556    return s_extensions[contextID].get();
557}
558
559void Texture3D::setExtensions(unsigned int contextID,Extensions* extensions)
560{
561    s_extensions[contextID] = extensions;
562}
563
564#ifndef GL_MAX_3D_TEXTURE_SIZE
565#define GL_MAX_3D_TEXTURE_SIZE 0x8073
566#endif
567
568Texture3D::Extensions::Extensions(unsigned int contextID)
569{
570    setupGLExtensions(contextID);
571}
572
573Texture3D::Extensions::Extensions(const Extensions& rhs):
574    Referenced()
575{
576    _isTexture3DSupported = rhs._isTexture3DSupported;
577    _isTexture3DFast = rhs._isTexture3DFast;
578    _maxTexture3DSize = rhs._maxTexture3DSize;
579
580    _glTexImage3D = rhs._glTexImage3D;
581    _glTexSubImage3D = rhs._glTexSubImage3D;
582    _glCopyTexSubImage3D = rhs._glCopyTexSubImage3D;
583    _gluBuild3DMipmaps = rhs._gluBuild3DMipmaps;
584}
585
586void Texture3D::Extensions::lowestCommonDenominator(const Extensions& rhs)
587{
588    if (!rhs._isTexture3DSupported)                 _isTexture3DSupported = false;
589    if (!rhs._isTexture3DFast)                      _isTexture3DFast = false;
590    if (rhs._maxTexture3DSize<_maxTexture3DSize)    _maxTexture3DSize = rhs._maxTexture3DSize;
591
592    if (!rhs._glTexImage3D)                         _glTexImage3D = 0;
593    if (!rhs._glTexSubImage3D)                      _glTexSubImage3D = 0;
594    if (!rhs._glCompressedTexImage3D)               _glTexImage3D = 0;
595    if (!rhs._glCompressedTexSubImage3D)            _glTexSubImage3D = 0;
596    if (!rhs._glCopyTexSubImage3D)                  _glCopyTexSubImage3D = 0;
597    if (!rhs._gluBuild3DMipmaps)                    _gluBuild3DMipmaps = 0;
598}
599
600void Texture3D::Extensions::setupGLExtensions(unsigned int contextID)
601{
602    _isTexture3DFast = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D");
603
604    if (_isTexture3DFast) _isTexture3DSupported = true;
605    else _isTexture3DSupported = strncmp((const char*)glGetString(GL_VERSION),"1.2",3)>=0;
606   
607    glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &_maxTexture3DSize);
608
609    setGLExtensionFuncPtr(_glTexImage3D,"glTexImage3D","glTexImage3DEXT");
610    setGLExtensionFuncPtr(_glTexSubImage3D,"glTexSubImage3D","glTexSubImage3DEXT");
611    setGLExtensionFuncPtr(_glCompressedTexImage3D,"glCompressedTexImage3D","glCompressedTexImage3DARB");
612    setGLExtensionFuncPtr(_glCompressedTexSubImage3D,"glCompressedTexSubImage3D","glCompressedTexSubImage3DARB");
613    setGLExtensionFuncPtr(_glCopyTexSubImage3D,"glCopyTexSubImage3D","glCopyTexSubImage3DEXT");
614    setGLExtensionFuncPtr(_gluBuild3DMipmaps,"gluBuild3DMipmaps");
615
616}
617
618void Texture3D::Extensions::glTexImage3D( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) const
619{
620//    ::glTexImage3D( target, level, internalFormat, width, height, depth, border, format, type, pixels);
621    if (_glTexImage3D)
622    {
623        _glTexImage3D( target, level, internalFormat, width, height, depth, border, format, type, pixels);
624    }
625    else
626    {
627        notify(WARN)<<"Error: glTexImage3D not supported by OpenGL driver"<<std::endl;
628    }
629}
630
631void Texture3D::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
632{
633//    ::glTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
634    if (_glTexSubImage3D)
635    {
636        _glTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
637    }
638    else
639    {
640        notify(WARN)<<"Error: glTexSubImage3D not supported by OpenGL driver"<<std::endl;
641    }
642}
643
644void Texture3D::Extensions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) const
645{
646    if (_glCompressedTexImage3D)
647    {
648        _glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
649    }
650    else
651    {
652        notify(WARN)<<"Error: glCompressedTexImage3D not supported by OpenGL driver"<<std::endl;
653    }
654}
655
656void Texture3D::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
657{
658    if (_glCompressedTexSubImage3D)
659    {
660        _glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
661    }
662    else
663    {
664        notify(WARN)<<"Error: glCompressedTexImage2D not supported by OpenGL driver"<<std::endl;
665    }
666}
667
668void Texture3D::Extensions::glCopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) const
669{
670//    ::glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
671    if (_glCopyTexSubImage3D)
672    {
673        _glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
674    }
675    else
676    {
677        notify(WARN)<<"Error: glCopyTexSubImage3D not supported by OpenGL driver"<<std::endl;
678    }
679}
680
681void Texture3D::Extensions::gluBuild3DMipmaps( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data) const
682{
683//    ::gluBuild3DMipmaps(target, internalFormat, width, height, depth, format, type, data);
684    if (_gluBuild3DMipmaps)
685    {
686        _gluBuild3DMipmaps(target, internalFormat, width, height, depth, format, type, data);
687    }
688    else
689    {
690        notify(WARN)<<"Error: gluBuild3DMipmaps not supported by OpenGL driver"<<std::endl;
691    }
692}
Note: See TracBrowser for help on using the browser.