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

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

Added check for image compatibility with existing texture object, releasing the existing texture object in cases when the new image size/pixel format is not compatible.

  • 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        if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount())
217        {
218            // compute the internal texture format, this set the _internalFormat to an appropriate value.
219            computeInternalFormat();
220
221            GLsizei new_width, new_height, new_depth, new_numMipmapLevels;
222
223            // compute the dimensions of the texture.
224            computeRequiredTextureDimensions(state, *_image, new_width, new_height, new_depth, new_numMipmapLevels);
225
226            if (!textureObject->match(GL_TEXTURE_3D, new_numMipmapLevels, _internalFormat, new_width, new_height, new_depth, _borderWidth))
227            {
228                Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
229                _textureObjectBuffer[contextID] = 0;
230                textureObject = 0;
231            }
232        }
233    }
234
235    if (textureObject)
236    {
237        // we have a valid image
238        textureObject->bind();
239
240        if (getTextureParameterDirty(state.getContextID())) applyTexParameters(GL_TEXTURE_3D,state);
241
242        if (_subloadCallback.valid())
243        {
244            _subloadCallback->subload(*this,state);
245        }
246        else if (_image.get() && getModifiedCount(contextID) != _image->getModifiedCount())
247        {
248           computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
249
250            applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
251
252            // update the modified count to show that it is upto date.
253            getModifiedCount(contextID) = _image->getModifiedCount();
254        }
255
256    }
257    else if (_subloadCallback.valid())
258    {
259
260        _textureObjectBuffer[contextID] = textureObject = generateTextureObject(this, contextID,GL_TEXTURE_3D);
261
262        textureObject->bind();
263
264        applyTexParameters(GL_TEXTURE_3D,state);
265
266        _subloadCallback->load(*this,state);
267
268        textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
269
270        // in theory the following line is redundent, but in practice
271        // have found that the first frame drawn doesn't apply the textures
272        // unless a second bind is called?!!
273        // perhaps it is the first glBind which is not required...
274        //glBindTexture( GL_TEXTURE_3D, handle );
275
276    }
277    else if (_image.valid() && _image->data())
278    {
279
280        // compute the internal texture format, this set the _internalFormat to an appropriate value.
281        computeInternalFormat();
282
283        // compute the dimensions of the texture.
284        computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
285
286        textureObject = generateTextureObject(this, contextID,GL_TEXTURE_3D);
287
288        textureObject->bind();
289
290
291        applyTexParameters(GL_TEXTURE_3D,state);
292
293        applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
294
295        textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
296
297        // update the modified count to show that it is upto date.
298        getModifiedCount(contextID) = _image->getModifiedCount();
299
300        _textureObjectBuffer[contextID] = textureObject;
301
302        if (state.getMaxTexturePoolSize()==0 && _unrefImageDataAfterApply && areAllTextureObjectsLoaded() && _image->getDataVariance()==STATIC)
303        {
304            Texture3D* non_const_this = const_cast<Texture3D*>(this);
305            non_const_this->_image = 0;
306        }
307
308    }
309    else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_textureDepth!=0) && (_internalFormat!=0) )
310    {
311        _textureObjectBuffer[contextID] = textureObject = generateTextureObject(
312                this, contextID,GL_TEXTURE_3D,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
313       
314        textureObject->bind();
315
316        applyTexParameters(GL_TEXTURE_3D,state);
317
318        // no image present, but dimensions at set so lets create the texture
319        extensions->glTexImage3D( GL_TEXTURE_3D, 0, _internalFormat,
320                     _textureWidth, _textureHeight, _textureDepth,
321                     _borderWidth,
322                     _sourceFormat ? _sourceFormat : _internalFormat,
323                     _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
324                     0);               
325                     
326        if (_readPBuffer.valid())
327        {
328            _readPBuffer->bindPBufferToTexture(GL_FRONT);
329        }
330       
331    }
332    else
333    {
334        glBindTexture( GL_TEXTURE_3D, 0 );
335    }
336   
337    // if texture object is now valid and we have to allocate mipmap levels, then
338    if (textureObject != 0 && _texMipmapGenerationDirtyList[contextID])
339    {
340        generateMipmap(state);
341    }
342}
343
344void Texture3D::computeInternalFormat() const
345{
346    if (_image.valid()) computeInternalFormatWithImage(*_image);
347    else computeInternalFormatType();
348}
349
350void Texture3D::applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMipmapLevels) const
351{
352    // if we don't have a valid image we can't create a texture!
353    if (!image || !image->data())
354        return;
355
356    // get the contextID (user defined ID of 0 upwards) for the
357    // current OpenGL context.
358    const unsigned int contextID = state.getContextID();
359    const Extensions* extensions = getExtensions(contextID,true);   
360    const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true);
361
362    // compute the internal texture format, this set the _internalFormat to an appropriate value.
363    computeInternalFormat();
364
365    // select the internalFormat required for the texture.
366    bool compressed = isCompressedInternalFormat(_internalFormat);
367    bool compressed_image = isCompressedInternalFormat((GLenum)image->getPixelFormat());
368
369    if (compressed)
370    {
371        //notify(WARN)<<"Warning::cannot currently use compressed format with 3D textures."<<std::endl;
372        //return;
373    }   
374   
375    //Rescale if resize hint is set or NPOT not supported or dimensions exceed max size
376    if( _resizeNonPowerOfTwoHint || !texExtensions->isNonPowerOfTwoTextureSupported(_min_filter)
377        || inwidth > extensions->maxTexture3DSize()
378        || inheight > extensions->maxTexture3DSize()
379        || indepth > extensions->maxTexture3DSize() )
380        image->ensureValidSizeForTexturing(extensions->maxTexture3DSize());
381
382    glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());
383
384    bool useHardwareMipMapGeneration = !image->isMipmap() && _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported();
385
386    if( _min_filter == LINEAR || _min_filter == NEAREST || useHardwareMipMapGeneration )
387    {
388        bool hardwareMipMapOn = false;
389        if (_min_filter != LINEAR && _min_filter != NEAREST)
390        {
391            if (useHardwareMipMapGeneration) glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
392            hardwareMipMapOn = true;
393        }
394
395        numMipmapLevels = 1;
396
397        if (!compressed_image)
398        {
399            extensions->glTexImage3D( target, 0, _internalFormat,
400                                      inwidth, inheight, indepth,
401                                      _borderWidth,
402                                      (GLenum)image->getPixelFormat(),
403                                      (GLenum)image->getDataType(),
404                                      image->data() );
405        }
406        else if (extensions->isCompressedTexImage3DSupported())
407        {
408            // notify(WARN)<<"glCompressedTexImage3D "<<inwidth<<", "<<inheight<<", "<<indepth<<std::endl;
409            numMipmapLevels = 1;
410
411            GLint blockSize, size;
412            getCompressedSize(_internalFormat, inwidth, inheight, indepth, blockSize,size);
413
414            extensions->glCompressedTexImage3D(target, 0, _internalFormat,
415                inwidth, inheight, indepth,
416                _borderWidth,
417                size,
418                image->data());
419        }
420
421        if (hardwareMipMapOn) glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS,GL_FALSE);
422    }
423    else
424    {
425        if(!image->isMipmap())
426        {
427
428            numMipmapLevels = 1;
429
430            extensions->gluBuild3DMipmaps( target, _internalFormat,
431                                           image->s(),image->t(),image->r(),
432                                           (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(),
433                                           image->data() );
434
435        }
436        else
437        {
438            numMipmapLevels = image->getNumMipmapLevels();
439
440            int width  = image->s();
441            int height = image->t();
442            int depth = image->r();
443
444            for( GLsizei k = 0 ; k < numMipmapLevels  && (width || height || depth) ;k++)
445            {
446
447                if (width == 0)
448                    width = 1;
449                if (height == 0)
450                    height = 1;
451                if (depth == 0)
452                    depth = 1;
453
454                extensions->glTexImage3D( target, k, _internalFormat,
455                                          width, height, depth, _borderWidth,
456                                          (GLenum)image->getPixelFormat(),
457                                          (GLenum)image->getDataType(),
458                                          image->getMipmapData(k));
459
460                width >>= 1;
461                height >>= 1;
462                depth >>= 1;
463            }
464        }
465
466    }
467
468    inwidth  = image->s();
469    inheight = image->t();
470    indepth  = image->r();
471   
472}
473
474void Texture3D::copyTexSubImage3D(State& state, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height )
475{
476    const unsigned int contextID = state.getContextID();
477    const Extensions* extensions = getExtensions(contextID,true);
478
479    // get the texture object for the current contextID.
480    TextureObject* textureObject = getTextureObject(contextID);
481
482    if (textureObject != 0)
483    {
484        textureObject->bind();
485
486        applyTexParameters(GL_TEXTURE_3D,state);
487        extensions->glCopyTexSubImage3D( GL_TEXTURE_3D, 0, xoffset,yoffset,zoffset, x, y, width, height);
488
489        /* Redundant, delete later */
490        //glBindTexture( GL_TEXTURE_3D, handle );
491
492        // inform state that this texture is the current one bound.
493        state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);
494
495    }
496    else
497    {
498        notify(WARN)<<"Warning: Texture3D::copyTexSubImage3D(..) failed, cannot not copy to a non existant texture."<<std::endl;
499    }
500}
501
502void Texture3D::allocateMipmap(State& state) const
503{
504    const unsigned int contextID = state.getContextID();
505
506    // get the texture object for the current contextID.
507    TextureObject* textureObject = getTextureObject(contextID);
508   
509    if (textureObject && _textureWidth != 0 && _textureHeight != 0 && _textureDepth != 0)
510    {
511        const Extensions* extensions = getExtensions(contextID,true);
512   
513        // bind texture
514        textureObject->bind();
515
516        // compute number of mipmap levels
517        int width = _textureWidth;
518        int height = _textureHeight;
519        int depth = _textureDepth;
520        int numMipmapLevels = Image::computeNumberOfMipmapLevels(width, height, depth);
521
522        // we do not reallocate the level 0, since it was already allocated
523        width >>= 1;
524        height >>= 1;
525        depth >>= 1;
526               
527        for( GLsizei k = 1; k < numMipmapLevels  && (width || height || depth); k++)
528        {
529            if (width == 0)
530                width = 1;
531            if (height == 0)
532                height = 1;
533            if (depth == 0)
534                depth = 1;
535
536            extensions->glTexImage3D( GL_TEXTURE_3D, k, _internalFormat,
537                     width, height, depth, _borderWidth,
538                     _sourceFormat ? _sourceFormat : _internalFormat,
539                     _sourceType ? _sourceType : GL_UNSIGNED_BYTE, NULL);
540
541            width >>= 1;
542            height >>= 1;
543            depth >>= 1;
544        }
545               
546        // inform state that this texture is the current one bound.
547        state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);       
548    }
549}
550
551typedef buffered_value< ref_ptr<Texture3D::Extensions> > BufferedExtensions;
552static BufferedExtensions s_extensions;
553
554Texture3D::Extensions* Texture3D::getExtensions(unsigned int contextID,bool createIfNotInitalized)
555{
556    if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new Extensions(contextID);
557    return s_extensions[contextID].get();
558}
559
560void Texture3D::setExtensions(unsigned int contextID,Extensions* extensions)
561{
562    s_extensions[contextID] = extensions;
563}
564
565#ifndef GL_MAX_3D_TEXTURE_SIZE
566#define GL_MAX_3D_TEXTURE_SIZE 0x8073
567#endif
568
569Texture3D::Extensions::Extensions(unsigned int contextID)
570{
571    setupGLExtensions(contextID);
572}
573
574Texture3D::Extensions::Extensions(const Extensions& rhs):
575    Referenced()
576{
577    _isTexture3DSupported = rhs._isTexture3DSupported;
578    _isTexture3DFast = rhs._isTexture3DFast;
579    _maxTexture3DSize = rhs._maxTexture3DSize;
580
581    _glTexImage3D = rhs._glTexImage3D;
582    _glTexSubImage3D = rhs._glTexSubImage3D;
583    _glCopyTexSubImage3D = rhs._glCopyTexSubImage3D;
584    _gluBuild3DMipmaps = rhs._gluBuild3DMipmaps;
585}
586
587void Texture3D::Extensions::lowestCommonDenominator(const Extensions& rhs)
588{
589    if (!rhs._isTexture3DSupported)                 _isTexture3DSupported = false;
590    if (!rhs._isTexture3DFast)                      _isTexture3DFast = false;
591    if (rhs._maxTexture3DSize<_maxTexture3DSize)    _maxTexture3DSize = rhs._maxTexture3DSize;
592
593    if (!rhs._glTexImage3D)                         _glTexImage3D = 0;
594    if (!rhs._glTexSubImage3D)                      _glTexSubImage3D = 0;
595    if (!rhs._glCompressedTexImage3D)               _glTexImage3D = 0;
596    if (!rhs._glCompressedTexSubImage3D)            _glTexSubImage3D = 0;
597    if (!rhs._glCopyTexSubImage3D)                  _glCopyTexSubImage3D = 0;
598    if (!rhs._gluBuild3DMipmaps)                    _gluBuild3DMipmaps = 0;
599}
600
601void Texture3D::Extensions::setupGLExtensions(unsigned int contextID)
602{
603    _isTexture3DFast = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D");
604
605    if (_isTexture3DFast) _isTexture3DSupported = true;
606    else _isTexture3DSupported = strncmp((const char*)glGetString(GL_VERSION),"1.2",3)>=0;
607   
608    glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &_maxTexture3DSize);
609
610    setGLExtensionFuncPtr(_glTexImage3D,"glTexImage3D","glTexImage3DEXT");
611    setGLExtensionFuncPtr(_glTexSubImage3D,"glTexSubImage3D","glTexSubImage3DEXT");
612    setGLExtensionFuncPtr(_glCompressedTexImage3D,"glCompressedTexImage3D","glCompressedTexImage3DARB");
613    setGLExtensionFuncPtr(_glCompressedTexSubImage3D,"glCompressedTexSubImage3D","glCompressedTexSubImage3DARB");
614    setGLExtensionFuncPtr(_glCopyTexSubImage3D,"glCopyTexSubImage3D","glCopyTexSubImage3DEXT");
615    setGLExtensionFuncPtr(_gluBuild3DMipmaps,"gluBuild3DMipmaps");
616
617}
618
619void 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
620{
621//    ::glTexImage3D( target, level, internalFormat, width, height, depth, border, format, type, pixels);
622    if (_glTexImage3D)
623    {
624        _glTexImage3D( target, level, internalFormat, width, height, depth, border, format, type, pixels);
625    }
626    else
627    {
628        notify(WARN)<<"Error: glTexImage3D not supported by OpenGL driver"<<std::endl;
629    }
630}
631
632void 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
633{
634//    ::glTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
635    if (_glTexSubImage3D)
636    {
637        _glTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
638    }
639    else
640    {
641        notify(WARN)<<"Error: glTexSubImage3D not supported by OpenGL driver"<<std::endl;
642    }
643}
644
645void Texture3D::Extensions::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) const
646{
647    if (_glCompressedTexImage3D)
648    {
649        _glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
650    }
651    else
652    {
653        notify(WARN)<<"Error: glCompressedTexImage3D not supported by OpenGL driver"<<std::endl;
654    }
655}
656
657void 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
658{
659    if (_glCompressedTexSubImage3D)
660    {
661        _glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
662    }
663    else
664    {
665        notify(WARN)<<"Error: glCompressedTexImage2D not supported by OpenGL driver"<<std::endl;
666    }
667}
668
669void Texture3D::Extensions::glCopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) const
670{
671//    ::glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
672    if (_glCopyTexSubImage3D)
673    {
674        _glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
675    }
676    else
677    {
678        notify(WARN)<<"Error: glCopyTexSubImage3D not supported by OpenGL driver"<<std::endl;
679    }
680}
681
682void Texture3D::Extensions::gluBuild3DMipmaps( GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data) const
683{
684//    ::gluBuild3DMipmaps(target, internalFormat, width, height, depth, format, type, data);
685    if (_gluBuild3DMipmaps)
686    {
687        _gluBuild3DMipmaps(target, internalFormat, width, height, depth, format, type, data);
688    }
689    else
690    {
691        notify(WARN)<<"Error: gluBuild3DMipmaps not supported by OpenGL driver"<<std::endl;
692    }
693}
Note: See TracBrowser for help on using the browser.