From a500be6ef2291ff3dd9fca27705132cb8ce91521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 2 Jul 2013 01:31:36 +0200 Subject: [PATCH] Pass image as reference, not pointer to *Texture::set*Image(). Avoids some nullptr-related errors and leads to simpler implementation, as we need to only handle ImageReference and BufferImage types. All other Image classes are implicitly convertible to ImageReference and implicit conversion works only with references, not with pointers. The usage might be clumsy at this point, as Trade::*Importer classes return pointer to Trade::ImageData which then needs to be dereferenced. Hopefully introducing C++14's std::optional (or equivalent) might help solve that issue. Also removed "convenience" overloads for setting e.g. 2D subdata of 3D texture. The convenience overload doesn't cover all subdata cases (only XY plane, not YZ or XZ ones) and overly complicates the implementation. This can be done in the future in Image classes themselves. --- src/AbstractTexture.cpp | 91 ++++++++++++++++++++++++---- src/AbstractTexture.h | 65 +++++++------------- src/CubeMapTexture.h | 26 ++++++-- src/CubeMapTextureArray.h | 31 ++++------ src/Text/DistanceFieldGlyphCache.cpp | 20 +++--- src/Text/DistanceFieldGlyphCache.h | 4 +- src/Text/GlyphCache.cpp | 2 +- src/Text/GlyphCache.h | 2 +- src/Texture.h | 37 +++++------ 9 files changed, 165 insertions(+), 113 deletions(-) diff --git a/src/AbstractTexture.cpp b/src/AbstractTexture.cpp index 70d443b5b..22c898d27 100644 --- a/src/AbstractTexture.cpp +++ b/src/AbstractTexture.cpp @@ -978,19 +978,6 @@ template void AbstractTexture::image<3>(GLenum, GLint, BufferImage<3>&, Buffer:: #endif #ifndef DOXYGEN_GENERATING_OUTPUT -#ifndef MAGNUM_TARGET_GLES2 -namespace Implementation { - template const GLvoid* ImageHelper>::dataOrPixelUnpackBuffer(BufferImage* image) { - image->buffer()->bind(Buffer::Target::PixelUnpack); - return nullptr; - } - - template struct ImageHelper; - template struct ImageHelper; - template struct ImageHelper; -} -#endif - #ifndef MAGNUM_TARGET_GLES Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture* texture, GLenum target, GLint level) { Math::Vector<1, GLint> value; @@ -1014,6 +1001,84 @@ Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture* texture, GLe } #endif +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::DataHelper<1>::setImage(AbstractTexture* const texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) { + Buffer::unbind(Buffer::Target::PixelUnpack); + (texture->*image1DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data()); +} + +void AbstractTexture::DataHelper<1>::setImage(AbstractTexture* const texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) { + image.buffer()->bind(Buffer::Target::PixelUnpack); + (texture->*image1DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr); +} + +void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture* const texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image) { + Buffer::unbind(Buffer::Target::PixelUnpack); + (texture->*subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); +} + +void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture* const texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) { + image.buffer()->bind(Buffer::Target::PixelUnpack); + (texture->*subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); +} +#endif + +void AbstractTexture::DataHelper<2>::setImage(AbstractTexture* const texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference2D& image) { + #ifndef MAGNUM_TARGET_GLES2 + Buffer::unbind(Buffer::Target::PixelUnpack); + #endif + (texture->*image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data()); +} + +#ifndef MAGNUM_TARGET_GLES2 +void AbstractTexture::DataHelper<2>::setImage(AbstractTexture* const texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage2D& image) { + image.buffer()->bind(Buffer::Target::PixelUnpack); + (texture->*image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr); +} +#endif + +void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture* const texture, const GLenum target, const GLint level, const Vector2i& offset, const ImageReference2D& image) { + #ifndef MAGNUM_TARGET_GLES2 + Buffer::unbind(Buffer::Target::PixelUnpack); + #endif + (texture->*subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); +} + +#ifndef MAGNUM_TARGET_GLES2 +void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture* const texture, const GLenum target, const GLint level, const Vector2i& offset, BufferImage2D& image) { + image.buffer()->bind(Buffer::Target::PixelUnpack); + (texture->*subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); +} +#endif + +void AbstractTexture::DataHelper<3>::setImage(AbstractTexture* const texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference3D& image) { + #ifndef MAGNUM_TARGET_GLES2 + Buffer::unbind(Buffer::Target::PixelUnpack); + #endif + (texture->*image3DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data()); +} + +#ifndef MAGNUM_TARGET_GLES2 +void AbstractTexture::DataHelper<3>::setImage(AbstractTexture* const texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) { + image.buffer()->bind(Buffer::Target::PixelUnpack); + (texture->*image3DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr); +} +#endif + +void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture* const texture, const GLenum target, const GLint level, const Vector3i& offset, const ImageReference3D& image) { + #ifndef MAGNUM_TARGET_GLES2 + Buffer::unbind(Buffer::Target::PixelUnpack); + #endif + (texture->*subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data()); +} + +#ifndef MAGNUM_TARGET_GLES2 +void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture* const texture, const GLenum target, const GLint level, const Vector3i& offset, BufferImage3D& image) { + image.buffer()->bind(Buffer::Target::PixelUnpack); + (texture->*subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr); +} +#endif + void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const Array2D& wrapping) { #ifndef MAGNUM_TARGET_GLES CORRADE_ASSERT(texture->_target != GL_TEXTURE_RECTANGLE || ((wrapping.x() == Sampler::Wrapping::ClampToEdge || wrapping.x() == Sampler::Wrapping::ClampToBorder) && (wrapping.y() == Sampler::Wrapping::ClampToEdge || wrapping.y() == Sampler::Wrapping::ClampToEdge)), "AbstractTexture: rectangle texture wrapping must either clamp to border or to edge", ); diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index 83b0d3249..0cf278646 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -419,25 +419,8 @@ class MAGNUM_EXPORT AbstractTexture { }; #ifndef DOXYGEN_GENERATING_OUTPUT -namespace Implementation { - template struct ImageHelper { - static const GLvoid* dataOrPixelUnpackBuffer(Image* image) { - #ifndef MAGNUM_TARGET_GLES2 - Buffer::unbind(Buffer::Target::PixelUnpack); - #endif - return image->data(); - } - }; - - #ifndef MAGNUM_TARGET_GLES2 - template struct MAGNUM_EXPORT ImageHelper> { - static const GLvoid* dataOrPixelUnpackBuffer(BufferImage* image); - }; - #endif -} - #ifndef MAGNUM_TARGET_GLES -template<> struct AbstractTexture::DataHelper<1> { +template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> { enum class Target: GLenum { Texture1D = GL_TEXTURE_1D }; @@ -454,13 +437,11 @@ template<> struct AbstractTexture::DataHelper<1> { (texture->*storage1DImplementation)(target, levels, internalFormat, size); } - template static typename std::enable_if::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { - (texture->*image1DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper::dataOrPixelUnpackBuffer(image)); - } + static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference1D& image); + static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage1D& image); - template static typename std::enable_if::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, Image* image) { - (texture->*subImage1DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper::dataOrPixelUnpackBuffer(image)); - } + static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image); + static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image); static void invalidateSubImage(AbstractTexture* texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size) { (texture->*invalidateSubImageImplementation)(level, {offset[0], 0, 0}, {size[0], 1, 1}); @@ -489,17 +470,15 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { (texture->*storage2DImplementation)(target, levels, internalFormat, size); } - template static typename std::enable_if::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { - (texture->*image2DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper::dataOrPixelUnpackBuffer(image)); - } - - template static typename std::enable_if::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) { - (texture->*subImage2DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper::dataOrPixelUnpackBuffer(image)); - } + static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference2D& image); + #ifndef MAGNUM_TARGET_GLES2 + static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage2D& image); + #endif - template static typename std::enable_if::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) { - (texture->*subImage2DImplementation)(target, level, offset, Vector2i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper::dataOrPixelUnpackBuffer(image)); - } + static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, const ImageReference2D& image); + #ifndef MAGNUM_TARGET_GLES2 + static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, BufferImage2D& image); + #endif static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector2i& offset, const Vector2i& size) { (texture->*invalidateSubImageImplementation)(level, {offset, 0}, {size, 1}); @@ -530,17 +509,15 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { (texture->*storage3DImplementation)(target, levels, internalFormat, size); } - template static typename std::enable_if::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { - (texture->*image3DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper::dataOrPixelUnpackBuffer(image)); - } - - template static typename std::enable_if::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) { - (texture->*subImage3DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper::dataOrPixelUnpackBuffer(image)); - } + static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference3D& image); + #ifndef MAGNUM_TARGET_GLES2 + static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage3D& image); + #endif - template static typename std::enable_if::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) { - (texture->*subImage3DImplementation)(target, level, offset, Vector3i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper::dataOrPixelUnpackBuffer(image)); - } + static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, const ImageReference3D& image); + #ifndef MAGNUM_TARGET_GLES2 + static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, BufferImage3D& image); + #endif static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector3i& offset, const Vector3i& size) { (texture->*invalidateSubImageImplementation)(level, offset, size); diff --git a/src/CubeMapTexture.h b/src/CubeMapTexture.h index 0bc8a642c..2308568f2 100644 --- a/src/CubeMapTexture.h +++ b/src/CubeMapTexture.h @@ -165,33 +165,47 @@ class CubeMapTexture: public AbstractTexture { * @param coordinate Coordinate * @param level Mip level * @param internalFormat Internal format - * @param image Image, ImageReference, BufferImage or - * Trade::ImageData of the same dimension count + * @param image %Image * @return Pointer to self (for method chaining) * * See Texture::setImage() for more information. */ - template CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, Image* image) { + CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, const ImageReference2D& image) { DataHelper<2>::setImage(this, static_cast(coordinate), level, internalFormat, image); return this; } + #ifndef MAGNUM_TARGET_GLES2 + /** @overload */ + CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D& image) { + DataHelper<2>::setImage(this, static_cast(coordinate), level, internalFormat, image); + return this; + } + #endif + /** * @brief Set image subdata * @param coordinate Coordinate * @param level Mip level * @param offset Offset where to put data in the texture - * @param image Image, ImageReference, BufferImage or - * Trade::ImageData of the same or one less dimension count + * @param image %Image * @return Pointer to self (for method chaining) * * See Texture::setSubImage() for more information. */ - template CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) { + CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image) { DataHelper<2>::setSubImage(this, static_cast(coordinate), level, offset, image); return this; } + #ifndef MAGNUM_TARGET_GLES2 + /** @overload */ + CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image) { + DataHelper<2>::setSubImage(this, static_cast(coordinate), level, offset, image); + return this; + } + #endif + /** * @brief Invalidate texture subimage * @param level Mip level diff --git a/src/CubeMapTextureArray.h b/src/CubeMapTextureArray.h index 0f64d3720..7219706c8 100644 --- a/src/CubeMapTextureArray.h +++ b/src/CubeMapTextureArray.h @@ -175,7 +175,13 @@ class CubeMapTextureArray: public AbstractTexture { * * See Texture::setImage() for more information. */ - template CubeMapTextureArray* setImage(Int level, TextureFormat internalFormat, T* image) { + CubeMapTextureArray* setImage(Int level, TextureFormat internalFormat, const ImageReference3D& image) { + DataHelper<3>::setImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image); + return this; + } + + /** @overload */ + CubeMapTextureArray* setImage(Int level, TextureFormat internalFormat, BufferImage3D& image) { DataHelper<3>::setImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image); return this; } @@ -199,27 +205,14 @@ class CubeMapTextureArray: public AbstractTexture { * * @see setSubImage(Int, Coordinate, Int, const Math::Vector<2, Int>&, const Image*) */ - template CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const Image* image) { - DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image, Vector3i(Math::Vector())); + CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image) { + DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image); return this; } - /** - * @brief Set texture image 2D subdata - * @param layer Array layer - * @param coordinate Coordinate - * @param level Mip level - * @param offset Offset where to put data in the texture - * @param image Image2D, ImageReference2D, BufferImage2D or - * Trade::ImageData2D - * @return Pointer to self (for method chaining) - * - * See Texture::setSubImage() for more information. - * - * @see setSubImage(Int, const Math::Vector<3, Int>&, const Image*) - */ - template CubeMapTextureArray* setSubImage(Int layer, Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) { - DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, Vector3i(offset, layer*6+static_cast(coordinate)), image, Vector2i(Math::Vector())); + /** @overload */ + CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, BufferImage3D& image) { + DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image); return this; } diff --git a/src/Text/DistanceFieldGlyphCache.cpp b/src/Text/DistanceFieldGlyphCache.cpp index 83daad155..78ce1b833 100644 --- a/src/Text/DistanceFieldGlyphCache.cpp +++ b/src/Text/DistanceFieldGlyphCache.cpp @@ -25,10 +25,10 @@ #include "DistanceFieldGlyphCache.h" #include "Extensions.h" -#include "Image.h" #ifndef CORRADE_NO_ASSERT #include "ImageFormat.h" #endif +#include "ImageReference.h" #include "TextureFormat.h" #include "TextureTools/DistanceField.h" @@ -52,25 +52,25 @@ DistanceFieldGlyphCache::DistanceFieldGlyphCache(const Vector2i& originalSize, c initialize(internalFormat, distanceFieldSize); } -void DistanceFieldGlyphCache::setImage(const Vector2i& offset, Image2D* const image) { +void DistanceFieldGlyphCache::setImage(const Vector2i& offset, const ImageReference2D& image) { #ifndef MAGNUM_TARGET_GLES MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); #endif #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES3) const TextureFormat internalFormat = TextureFormat::R8; - CORRADE_ASSERT(image->format() == ImageFormat::Red, - "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Red << "but got" << image->format(), ); + CORRADE_ASSERT(image.format() == ImageFormat::Red, + "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Red << "but got" << image.format(), ); #else TextureFormat internalFormat; if(Context::current()->isExtensionSupported()) { internalFormat = TextureFormat::Red; - CORRADE_ASSERT(image->format() == ImageFormat::Red, - "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Red << "but got" << image->format(), ); + CORRADE_ASSERT(image.format() == ImageFormat::Red, + "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Red << "but got" << image.format(), ); } else { internalFormat = TextureFormat::Luminance; - CORRADE_ASSERT(image->format() == ImageFormat::Luminance, - "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Luminance << "but got" << image->format(), ); + CORRADE_ASSERT(image.format() == ImageFormat::Luminance, + "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Luminance << "but got" << image.format(), ); } #endif @@ -81,10 +81,10 @@ void DistanceFieldGlyphCache::setImage(const Vector2i& offset, Image2D* const im ->setImage(0, internalFormat, image); /* Create distance field from input texture */ - TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize(offset*scale, image->size()*scale), radius, image->size()); + TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize(offset*scale, image.size()*scale), radius, image.size()); } -void DistanceFieldGlyphCache::setDistanceFieldImage(const Vector2i& offset, Image2D* const image) { +void DistanceFieldGlyphCache::setDistanceFieldImage(const Vector2i& offset, const ImageReference2D& image) { _texture.setSubImage(0, offset, image); } diff --git a/src/Text/DistanceFieldGlyphCache.h b/src/Text/DistanceFieldGlyphCache.h index bb5d1194c..011d11943 100644 --- a/src/Text/DistanceFieldGlyphCache.h +++ b/src/Text/DistanceFieldGlyphCache.h @@ -78,7 +78,7 @@ class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { * Uploads image for one or more glyphs to given offset in original * cache texture. The texture is then converted to distance field. */ - void setImage(const Vector2i& offset, Image2D* image) override; + void setImage(const Vector2i& offset, const ImageReference2D& image) override; /** * @brief Set distance field cache image @@ -86,7 +86,7 @@ class MAGNUM_TEXT_EXPORT DistanceFieldGlyphCache: public GlyphCache { * Uploads already computed distance field image to given offset in * distance field texture. */ - void setDistanceFieldImage(const Vector2i& offset, Image2D* image); + void setDistanceFieldImage(const Vector2i& offset, const ImageReference2D& image); private: const Vector2 scale; diff --git a/src/Text/GlyphCache.cpp b/src/Text/GlyphCache.cpp index 8d96ef2a3..115e1ece6 100644 --- a/src/Text/GlyphCache.cpp +++ b/src/Text/GlyphCache.cpp @@ -77,7 +77,7 @@ void GlyphCache::insert(const UnsignedInt glyph, Vector2i position, Rectanglei r glyphs.insert({glyph, {position, rectangle}}); } -void GlyphCache::setImage(const Vector2i& offset, Image2D* const image) { +void GlyphCache::setImage(const Vector2i& offset, const ImageReference2D& image) { _texture.setSubImage(0, offset, image); } diff --git a/src/Text/GlyphCache.h b/src/Text/GlyphCache.h index 35d93cf52..39dacc9c0 100644 --- a/src/Text/GlyphCache.h +++ b/src/Text/GlyphCache.h @@ -135,7 +135,7 @@ class MAGNUM_TEXT_EXPORT GlyphCache { * Uploads image for one or more glyphs to given offset in cache * texture. */ - virtual void setImage(const Vector2i& offset, Image2D* image); + virtual void setImage(const Vector2i& offset, const ImageReference2D& image); #ifdef DOXYGEN_GENERATING_OUTPUT private: diff --git a/src/Texture.h b/src/Texture.h index a6c6e0a68..dce833157 100644 --- a/src/Texture.h +++ b/src/Texture.h @@ -346,12 +346,9 @@ template class Texture: public AbstractTexture { * @brief Set image data * @param level Mip level * @param internalFormat Internal format - * @param image Image, ImageReference, BufferImage or - * Trade::ImageData of the same dimension count + * @param image %Image * @return Pointer to self (for method chaining) * - * The image is not deleted afterwards. - * * For better performance when generating mipmaps using * generateMipmap() or calling setImage() more than once use * setStorage() and setSubImage() instead. @@ -364,28 +361,26 @@ template class Texture: public AbstractTexture { * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureImage3D,EXT,direct_state_access} */ - template Texture* setImage(Int level, TextureFormat internalFormat, Image* image) { + Texture* setImage(Int level, TextureFormat internalFormat, const ImageReference& image) { DataHelper::setImage(this, _target, level, internalFormat, image); return this; } + #ifndef MAGNUM_TARGET_GLES2 + /** @overload */ + Texture* setImage(Int level, TextureFormat internalFormat, BufferImage& image) { + DataHelper::setImage(this, _target, level, internalFormat, image); + return this; + } + #endif + /** * @brief Set image subdata * @param level Mip level * @param offset Offset where to put data in the texture - * @param image Image, ImageReference, BufferImage or - * Trade::ImageData of the same or one less dimension count + * @param image %Image * @return Pointer to self (for method chaining) * - * The image is not deleted afterwards. The image can have either the - * same dimension count or have one dimension less, but at least one - * dimension. - * - * If the image has one dimension less than the texture, the image is - * taken as if it had the last dimension equal to 1. It can be used - * for e.g. updating 3D texture with multiple 2D images or for filling - * 1D texture array (which is two-dimensional) with 1D images. - * * If @extension{EXT,direct_state_access} is not available, the * texture is bound to some layer before the operation. * @see setStorage(), setImage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} @@ -394,10 +389,18 @@ template class Texture: public AbstractTexture { * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} */ - template Texture* setSubImage(Int level, const typename DimensionTraits::VectorType& offset, Image* image) { + Texture* setSubImage(Int level, const typename DimensionTraits::VectorType& offset, const ImageReference& image) { + DataHelper::setSubImage(this, _target, level, offset, image); + return this; + } + + #ifndef MAGNUM_TARGET_GLES2 + /** @overload */ + Texture* setSubImage(Int level, const typename DimensionTraits::VectorType& offset, BufferImage& image) { DataHelper::setSubImage(this, _target, level, offset, image); return this; } + #endif /** * @brief Invalidate texture subimage