Hi Ricardo,

Current texture2DArray implementation does not handle loading and generation of mipmaps for compressed formats. If you can rebuild OSG you may try attached patch to Texture2DArray class. I intend to post it ultimately to submissions list, but lets say its in "alpha" version and I want to make one more review before posting and other tasks prevented me from doing it, yet. You may test it. There is a chance it will solve your problem.

Cheers,
Wojtek Lewandowski



----- Original Message ----- From: "Robert Osfield" <[email protected]>
To: "OpenSceneGraph Users" <[email protected]>
Sent: Friday, April 23, 2010 10:24 AM
Subject: Re: [osg-users] texture2Darray issue with different image format


Hi Riccardo,

On Fri, Apr 23, 2010 at 8:27 AM, Riccardo Corsi
<[email protected]> wrote:
as a follow-up I discovered that the limitation seems to depend on the
"internalTextureFormat" of the images loaded.
I succeded in fixing the TGA settings but not the DDS.
Here the setting for the different image types as read from the plugins:

I'm afraid I don't have an specific answers on this topic as I haven't
use texture arrays and compression, but the inconsistency in how the
internal texture format us used, i.e. something that works OK for
Texture2D doesn't work for Texture2DArray, makes me wonder if there is
either a bug in osg::Texture2DArray or with the OpenGL driver.

As an aside one of the things I found with the GLES port was GLES was
a bit more picky about the internal format not being one of the 1,2,3
or 4 values that some of the plugins still use.


Robert.
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
* * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details.
*/
#include <osg/GLExtensions>
#include <osg/Texture2DArray>
#include <osg/State>
#include <osg/Notify>

#include <string.h>


using namespace osg;

Texture2DArray::Texture2DArray():
           _textureWidth(0),
           _textureHeight(0),
           _textureDepth(0),
           _numMipmapLevels(0)
{
}

Texture2DArray::Texture2DArray(const Texture2DArray& text,const CopyOp& copyop):
           Texture(text,copyop),
           _textureWidth(text._textureWidth),
           _textureHeight(text._textureHeight),
           _textureDepth(text._textureDepth),
           _numMipmapLevels(text._numMipmapLevels),
           _subloadCallback(text._subloadCallback)
{
   // copy all images by iterating through all of them
   for (int i=0; i < text._textureDepth; i++)
   {
       _images.push_back(copyop(text._images[i].get()));
       _modifiedCount.push_back(ImageModifiedCount());
   }
}

Texture2DArray::~Texture2DArray()
{
}

int Texture2DArray::compare(const StateAttribute& sa) const
{
   // check the types are equal and then create the rhs variable
   // used by the COMPARE_StateAttribute_Parameter macro's below.
   COMPARE_StateAttribute_Types(Texture2DArray,sa)

   bool noImages = true;
   for (int n=0; n < _textureDepth; n++)
   {
       if (noImages && _images[n].valid()) noImages = false;
       if (noImages && rhs._images[n].valid()) noImages = false;
if (_images[n]!=rhs._images[n]) // smart pointer comparison.
       {
           if (_images[n].valid())
           {
               if (rhs._images[n].valid())
               {
                   int result = _images[n]->compare(*rhs._images[n]);
                   if (result!=0) return result;
               }
               else
               {
return 1; // valid lhs._image is greater than null. }
           }
else if (rhs._images[n].valid()) { return -1; // valid rhs._image is greater than null. }
       }
   }

if (noImages)
   {
       int result = compareTextureObjects(rhs);
       if (result!=0) return result;
   }

   int result = compareTexture(rhs);
   if (result!=0) return result;

   // compare each parameter in turn against the rhs.
   COMPARE_StateAttribute_Parameter(_textureWidth)
   COMPARE_StateAttribute_Parameter(_textureHeight)
   COMPARE_StateAttribute_Parameter(_textureDepth)
   COMPARE_StateAttribute_Parameter(_subloadCallback)

   return 0; // passed all the above comparison macro's, must be equal.
}

void Texture2DArray::setImage(unsigned int layer, Image* image)
{
   // check if the layer exceeds the texture depth
   if (static_cast<int>(layer) >= _textureDepth)
   {
       // print warning and do nothing
       notify(WARN)<<"Warning: Texture2DArray::setImage(..) failed, the given layer number 
is bigger then the size of the texture array."<<std::endl;
       return;
   }
if (_images[layer] == image) return;

   unsigned numImageRequireUpdateBefore = 0;
   for (unsigned int i=0; i<getNumImages(); ++i)
   {
       if (_images[i].valid() && _images[i]->requiresUpdateCall()) 
++numImageRequireUpdateBefore;
   }

   // set image
   _images[layer] = image;
  _modifiedCount[layer].setAllElementsTo(0);

   // find out if we need to reset the update callback to handle the animation 
of image
   unsigned numImageRequireUpdateAfter = 0;
   for (unsigned int i=0; i<getNumImages(); ++i)
   {
       if (_images[i].valid() && _images[i]->requiresUpdateCall()) 
++numImageRequireUpdateAfter;
   }

   if (numImageRequireUpdateBefore>0)
   {
       if (numImageRequireUpdateAfter==0)
       {
           setUpdateCallback(0);
           setDataVariance(osg::Object::STATIC);
       }
   }
   else if (numImageRequireUpdateAfter>0)
   {
       setUpdateCallback(new Image::UpdateCallback());
       setDataVariance(osg::Object::DYNAMIC);
   }
}

void Texture2DArray::setTextureSize(int width, int height, int depth)
{
   // set dimensions
   _textureWidth = width;
   _textureHeight = height;
   setTextureDepth(depth);
}

void Texture2DArray::setTextureDepth(int depth)
{ // if we decrease the number of layers, then delete non-used
   if (depth < _textureDepth)
   {
       _images.resize(depth);
       _modifiedCount.resize(depth);
   }
// if we increase the array, then add new empty elements
   if (depth > _textureDepth)
   {
       _images.resize(depth, ref_ptr<Image>(0));
       _modifiedCount.resize(depth, ImageModifiedCount());
   }
// resize the texture array
   _textureDepth = depth;
}

Image* Texture2DArray::getImage(unsigned int layer)
{
   return _images[layer].get();
}

const Image* Texture2DArray::getImage(unsigned int layer) const
{
   return _images[layer].get();
}

bool Texture2DArray::imagesValid() const
{
   if (_textureDepth < 1) return false;
   for (int n=0; n < _textureDepth; n++)
   {
       if (!_images[n].valid() || !_images[n]->data())
           return false;
   }
   return true;
}

void Texture2DArray::computeInternalFormat() const
{
if (imagesValid()) computeInternalFormatWithImage(*_images[0]); else computeInternalFormatType();
}


void Texture2DArray::apply(State& state) const
{
// get the contextID (user defined ID of 0 upwards) for the // current OpenGL context.
   const unsigned int contextID = state.getContextID();

   Texture::TextureObjectManager* tom = 
Texture::getTextureObjectManager(contextID).get();
   ElapsedTime elapsedTime(&(tom->getApplyTime()));
   tom->getNumberApplied()++;

   const Extensions* extensions = getExtensions(contextID,true);

   // if not supported, then return
   if (!extensions->isTexture2DArraySupported() || 
!extensions->isTexture3DSupported())
   {
       notify(WARN)<<"Warning: Texture2DArray::apply(..) failed, 2D texture arrays are not 
support by OpenGL driver."<<std::endl;
       return;
   }
// get the texture object for the current contextID.
   TextureObject* textureObject = getTextureObject(contextID);

   if (textureObject && _textureDepth>0)
   {
       const osg::Image* image = _images[0].get();
       if (image && getModifiedCount(0, contextID) != image->getModifiedCount())
       {
           // compute the internal texture format, this set the _internalFormat 
to an appropriate value.
           computeInternalFormat();

           GLsizei new_width, new_height, new_numMipmapLevels;

           // compute the dimensions of the texture.
           computeRequiredTextureDimensions(state, *image, new_width, 
new_height, new_numMipmapLevels);

           if (!textureObject->match(GL_TEXTURE_2D_ARRAY_EXT, 
new_numMipmapLevels, _internalFormat, new_width, new_height, 1, _borderWidth))
           {
               Texture::releaseTextureObject(contextID, 
_textureObjectBuffer[contextID].get());
               _textureObjectBuffer[contextID] = 0;
               textureObject = 0;
           }
       }
   }

// if we already have an texture object, then if (textureObject)
   {
       // bind texture object
       textureObject->bind();

       // if texture parameters changed, then reset them
       if (getTextureParameterDirty(state.getContextID())) 
applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);

       // if subload is specified, then use it to subload the images to GPU 
memory
       if (_subloadCallback.valid())
       {
           _subloadCallback->subload(*this,state);
       }
       else
       {
           // for each image of the texture array do
           for (GLsizei n=0; n < _textureDepth; n++)
           {
               osg::Image* image = _images[n].get();
// if image content is modified, then upload it to the GPU memory
               if (image && getModifiedCount(n,contextID) != 
image->getModifiedCount())
               {
                   applyTexImage2DArray_subload(state, image, _textureWidth, 
_textureHeight, n, _internalFormat, _numMipmapLevels);
                   getModifiedCount(n,contextID) = image->getModifiedCount();
               }
           }
       }

   }
// there is no texture object, but exists a subload callback, so use it to upload images
   else if (_subloadCallback.valid())
   {
       // generate texture (i.e. glGenTexture) and apply parameters
       _textureObjectBuffer[contextID] = textureObject = 
generateTextureObject(this, contextID, GL_TEXTURE_2D_ARRAY_EXT);
       textureObject->bind();
       applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT, state);
       _subloadCallback->load(*this,state);
   }
// nothing before, but we have valid images, so do manual upload and create texture object manually
   // TODO: we assume _images[0] is valid, however this may not be always the 
case
   //       some kind of checking for the first valid image is required (Art, 
may 2008)
   else if (imagesValid())
   {
       // compute the internal texture format, this set the _internalFormat to 
an appropriate value.
       computeInternalFormat();

       // compute the dimensions of the texture.
       computeRequiredTextureDimensions(state,*_images[0],_textureWidth, 
_textureHeight, _numMipmapLevels);

       // create texture object
       textureObject = generateTextureObject(
               this, 
contextID,GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
// bind texture
       textureObject->bind();
       applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT, state);

       // first we need to allocate the texture memory
       extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
                    _textureWidth, _textureHeight, _textureDepth,
                    _borderWidth,
                    _sourceFormat ? _sourceFormat : _internalFormat,
                    _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
0);
       _textureObjectBuffer[contextID] = textureObject;

       // we also need to manually allocate memory for mipmaps if images are 
compressed
       if( _min_filter != LINEAR && _min_filter != NEAREST && _images[0]->isMipmap() 
&&
           isCompressedInternalFormat(_internalFormat) && 
extensions->isCompressedTexImage3DSupported() )
               allocateMipmap( state );

       // now for each layer we upload it into the memory
       for (GLsizei n=0; n<_textureDepth; n++)
       {
           // if image is valid then upload it to the texture memory
           osg::Image* image = _images[n].get();
           if (image)
           {
               // now load the image data into the memory, this will also check 
if image do have valid properties
               applyTexImage2DArray_subload(state, image, _textureWidth, 
_textureHeight, n, _internalFormat, _numMipmapLevels);
               getModifiedCount(n,contextID) = image->getModifiedCount();
           }
       }

       const Texture::Extensions* texExtensions = 
Texture::getExtensions(contextID,true);
// source images have no mipmamps but we could generate them... if( _min_filter != LINEAR && _min_filter != NEAREST && !_images[0]->isMipmap() && _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported() )
           {
               _numMipmapLevels = Image::computeNumberOfMipmapLevels( 
_textureWidth, _textureHeight );
               generateMipmap( state );
           }

       
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
// no idea what this for ;-)
       if (state.getMaxTexturePoolSize()==0 && _unrefImageDataAfterApply && 
areAllTextureObjectsLoaded())
       {
           Texture2DArray* non_const_this = const_cast<Texture2DArray*>(this);
           for (int n=0; n<_textureDepth; n++)
{ if (_images[n].valid() && _images[n]->getDataVariance()==STATIC)
               {
                   non_const_this->_images[n] = 0;
               }
           }
       }
} // No images present, but dimensions are set. So create empty texture
   else if ( (_textureWidth > 0) && (_textureHeight > 0) && (_textureDepth > 0) 
&& (_internalFormat!=0) )
   {
// generate texture _textureObjectBuffer[contextID] = textureObject = generateTextureObject(
               this, contextID, 
GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
textureObject->bind();
       applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);
extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
                    _textureWidth, _textureHeight, _textureDepth,
                    _borderWidth,
                    _sourceFormat ? _sourceFormat : _internalFormat,
                    _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
0); } // nothing before, so just unbind the texture target
   else
   {
       glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, 0 );
   }

   // if texture object is now valid and we have to allocate mipmap levels, then
   if (textureObject != 0 && _texMipmapGenerationDirtyList[contextID])
   {
       generateMipmap(state);
   }
}

void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, 
GLsizei inwidth, GLsizei inheight, GLsizei indepth, GLint inInternalFormat, 
GLsizei& numMipmapLevels) const
{
   // if we don't have a valid image we can't create a texture!
   if (!imagesValid())
       return;

// get the contextID (user defined ID of 0 upwards) for the // current OpenGL context.
   const unsigned int contextID = state.getContextID();
const Extensions* extensions = getExtensions(contextID,true); const Texture::Extensions* texExtensions = Texture::getExtensions(contextID,true);
   GLenum target = GL_TEXTURE_2D_ARRAY_EXT;
// compute the internal texture format, this set the _internalFormat to an appropriate value.
   computeInternalFormat();

   // select the internalFormat required for the texture.
//    bool compressed = isCompressedInternalFormat(_internalFormat);
   bool compressed_image = 
isCompressedInternalFormat((GLenum)image->getPixelFormat());

   // if the required layer is exceeds the maximum allowed layer sizes
   if (indepth > extensions->maxLayerCount())
   {
       // we give a warning and do nothing
       notify(WARN)<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) the given 
layer number exceeds the maximum number of supported layers."<<std::endl;
return; }

   //Rescale if resize hint is set or NPOT not supported or dimensions exceed 
max size
   if( _resizeNonPowerOfTwoHint || 
!texExtensions->isNonPowerOfTwoTextureSupported(_min_filter)
       || inwidth > extensions->max2DSize()
       || inheight > extensions->max2DSize())
       image->ensureValidSizeForTexturing(extensions->max2DSize());

   // image size or format has changed, this is not allowed, hence return
if (image->s()!=inwidth || image->t()!=inheight || image->getInternalTextureFormat()!=inInternalFormat ) {
       notify(WARN)<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) given 
image do have wrong dimension or internal format."<<std::endl;
return; } glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking());

bool useHardwareMipmapGeneration = !image->isMipmap() && _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported();

   // if no special mipmapping is required, then
   if( _min_filter == LINEAR || _min_filter == NEAREST || 
useHardwareMipmapGeneration )
   {
       if( _min_filter == LINEAR || _min_filter == NEAREST )
           numMipmapLevels = 1;
       else //Hardware Mipmap Generation
           numMipmapLevels = image->getNumMipmapLevels();

       // upload non-compressed image
       if ( !compressed_image )
       {
           extensions->glTexSubImage3D( target, 0,
                                     0, 0, indepth,
                                     inwidth, inheight, 1,
                                     (GLenum)image->getPixelFormat(),
                                     (GLenum)image->getDataType(),
                                     image->data() );
       }
// if we support compression and image is compressed, then
       else if (extensions->isCompressedTexImage3DSupported())
       {
           // notify(WARN)<<"glCompressedTexImage3D "<<inwidth<<", "<<inheight<<", 
"<<indepth<<std::endl;

           GLint blockSize, size;
           getCompressedSize(_internalFormat, inwidth, inheight, 1, 
blockSize,size);

           extensions->glCompressedTexSubImage3D(target, 0,
0, 0, indepth, inwidth, inheight, 1, (GLenum)image->getPixelFormat(), size, image->data());
       }

   // we want to use mipmapping, so enable it
   }else
   {
       // image does not provide mipmaps, so we have to create them
       if( !image->isMipmap() )
       {
           numMipmapLevels = 1;
           notify(WARN)<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) mipmap 
layer not passed, and auto mipmap generation turned off or not available. Check texture's min/mag filters 
& hardware mipmap generation."<<std::endl;

           // the image object does provide mipmaps, so upload the in the 
certain levels of a layer
       }else
       {
           numMipmapLevels = image->getNumMipmapLevels();

           int width  = image->s();
           int height = image->t();

           if( !compressed_image )
           {

               for( GLsizei k = 0 ; k < numMipmapLevels  && (width || height ) 
;k++)
               {
                   if (width == 0)
                      width = 1;
                   if (height == 0)
                      height = 1;

                   extensions->glTexSubImage3D( target, k, 0, 0, indepth,
width, height, 1, (GLenum)image->getPixelFormat(),
                                             (GLenum)image->getDataType(),
                                              image->getMipmapData(k));

                   width >>= 1;
                   height >>= 1;
               }
           }
           else if (extensions->isCompressedTexImage3DSupported())
           {
               GLint blockSize,size;
               for( GLsizei k = 0 ; k < numMipmapLevels  && (width || height) 
;k++)
               {
                   if (width == 0)
                       width = 1;
                   if (height == 0)
                       height = 1;

                   getCompressedSize(image->getInternalTextureFormat(), width, 
height, 1, blockSize,size);

//                    state.checkGLErrors("before 
extensions->glCompressedTexSubImage3D(");

                   extensions->glCompressedTexSubImage3D(target, k, 0, 0, 
indepth,
                                                      width, height, 1,
                                                      
(GLenum)image->getPixelFormat(),
                                                      size,
                                                      image->getMipmapData(k));

//                    state.checkGLErrors("after 
extensions->glCompressedTexSubImage3D(");

                   width >>= 1;
                   height >>= 1;
               }
           }
       }

   }
}


void Texture2DArray::copyTexSubImage2DArray(State& state, int xoffset, int 
yoffset, int zoffset, int x, int y, int width, int height )
{
   const unsigned int contextID = state.getContextID();
   const Extensions* extensions = getExtensions(contextID,true);

   // get the texture object for the current contextID.
   TextureObject* textureObject = getTextureObject(contextID);

   // if texture object is valid
   if (textureObject != 0)
   {
       textureObject->bind();

       applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);
       extensions->glCopyTexSubImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, 
xoffset,yoffset,zoffset, x, y, width, height);

       // inform state that this texture is the current one bound.
       state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this);

   }
   else
   {
       notify(WARN)<<"Warning: Texture2DArray::copyTexSubImage2DArray(..) failed, cannot 
not copy to a non existant texture."<<std::endl;
   }
}

void Texture2DArray::allocateMipmap(State& state) const
{
   const unsigned int contextID = state.getContextID();

   // get the texture object for the current contextID.
   TextureObject* textureObject = getTextureObject(contextID);
if (textureObject && _textureWidth != 0 && _textureHeight != 0 && _textureDepth != 0)
   {
       const Extensions* extensions = getExtensions(contextID,true);
       // const Texture::Extensions* texExtensions = 
Texture::getExtensions(contextID,true);
// bind texture
       textureObject->bind();

       // compute number of mipmap levels
       int width = _textureWidth;
       int height = _textureHeight;
       int numMipmapLevels = Image::computeNumberOfMipmapLevels(width, height);

       // we do not reallocate the level 0, since it was already allocated
       width >>= 1;
       height >>= 1;
for( GLsizei k = 1; k < numMipmapLevels && (width || height); k++)
       {
           if (width == 0)
               width = 1;
           if (height == 0)
               height = 1;

           extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, k, 
_internalFormat,
                    width, height, _textureDepth, _borderWidth,
                    _sourceFormat ? _sourceFormat : _internalFormat,
                    _sourceType ? _sourceType : GL_UNSIGNED_BYTE, NULL);

           width >>= 1;
           height >>= 1;
       }
// inform state that this texture is the current one bound. state.haveAppliedTextureAttribute(state.getActiveTextureUnit(), this); }
}

typedef buffered_value< ref_ptr<Texture2DArray::Extensions> > 
BufferedExtensions;
static BufferedExtensions s_extensions;

Texture2DArray::Extensions* Texture2DArray::getExtensions(unsigned int 
contextID,bool createIfNotInitalized)
{
   if (!s_extensions[contextID] && createIfNotInitalized) 
s_extensions[contextID] = new Extensions(contextID);
   return s_extensions[contextID].get();
}

void Texture2DArray::setExtensions(unsigned int contextID,Extensions* 
extensions)
{
   s_extensions[contextID] = extensions;
}

Texture2DArray::Extensions::Extensions(unsigned int contextID)
{
   setupGLExtensions(contextID);
}

Texture2DArray::Extensions::Extensions(const Extensions& rhs):
   Referenced()
{
   _isTexture3DSupported = rhs._isTexture3DSupported;
   _isTexture2DArraySupported = rhs._isTexture2DArraySupported;
_max2DSize = rhs._max2DSize;
   _maxLayerCount = rhs._maxLayerCount;
_glTexImage3D = rhs._glTexImage3D;
   _glTexSubImage3D = rhs._glTexSubImage3D;
   _glCopyTexSubImage3D = rhs._glCopyTexSubImage3D;
   _glCompressedTexImage3D = rhs._glCompressedTexImage3D;
   _glCompressedTexSubImage3D = rhs._glCompressedTexSubImage3D;;
}

void Texture2DArray::Extensions::lowestCommonDenominator(const Extensions& rhs)
{
   if (!rhs._isTexture3DSupported)                 _isTexture3DSupported = 
false;
   if (!rhs._isTexture2DArraySupported)            _isTexture2DArraySupported = 
false;
   if (rhs._max2DSize<_max2DSize)                  _max2DSize = rhs._max2DSize;
   if (rhs._maxLayerCount<_maxLayerCount)          _maxLayerCount = 
rhs._maxLayerCount;

   if (!rhs._glTexImage3D)                         _glTexImage3D = 0;
   if (!rhs._glTexSubImage3D)                      _glTexSubImage3D = 0;
   if (!rhs._glCompressedTexImage3D)               _glTexImage3D = 0;
   if (!rhs._glCompressedTexSubImage3D)            _glTexSubImage3D = 0;
   if (!rhs._glCopyTexSubImage3D)                  _glCopyTexSubImage3D = 0;
}

void Texture2DArray::Extensions::setupGLExtensions(unsigned int contextID)
{
   _isTexture3DSupported = OSG_GL3_FEATURES || 
isGLExtensionSupported(contextID,"GL_EXT_texture3D");
   _isTexture2DArraySupported = OSG_GL3_FEATURES || 
isGLExtensionSupported(contextID,"GL_EXT_texture_array");

   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_max2DSize);
   glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &_maxLayerCount);

   setGLExtensionFuncPtr(_glTexImage3D, "glTexImage3D","glTexImage3DEXT");
   setGLExtensionFuncPtr(_glTexSubImage3D, 
"glTexSubImage3D","glTexSubImage3DEXT");
   setGLExtensionFuncPtr(_glCompressedTexImage3D, 
"glCompressedTexImage3D","glCompressedTexImage3DARB");
   setGLExtensionFuncPtr(_glCompressedTexSubImage3D, 
"glCompressedTexSubImage3D","glCompressedTexSubImage3DARB");
   setGLExtensionFuncPtr(_glCopyTexSubImage3D, 
"glCopyTexSubImage3D","glCopyTexSubImage3DEXT");
}

void 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
{
   if (_glTexImage3D)
   {
       _glTexImage3D( target, level, internalFormat, width, height, depth, 
border, format, type, pixels);
   }
   else
   {
       notify(WARN)<<"Error: glTexImage3D not supported by OpenGL 
driver"<<std::endl;
   }
}

void 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
{
   if (_glTexSubImage3D)
   {
       _glTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, 
height, depth, format, type, pixels);
   }
   else
   {
       notify(WARN)<<"Error: glTexSubImage3D not supported by OpenGL 
driver"<<std::endl;
   }
}

void Texture2DArray::Extensions::glCompressedTexImage3D(GLenum target, GLint 
level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, 
GLint border, GLsizei imageSize, const GLvoid *data) const
{
   if (_glCompressedTexImage3D)
   {
       _glCompressedTexImage3D(target, level, internalformat, width, height, 
depth, border, imageSize, data);
   }
   else
   {
       notify(WARN)<<"Error: glCompressedTexImage3D not supported by OpenGL 
driver"<<std::endl;
   }
}

void 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
{
   if (_glCompressedTexSubImage3D)
   {
       _glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, 
width, height, depth, format, imageSize, data);
   }
   else
   {
       notify(WARN)<<"Error: glCompressedTexImage2D not supported by OpenGL 
driver"<<std::endl;
   }
}

void Texture2DArray::Extensions::glCopyTexSubImage3D( GLenum target, GLint 
level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei 
width, GLsizei height ) const
{
   if (_glCopyTexSubImage3D)
   {
       _glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, 
width, height);
   }
   else
   {
       notify(WARN)<<"Error: glCopyTexSubImage3D not supported by OpenGL 
driver"<<std::endl;
   }
}

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to