From b12792d15a186635e2eea250b4e3ddf1ad7ce708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 2 Nov 2012 16:32:58 +0100 Subject: [PATCH] Updated OpenGL ES support in textures. --- src/AbstractTexture.cpp | 53 +++++++++++++++++++++++++++++++++++++-- src/AbstractTexture.h | 35 +++++++++++++++++++------- src/CubeMapTexture.h | 4 +-- src/CubeMapTextureArray.h | 7 ++++-- src/Texture.h | 19 ++++++++------ 5 files changed, 95 insertions(+), 23 deletions(-) diff --git a/src/AbstractTexture.cpp b/src/AbstractTexture.cpp index 6cb0ca856..8012626b7 100644 --- a/src/AbstractTexture.cpp +++ b/src/AbstractTexture.cpp @@ -32,14 +32,18 @@ AbstractTexture::ParameterfvImplementation AbstractTexture::parameterfvImplement &AbstractTexture::parameterImplementationDefault; AbstractTexture::MipmapImplementation AbstractTexture::mipmapImplementation = &AbstractTexture::mipmapImplementationDefault; +#ifndef MAGNUM_TARGET_GLES 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 = @@ -66,17 +70,18 @@ GLint AbstractTexture::maxSupportedLayerCount() { return Context::current()->state()->texture->maxSupportedLayerCount; } -#ifndef MAGNUM_TARGET_GLES GLfloat AbstractTexture::maxSupportedAnisotropy() { GLfloat& value = Context::current()->state()->texture->maxSupportedAnisotropy; + /** @todo Re-enable when extension header is available */ + #ifndef MAGNUM_TARGET_GLES /* Get the value, if not already cached */ if(value == 0.0f) glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &value); + #endif return value; } -#endif AbstractTexture::~AbstractTexture() { /* Remove all bindings */ @@ -106,9 +111,11 @@ void AbstractTexture::bindImplementationDefault(GLint layer) { glBindTexture(_target, (textureState->bindings[layer] = _id)); } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::bindImplementationDSA(GLint layer) { glBindMultiTextureEXT(GL_TEXTURE0 + layer, _target, (Context::current()->state()->texture->bindings[layer] = _id)); } +#endif AbstractTexture* AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) { #ifndef MAGNUM_TARGET_GLES @@ -134,9 +141,11 @@ void AbstractTexture::mipmapImplementationDefault() { glGenerateMipmap(_target); } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::mipmapImplementationDSA() { glGenerateTextureMipmapEXT(_id, _target); } +#endif #ifndef DOXYGEN_GENERATING_OUTPUT void AbstractTexture::bindInternal() { @@ -165,6 +174,7 @@ void AbstractTexture::initializeContextBasedFunctionality(Context* context) { glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &value); textureState->bindings.resize(value); + #ifndef MAGNUM_TARGET_GLES if(context->isExtensionSupported()) { Debug() << "AbstractTexture: using" << Extensions::GL::EXT::direct_state_access::string() << "features"; @@ -180,6 +190,7 @@ void AbstractTexture::initializeContextBasedFunctionality(Context* context) { subImage2DImplementation = &AbstractTexture::subImageImplementationDSA; subImage3DImplementation = &AbstractTexture::subImageImplementationDSA; } + #endif } void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint value) { @@ -187,24 +198,29 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint val glTexParameteri(_target, parameter, value); } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLint value) { glTextureParameteriEXT(_id, _target, parameter, value); } +#endif void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLfloat value) { bindInternal(); glTexParameterf(_target, parameter, value); } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLfloat value) { glTextureParameterfEXT(_id, _target, parameter, value); } +#endif void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLfloat* values) { bindInternal(); glTexParameterfv(_target, parameter, values); } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLfloat* values) { glTextureParameterfvEXT(_id, _target, parameter, values); } @@ -217,25 +233,42 @@ void AbstractTexture::imageImplementationDefault(GLenum target, GLint mipLevel, void AbstractTexture::imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { glTextureImage1DEXT(_id, target, mipLevel, internalFormat, size[0], 0, static_cast(components), static_cast(type), data); } +#endif void AbstractTexture::imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { bindInternal(); glTexImage2D(target, mipLevel, internalFormat, size.x(), size.y(), 0, static_cast(components), static_cast(type), data); } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { glTextureImage2DEXT(_id, target, mipLevel, internalFormat, size.x(), size.y(), 0, static_cast(components), static_cast(type), data); } +#endif void AbstractTexture::imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { bindInternal(); + /** @todo Get some extension wrangler instead to avoid linker errors to glTexImage3D() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 glTexImage3D(target, mipLevel, internalFormat, size.x(), size.y(), size.z(), 0, static_cast(components), static_cast(type), data); + #else + static_cast(target); + static_cast(mipLevel); + static_cast(internalFormat); + static_cast(size); + static_cast(components); + static_cast(type); + static_cast(data); + #endif } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { glTextureImage3DEXT(_id, target, mipLevel, internalFormat, size.x(), size.y(), size.z(), 0, static_cast(components), static_cast(type), data); } +#endif +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { bindInternal(); glTexSubImage1D(target, mipLevel, offset[0], size[0], static_cast(components), static_cast(type), data); @@ -244,24 +277,40 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint mipLeve void AbstractTexture::subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { glTextureSubImage1DEXT(_id, target, mipLevel, offset[0], size[0], static_cast(components), static_cast(type), data); } +#endif void AbstractTexture::subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { bindInternal(); glTexSubImage2D(target, mipLevel, offset.x(), offset.y(), size.x(), size.y(), static_cast(components), static_cast(type), data); } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { glTextureSubImage2DEXT(_id, target, mipLevel, offset.x(), offset.y(), size.x(), size.y(), static_cast(components), static_cast(type), data); } +#endif void AbstractTexture::subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector3& offset, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { bindInternal(); + /** @todo Get some extension wrangler instead to avoid linker errors to glTexSubImage3D() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 glTexSubImage3D(target, mipLevel, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), static_cast(components), static_cast(type), data); + #else + static_cast(target); + static_cast(mipLevel); + static_cast(offset); + static_cast(size); + static_cast(components); + static_cast(type); + static_cast(data); + #endif } +#ifndef MAGNUM_TARGET_GLES void AbstractTexture::subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector3& offset, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { glTextureSubImage3DEXT(_id, target, mipLevel, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), static_cast(components), static_cast(type), data); } +#endif AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components components, AbstractTexture::ComponentType type) { #ifndef MAGNUM_TARGET_GLES diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index f53d7c690..27b1895eb 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -133,7 +133,7 @@ class MAGNUM_EXPORT AbstractTexture { /** * Clamp to border color. Coordinates out of range will be clamped * to border color (set with setBorderColor()). - * @requires_gl + * @requires_gl Texture border is not available in OpenGL ES. */ ClampToBorder = GL_CLAMP_TO_BORDER #endif @@ -564,16 +564,14 @@ class MAGNUM_EXPORT AbstractTexture { */ static GLint maxSupportedLayerCount(); - #ifndef MAGNUM_TARGET_GLES /** * @brief Max supported anisotropy * * @see setMaxAnisotropy(), @fn_gl{Get} with @def_gl{MAX_TEXTURE_MAX_ANISOTROPY_EXT} - * @requires_gl - * @requires_extension @extension{EXT,texture_filter_anisotropic} + * @requires_extension %Extension @extension{EXT,texture_filter_anisotropic} + * @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic} */ static GLfloat maxSupportedAnisotropy(); - #endif /** * @brief Constructor @@ -659,12 +657,13 @@ class MAGNUM_EXPORT AbstractTexture { * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} * with @def_gl{TEXTURE_BORDER_COLOR} - * @requires_gl + * @requires_gl Texture border is not available in OpenGL ES. */ inline AbstractTexture* setBorderColor(const Color4& color) { (this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data()); return this; } + #endif /** * @brief Set max anisotropy @@ -678,14 +677,18 @@ class MAGNUM_EXPORT AbstractTexture { * @fn_gl{BindTexture} and @fn_gl{TexParameter} or * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with * @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} - * @requires_gl - * @requires_extension @extension{EXT,texture_filter_anisotropic} + * @requires_extension %Extension @extension{EXT,texture_filter_anisotropic} + * @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic} */ inline AbstractTexture* setMaxAnisotropy(GLfloat anisotropy) { + /** @todo Remove `ifndef` when extension header is available */ + #ifndef MAGNUM_TARGET_GLES (this->*parameterfImplementation)(GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); + #else + static_cast(anisotropy); + #endif return this; } - #endif /** * @brief Generate mipmap @@ -716,33 +719,45 @@ class MAGNUM_EXPORT AbstractTexture { 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::*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::*Image1DImplementation)(GLenum, GLint, InternalFormat, const Math::Vector<1, GLsizei>&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); static Image1DImplementation image1DImplementation; + #endif typedef void(AbstractTexture::*Image2DImplementation)(GLenum, GLint, InternalFormat, const Math::Vector2&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); @@ -754,10 +769,12 @@ class MAGNUM_EXPORT AbstractTexture { void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); static Image3DImplementation image3DImplementation; + #ifndef MAGNUM_TARGET_GLES typedef void(AbstractTexture::*SubImage1DImplementation)(GLenum, GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); static SubImage1DImplementation subImage1DImplementation; + #endif typedef void(AbstractTexture::*SubImage2DImplementation)(GLenum, GLint, const Math::Vector2&, const Math::Vector2&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); diff --git a/src/CubeMapTexture.h b/src/CubeMapTexture.h index 110214c42..df1d3b77f 100644 --- a/src/CubeMapTexture.h +++ b/src/CubeMapTexture.h @@ -65,9 +65,9 @@ class CubeMapTexture: public AbstractTexture { * * Initially disabled on desktop OpenGL. * @see @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS} + * @requires_gl32 Extension @extension{ARB,seamless_cube_map} * @requires_gl Not available in OpenGL ES 2.0, always enabled in * OpenGL ES 3.0. - * @requires_gl32 Extension @extension{ARB,seamless_cube_map} */ inline static void setSeamless(bool enabled) { enabled ? glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) : glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); @@ -125,11 +125,11 @@ class CubeMapTexture: public AbstractTexture { AbstractTexture::setBorderColor(color); return this; } + #endif inline CubeMapTexture* setMaxAnisotropy(GLfloat anisotropy) { AbstractTexture::setMaxAnisotropy(anisotropy); return this; } - #endif inline CubeMapTexture* generateMipmap() { AbstractTexture::generateMipmap(); return this; diff --git a/src/CubeMapTextureArray.h b/src/CubeMapTextureArray.h index 165e38e54..0aa441935 100644 --- a/src/CubeMapTextureArray.h +++ b/src/CubeMapTextureArray.h @@ -15,12 +15,15 @@ GNU Lesser General Public License version 3 for more details. */ +#ifndef MAGNUM_TARGET_GLES /** @file * @brief Class Magnum::CubeMapTextureArray */ +#endif #include "Texture.h" +#ifndef MAGNUM_TARGET_GLES namespace Magnum { /** @@ -35,6 +38,7 @@ the cube map. @see CubeMapTexture::setSeamless() @requires_gl40 Extension @extension{ARB,texture_cube_map_array} +@requires_gl Cube map texture arrays are not available in OpenGL ES. */ class CubeMapTextureArray: public AbstractTexture { public: @@ -129,7 +133,6 @@ class CubeMapTextureArray: public AbstractTexture { AbstractTexture::setMagnificationFilter(filter); return this; } - #ifndef MAGNUM_TARGET_GLES inline CubeMapTextureArray* setBorderColor(const Color4& color) { AbstractTexture::setBorderColor(color); return this; @@ -138,7 +141,6 @@ class CubeMapTextureArray: public AbstractTexture { AbstractTexture::setMaxAnisotropy(anisotropy); return this; } - #endif inline CubeMapTextureArray* generateMipmap() { AbstractTexture::generateMipmap(); return this; @@ -147,5 +149,6 @@ class CubeMapTextureArray: public AbstractTexture { }; } +#endif #endif diff --git a/src/Texture.h b/src/Texture.h index 0dd5bcf2d..c73550993 100644 --- a/src/Texture.h +++ b/src/Texture.h @@ -44,7 +44,7 @@ don't support mipmapping and repeating wrapping modes, see @ref Texture::Filter "Filter", @ref Texture::Mipmap "Mipmap" and generateMipmap() documentation for more information. -@requires_gl (rectangle textures) +@requires_gl Rectangle textures are not available in OpenGL ES. @requires_gl31 Extension @extension{ARB,texture_rectangle} (rectangle textures) @see Texture1D, Texture2D, Texture3D, CubeMapTexture, CubeMapTextureArray @@ -63,7 +63,8 @@ template class Texture: public AbstractTexture { enum class Target: GLenum { /** * One-dimensional texture - * @requires_gl + * @requires_gl Only 2D and 3D textures are available in OpenGL + * ES. */ Texture1D = GL_TEXTURE_1D, @@ -71,28 +72,30 @@ template class Texture: public AbstractTexture { /** * Three-dimensional texture - * @requires_gles30 (no extension providing this functionality) + * @requires_gles30 %Extension @es_extension{OES,texture_3D} */ Texture3D = GL_TEXTURE_3D, /** * One-dimensional texture array (i.e. two dimensions in total) - * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_array} + * @requires_gl Only 2D and 3D textures are available in OpenGL + * ES. */ Texture1DArray = GL_TEXTURE_1D_ARRAY, /** * Two-dimensional texture array (i.e. three dimensions in total) * @requires_gl30 Extension @extension{EXT,texture_array} - * @requires_gles30 (no extension providing this functionality) + * @requires_gles30 Array textures are not available in OpenGL ES + * 2.0. */ Texture2DArray = GL_TEXTURE_2D_ARRAY, /** * Rectangle texture (i.e. two dimensions) - * @requires_gl * @requires_gl31 Extension @extension{ARB,texture_rectangle} + * @requires_gl Rectangle textures are not available in OpenGL ES. */ Rectangle = GL_TEXTURE_RECTANGLE }; @@ -220,7 +223,7 @@ template class Texture: public AbstractTexture { /** @brief One-dimensional texture -@requires_gl +@requires_gl Only 2D and 3D textures are available in OpenGL ES. */ typedef Texture<1> Texture1D; #endif @@ -231,7 +234,7 @@ typedef Texture<2> Texture2D; /** @brief Three-dimensional texture -@requires_gles30 (no extension providing this functionality) +@requires_gles30 %Extension @es_extension{OES,texture_3D} */ typedef Texture<3> Texture3D;