From 804c91c8c1571bf5bdd39092d39fa7e8c86f97c9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 26 May 2008 21:53:57 +0000 Subject: [PATCH] From Art Tevs, "I've attached a patch for the Texture2DArray which solves problems of loading image data into the texture array. So here are a small description: - Solves issues of loading image data into the texture memory - Print a warning if images are of different dimensions or have different internal formats (GL specification requires images to be the same) Patch is tested and seems to work fine. It shouldn't break any other functionality. It should go into include/osg and src/osg " --- include/osg/Texture2DArray | 2 +- src/osg/Texture2DArray.cpp | 51 ++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/include/osg/Texture2DArray b/include/osg/Texture2DArray index b73f36e42..4feb52360 100644 --- a/include/osg/Texture2DArray +++ b/include/osg/Texture2DArray @@ -206,7 +206,7 @@ class OSG_EXPORT Texture2DArray : public Texture virtual void computeInternalFormat() const; void allocateMipmap(State& state) const; - void applyTexImage2DArray_subload(State& state, Image* image, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMipmapLevels) const; + void applyTexImage2DArray_subload(State& state, Image* image, GLsizei inwidth, GLsizei inheight, GLsizei indepth, GLenum inInternalFormat, GLsizei& numMipmapLevels) const; /** * Use std::vector to encapsulate referenced pointers to images of different layers. diff --git a/src/osg/Texture2DArray.cpp b/src/osg/Texture2DArray.cpp index e52753d12..3c7e9f298 100644 --- a/src/osg/Texture2DArray.cpp +++ b/src/osg/Texture2DArray.cpp @@ -212,7 +212,7 @@ void Texture2DArray::apply(State& state) const // 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, _numMipmapLevels); + applyTexImage2DArray_subload(state, image, _textureWidth, _textureHeight, n, _internalFormat, _numMipmapLevels); getModifiedCount(n,contextID) = image->getModifiedCount(); } } @@ -231,9 +231,10 @@ void Texture2DArray::apply(State& state) const } // 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(); @@ -248,14 +249,23 @@ void Texture2DArray::apply(State& state) const textureObject->bind(); applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT, state); - // now for each layer do + // 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); + + // 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) { - applyTexImage2DArray_subload(state, image, _textureWidth, _textureHeight, n, _numMipmapLevels); + // 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(); } } @@ -308,7 +318,7 @@ void Texture2DArray::apply(State& state) const } } -void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMipmapLevels) const +void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GLsizei inwidth, GLsizei inheight, GLsizei indepth, GLenum inInternalFormat, GLsizei& numMipmapLevels) const { // if we don't have a valid image we can't create a texture! if (!imagesValid()) @@ -335,13 +345,19 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL notify(WARN)<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) the given layer number exceeds the maximum number of supported layers."<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."<getPacking()); @@ -353,9 +369,9 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL // upload non-compressed image if (!compressed_image) { - extensions->glTexImage3D( target, 0, _internalFormat, - inwidth, inheight, indepth, - _borderWidth, + extensions->glTexSubImage3D( target, 0, + 0, 0, indepth, + inwidth, inheight, 1, (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), image->data() ); @@ -370,9 +386,10 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL GLint blockSize, size; getCompressedSize(_internalFormat, inwidth, inheight, indepth, blockSize,size); - extensions->glCompressedTexImage3D(target, 0, _internalFormat, - inwidth, inheight, indepth, - _borderWidth, + extensions->glCompressedTexSubImage3D(target, 0, + 0, 0, indepth, + inwidth, inheight, 1, + (GLenum)image->getPixelFormat(), size, image->data()); } @@ -383,7 +400,7 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL // image does not provide mipmaps, so we have to create them if(!image->isMipmap()) { - notify(WARN)<<"Warning: Texture2DArray::applyTexImage2DArray_subload(..) automagic mipmap generation is currently not implemented."<glTexImage3D( target, k, _internalFormat, - width, height, indepth, _borderWidth, + extensions->glTexSubImage3D( target, k, 0, 0, indepth, + width, height, 1, (GLenum)image->getPixelFormat(), (GLenum)image->getDataType(), image->getMipmapData(k)); @@ -413,10 +430,6 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL } } - - // set new sizes back - inwidth = image->s(); - inheight = image->t(); }