Hi Ricky,

I have just succesfully compiled osg trunk with this file. I am on windows and 
have not checked GLES compatibility though. Texture2DArray.cpp attached (the 
same as before)

Wojtek
  ----- Original Message ----- 
  From: Wojciech Lewandowski 
  To: OpenSceneGraph Users 
  Sent: Monday, April 26, 2010 7:58 AM
  Subject: Re: [osg-users] texture2Darray issue with different image format


  It was based on the trunk. What were the problems ? I'll recheck if the code 
still compiles later today. 

  WL


  From: Riccardo Corsi 
  Sent: Monday, April 26, 2010 1:38 AM
  To: OpenSceneGraph Users 
  Subject: Re: [osg-users] texture2Darray issue with different image format


  Hi Wojtek,

  I didn't manage to compile your patch with neither osg 2.8.2 nor the trunk.
  What osg revision is needed?

  Ricky


  On Fri, Apr 23, 2010 at 12:08, Riccardo Corsi <[email protected]> 
wrote:

    Hi Wojtek and Robert,

    thanks for your replies. 
    I'll try the patch in the evening and let you know if it fixes the problem 
on my side.

    Robert, the restricion on the values 1, 2, 3 or 4 that you mention is 
related to ES profile only, or even to openGL 3.x and 4.x ??
    That might be an issue to address when reviewing the different plugins.

    Cheers,
    Ricky




    On Fri, Apr 23, 2010 at 11:08, Wojciech Lewandowski <[email protected]> 
wrote:

      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 


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








------------------------------------------------------------------------------


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



------------------------------------------------------------------------------


  _______________________________________________
  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