Browse Source

Moved global data from texture classes to per-context state.

pull/51/head
Vladimír Vondruš 12 years ago
parent
commit
37b9f4d846
  1. 240
      src/Magnum/AbstractTexture.cpp
  2. 95
      src/Magnum/AbstractTexture.h
  3. 14
      src/Magnum/BufferTexture.cpp
  4. 16
      src/Magnum/BufferTexture.h
  5. 4
      src/Magnum/Context.cpp
  6. 2
      src/Magnum/Implementation/State.cpp
  7. 135
      src/Magnum/Implementation/TextureState.cpp
  8. 36
      src/Magnum/Implementation/TextureState.h

240
src/Magnum/AbstractTexture.cpp

@ -41,52 +41,6 @@
namespace Magnum {
AbstractTexture::BindImplementation AbstractTexture::bindImplementation =
&AbstractTexture::bindImplementationDefault;
AbstractTexture::ParameteriImplementation AbstractTexture::parameteriImplementation =
&AbstractTexture::parameterImplementationDefault;
AbstractTexture::ParameterfImplementation AbstractTexture::parameterfImplementation =
&AbstractTexture::parameterImplementationDefault;
AbstractTexture::ParameterfvImplementation AbstractTexture::parameterfvImplementation =
&AbstractTexture::parameterImplementationDefault;
AbstractTexture::SetMaxAnisotropyImplementation AbstractTexture::setMaxAnisotropyImplementation =
&AbstractTexture::setMaxAnisotropyImplementationNoOp;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::GetLevelParameterivImplementation AbstractTexture::getLevelParameterivImplementation =
&AbstractTexture::getLevelParameterImplementationDefault;
#endif
AbstractTexture::MipmapImplementation AbstractTexture::mipmapImplementation =
&AbstractTexture::mipmapImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::Storage1DImplementation AbstractTexture::storage1DImplementation =
&AbstractTexture::storageImplementationFallback;
#endif
AbstractTexture::Storage2DImplementation AbstractTexture::storage2DImplementation =
&AbstractTexture::storageImplementationFallback;
AbstractTexture::Storage3DImplementation AbstractTexture::storage3DImplementation =
&AbstractTexture::storageImplementationFallback;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::GetImageImplementation AbstractTexture::getImageImplementation =
&AbstractTexture::getImageImplementationDefault;
AbstractTexture::Image1DImplementation AbstractTexture::image1DImplementation =
&AbstractTexture::imageImplementationDefault;
#endif
AbstractTexture::Image2DImplementation AbstractTexture::image2DImplementation =
&AbstractTexture::imageImplementationDefault;
AbstractTexture::Image3DImplementation AbstractTexture::image3DImplementation =
&AbstractTexture::imageImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::SubImage1DImplementation AbstractTexture::subImage1DImplementation =
&AbstractTexture::subImageImplementationDefault;
#endif
AbstractTexture::SubImage2DImplementation AbstractTexture::subImage2DImplementation =
&AbstractTexture::subImageImplementationDefault;
AbstractTexture::SubImage3DImplementation AbstractTexture::subImage3DImplementation =
&AbstractTexture::subImageImplementationDefault;
AbstractTexture::InvalidateImageImplementation AbstractTexture::invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationNoOp;
AbstractTexture::InvalidateSubImageImplementation AbstractTexture::invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp;
Int AbstractTexture::maxLayers() { return Shader::maxCombinedTextureImageUnits(); }
#ifndef MAGNUM_TARGET_GLES
@ -160,7 +114,7 @@ void AbstractTexture::bind(Int layer) {
/* If already bound in given layer, nothing to do */
if(textureState->bindings[layer] == _id) return;
(this->*bindImplementation)(layer);
(this->*Context::current()->state().texture->bindImplementation)(layer);
}
void AbstractTexture::bindImplementationDefault(GLint layer) {
@ -185,16 +139,39 @@ AbstractTexture& AbstractTexture::setMinificationFilter(Sampler::Filter filter,
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Sampler::Mipmap::Base, "AbstractTexture: rectangle textures cannot have mipmaps", *this);
#endif
(this->*parameteriImplementation)(GL_TEXTURE_MIN_FILTER, GLint(filter)|GLint(mipmap));
(this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_MIN_FILTER, GLint(filter)|GLint(mipmap));
return *this;
}
AbstractTexture& AbstractTexture::setMagnificationFilter(const Sampler::Filter filter) {
(this->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_MAG_FILTER, GLint(filter));
return *this;
}
AbstractTexture& AbstractTexture::setBorderColor(const Color4& color) {
#ifndef MAGNUM_TARGET_GLES
(this->*Context::current()->state().texture->parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data());
#else
(this->*Context::current()->state().texture->parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR_NV, color.data());
#endif
return *this;
}
AbstractTexture& AbstractTexture::setMaxAnisotropy(const Float anisotropy) {
(this->*Context::current()->state().texture->setMaxAnisotropyImplementation)(anisotropy);
return *this;
}
void AbstractTexture::invalidateImage(const Int level) {
(this->*Context::current()->state().texture->invalidateImageImplementation)(level);
}
AbstractTexture& AbstractTexture::generateMipmap() {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", *this);
#endif
(this->*mipmapImplementation)();
(this->*Context::current()->state().texture->mipmapImplementation)();
return *this;
}
@ -226,65 +203,6 @@ void AbstractTexture::bindInternal() {
glBindTexture(_target, (textureState->bindings[internalLayer] = _id));
}
void AbstractTexture::initializeContextBasedFunctionality(Context& context) {
/* Resize bindings array to hold all possible layers */
context.state().texture->bindings.resize(maxLayers());
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::EXT::direct_state_access::string() << "features";
bindImplementation = &AbstractTexture::bindImplementationDSA;
parameteriImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfvImplementation = &AbstractTexture::parameterImplementationDSA;
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSA;
mipmapImplementation = &AbstractTexture::mipmapImplementationDSA;
getImageImplementation = &AbstractTexture::getImageImplementationDSA;
image1DImplementation = &AbstractTexture::imageImplementationDSA;
image2DImplementation = &AbstractTexture::imageImplementationDSA;
image3DImplementation = &AbstractTexture::imageImplementationDSA;
subImage1DImplementation = &AbstractTexture::subImageImplementationDSA;
subImage2DImplementation = &AbstractTexture::subImageImplementationDSA;
subImage3DImplementation = &AbstractTexture::subImageImplementationDSA;
}
if(context.isExtensionSupported<Extensions::GL::ARB::invalidate_subdata>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::ARB::invalidate_subdata::string() << "features";
invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationARB;
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationARB;
}
if(context.isExtensionSupported<Extensions::GL::ARB::robustness>() &&
!context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::ARB::robustness::string() << "features";
getImageImplementation = &AbstractTexture::getImageImplementationRobustness;
}
if(context.isExtensionSupported<Extensions::GL::ARB::texture_storage>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::ARB::texture_storage::string() << "features";
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
storage1DImplementation = &AbstractTexture::storageImplementationDSA;
storage2DImplementation = &AbstractTexture::storageImplementationDSA;
storage3DImplementation = &AbstractTexture::storageImplementationDSA;
} else {
storage1DImplementation = &AbstractTexture::storageImplementationDefault;
storage2DImplementation = &AbstractTexture::storageImplementationDefault;
storage3DImplementation = &AbstractTexture::storageImplementationDefault;
}
}
#endif
if(context.isExtensionSupported<Extensions::GL::EXT::texture_filter_anisotropic>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::EXT::texture_filter_anisotropic::string() << "features";
setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationExt;
}
}
ColorFormat AbstractTexture::imageFormatForInternalFormat(const TextureFormat internalFormat) {
switch(internalFormat) {
case TextureFormat::Red:
@ -690,7 +608,7 @@ void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLfloat
void AbstractTexture::setMaxAnisotropyImplementationNoOp(GLfloat) {}
void AbstractTexture::setMaxAnisotropyImplementationExt(GLfloat anisotropy) {
(this->*parameterfImplementation)(GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
(this->*Context::current()->state().texture->parameterfImplementation)(GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
}
#ifndef MAGNUM_TARGET_GLES
@ -712,7 +630,7 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G
const ColorType type = imageTypeForInternalFormat(internalFormat);
for(GLsizei level = 0; level != levels; ++level) {
(this->*image1DImplementation)(target, level, internalFormat, Math::max(Math::Vector<1, GLsizei>(1), size >> level), format, type, nullptr);
(this->*Context::current()->state().texture->image1DImplementation)(target, level, internalFormat, Math::max(Math::Vector<1, GLsizei>(1), size >> level), format, type, nullptr);
}
}
@ -748,7 +666,7 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G
#endif
{
for(GLsizei level = 0; level != levels; ++level) {
(this->*image2DImplementation)(target, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr);
(this->*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr);
}
/* Cube map additionally needs to specify all faces */
@ -760,14 +678,14 @@ void AbstractTexture::storageImplementationFallback(const GLenum target, const G
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z})
(this->*image2DImplementation)(face, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr);
(this->*Context::current()->state().texture->image2DImplementation)(face, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr);
}
#ifndef MAGNUM_TARGET_GLES
/* Array texture is not scaled in "layer" dimension */
} else if(target == GL_TEXTURE_1D_ARRAY) {
for(GLsizei level = 0; level != levels; ++level) {
(this->*image2DImplementation)(target, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr);
(this->*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, Math::max(Vector2i(1), size >> level), format, type, nullptr);
}
#endif
@ -808,7 +726,7 @@ void AbstractTexture::storageImplementationFallback(GLenum target, GLsizei level
#endif
{
for(GLsizei level = 0; level != levels; ++level) {
(this->*image3DImplementation)(target, level, internalFormat, Math::max(Vector3i(1), size >> level), format, type, nullptr);
(this->*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, Math::max(Vector3i(1), size >> level), format, type, nullptr);
}
#ifndef MAGNUM_TARGET_GLES2
@ -821,7 +739,7 @@ void AbstractTexture::storageImplementationFallback(GLenum target, GLsizei level
#endif
{
for(GLsizei level = 0; level != levels; ++level) {
(this->*image3DImplementation)(target, level, internalFormat, Math::max(Vector3i(1), size >> level), format, type, nullptr);
(this->*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, Math::max(Vector3i(1), size >> level), format, type, nullptr);
}
#endif
@ -991,7 +909,7 @@ template<UnsignedInt dimensions> void AbstractTexture::image(GLenum target, GLin
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(this, target, level);
const std::size_t dataSize = size.product()*image.pixelSize();
char* data = new char[dataSize];
(this->*getImageImplementation)(target, level, image.format(), image.type(), dataSize, data);
(this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, data);
image.setData(image.format(), image.type(), size, data);
}
@ -1006,7 +924,7 @@ template<UnsignedInt dimensions> void AbstractTexture::image(GLenum target, GLin
image.setData(image.format(), image.type(), size, nullptr, usage);
image.buffer().bind(Buffer::Target::PixelPack);
(this->*getImageImplementation)(target, level, image.format(), image.type(), dataSize, nullptr);
(this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, nullptr);
}
template void MAGNUM_EXPORT AbstractTexture::image<1>(GLenum, GLint, BufferImage<1>&, BufferUsage);
@ -1019,45 +937,63 @@ template void MAGNUM_EXPORT AbstractTexture::image<3>(GLenum, GLint, BufferImage
#ifndef MAGNUM_TARGET_GLES
Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture* texture, GLenum target, GLint level) {
Math::Vector<1, GLint> value;
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture->*Context::current()->state().texture->getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
return value;
}
Vector2i AbstractTexture::DataHelper<2>::imageSize(AbstractTexture* texture, GLenum target, GLint level) {
const Implementation::TextureState& state = *Context::current()->state().texture;
Vector2i value;
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]);
(texture->*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture->*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]);
return value;
}
Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture* texture, GLenum target, GLint level) {
const Implementation::TextureState& state = *Context::current()->state().texture;
Vector3i value;
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]);
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_DEPTH, &value[2]);
(texture->*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture->*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]);
(texture->*state.getLevelParameterivImplementation)(target, level, GL_TEXTURE_DEPTH, &value[2]);
return value;
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<1>::setStorage(AbstractTexture* const texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
(texture->*Context::current()->state().texture->storage1DImplementation)(target, levels, internalFormat, size);
}
#endif
void AbstractTexture::DataHelper<2>::setStorage(AbstractTexture* const texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector2i& size) {
(texture->*Context::current()->state().texture->storage2DImplementation)(target, levels, internalFormat, size);
}
void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture* const texture, const GLenum target, const GLsizei levels, const TextureFormat internalFormat, const Vector3i& size) {
(texture->*Context::current()->state().texture->storage3DImplementation)(target, levels, internalFormat, size);
}
#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());
(texture->*Context::current()->state().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);
(texture->*Context::current()->state().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());
(texture->*Context::current()->state().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);
(texture->*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif
@ -1065,13 +1001,13 @@ void AbstractTexture::DataHelper<2>::setImage(AbstractTexture* const texture, co
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbind(Buffer::Target::PixelUnpack);
#endif
(texture->*image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data());
(texture->*Context::current()->state().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);
(texture->*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr);
}
#endif
@ -1079,13 +1015,13 @@ void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture* const texture,
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbind(Buffer::Target::PixelUnpack);
#endif
(texture->*subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data());
(texture->*Context::current()->state().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);
(texture->*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif
@ -1093,13 +1029,13 @@ void AbstractTexture::DataHelper<3>::setImage(AbstractTexture* const texture, co
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbind(Buffer::Target::PixelUnpack);
#endif
(texture->*image3DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data());
(texture->*Context::current()->state().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);
(texture->*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr);
}
#endif
@ -1107,13 +1043,33 @@ void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture* const texture,
#ifndef MAGNUM_TARGET_GLES2
Buffer::unbind(Buffer::Target::PixelUnpack);
#endif
(texture->*subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data());
(texture->*Context::current()->state().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);
(texture->*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<1>::invalidateSubImage(AbstractTexture* const texture, const GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size) {
(texture->*Context::current()->state().texture->invalidateSubImageImplementation)(level, {offset[0], 0, 0}, {size[0], 1, 1});
}
#endif
void AbstractTexture::DataHelper<2>::invalidateSubImage(AbstractTexture* const texture, const GLint level, const Vector2i& offset, const Vector2i& size) {
(texture->*Context::current()->state().texture->invalidateSubImageImplementation)(level, {offset, 0}, {size, 1});
}
void AbstractTexture::DataHelper<3>::invalidateSubImage(AbstractTexture* const texture, const GLint level, const Vector3i& offset, const Vector3i& size) {
(texture->*Context::current()->state().texture->invalidateSubImageImplementation)(level, offset, size);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<1>::setWrapping(AbstractTexture* const texture, const Array1D<Sampler::Wrapping>& wrapping) {
(texture->*Context::current()->state().texture->parameteriImplementation)(GL_TEXTURE_WRAP_S, GLint(wrapping.x()));
}
#endif
@ -1122,15 +1078,19 @@ void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const
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::ClampToBorder)), "Texture2D::setWrapping(): rectangle texture must be clamped to border or to edge", );
#endif
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, GLint(wrapping.x()));
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_T, GLint(wrapping.y()));
const Implementation::TextureState& state = *Context::current()->state().texture;
(texture->*state.parameteriImplementation)(GL_TEXTURE_WRAP_S, GLint(wrapping.x()));
(texture->*state.parameteriImplementation)(GL_TEXTURE_WRAP_T, GLint(wrapping.y()));
}
void AbstractTexture::DataHelper<3>::setWrapping(AbstractTexture* texture, const Array3D<Sampler::Wrapping>& wrapping) {
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, GLint(wrapping.x()));
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_T, GLint(wrapping.y()));
const Implementation::TextureState& state = *Context::current()->state().texture;
(texture->*state.parameteriImplementation)(GL_TEXTURE_WRAP_S, GLint(wrapping.x()));
(texture->*state.parameteriImplementation)(GL_TEXTURE_WRAP_T, GLint(wrapping.y()));
#ifndef MAGNUM_TARGET_GLES
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_R, GLint(wrapping.z()));
(texture->*state.parameteriImplementation)(GL_TEXTURE_WRAP_R, GLint(wrapping.z()));
#endif
}
#endif

95
src/Magnum/AbstractTexture.h

@ -36,6 +36,8 @@
namespace Magnum {
namespace Implementation { struct TextureState; }
/**
@brief Base for textures
@ -99,7 +101,7 @@ nothing.
@todo Query for immutable levels (@extension{ARB,ES3_compatibility})
*/
class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
friend class Context;
friend class Implementation::TextureState;
public:
/**
@ -243,10 +245,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MAG_FILTER}
*/
AbstractTexture& setMagnificationFilter(Sampler::Filter filter) {
(this->*parameteriImplementation)(GL_TEXTURE_MAG_FILTER, GLint(filter));
return *this;
}
AbstractTexture& setMagnificationFilter(Sampler::Filter filter);
/**
* @brief Set border color
@ -261,14 +260,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* with @def_gl{TEXTURE_BORDER_COLOR}
* @requires_es_extension %Extension @es_extension{NV,texture_border_clamp}
*/
AbstractTexture& setBorderColor(const Color4& color) {
#ifndef MAGNUM_TARGET_GLES
(this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data());
#else
(this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR_NV, color.data());
#endif
return *this;
}
AbstractTexture& setBorderColor(const Color4& color);
/**
* @brief Set max anisotropy
@ -285,10 +277,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MAX_ANISOTROPY_EXT}
*/
AbstractTexture& setMaxAnisotropy(Float anisotropy) {
(this->*setMaxAnisotropyImplementation)(anisotropy);
return *this;
}
AbstractTexture& setMaxAnisotropy(Float anisotropy);
/**
* @brief Invalidate texture image
@ -299,9 +288,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* @see @ref Texture::invalidateSubImage() "invalidateSubImage()",
* @fn_gl{InvalidateTexImage}
*/
void invalidateImage(Int level) {
(this->*invalidateImageImplementation)(level);
}
void invalidateImage(Int level);
/**
* @brief Generate mipmap
@ -352,142 +339,102 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
GLenum _target;
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context& context);
typedef void(AbstractTexture::*BindImplementation)(GLint);
void MAGNUM_LOCAL bindImplementationDefault(GLint layer);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL bindImplementationDSA(GLint layer);
#endif
static MAGNUM_LOCAL BindImplementation bindImplementation;
typedef void(AbstractTexture::*ParameteriImplementation)(GLenum, GLint);
void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, GLint value);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLint value);
#endif
static ParameteriImplementation parameteriImplementation;
typedef void(AbstractTexture::*ParameterfImplementation)(GLenum, GLfloat);
void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, GLfloat value);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLfloat value);
#endif
static ParameterfImplementation parameterfImplementation;
typedef void(AbstractTexture::*ParameterfvImplementation)(GLenum, const GLfloat*);
void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, const GLfloat* values);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLfloat* values);
#endif
static ParameterfvImplementation parameterfvImplementation;
typedef void(AbstractTexture::*SetMaxAnisotropyImplementation)(GLfloat);
void MAGNUM_LOCAL setMaxAnisotropyImplementationNoOp(GLfloat);
void MAGNUM_LOCAL setMaxAnisotropyImplementationExt(GLfloat anisotropy);
static SetMaxAnisotropyImplementation setMaxAnisotropyImplementation;
#ifndef MAGNUM_TARGET_GLES
typedef void(AbstractTexture::*GetLevelParameterivImplementation)(GLenum, GLint, GLenum, GLint*);
void MAGNUM_LOCAL getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values);
void MAGNUM_LOCAL getLevelParameterImplementationDSA(GLenum target, GLint level, GLenum parameter, GLint* values);
static MAGNUM_LOCAL GetLevelParameterivImplementation getLevelParameterivImplementation;
#endif
typedef void(AbstractTexture::*MipmapImplementation)();
void MAGNUM_LOCAL mipmapImplementationDefault();
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL mipmapImplementationDSA();
#endif
static MAGNUM_LOCAL MipmapImplementation mipmapImplementation;
#ifndef MAGNUM_TARGET_GLES
typedef void(AbstractTexture::*Storage1DImplementation)(GLenum, GLsizei, TextureFormat, const Math::Vector<1, GLsizei>&);
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
static Storage1DImplementation storage1DImplementation;
#endif
typedef void(AbstractTexture::*Storage2DImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&);
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
#endif
static Storage2DImplementation storage2DImplementation;
typedef void(AbstractTexture::*Storage3DImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&);
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#endif
static Storage3DImplementation storage3DImplementation;
#ifndef MAGNUM_TARGET_GLES
typedef void(AbstractTexture::*GetImageImplementation)(GLenum, GLint, ColorFormat, ColorType, std::size_t, GLvoid*);
void MAGNUM_LOCAL getImageImplementationDefault(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationDSA(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationRobustness(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
static MAGNUM_LOCAL GetImageImplementation getImageImplementation;
#endif
#ifndef MAGNUM_TARGET_GLES
typedef void(AbstractTexture::*Image1DImplementation)(GLenum, GLint, TextureFormat, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*);
void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
static Image1DImplementation image1DImplementation;
#endif
typedef void(AbstractTexture::*Image2DImplementation)(GLenum, GLint, TextureFormat, const Vector2i&, ColorFormat, ColorType, const GLvoid*);
void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
static Image2DImplementation image2DImplementation;
typedef void(AbstractTexture::*Image3DImplementation)(GLenum, GLint, TextureFormat, const Vector3i&, ColorFormat, ColorType, const GLvoid*);
void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
static Image3DImplementation image3DImplementation;
#ifndef MAGNUM_TARGET_GLES
typedef void(AbstractTexture::*SubImage1DImplementation)(GLenum, GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*);
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
static SubImage1DImplementation subImage1DImplementation;
#endif
typedef void(AbstractTexture::*SubImage2DImplementation)(GLenum, GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*);
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
static SubImage2DImplementation subImage2DImplementation;
typedef void(AbstractTexture::*SubImage3DImplementation)(GLenum, GLint, const Vector3i&, const Vector3i&, ColorFormat, ColorType, const GLvoid*);
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
static SubImage3DImplementation subImage3DImplementation;
typedef void(AbstractTexture::*InvalidateImageImplementation)(GLint);
void MAGNUM_LOCAL invalidateImageImplementationNoOp(GLint level);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL invalidateImageImplementationARB(GLint level);
#endif
static InvalidateImageImplementation invalidateImageImplementation;
typedef void(AbstractTexture::*InvalidateSubImageImplementation)(GLint, const Vector3i&, const Vector3i&);
void MAGNUM_LOCAL invalidateSubImageImplementationNoOp(GLint level, const Vector3i& offset, const Vector3i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL invalidateSubImageImplementationARB(GLint level, const Vector3i& offset, const Vector3i& size);
#endif
static InvalidateSubImageImplementation invalidateSubImageImplementation;
ColorFormat MAGNUM_LOCAL imageFormatForInternalFormat(TextureFormat internalFormat);
ColorType MAGNUM_LOCAL imageTypeForInternalFormat(TextureFormat internalFormat);
@ -506,13 +453,9 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> {
static Math::Vector<1, GLint> imageSize(AbstractTexture* texture, GLenum target, GLint level);
static void setWrapping(AbstractTexture* texture, const Array1D<Sampler::Wrapping>& wrapping) {
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, GLint(wrapping.x()));
}
static void setWrapping(AbstractTexture* texture, const Array1D<Sampler::Wrapping>& wrapping);
static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
(texture->*storage1DImplementation)(target, levels, internalFormat, size);
}
static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
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);
@ -520,9 +463,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<1> {
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});
}
static void invalidateSubImage(AbstractTexture* texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size);
};
#endif
template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
@ -543,9 +484,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
static void setWrapping(AbstractTexture* texture, const Array2D<Sampler::Wrapping>& wrapping);
static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
(texture->*storage2DImplementation)(target, levels, internalFormat, size);
}
static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference2D& image);
#ifndef MAGNUM_TARGET_GLES2
@ -557,9 +496,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
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});
}
static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector2i& offset, const Vector2i& size);
};
template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
enum class Target: GLenum {
@ -582,9 +519,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
static void setWrapping(AbstractTexture* texture, const Array3D<Sampler::Wrapping>& wrapping);
static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
(texture->*storage3DImplementation)(target, levels, internalFormat, size);
}
static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
static void setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference3D& image);
#ifndef MAGNUM_TARGET_GLES2
@ -596,9 +531,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
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);
}
static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector3i& offset, const Vector3i& size);
};
#endif

14
src/Magnum/BufferTexture.cpp

@ -35,9 +35,6 @@
namespace Magnum {
BufferTexture::SetBufferImplementation BufferTexture::setBufferImplementation = &BufferTexture::setBufferImplementationDefault;
BufferTexture::SetBufferRangeImplementation BufferTexture::setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault;
Int BufferTexture::offsetAlignment() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_buffer_range>())
return 0;
@ -51,13 +48,12 @@ Int BufferTexture::offsetAlignment() {
return value;
}
void BufferTexture::initializeContextBasedFunctionality(Context& context) {
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
Debug() << "BufferTexture: using" << Extensions::GL::EXT::direct_state_access::string() << "features";
void BufferTexture::setBuffer(const BufferTextureFormat internalFormat, Buffer& buffer) {
(this->*Context::current()->state().texture->setBufferImplementation)(internalFormat, buffer);
}
setBufferImplementation = &BufferTexture::setBufferImplementationDSA;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSA;
}
void BufferTexture::setBuffer(const BufferTextureFormat internalFormat, Buffer& buffer, const GLintptr offset, const GLsizeiptr size) {
(this->*Context::current()->state().texture->setBufferRangeImplementation)(internalFormat, buffer, offset, size);
}
void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer) {

16
src/Magnum/BufferTexture.h

@ -200,7 +200,7 @@ and respective function documentation for more information.
@requires_gl Texture buffers are not available in OpenGL ES.
*/
class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
friend class Context;
friend class Implementation::TextureState;
public:
/** @copydoc AbstractTexture::maxLabelLength() */
@ -244,9 +244,7 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBuffer}
* or @fn_gl_extension{TextureBuffer,EXT,direct_state_access}
*/
void setBuffer(BufferTextureFormat internalFormat, Buffer& buffer) {
(this->*setBufferImplementation)(internalFormat, buffer);
}
void setBuffer(BufferTextureFormat internalFormat, Buffer& buffer);
/**
* @brief Set texture buffer
@ -262,22 +260,14 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBufferRange}
* or @fn_gl_extension{TextureBufferRange,EXT,direct_state_access}
*/
void setBuffer(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) {
(this->*setBufferRangeImplementation)(internalFormat, buffer, offset, size);
}
void setBuffer(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context& context);
typedef void(BufferTexture::*SetBufferImplementation)(BufferTextureFormat, Buffer&);
void MAGNUM_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer);
void MAGNUM_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer);
static SetBufferImplementation setBufferImplementation;
typedef void(BufferTexture::*SetBufferRangeImplementation)(BufferTextureFormat, Buffer&, GLintptr, GLsizeiptr);
void MAGNUM_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
void MAGNUM_LOCAL setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
static SetBufferRangeImplementation setBufferRangeImplementation;
};
}

4
src/Magnum/Context.cpp

@ -449,11 +449,7 @@ Context::Context() {
/* Initialize functionality based on current OpenGL version and extensions */
AbstractShaderProgram::initializeContextBasedFunctionality(*this);
AbstractTexture::initializeContextBasedFunctionality(*this);
Buffer::initializeContextBasedFunctionality(*this);
#ifndef MAGNUM_TARGET_GLES
BufferTexture::initializeContextBasedFunctionality(*this);
#endif
DefaultFramebuffer::initializeContextBasedFunctionality(*this);
Mesh::initializeContextBasedFunctionality(*this);
Renderer::initializeContextBasedFunctionality(*this);

2
src/Magnum/Implementation/State.cpp

@ -58,7 +58,7 @@ State::State(Context& context) {
renderer = new RendererState;
shader = new ShaderState;
shaderProgram = new ShaderProgramState;
texture = new TextureState;
texture = new TextureState(context, extensions);
/* Sort the features and remove duplicates */
std::sort(extensions.begin(), extensions.end());

135
src/Magnum/Implementation/TextureState.cpp

@ -25,13 +25,144 @@
#include "TextureState.h"
#include "Magnum/AbstractTexture.h"
#ifndef MAGNUM_TARGET_GLES
#include "Magnum/BufferTexture.h"
#endif
#include "Magnum/Context.h"
#include "Magnum/Extensions.h"
namespace Magnum { namespace Implementation {
TextureState::TextureState(): maxMaxAnisotropy(0.0f), currentLayer(0)
TextureState::TextureState(Context& context, std::vector<std::string>& extensions): maxMaxAnisotropy(0.0f), currentLayer(0)
#ifndef MAGNUM_TARGET_GLES
, maxColorSamples(0), maxDepthSamples(0), maxIntegerSamples(0), bufferOffsetAlignment(0)
#endif
{}
{
/* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
bindImplementation = &AbstractTexture::bindImplementationDSA;
parameteriImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfvImplementation = &AbstractTexture::parameterImplementationDSA;
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSA;
mipmapImplementation = &AbstractTexture::mipmapImplementationDSA;
getImageImplementation = &AbstractTexture::getImageImplementationDSA;
image1DImplementation = &AbstractTexture::imageImplementationDSA;
image2DImplementation = &AbstractTexture::imageImplementationDSA;
image3DImplementation = &AbstractTexture::imageImplementationDSA;
subImage1DImplementation = &AbstractTexture::subImageImplementationDSA;
subImage2DImplementation = &AbstractTexture::subImageImplementationDSA;
subImage3DImplementation = &AbstractTexture::subImageImplementationDSA;
setBufferImplementation = &BufferTexture::setBufferImplementationDSA;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSA;
} else
#endif
{
bindImplementation = &AbstractTexture::bindImplementationDefault;
parameteriImplementation = &AbstractTexture::parameterImplementationDefault;
parameterfImplementation = &AbstractTexture::parameterImplementationDefault;
parameterfvImplementation = &AbstractTexture::parameterImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDefault;
#endif
mipmapImplementation = &AbstractTexture::mipmapImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
getImageImplementation = &AbstractTexture::getImageImplementationDefault;
image1DImplementation = &AbstractTexture::imageImplementationDefault;
#endif
image2DImplementation = &AbstractTexture::imageImplementationDefault;
image3DImplementation = &AbstractTexture::imageImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
subImage1DImplementation = &AbstractTexture::subImageImplementationDefault;
#endif
subImage2DImplementation = &AbstractTexture::subImageImplementationDefault;
subImage3DImplementation = &AbstractTexture::subImageImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
setBufferImplementation = &BufferTexture::setBufferImplementationDefault;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault;
#endif
}
/* Data invalidation implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::invalidate_subdata>()) {
extensions.push_back(Extensions::GL::ARB::invalidate_subdata::string());
invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationARB;
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationARB;
} else
#endif
{
invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationNoOp;
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp;
}
/* Image retrieval implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::robustness>() &&
!context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
extensions.push_back(Extensions::GL::ARB::robustness::string());
getImageImplementation = &AbstractTexture::getImageImplementationRobustness;
} else getImageImplementation = &AbstractTexture::getImageImplementationDefault;
#endif
/* Texture storage implementation */
#ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::texture_storage>())
#endif
{
#ifndef MAGNUM_TARGET_GLES
extensions.push_back(Extensions::GL::ARB::texture_storage::string());
#endif
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
storage1DImplementation = &AbstractTexture::storageImplementationDSA;
storage2DImplementation = &AbstractTexture::storageImplementationDSA;
storage3DImplementation = &AbstractTexture::storageImplementationDSA;
} else
#endif
{
#ifndef MAGNUM_TARGET_GLES
storage1DImplementation = &AbstractTexture::storageImplementationDefault;
#endif
storage2DImplementation = &AbstractTexture::storageImplementationDefault;
storage3DImplementation = &AbstractTexture::storageImplementationDefault;
}
}
#endif
#ifndef MAGNUM_TARGET_GLES3
#ifndef MAGNUM_TARGET_GLES
else
#endif
{
#ifndef MAGNUM_TARGET_GLES
storage1DImplementation = &AbstractTexture::storageImplementationFallback;
#endif
storage2DImplementation = &AbstractTexture::storageImplementationFallback;
storage3DImplementation = &AbstractTexture::storageImplementationFallback;
}
#endif
/* Anisotropic filter implementation */
if(context.isExtensionSupported<Extensions::GL::EXT::texture_filter_anisotropic>()) {
extensions.push_back(Extensions::GL::EXT::texture_filter_anisotropic::string());
setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationExt;
} else setMaxAnisotropyImplementation = &AbstractTexture::setMaxAnisotropyImplementationNoOp;
/* Resize bindings array to hold all possible layers */
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxLayers);
bindings.resize(maxLayers);
}
TextureState::~TextureState() = default;

36
src/Magnum/Implementation/TextureState.h

@ -25,16 +25,50 @@
DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include <vector>
#include "Magnum/Magnum.h"
#include "Magnum/OpenGL.h"
namespace Magnum { namespace Implementation {
struct TextureState {
explicit TextureState();
explicit TextureState(Context& context, std::vector<std::string>& extensions);
~TextureState();
void(AbstractTexture::*bindImplementation)(GLint);
void(AbstractTexture::*parameteriImplementation)(GLenum, GLint);
void(AbstractTexture::*parameterfImplementation)(GLenum, GLfloat);
void(AbstractTexture::*parameterfvImplementation)(GLenum, const GLfloat*);
void(AbstractTexture::*setMaxAnisotropyImplementation)(GLfloat);
void(AbstractTexture::*getLevelParameterivImplementation)(GLenum, GLint, GLenum, GLint*);
void(AbstractTexture::*mipmapImplementation)();
#ifndef MAGNUM_TARGET_GLES
void(AbstractTexture::*storage1DImplementation)(GLenum, GLsizei, TextureFormat, const Math::Vector<1, GLsizei>&);
#endif
void(AbstractTexture::*storage2DImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&);
void(AbstractTexture::*storage3DImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&);
#ifndef MAGNUM_TARGET_GLES
void(AbstractTexture::*getImageImplementation)(GLenum, GLint, ColorFormat, ColorType, std::size_t, GLvoid*);
void(AbstractTexture::*image1DImplementation)(GLenum, GLint, TextureFormat, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*);
#endif
void(AbstractTexture::*image2DImplementation)(GLenum, GLint, TextureFormat, const Vector2i&, ColorFormat, ColorType, const GLvoid*);
void(AbstractTexture::*image3DImplementation)(GLenum, GLint, TextureFormat, const Vector3i&, ColorFormat, ColorType, const GLvoid*);
#ifndef MAGNUM_TARGET_GLES
void(AbstractTexture::*subImage1DImplementation)(GLenum, GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*);
#endif
void(AbstractTexture::*subImage2DImplementation)(GLenum, GLint, const Vector2i&, const Vector2i&, ColorFormat, ColorType, const GLvoid*);
void(AbstractTexture::*subImage3DImplementation)(GLenum, GLint, const Vector3i&, const Vector3i&, ColorFormat, ColorType, const GLvoid*);
void(AbstractTexture::*invalidateImageImplementation)(GLint);
void(AbstractTexture::*invalidateSubImageImplementation)(GLint, const Vector3i&, const Vector3i&);
#ifndef MAGNUM_TARGET_GLES
void(BufferTexture::*setBufferImplementation)(BufferTextureFormat, Buffer&);
void(BufferTexture::*setBufferRangeImplementation)(BufferTextureFormat, Buffer&, GLintptr, GLsizeiptr);
#endif
GLint maxLayers;
GLfloat maxMaxAnisotropy;
GLint currentLayer;
#ifndef MAGNUM_TARGET_GLES

Loading…
Cancel
Save