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

Revision 10723, 23.5 kB (checked in by robert, 5 years ago)

Fixed build with no automatic conversion of ref_ptr<> to C pointer

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