Browse Source

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.
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
a500be6ef2
  1. 91
      src/AbstractTexture.cpp
  2. 65
      src/AbstractTexture.h
  3. 26
      src/CubeMapTexture.h
  4. 31
      src/CubeMapTextureArray.h
  5. 20
      src/Text/DistanceFieldGlyphCache.cpp
  6. 4
      src/Text/DistanceFieldGlyphCache.h
  7. 2
      src/Text/GlyphCache.cpp
  8. 2
      src/Text/GlyphCache.h
  9. 37
      src/Texture.h

91
src/AbstractTexture.cpp

@ -978,19 +978,6 @@ template void AbstractTexture::image<3>(GLenum, GLint, BufferImage<3>&, Buffer::
#endif #endif
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES2
namespace Implementation {
template<UnsignedInt dimensions> const GLvoid* ImageHelper<BufferImage<dimensions>>::dataOrPixelUnpackBuffer(BufferImage<dimensions>* image) {
image->buffer()->bind(Buffer::Target::PixelUnpack);
return nullptr;
}
template struct ImageHelper<BufferImage1D>;
template struct ImageHelper<BufferImage2D>;
template struct ImageHelper<BufferImage3D>;
}
#endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture* texture, GLenum target, GLint level) { Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture* texture, GLenum target, GLint level) {
Math::Vector<1, GLint> value; Math::Vector<1, GLint> value;
@ -1014,6 +1001,84 @@ Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture* texture, GLe
} }
#endif #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<Sampler::Wrapping>& wrapping) { void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const Array2D<Sampler::Wrapping>& wrapping) {
#ifndef MAGNUM_TARGET_GLES #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", ); 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", );

65
src/AbstractTexture.h

@ -419,25 +419,8 @@ class MAGNUM_EXPORT AbstractTexture {
}; };
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class Image> 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<UnsignedInt dimensions> struct MAGNUM_EXPORT ImageHelper<BufferImage<dimensions>> {
static const GLvoid* dataOrPixelUnpackBuffer(BufferImage<dimensions>* image);
};
#endif
}
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
template<> struct AbstractTexture::DataHelper<1> { template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> {
enum class Target: GLenum { enum class Target: GLenum {
Texture1D = GL_TEXTURE_1D Texture1D = GL_TEXTURE_1D
}; };
@ -454,13 +437,11 @@ template<> struct AbstractTexture::DataHelper<1> {
(texture->*storage1DImplementation)(target, levels, internalFormat, size); (texture->*storage1DImplementation)(target, levels, internalFormat, size);
} }
template<class Image> static typename std::enable_if<Image::Dimensions == 1, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference1D& image);
(texture->*image1DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage1D& image);
}
template<class Image> static typename std::enable_if<Image::Dimensions == 1, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, Image* image) { static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image);
(texture->*subImage1DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(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) { 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}); (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); (texture->*storage2DImplementation)(target, levels, internalFormat, size);
} }
template<class Image> static typename std::enable_if<Image::Dimensions == 2, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference2D& image);
(texture->*image2DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); #ifndef MAGNUM_TARGET_GLES2
} static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage2D& image);
#endif
template<class Image> static typename std::enable_if<Image::Dimensions == 2, void>::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<Image>::dataOrPixelUnpackBuffer(image));
}
template<class Image> static typename std::enable_if<Image::Dimensions == 1, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) { static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, const ImageReference2D& image);
(texture->*subImage2DImplementation)(target, level, offset, Vector2i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(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) { static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector2i& offset, const Vector2i& size) {
(texture->*invalidateSubImageImplementation)(level, {offset, 0}, {size, 1}); (texture->*invalidateSubImageImplementation)(level, {offset, 0}, {size, 1});
@ -530,17 +509,15 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
(texture->*storage3DImplementation)(target, levels, internalFormat, size); (texture->*storage3DImplementation)(target, levels, internalFormat, size);
} }
template<class Image> static typename std::enable_if<Image::Dimensions == 3, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference3D& image);
(texture->*image3DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); #ifndef MAGNUM_TARGET_GLES2
} static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage3D& image);
#endif
template<class Image> static typename std::enable_if<Image::Dimensions == 3, void>::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<Image>::dataOrPixelUnpackBuffer(image));
}
template<class Image> static typename std::enable_if<Image::Dimensions == 2, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) { static void setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, const ImageReference3D& image);
(texture->*subImage3DImplementation)(target, level, offset, Vector3i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(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) { static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector3i& offset, const Vector3i& size) {
(texture->*invalidateSubImageImplementation)(level, offset, size); (texture->*invalidateSubImageImplementation)(level, offset, size);

26
src/CubeMapTexture.h

@ -165,33 +165,47 @@ class CubeMapTexture: public AbstractTexture {
* @param coordinate Coordinate * @param coordinate Coordinate
* @param level Mip level * @param level Mip level
* @param internalFormat Internal format * @param internalFormat Internal format
* @param image Image, ImageReference, BufferImage or * @param image %Image
* Trade::ImageData of the same dimension count
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
* *
* See Texture::setImage() for more information. * See Texture::setImage() for more information.
*/ */
template<class Image> 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<GLenum>(coordinate), level, internalFormat, image); DataHelper<2>::setImage(this, static_cast<GLenum>(coordinate), level, internalFormat, image);
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D& image) {
DataHelper<2>::setImage(this, static_cast<GLenum>(coordinate), level, internalFormat, image);
return this;
}
#endif
/** /**
* @brief Set image subdata * @brief Set image subdata
* @param coordinate Coordinate * @param coordinate Coordinate
* @param level Mip level * @param level Mip level
* @param offset Offset where to put data in the texture * @param offset Offset where to put data in the texture
* @param image Image, ImageReference, BufferImage or * @param image %Image
* Trade::ImageData of the same or one less dimension count
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
* *
* See Texture::setSubImage() for more information. * See Texture::setSubImage() for more information.
*/ */
template<class Image> 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<GLenum>(coordinate), level, offset, image); DataHelper<2>::setSubImage(this, static_cast<GLenum>(coordinate), level, offset, image);
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image) {
DataHelper<2>::setSubImage(this, static_cast<GLenum>(coordinate), level, offset, image);
return this;
}
#endif
/** /**
* @brief Invalidate texture subimage * @brief Invalidate texture subimage
* @param level Mip level * @param level Mip level

31
src/CubeMapTextureArray.h

@ -175,7 +175,13 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* See Texture::setImage() for more information. * See Texture::setImage() for more information.
*/ */
template<class T> 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); DataHelper<3>::setImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image);
return this; return this;
} }
@ -199,27 +205,14 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* @see setSubImage(Int, Coordinate, Int, const Math::Vector<2, Int>&, const Image*) * @see setSubImage(Int, Coordinate, Int, const Math::Vector<2, Int>&, const Image*)
*/ */
template<class Image> CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const Image* image) { CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image) {
DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image, Vector3i(Math::Vector<Image::Dimensions, GLsizei>())); DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image);
return this; return this;
} }
/** /** @overload */
* @brief Set texture image 2D subdata CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, BufferImage3D& image) {
* @param layer Array layer DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image);
* @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<class Image> 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<GLsizei>(coordinate)), image, Vector2i(Math::Vector<Image::Dimensions, GLsizei>()));
return this; return this;
} }

20
src/Text/DistanceFieldGlyphCache.cpp

@ -25,10 +25,10 @@
#include "DistanceFieldGlyphCache.h" #include "DistanceFieldGlyphCache.h"
#include "Extensions.h" #include "Extensions.h"
#include "Image.h"
#ifndef CORRADE_NO_ASSERT #ifndef CORRADE_NO_ASSERT
#include "ImageFormat.h" #include "ImageFormat.h"
#endif #endif
#include "ImageReference.h"
#include "TextureFormat.h" #include "TextureFormat.h"
#include "TextureTools/DistanceField.h" #include "TextureTools/DistanceField.h"
@ -52,25 +52,25 @@ DistanceFieldGlyphCache::DistanceFieldGlyphCache(const Vector2i& originalSize, c
initialize(internalFormat, distanceFieldSize); 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 #ifndef MAGNUM_TARGET_GLES
MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg);
#endif #endif
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES3) #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES3)
const TextureFormat internalFormat = TextureFormat::R8; const TextureFormat internalFormat = TextureFormat::R8;
CORRADE_ASSERT(image->format() == ImageFormat::Red, CORRADE_ASSERT(image.format() == ImageFormat::Red,
"Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Red << "but got" << image->format(), ); "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Red << "but got" << image.format(), );
#else #else
TextureFormat internalFormat; TextureFormat internalFormat;
if(Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>()) { if(Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>()) {
internalFormat = TextureFormat::Red; internalFormat = TextureFormat::Red;
CORRADE_ASSERT(image->format() == ImageFormat::Red, CORRADE_ASSERT(image.format() == ImageFormat::Red,
"Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Red << "but got" << image->format(), ); "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Red << "but got" << image.format(), );
} else { } else {
internalFormat = TextureFormat::Luminance; internalFormat = TextureFormat::Luminance;
CORRADE_ASSERT(image->format() == ImageFormat::Luminance, CORRADE_ASSERT(image.format() == ImageFormat::Luminance,
"Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Luminance << "but got" << image->format(), ); "Text::DistanceFieldGlyphCache::setImage(): expected" << ImageFormat::Luminance << "but got" << image.format(), );
} }
#endif #endif
@ -81,10 +81,10 @@ void DistanceFieldGlyphCache::setImage(const Vector2i& offset, Image2D* const im
->setImage(0, internalFormat, image); ->setImage(0, internalFormat, image);
/* Create distance field from input texture */ /* 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); _texture.setSubImage(0, offset, image);
} }

4
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 * Uploads image for one or more glyphs to given offset in original
* cache texture. The texture is then converted to distance field. * 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 * @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 * Uploads already computed distance field image to given offset in
* distance field texture. * distance field texture.
*/ */
void setDistanceFieldImage(const Vector2i& offset, Image2D* image); void setDistanceFieldImage(const Vector2i& offset, const ImageReference2D& image);
private: private:
const Vector2 scale; const Vector2 scale;

2
src/Text/GlyphCache.cpp

@ -77,7 +77,7 @@ void GlyphCache::insert(const UnsignedInt glyph, Vector2i position, Rectanglei r
glyphs.insert({glyph, {position, rectangle}}); 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); _texture.setSubImage(0, offset, image);
} }

2
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 * Uploads image for one or more glyphs to given offset in cache
* texture. * texture.
*/ */
virtual void setImage(const Vector2i& offset, Image2D* image); virtual void setImage(const Vector2i& offset, const ImageReference2D& image);
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
private: private:

37
src/Texture.h

@ -346,12 +346,9 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @brief Set image data * @brief Set image data
* @param level Mip level * @param level Mip level
* @param internalFormat Internal format * @param internalFormat Internal format
* @param image Image, ImageReference, BufferImage or * @param image %Image
* Trade::ImageData of the same dimension count
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
* *
* The image is not deleted afterwards.
*
* For better performance when generating mipmaps using * For better performance when generating mipmaps using
* generateMipmap() or calling setImage() more than once use * generateMipmap() or calling setImage() more than once use
* setStorage() and setSubImage() instead. * setStorage() and setSubImage() instead.
@ -364,28 +361,26 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access} * @fn_gl_extension{TextureImage3D,EXT,direct_state_access}
*/ */
template<class Image> Texture<Dimensions>* setImage(Int level, TextureFormat internalFormat, Image* image) { Texture<Dimensions>* setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions>& image) {
DataHelper<Dimensions>::setImage(this, _target, level, internalFormat, image); DataHelper<Dimensions>::setImage(this, _target, level, internalFormat, image);
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
Texture<Dimensions>* setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>& image) {
DataHelper<Dimensions>::setImage(this, _target, level, internalFormat, image);
return this;
}
#endif
/** /**
* @brief Set image subdata * @brief Set image subdata
* @param level Mip level * @param level Mip level
* @param offset Offset where to put data in the texture * @param offset Offset where to put data in the texture
* @param image Image, ImageReference, BufferImage or * @param image %Image
* Trade::ImageData of the same or one less dimension count
* @return Pointer to self (for method chaining) * @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 * If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation. * texture is bound to some layer before the operation.
* @see setStorage(), setImage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} * @see setStorage(), setImage(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
@ -394,10 +389,18 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}
*/ */
template<class Image> Texture<Dimensions>* setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, Image* image) { Texture<Dimensions>* setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, const ImageReference<dimensions>& image) {
DataHelper<Dimensions>::setSubImage(this, _target, level, offset, image);
return this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
Texture<Dimensions>* setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, BufferImage<dimensions>& image) {
DataHelper<Dimensions>::setSubImage(this, _target, level, offset, image); DataHelper<Dimensions>::setSubImage(this, _target, level, offset, image);
return this; return this;
} }
#endif
/** /**
* @brief Invalidate texture subimage * @brief Invalidate texture subimage

Loading…
Cancel
Save