diff --git a/src/osg/Texture1D.cpp b/src/osg/Texture1D.cpp index dd0a28ad6..f316968ef 100644 --- a/src/osg/Texture1D.cpp +++ b/src/osg/Texture1D.cpp @@ -230,18 +230,30 @@ void Texture1D::apply(State& state) const } else if ( (_textureWidth!=0) && (_internalFormat!=0) ) { - textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_1D,_numMipmapLevels,_internalFormat,_textureWidth,1,1,0); + // no image present, but dimensions at set so lets create the texture + GLExtensions * extensions = state.get(); + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled ? selectSizedInternalFormat() : 0; + if (texStorageSizedInternalFormat!=0) + { + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_1D, _numMipmapLevels, texStorageSizedInternalFormat, _textureWidth, 1, 1, 0); + textureObject->bind(); + applyTexParameters(GL_TEXTURE_1D, state); - textureObject->bind(); + extensions->glTexStorage1D( GL_TEXTURE_1D, (_numMipmapLevels >0)?_numMipmapLevels:1, texStorageSizedInternalFormat, _textureWidth); + } + else + { + GLenum internalFormat = _sourceFormat ? _sourceFormat : _internalFormat; + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_1D, _numMipmapLevels, internalFormat, _textureWidth, 1, 1, 0); + textureObject->bind(); + applyTexParameters(GL_TEXTURE_1D, state); - applyTexParameters(GL_TEXTURE_1D,state); - - // no image present, but dimensions are set so lets create the texture - glTexImage1D( GL_TEXTURE_1D, 0, _internalFormat, + glTexImage1D( GL_TEXTURE_1D, 0, _internalFormat, _textureWidth, _borderWidth, - _sourceFormat ? _sourceFormat : _internalFormat, + internalFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE, 0); + } if (_readPBuffer.valid()) { diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index 06ca1aed3..950bc9061 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -243,6 +243,7 @@ void Texture2D::apply(State& state) const } else if (_image.valid() && _image->data()) { + GLExtensions * extensions = state.get(); // keep the image around at least till we go out of scope. osg::ref_ptr image = _image; @@ -253,7 +254,10 @@ void Texture2D::apply(State& state) const // compute the dimensions of the texture. computeRequiredTextureDimensions(state,*image,_textureWidth, _textureHeight, _numMipmapLevels); - textureObject = generateAndAssignTextureObject(contextID,GL_TEXTURE_2D,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,_borderWidth); + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled && (_borderWidth==0) ? selectSizedInternalFormat(_image) : 0; + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_2D, _numMipmapLevels, + texStorageSizedInternalFormat!=0 ? texStorageSizedInternalFormat : _internalFormat, + _textureWidth, _textureHeight, 1, _borderWidth); textureObject->bind(); @@ -293,18 +297,30 @@ void Texture2D::apply(State& state) const } else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_internalFormat!=0) ) { - textureObject = generateAndAssignTextureObject(contextID,GL_TEXTURE_2D,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,_borderWidth); - - textureObject->bind(); - - applyTexParameters(GL_TEXTURE_2D,state); // no image present, but dimensions at set so lets create the texture - glTexImage2D( GL_TEXTURE_2D, 0, _internalFormat, - _textureWidth, _textureHeight, _borderWidth, - _sourceFormat ? _sourceFormat : _internalFormat, - _sourceType ? _sourceType : GL_UNSIGNED_BYTE, - 0); + GLExtensions * extensions = state.get(); + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled && (_borderWidth==0) ? selectSizedInternalFormat() : 0; + if (texStorageSizedInternalFormat!=0) + { + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_2D, _numMipmapLevels, texStorageSizedInternalFormat, _textureWidth, _textureHeight, 1, _borderWidth); + textureObject->bind(); + applyTexParameters(GL_TEXTURE_2D, state); + extensions->glTexStorage2D( GL_TEXTURE_2D, (_numMipmapLevels >0)?_numMipmapLevels:1, texStorageSizedInternalFormat, + _textureWidth, _textureHeight); + } + else + { + GLenum internalFormat = _sourceFormat ? _sourceFormat : _internalFormat; + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_2D, _numMipmapLevels, internalFormat, _textureWidth, _textureHeight, 1, _borderWidth); + textureObject->bind(); + applyTexParameters(GL_TEXTURE_2D, state); + glTexImage2D( GL_TEXTURE_2D, 0, _internalFormat, + _textureWidth, _textureHeight, _borderWidth, + internalFormat, + _sourceType ? _sourceType : GL_UNSIGNED_BYTE, + 0); + } if (_readPBuffer.valid()) { diff --git a/src/osg/Texture2DArray.cpp b/src/osg/Texture2DArray.cpp index 5c78b171b..0778d3b10 100644 --- a/src/osg/Texture2DArray.cpp +++ b/src/osg/Texture2DArray.cpp @@ -336,42 +336,53 @@ void Texture2DArray::apply(State& state) const // compute the internal texture format, this set the _internalFormat to an appropriate value. computeInternalFormat(); + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled && (_borderWidth==0) ? selectSizedInternalFormat(_images[0]) : 0; + // compute the dimensions of the texture. computeRequiredTextureDimensions(state,*_images[0],_textureWidth, _textureHeight, _numMipmapLevels); // create texture object textureObject = generateAndAssignTextureObject( - contextID, GL_TEXTURE_2D_ARRAY,_numMipmapLevels, _internalFormat, _textureWidth, _textureHeight, textureDepth,0); + contextID, GL_TEXTURE_2D_ARRAY, _numMipmapLevels, + texStorageSizedInternalFormat!=0 ? texStorageSizedInternalFormat : _internalFormat, + _textureWidth, _textureHeight, textureDepth,0); // bind texture textureObject->bind(); + applyTexParameters(GL_TEXTURE_2D_ARRAY, state); // First we need to allocate the texture memory - int sourceFormat = _sourceFormat ? _sourceFormat : _internalFormat; - - if( isCompressedInternalFormat( sourceFormat ) && - sourceFormat == _internalFormat && - extensions->isCompressedTexImage3DSupported() ) + if(texStorageSizedInternalFormat!=0) { - extensions->glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY, 0, _internalFormat, - _textureWidth, _textureHeight, textureDepth, _borderWidth, - _images[0]->getImageSizeInBytes() * textureDepth, - 0); + extensions->glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, texStorageSizedInternalFormat, _textureWidth, _textureHeight, textureDepth); } else { + int sourceFormat = _sourceFormat ? _sourceFormat : _internalFormat; + + if( isCompressedInternalFormat( sourceFormat ) && + sourceFormat == _internalFormat && + extensions->isCompressedTexImage3DSupported() ) + { + extensions->glCompressedTexImage3D( GL_TEXTURE_2D_ARRAY, 0, _internalFormat, + _textureWidth, _textureHeight, textureDepth, _borderWidth, + _images[0]->getImageSizeInBytes() * textureDepth, + 0); + } + else + { // Override compressed source format with safe GL_RGBA value which not generate error // We can safely do this as source format is not important when source data is NULL if( isCompressedInternalFormat( sourceFormat ) ) sourceFormat = GL_RGBA; - extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY, 0, _internalFormat, - _textureWidth, _textureHeight, textureDepth, _borderWidth, - sourceFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE, - 0); + extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY, 0, _internalFormat, + _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 necessary for plain texture formats but @@ -430,19 +441,28 @@ void Texture2DArray::apply(State& state) const else if ( (_textureWidth > 0) && (_textureHeight > 0) && (_textureDepth > 0) && (_internalFormat!=0) ) { // generate texture + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled ? selectSizedInternalFormat() : 0; + textureObject = generateAndAssignTextureObject( - contextID, GL_TEXTURE_2D_ARRAY,_numMipmapLevels,_internalFormat, _textureWidth, _textureHeight, _textureDepth,0); + contextID, GL_TEXTURE_2D_ARRAY, _numMipmapLevels, + texStorageSizedInternalFormat!=0 ? texStorageSizedInternalFormat :_internalFormat, + _textureWidth, _textureHeight, _textureDepth, 0); textureObject->bind(); + applyTexParameters(GL_TEXTURE_2D_ARRAY,state); - extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY, 0, _internalFormat, + if (texStorageSizedInternalFormat!=0) + { + extensions->glTexStorage3D( GL_TEXTURE_2D_ARRAY, (_numMipmapLevels >0)?_numMipmapLevels:1, texStorageSizedInternalFormat, _textureWidth, _textureHeight, _textureDepth); + } + else + extensions->glTexImage3D( GL_TEXTURE_2D_ARRAY, 0, _internalFormat, _textureWidth, _textureHeight, _textureDepth, _borderWidth, _sourceFormat ? _sourceFormat : _internalFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE, 0); - } // nothing before, so just unbind the texture target diff --git a/src/osg/Texture2DMultisample.cpp b/src/osg/Texture2DMultisample.cpp index c723da906..94e5b53ae 100644 --- a/src/osg/Texture2DMultisample.cpp +++ b/src/osg/Texture2DMultisample.cpp @@ -102,29 +102,32 @@ void Texture2DMultisample::apply(State& state) const } else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_numSamples!=0) ) { - textureObject = generateAndAssignTextureObject( - contextID, - getTextureTarget(), - 1, - _internalFormat, - _textureWidth, - _textureHeight, - 1, - _borderWidth); + // no image present, but dimensions at set so lets create the texture + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled && (_borderWidth==0) ? selectSizedInternalFormat() : 0; + if (texStorageSizedInternalFormat!=0) + { + textureObject = generateAndAssignTextureObject(contextID, getTextureTarget(), 1, texStorageSizedInternalFormat, _textureWidth, _textureHeight, 1, 0); + textureObject->bind(); - textureObject->bind(); + extensions->glTexStorage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, _numSamples, texStorageSizedInternalFormat, _textureWidth, _textureHeight, _fixedsamplelocations); + } + else + { + textureObject = generateAndAssignTextureObject(contextID, getTextureTarget(), 1, _internalFormat, _textureWidth, _textureHeight, 1, _borderWidth); + textureObject->bind(); - extensions->glTexImage2DMultisample( getTextureTarget(), + extensions->glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, _numSamples, _internalFormat, _textureWidth, _textureHeight, _fixedsamplelocations ); + } } else { - glBindTexture( getTextureTarget(), 0 ); + glBindTexture( GL_TEXTURE_2D_MULTISAMPLE, 0 ); } } diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index 1fc2f26c1..eee22cc6f 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -315,20 +315,30 @@ void Texture3D::apply(State& state) const } else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_textureDepth!=0) && (_internalFormat!=0) ) { - textureObject = generateAndAssignTextureObject( - contextID,GL_TEXTURE_3D,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0); - - textureObject->bind(); - - applyTexParameters(GL_TEXTURE_3D,state); - // no image present, but dimensions at set so lets create the texture - extensions->glTexImage3D( GL_TEXTURE_3D, 0, _internalFormat, + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled ? selectSizedInternalFormat() : 0; + if (texStorageSizedInternalFormat!=0) + { + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_3D, _numMipmapLevels, texStorageSizedInternalFormat, _textureWidth, _textureHeight, _textureDepth,0); + textureObject->bind(); + applyTexParameters(GL_TEXTURE_3D, state); + + extensions->glTexStorage3D( GL_TEXTURE_3D, (_numMipmapLevels >0)?_numMipmapLevels:1, texStorageSizedInternalFormat, _textureWidth, _textureHeight, _textureDepth); + } + else + { + GLenum internalFormat = _sourceFormat ? _sourceFormat : _internalFormat; + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_3D, _numMipmapLevels, internalFormat, _textureWidth, _textureHeight, _textureDepth,0); + textureObject->bind(); + applyTexParameters(GL_TEXTURE_3D, state); + + extensions->glTexImage3D( GL_TEXTURE_3D, 0, _internalFormat, _textureWidth, _textureHeight, _textureDepth, _borderWidth, - _sourceFormat ? _sourceFormat : _internalFormat, + internalFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE, 0); + } if (_readPBuffer.valid()) { diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index ed43d2b2c..3c4134fe3 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -293,8 +293,12 @@ void TextureCubeMap::apply(State& state) const _textureWidth = _textureHeight = minimum( _textureWidth , _textureHeight ); } + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled && (_borderWidth==0) ? selectSizedInternalFormat(_images[0]) : 0; + textureObject = generateAndAssignTextureObject( - contextID,GL_TEXTURE_CUBE_MAP,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0); + contextID, GL_TEXTURE_CUBE_MAP, _numMipmapLevels, + texStorageSizedInternalFormat!=0 ? texStorageSizedInternalFormat : _internalFormat, + _textureWidth, _textureHeight, 1, 0); textureObject->bind(); @@ -335,22 +339,33 @@ void TextureCubeMap::apply(State& state) const } else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_internalFormat!=0) ) { + + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled && (_borderWidth==0) ? selectSizedInternalFormat() : 0; + textureObject = generateAndAssignTextureObject( - contextID,GL_TEXTURE_CUBE_MAP,_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,0); + contextID, GL_TEXTURE_CUBE_MAP, _numMipmapLevels, + texStorageSizedInternalFormat!=0 ? texStorageSizedInternalFormat : _internalFormat, + _textureWidth, _textureHeight, 1, 0); textureObject->bind(); applyTexParameters(GL_TEXTURE_CUBE_MAP,state); - for (int n=0; n<6; n++) + if(texStorageSizedInternalFormat!=0) { - // no image present, but dimensions at set so less create the texture - glTexImage2D( faceTarget[n], 0, _internalFormat, - _textureWidth, _textureHeight, _borderWidth, - _sourceFormat ? _sourceFormat : _internalFormat, - _sourceType ? _sourceType : GL_UNSIGNED_BYTE, - 0); + extensions->glTexStorage2D(GL_TEXTURE_CUBE_MAP, _numMipmapLevels==0 ? 1 : _numMipmapLevels, texStorageSizedInternalFormat, _textureWidth, _textureHeight); + } + else + for (int n=0; n<6; n++) + { + // no image present, but dimensions at set so less create the texture + glTexImage2D( faceTarget[n], 0, _internalFormat, + _textureWidth, _textureHeight, _borderWidth, + _sourceFormat ? _sourceFormat : _internalFormat, + _sourceType ? _sourceType : GL_UNSIGNED_BYTE, + 0); + } } else diff --git a/src/osg/TextureRectangle.cpp b/src/osg/TextureRectangle.cpp index 4a60e166d..27c5dfff2 100644 --- a/src/osg/TextureRectangle.cpp +++ b/src/osg/TextureRectangle.cpp @@ -231,7 +231,7 @@ void TextureRectangle::apply(State& state) const } else if (_image.valid() && _image->data()) { - + GLExtensions * extensions = state.get(); // keep the image around at least till we go out of scope. osg::ref_ptr image = _image; @@ -239,11 +239,16 @@ void TextureRectangle::apply(State& state) const // compute the internal texture format, this set the _internalFormat to an appropriate value. computeInternalFormat(); + //get sizedInternalFormat if TexStorage available + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled && (_borderWidth==0) ? selectSizedInternalFormat(image) : 0; + _textureWidth = image->s(); _textureHeight = image->t(); textureObject = generateAndAssignTextureObject( - contextID,GL_TEXTURE_RECTANGLE,1,_internalFormat,_textureWidth,_textureHeight,1,0); + contextID, GL_TEXTURE_RECTANGLE, 1, + texStorageSizedInternalFormat!=0 ? texStorageSizedInternalFormat : _internalFormat, + _textureWidth, _textureHeight, 1, 0); textureObject->bind(); @@ -268,19 +273,30 @@ void TextureRectangle::apply(State& state) const } else if ( (_textureWidth!=0) && (_textureHeight!=0) && (_internalFormat!=0) ) { - textureObject = generateAndAssignTextureObject( - contextID,GL_TEXTURE_RECTANGLE,0,_internalFormat,_textureWidth,_textureHeight,1,0); - - textureObject->bind(); - - applyTexParameters(GL_TEXTURE_RECTANGLE,state); - // no image present, but dimensions at set so lets create the texture - glTexImage2D( GL_TEXTURE_RECTANGLE, 0, _internalFormat, + GLExtensions * extensions = state.get(); + GLenum texStorageSizedInternalFormat = extensions->isTextureStorageEnabled ? selectSizedInternalFormat() : 0; + if (texStorageSizedInternalFormat!=0) + { + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_RECTANGLE, 0, texStorageSizedInternalFormat, _textureWidth, _textureHeight, 1, 0); + textureObject->bind(); + applyTexParameters(GL_TEXTURE_RECTANGLE, state); + + extensions->glTexStorage2D( GL_TEXTURE_RECTANGLE, 1, texStorageSizedInternalFormat, _textureWidth, _textureHeight); + } + else + { + GLenum internalFormat = _sourceFormat ? _sourceFormat : _internalFormat; + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_RECTANGLE, 0, internalFormat, _textureWidth, _textureHeight, 1, 0); + textureObject->bind(); + applyTexParameters(GL_TEXTURE_RECTANGLE, state); + + glTexImage2D( GL_TEXTURE_RECTANGLE, 0, _internalFormat, _textureWidth, _textureHeight, _borderWidth, - _sourceFormat ? _sourceFormat : _internalFormat, + internalFormat, _sourceType ? _sourceType : GL_UNSIGNED_BYTE, 0); + } if (_readPBuffer.valid()) {