Completed support for assigning 3D osg::Image to osg::Texture2DArray.
Improved the osgtexture2DArray example to add --mipmap and --packed command line options to help with testing. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14775 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
@@ -38,8 +38,7 @@ Texture2DArray::Texture2DArray(const Texture2DArray& text,const CopyOp& copyop):
|
||||
{
|
||||
setTextureDepth(text._textureDepth);
|
||||
|
||||
// copy all images by iterating through all of them
|
||||
for (int i=0; i < text._textureDepth; i++)
|
||||
for(unsigned int i = 0; i<static_cast<unsigned int>(_images.size()); ++i)
|
||||
{
|
||||
setImage(i, copyop(text._images[i].get()));
|
||||
}
|
||||
@@ -47,7 +46,7 @@ Texture2DArray::Texture2DArray(const Texture2DArray& text,const CopyOp& copyop):
|
||||
|
||||
Texture2DArray::~Texture2DArray()
|
||||
{
|
||||
for (int i=0; i<_textureDepth; ++i)
|
||||
for(unsigned int i = 0; i<static_cast<unsigned int>(_images.size()); ++i)
|
||||
{
|
||||
setImage(i, NULL);
|
||||
}
|
||||
@@ -59,8 +58,11 @@ int Texture2DArray::compare(const StateAttribute& sa) const
|
||||
// used by the COMPARE_StateAttribute_Parameter macros below.
|
||||
COMPARE_StateAttribute_Types(Texture2DArray,sa)
|
||||
|
||||
if (_images.size()<rhs._images.size()) return -1;
|
||||
if (_images.size()>rhs._images.size()) return 1;
|
||||
|
||||
bool noImages = true;
|
||||
for (int n=0; n < _textureDepth; n++)
|
||||
for (unsigned int n=0; n < static_cast<unsigned int>(_images.size()); n++)
|
||||
{
|
||||
if (noImages && _images[n].valid()) noImages = false;
|
||||
if (noImages && rhs._images[n].valid()) noImages = false;
|
||||
@@ -86,7 +88,6 @@ int Texture2DArray::compare(const StateAttribute& sa) const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (noImages)
|
||||
{
|
||||
int result = compareTextureObjects(rhs);
|
||||
@@ -211,6 +212,22 @@ void Texture2DArray::computeInternalFormat() const
|
||||
else computeInternalFormatType();
|
||||
}
|
||||
|
||||
GLsizei Texture2DArray::computeTextureDepth() const
|
||||
{
|
||||
GLsizei textureDepth = _textureDepth;
|
||||
if (textureDepth==0)
|
||||
{
|
||||
for(Images::const_iterator itr = _images.begin();
|
||||
itr != _images.end();
|
||||
++itr)
|
||||
{
|
||||
const osg::Image* image = itr->get();
|
||||
if (image) textureDepth += image->r();
|
||||
}
|
||||
}
|
||||
return textureDepth;
|
||||
}
|
||||
|
||||
|
||||
void Texture2DArray::apply(State& state) const
|
||||
{
|
||||
@@ -234,7 +251,9 @@ void Texture2DArray::apply(State& state) const
|
||||
// get the texture object for the current contextID.
|
||||
TextureObject* textureObject = getTextureObject(contextID);
|
||||
|
||||
if (textureObject && _textureDepth>0)
|
||||
GLsizei textureDepth = computeTextureDepth();
|
||||
|
||||
if (textureObject && textureDepth>0)
|
||||
{
|
||||
const osg::Image* image = _images[0].get();
|
||||
if (image && getModifiedCount(0, contextID) != image->getModifiedCount())
|
||||
@@ -247,7 +266,7 @@ void Texture2DArray::apply(State& state) const
|
||||
// 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, _textureDepth, _borderWidth))
|
||||
if (!textureObject->match(GL_TEXTURE_2D_ARRAY_EXT, new_numMipmapLevels, _internalFormat, new_width, new_height, textureDepth, _borderWidth))
|
||||
{
|
||||
Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
|
||||
_textureObjectBuffer[contextID] = 0;
|
||||
@@ -272,19 +291,23 @@ void Texture2DArray::apply(State& state) const
|
||||
}
|
||||
else
|
||||
{
|
||||
// for each image of the texture array do
|
||||
for (GLsizei n=0; n < _textureDepth; n++)
|
||||
GLsizei n = 0;
|
||||
for(Images::const_iterator itr = _images.begin();
|
||||
itr != _images.end();
|
||||
++itr)
|
||||
{
|
||||
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())
|
||||
osg::Image* image = itr->get();
|
||||
if (image)
|
||||
{
|
||||
applyTexImage2DArray_subload(state, image, _textureWidth, _textureHeight, n, _internalFormat, _numMipmapLevels);
|
||||
getModifiedCount(n,contextID) = image->getModifiedCount();
|
||||
if (getModifiedCount(n,contextID) != image->getModifiedCount())
|
||||
{
|
||||
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
|
||||
getModifiedCount(n,contextID) = image->getModifiedCount();
|
||||
}
|
||||
n += image->r();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -311,7 +334,7 @@ void Texture2DArray::apply(State& state) const
|
||||
|
||||
// create texture object
|
||||
textureObject = generateTextureObject(
|
||||
this, contextID,GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
|
||||
this, contextID, GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels, _internalFormat, _textureWidth, _textureHeight, textureDepth,0);
|
||||
|
||||
// bind texture
|
||||
textureObject->bind();
|
||||
@@ -327,8 +350,8 @@ void Texture2DArray::apply(State& state) const
|
||||
extensions->isCompressedTexImage3DSupported() )
|
||||
{
|
||||
extensions->glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
|
||||
_textureWidth, _textureHeight, _textureDepth, _borderWidth,
|
||||
_images[0]->getImageSizeInBytes() * _textureDepth,
|
||||
_textureWidth, _textureHeight, textureDepth, _borderWidth,
|
||||
_images[0]->getImageSizeInBytes() * textureDepth,
|
||||
0);
|
||||
}
|
||||
else
|
||||
@@ -339,28 +362,34 @@ void Texture2DArray::apply(State& state) const
|
||||
sourceFormat = GL_RGBA;
|
||||
|
||||
extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, _internalFormat,
|
||||
_textureWidth, _textureHeight, _textureDepth, _borderWidth,
|
||||
_textureWidth, _textureHeight, textureDepth, _borderWidth,
|
||||
sourceFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
|
||||
0);
|
||||
}
|
||||
|
||||
// For certain we have to manually allocate memory for mipmaps if images are compressed
|
||||
// if not allocated OpenGL will produce errors on mipmap upload.
|
||||
// I have not tested if this is neccessary for plain texture formats but
|
||||
// common sense suggests its required as well.
|
||||
if( _min_filter != LINEAR && _min_filter != NEAREST && _images[0]->isMipmap() )
|
||||
allocateMipmap( state );
|
||||
|
||||
// now for each layer we upload it into the memory
|
||||
for (GLsizei n=0; n<_textureDepth; n++)
|
||||
// For certain we have to manually allocate memory for mipmaps if images are compressed
|
||||
// if not allocated OpenGL will produce errors on mipmap upload.
|
||||
// I have not tested if this is neccessary for plain texture formats but
|
||||
// common sense suggests its required as well.
|
||||
if( _min_filter != LINEAR && _min_filter != NEAREST && _images[0]->isMipmap() )
|
||||
{
|
||||
// if image is valid then upload it to the texture memory
|
||||
osg::Image* image = _images[n].get();
|
||||
allocateMipmap( state );
|
||||
}
|
||||
|
||||
GLsizei n = 0;
|
||||
for(Images::const_iterator itr = _images.begin();
|
||||
itr != _images.end();
|
||||
++itr)
|
||||
{
|
||||
osg::Image* image = itr->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();
|
||||
if (getModifiedCount(n,contextID) != image->getModifiedCount())
|
||||
{
|
||||
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
|
||||
getModifiedCount(n,contextID) = image->getModifiedCount();
|
||||
}
|
||||
n += image->r();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,22 +397,25 @@ void Texture2DArray::apply(State& state) const
|
||||
// source images have no mipmamps but we could generate them...
|
||||
if( _min_filter != LINEAR && _min_filter != NEAREST && !_images[0]->isMipmap() &&
|
||||
_useHardwareMipMapGeneration && extensions->isGenerateMipMapSupported )
|
||||
{
|
||||
_numMipmapLevels = Image::computeNumberOfMipmapLevels( _textureWidth, _textureHeight );
|
||||
generateMipmap( state );
|
||||
}
|
||||
{
|
||||
_numMipmapLevels = Image::computeNumberOfMipmapLevels( _textureWidth, _textureHeight );
|
||||
generateMipmap( state );
|
||||
}
|
||||
|
||||
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
|
||||
textureObject->setAllocated(_numMipmapLevels, _internalFormat, _textureWidth, _textureHeight, textureDepth,0);
|
||||
|
||||
// unref image data?
|
||||
if (isSafeToUnrefImageData(state))
|
||||
{
|
||||
Texture2DArray* non_const_this = const_cast<Texture2DArray*>(this);
|
||||
for (int n=0; n<_textureDepth; n++)
|
||||
for(Images::iterator itr = non_const_this->_images.begin();
|
||||
itr != non_const_this->_images.end();
|
||||
++itr)
|
||||
{
|
||||
if (_images[n].valid() && _images[n]->getDataVariance()==STATIC)
|
||||
osg::Image* image = itr->get();
|
||||
if (image && image->getDataVariance()==STATIC)
|
||||
{
|
||||
non_const_this->_images[n] = NULL;
|
||||
*itr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,7 +427,7 @@ void Texture2DArray::apply(State& state) const
|
||||
{
|
||||
// generate texture
|
||||
_textureObjectBuffer[contextID] = textureObject = generateTextureObject(
|
||||
this, contextID, GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
|
||||
this, contextID, GL_TEXTURE_2D_ARRAY_EXT,_numMipmapLevels,_internalFormat, _textureWidth, _textureHeight, _textureDepth,0);
|
||||
|
||||
textureObject->bind();
|
||||
applyTexParameters(GL_TEXTURE_2D_ARRAY_EXT,state);
|
||||
@@ -423,7 +455,7 @@ void Texture2DArray::apply(State& state) const
|
||||
}
|
||||
|
||||
|
||||
void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GLsizei inwidth, GLsizei inheight, GLsizei indepth, GLint inInternalFormat, GLsizei& numMipmapLevels) const
|
||||
void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GLsizei layer, 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())
|
||||
@@ -484,8 +516,8 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL
|
||||
if ( !compressed_image )
|
||||
{
|
||||
extensions->glTexSubImage3D( target, 0,
|
||||
0, 0, indepth,
|
||||
inwidth, inheight, 1,
|
||||
0, 0, layer,
|
||||
inwidth, inheight, indepth,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
(GLenum)image->getDataType(),
|
||||
image->data() );
|
||||
@@ -500,15 +532,16 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL
|
||||
getCompressedSize(_internalFormat, inwidth, inheight, 1, blockSize,size);
|
||||
|
||||
extensions->glCompressedTexSubImage3D(target, 0,
|
||||
0, 0, indepth,
|
||||
inwidth, inheight, 1,
|
||||
0, 0, layer,
|
||||
inwidth, inheight, indepth,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
size,
|
||||
image->data());
|
||||
}
|
||||
|
||||
// we want to use mipmapping, so enable it
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
// image does not provide mipmaps, so we have to create them
|
||||
if( !image->isMipmap() )
|
||||
@@ -517,7 +550,8 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL
|
||||
OSG_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
|
||||
}
|
||||
else
|
||||
{
|
||||
numMipmapLevels = image->getNumMipmapLevels();
|
||||
|
||||
@@ -534,8 +568,8 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL
|
||||
if (height == 0)
|
||||
height = 1;
|
||||
|
||||
extensions->glTexSubImage3D( target, k, 0, 0, indepth,
|
||||
width, height, 1,
|
||||
extensions->glTexSubImage3D( target, k, 0, 0, layer,
|
||||
width, height, indepth,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
(GLenum)image->getDataType(),
|
||||
image->getMipmapData(k));
|
||||
@@ -554,12 +588,12 @@ void Texture2DArray::applyTexImage2DArray_subload(State& state, Image* image, GL
|
||||
if (height == 0)
|
||||
height = 1;
|
||||
|
||||
getCompressedSize(image->getInternalTextureFormat(), width, height, 1, blockSize,size);
|
||||
getCompressedSize(image->getInternalTextureFormat(), width, height, indepth, blockSize,size);
|
||||
|
||||
// state.checkGLErrors("before extensions->glCompressedTexSubImage3D(");
|
||||
|
||||
extensions->glCompressedTexSubImage3D(target, k, 0, 0, indepth,
|
||||
width, height, 1,
|
||||
extensions->glCompressedTexSubImage3D(target, k, 0, 0, layer,
|
||||
width, height, indepth,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
size,
|
||||
image->getMipmapData(k));
|
||||
@@ -609,7 +643,9 @@ void Texture2DArray::allocateMipmap(State& state) const
|
||||
// get the texture object for the current contextID.
|
||||
TextureObject* textureObject = getTextureObject(contextID);
|
||||
|
||||
if (textureObject && _textureWidth != 0 && _textureHeight != 0 && _textureDepth != 0)
|
||||
GLsizei textureDepth = computeTextureDepth();
|
||||
|
||||
if (textureObject && _textureWidth != 0 && _textureHeight != 0 && textureDepth != 0)
|
||||
{
|
||||
const GLExtensions* extensions = state.get<GLExtensions>();
|
||||
|
||||
@@ -646,7 +682,7 @@ void Texture2DArray::allocateMipmap(State& state) const
|
||||
{
|
||||
int size = 0, blockSize = 0;
|
||||
|
||||
getCompressedSize( _internalFormat, width, height, _textureDepth, blockSize, size);
|
||||
getCompressedSize( _internalFormat, width, height, textureDepth, blockSize, size);
|
||||
|
||||
extensions->glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, k, _internalFormat,
|
||||
width, height, _textureDepth, _borderWidth,
|
||||
@@ -656,7 +692,7 @@ void Texture2DArray::allocateMipmap(State& state) const
|
||||
else
|
||||
{
|
||||
extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, k, _internalFormat,
|
||||
width, height, _textureDepth, _borderWidth,
|
||||
width, height, textureDepth, _borderWidth,
|
||||
safeSourceFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user