Browse Source

Proper passing of image data to textures.

Explicitly unbinding pixel unpack buffer when passing data from client
memory and binding it when passing data from BufferImage.
pull/7/head
Vladimír Vondruš 13 years ago
parent
commit
e29b608632
  1. 15
      src/AbstractTexture.cpp
  2. 37
      src/AbstractTexture.h
  3. 14
      src/BufferImage.h

15
src/AbstractTexture.cpp

@ -15,6 +15,8 @@
#include "AbstractTexture.h"
#include "Buffer.h"
#include "BufferImage.h"
#include "Context.h"
#include "Extensions.h"
#include "Implementation/State.h"
@ -431,6 +433,19 @@ void AbstractTexture::invalidateSubImplementationARB(GLint level, const Vector3i
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES2
namespace Implementation {
template<std::uint8_t dimensions> GLvoid* ImageHelper<BufferImage<dimensions>>::dataOrPixelUnpackBuffer(BufferImage<dimensions>* image) {
image->buffer()->bind(Buffer::Target::PixelUnpack);
return nullptr;
}
template class ImageHelper<BufferImage1D>;
template class ImageHelper<BufferImage2D>;
template class ImageHelper<BufferImage3D>;
}
#endif
void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const Array2D<Wrapping>& wrapping) {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(texture->_target != GL_TEXTURE_RECTANGLE || ((wrapping.x() == Wrapping::ClampToEdge || wrapping.x() == Wrapping::ClampToBorder) && (wrapping.y() == Wrapping::ClampToEdge || wrapping.y() == Wrapping::ClampToEdge)), "AbstractTexture: rectangle texture wrapping must either clamp to border or to edge", );

37
src/AbstractTexture.h

@ -20,6 +20,9 @@
*/
#include "Array.h"
#ifndef MAGNUM_TARGET_GLES2
#include "Buffer.h"
#endif
#include "Color.h"
#include "AbstractImage.h"
@ -64,6 +67,7 @@ do nothing.
@todo Texture copying
@todo Move constructor/assignment - how to avoid creation of empty texture and
then deleting it immediately?
@todo ES2 - proper support for pixel unpack buffer when extension is in headers
*/
class MAGNUM_EXPORT AbstractTexture {
friend class Context;
@ -1272,6 +1276,23 @@ class MAGNUM_EXPORT AbstractTexture {
};
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class Image> struct ImageHelper {
inline static GLvoid* dataOrPixelUnpackBuffer(Image* image) {
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbind(Buffer::Target::PixelUnpack);
#endif
return image->data();
}
};
#ifndef MAGNUM_TARGET_GLES2
template<std::uint8_t dimensions> struct MAGNUM_EXPORT ImageHelper<BufferImage<dimensions>> {
static GLvoid* dataOrPixelUnpackBuffer(BufferImage<dimensions>* image);
};
#endif
}
#ifndef MAGNUM_TARGET_GLES
template<> struct AbstractTexture::DataHelper<1> {
enum class Target: GLenum {
@ -1289,11 +1310,11 @@ template<> struct AbstractTexture::DataHelper<1> {
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 1, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) {
(texture->*image1DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data());
(texture->*image1DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 1, void>::type setSub(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(), image->data());
(texture->*subImage1DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
}
inline static void invalidateSub(AbstractTexture* texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size) {
@ -1320,15 +1341,15 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 2, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) {
(texture->*image2DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data());
(texture->*image2DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 2, void>::type setSub(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) {
(texture->*subImage2DImplementation)(target, level, offset, image->size(), image->format(), image->type(), image->data());
(texture->*subImage2DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 1, void>::type setSub(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) {
(texture->*subImage2DImplementation)(target, level, offset, Vector2i(image->size(), 1), image->format(), image->type(), image->data());
(texture->*subImage2DImplementation)(target, level, offset, Vector2i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
}
inline static void invalidateSub(AbstractTexture* texture, GLint level, const Vector2i& offset, const Vector2i& size) {
@ -1354,15 +1375,15 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 3, void>::type set(AbstractTexture* texture, GLenum target, GLint level, InternalFormat internalFormat, Image* image) {
(texture->*image3DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), image->data());
(texture->*image3DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 3, void>::type setSub(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) {
(texture->*subImage3DImplementation)(target, level, offset, image->size(), image->format(), image->type(), image->data());
(texture->*subImage3DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
}
template<class Image> inline static typename std::enable_if<Image::Dimensions == 2, void>::type setSub(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) {
(texture->*subImage3DImplementation)(target, level, offset, Vector3i(image->size(), 1), image->format(), image->type(), image->data());
(texture->*subImage3DImplementation)(target, level, offset, Vector3i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
}
inline static void invalidateSub(AbstractTexture* texture, GLint level, const Vector3i& offset, const Vector3i& size) {

14
src/BufferImage.h

@ -56,20 +56,6 @@ template<std::uint8_t dimensions> class MAGNUM_EXPORT BufferImage: public Abstra
/** @brief %Image size */
inline typename DimensionTraits<Dimensions, GLsizei>::VectorType size() const { return _size; }
/**
* @brief Data
*
* Binds the buffer to @ref Buffer::Target "pixel unpack
* target" and returns nullptr, so it can be used for texture updating
* functions the same way as Image::data().
*
* @see Buffer::bind(Target)
*/
inline void* data() {
_buffer.bind(Buffer::Target::PixelUnpack);
return nullptr;
}
/** @brief %Image buffer */
inline Buffer* buffer() { return &_buffer; }

Loading…
Cancel
Save