diff --git a/CMakeLists.txt b/CMakeLists.txt index 88253e669..014b64876 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 2.8.8) project(Magnum) +option(TARGET_GLES "Build for OpenGL ES 2 instead of desktop OpenGL" OFF) + option(BUILD_TESTS "Build unit tests (requires Qt4)." OFF) if(BUILD_TESTS) diff --git a/Doxyfile b/Doxyfile index 0354ae598..23f6dc968 100644 --- a/Doxyfile +++ b/Doxyfile @@ -198,6 +198,7 @@ ALIASES = \ "debugoperator{1}=@relates \1\n@brief Debug output operator" \ "collisionoperator{2}=@relates \1\n@brief Collision of %\1 and %\2\n@see \2::operator%(const \1&) const" \ "todoc=@xrefitem todoc \"Documentation todo\" \"Documentation-related todo list\"" \ + "requires_gl=@xrefitem requires-gl \"Requires desktop OpenGL\" \"Functionality requiring desktop OpenGL (not available on OpenGL ES 2)\" Not available on OpenGL ES 2." \ "requires_gl30=@xrefitem requires-gl30 \"Requires OpenGL 3.0\" \"Functionality requiring OpenGL 3.0\"" \ "requires_gl31=@xrefitem requires-gl31 \"Requires OpenGL 3.1\" \"Functionality requiring OpenGL 3.1\"" \ "requires_gl32=@xrefitem requires-gl32 \"Requires OpenGL 3.2\" \"Functionality requiring OpenGL 3.2\"" \ diff --git a/doc/building.dox b/doc/building.dox index 82eed47b1..a619c3384 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -14,7 +14,8 @@ Minimal set of tools and libraries required for building is: which are tested to support everything needed: **GCC** >= 4.6 and **Clang** >= 3.1. - **CMake** >= 2.8.8 (needed for `OBJECT` library target) -- **OpenGL** headers, on Linux most probably shipped with Mesa +- **OpenGL** headers, on Linux most probably shipped with Mesa or + **OpenGL ES 2** headers, if targetting OpenGL ES 2. - **GLEW** - OpenGL extension wrangler - **Corrade** - Plugin management and utility library. You can get it at http://github.com/mosra/corrade or at http://mosra.cz/blog/corrade.php. @@ -42,6 +43,9 @@ The library can be built and installed using these four commands: cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make make install +By default the engine is built for desktop OpenGL. If you want to target +OpenGL ES 2, pass `-DTARGET_GLES=True` to CMake. + If you want to build with another compiler (e.g. Clang), pass `-DCMAKE_CXX_COMPILER=clang++` to CMake. diff --git a/doc/mainpage.dox b/doc/mainpage.dox index b8356dd0f..460ce6399 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -25,8 +25,8 @@ Features: covered with unit tests. The engine is meant to be run on OpenGL 3 capable hardware, but most of the -functionality is working on OpenGL 2.1 hardware too. See also -@ref required-extensions. +functionality is working on OpenGL 2.1 hardware too. The engine can be built +also for OpenGL ES 2 with limited functionality. See also @ref required-extensions. @section download-build Downloading and building Magnum diff --git a/doc/required-extensions.dox b/doc/required-extensions.dox index 2eaa461f5..1b2daf898 100644 --- a/doc/required-extensions.dox +++ b/doc/required-extensions.dox @@ -1,15 +1,18 @@ /** @page required-extensions Functionality requiring specific OpenGL version or extensions -@brief Functions not available on OpenGL 2.1 hardware. +@brief List of functions not available on OpenGL 2.1 / OpenGL ES 2. The engine is meant to be run on OpenGL 3 capable hardware, but most of the functionality is working in OpenGL 2.1 hardware too (i.e. integrated Intel -GPUs), unless stated otherwise. Following are lists of functionality requiring -specific OpenGL version. In most cases it is also specified which extension is -required for given functionality, so if given hardware supports required -extension, it doesn't need to have required OpenGL version too (e.g. -`APPLE_vertex_array_object` is supported on Intel GPUs even if they are -capable of OpenGL 2.1 only). +GPUs), unless stated otherwise. OpenGL ES 2 is also supported, see +@ref building for guide how to build the engine for it. +Following are lists of functionality requiring specific OpenGL version. In +most cases it is also specified which extension is required for given +functionality, so if given hardware supports required extension, it doesn't +need to have required OpenGL version too (e.g. `APPLE_vertex_array_object` is +supported on Intel GPUs even if they are capable of OpenGL 2.1 only). + +- @subpage requires-gl - @subpage requires-gl30 - @subpage requires-gl31 - @subpage requires-gl32 @@ -19,6 +22,7 @@ capable of OpenGL 2.1 only). - @subpage requires-gl42 - @subpage requires-extension +@page requires-gl Functionality requiring desktop OpenGL (not available on OpenGL ES 2) @page requires-gl30 Functionality requiring OpenGL 3.0 @page requires-gl31 Functionality requiring OpenGL 3.1 @page requires-gl32 Functionality requiring OpenGL 3.2 diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index bed282f48..55accdb7b 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -43,8 +43,13 @@ # Dependencies find_package(Corrade REQUIRED) -find_package(OpenGL REQUIRED) -find_package(GLEW REQUIRED) + +if(NOT TARGET_GLES) + find_package(OpenGL REQUIRED) + find_package(GLEW REQUIRED) +else() + find_package(OpenGLES2 REQUIRED) +endif() # Magnum library find_library(MAGNUM_LIBRARY Magnum) diff --git a/src/AbstractImage.cpp b/src/AbstractImage.cpp index 186180e44..4194431c2 100644 --- a/src/AbstractImage.cpp +++ b/src/AbstractImage.cpp @@ -21,16 +21,25 @@ namespace Magnum { size_t AbstractImage::pixelSize(Components format, ComponentType type) { size_t size = 0; switch(type) { + #ifndef MAGNUM_TARGET_GLES case ComponentType::RGB332: case ComponentType::BGR233: return 1; + #endif case ComponentType::RGB565: + #ifndef MAGNUM_TARGET_GLES case ComponentType::BGR565: + #endif case ComponentType::RGBA4: + #ifndef MAGNUM_TARGET_GLES case ComponentType::ABGR4: + #endif case ComponentType::RGB5Alpha1: + #ifndef MAGNUM_TARGET_GLES case ComponentType::Alpha1BGR5: + #endif return 2; + #ifndef MAGNUM_TARGET_GLES case ComponentType::RGBA8: case ComponentType::ABGR8: case ComponentType::RGB10Alpha2: @@ -41,13 +50,16 @@ size_t AbstractImage::pixelSize(Components format, ComponentType type) { return 4; case ComponentType::Depth32FloatStencil8: return 8; + #endif case ComponentType::UnsignedByte: case ComponentType::Byte: size = 1; break; case ComponentType::UnsignedShort: case ComponentType::Short: + #ifndef MAGNUM_TARGET_GLES case ComponentType::HalfFloat: size = 2; break; + #endif case ComponentType::UnsignedInt: case ComponentType::Int: case ComponentType::Float: @@ -55,15 +67,21 @@ size_t AbstractImage::pixelSize(Components format, ComponentType type) { } switch(format) { + #ifndef MAGNUM_TARGET_GLES case Components::Red: return 1*size; case Components::RedGreen: return 2*size; + #endif case Components::RGB: + #ifndef MAGNUM_TARGET_GLES case Components::BGR: + #endif return 3*size; case Components::RGBA: + #ifndef MAGNUM_TARGET_GLES case Components::BGRA: + #endif return 4*size; default: return 0; diff --git a/src/AbstractImage.h b/src/AbstractImage.h index 5e7239e09..cdc437758 100644 --- a/src/AbstractImage.h +++ b/src/AbstractImage.h @@ -45,34 +45,64 @@ class MAGNUM_EXPORT AbstractImage { /** @brief Color components */ enum class Components: GLenum { - Red = GL_RED, /**< One-component (red channel) */ + #ifndef MAGNUM_TARGET_GLES + /** + * One-component (red channel) + * @requires_gl + */ + Red = GL_RED, - /** One-component (green channel). For framebuffer reading only. */ + /** + * One-component (green channel). For framebuffer reading only. + * @requires_gl + */ Green = GL_GREEN, - /** One-component (green channel). For framebuffer reading only. */ + /** + * One-component (green channel). For framebuffer reading only. + * @requires_gl + */ Blue = GL_BLUE, - /** Two-component (red and green channel). For texture data only. */ + /** + * Two-component (red and green channel). For texture data only. + * @requires_gl + */ RedGreen = GL_RG, + #endif RGB = GL_RGB, /**< Three-component RGB */ - BGR = GL_BGR, /**< Three-component BGR */ RGBA = GL_RGBA, /**< Four-component RGBA */ - BGRA = GL_BGRA, /**< Four-component BGRA */ + + #ifndef MAGNUM_TARGET_GLES + /** + * Three-component BGR + * @requires_gl + */ + BGR = GL_BGR, + + /** + * Four-component BGRA + * @requires_gl + */ + BGRA = GL_BGRA, + #endif /** Depth component. For framebuffer reading only. */ Depth = GL_DEPTH_COMPONENT, /** Stencil index. For framebuffer reading only. */ - StencilIndex = GL_STENCIL_INDEX, + StencilIndex = GL_STENCIL_INDEX + #ifndef MAGNUM_TARGET_GLES + , /** * Depth and stencil component. For framebuffer reading only. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,packed_depth_stencil} */ DepthStencil = GL_DEPTH_STENCIL + #endif }; /** @brief Data type */ @@ -84,26 +114,33 @@ class MAGNUM_EXPORT AbstractImage { UnsignedInt = GL_UNSIGNED_INT, /**< Each component unsigned int */ Int = GL_INT, /**< Each component int */ + #ifndef MAGNUM_TARGET_GLES /** * Each component half float (16bit). For framebuffer reading only. * + * @requires_gl * @requires_gl30 Extension @extension{NV,half_float} / @extension{ARB,half_float_pixel} */ HalfFloat = GL_HALF_FLOAT, + #endif Float = GL_FLOAT, /**< Each component float (32bit) */ + #ifndef MAGNUM_TARGET_GLES /** * Three-component RGB, unsigned normalized, red and green 3bit, * blue 2bit, 8bit total. + * @requires_gl */ RGB332 = GL_UNSIGNED_BYTE_3_3_2, /** * Three-component BGR, unsigned normalized, red and green 3bit, * blue 2bit, 8bit total. + * @requires_gl */ BGR233 = GL_UNSIGNED_BYTE_2_3_3_REV, + #endif /** * Three-component RGB, unsigned normalized, red and blue 5bit, @@ -111,11 +148,14 @@ class MAGNUM_EXPORT AbstractImage { */ RGB565 = GL_UNSIGNED_SHORT_5_6_5, + #ifndef MAGNUM_TARGET_GLES /** * Three-component BGR, unsigned normalized, red and blue 5bit, * green 6bit, 16bit total. + * @requires_gl */ BGR565 = GL_UNSIGNED_SHORT_5_6_5_REV, + #endif /** * Four-component RGBA, unsigned normalized, each component 4bit, @@ -123,11 +163,14 @@ class MAGNUM_EXPORT AbstractImage { */ RGBA4 = GL_UNSIGNED_SHORT_4_4_4_4, + #ifndef MAGNUM_TARGET_GLES /** * Four-component ABGR, unsigned normalized, each component 4bit, * 16bit total. + * @requires_gl */ ABGR4 = GL_UNSIGNED_SHORT_4_4_4_4_REV, + #endif /** * Four-component RGBA, unsigned normalized, each RGB component @@ -135,40 +178,46 @@ class MAGNUM_EXPORT AbstractImage { */ RGB5Alpha1 = GL_UNSIGNED_SHORT_5_5_5_1, + #ifndef MAGNUM_TARGET_GLES /** * Four-component ABGR, unsigned normalized, each RGB component * 5bit, alpha 1bit, 16bit total. + * @requires_gl */ Alpha1BGR5 = GL_UNSIGNED_SHORT_1_5_5_5_REV, /** * Four-component RGBA, unsigned normalized, each component 8bit, * 32bit total. + * @requires_gl */ RGBA8 = GL_UNSIGNED_INT_8_8_8_8, /** * Four-component ABGR, unsigned normalized, each component 8bit, * 32bit total. + * @requires_gl */ ABGR8 = GL_UNSIGNED_INT_8_8_8_8_REV, /** * Four-component RGBA, unsigned normalized, each RGB component * 10bit, alpha 2bit, 32bit total. + * @requires_gl */ RGB10Alpha2 = GL_UNSIGNED_INT_10_10_10_2, /** * Four-component ABGR, unsigned normalized, each RGB component * 10bit, alpha 2bit, 32bit total. + * @requires_gl */ Alpha2RGB10 = GL_UNSIGNED_INT_2_10_10_10_REV, /** * Three-component BGR, float, red and green 11bit, blue 10bit, * 32bit total. For framebuffer reading only. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,packed_float} */ B10GR11Float = GL_UNSIGNED_INT_10F_11F_11F_REV, @@ -177,7 +226,7 @@ class MAGNUM_EXPORT AbstractImage { * Three-component BGR, unsigned integers with exponent, each * component 9bit, exponent 5bit, 32bit total. For framebuffer * reading only. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_shared_exponent} */ Exponent5RGB9 = GL_UNSIGNED_INT_5_9_9_9_REV, @@ -185,7 +234,7 @@ class MAGNUM_EXPORT AbstractImage { /** * 24bit depth and 8bit stencil component, 32bit total. For * framebuffer reading only. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,packed_depth_stencil} */ Depth24Stencil8 = GL_UNSIGNED_INT_24_8, @@ -193,10 +242,11 @@ class MAGNUM_EXPORT AbstractImage { /** * 32bit float depth component and 8bit stencil component, 64bit * total. For framebuffer reading only. - * + * @requires_gl * @requires_gl30 Extension @extension{ARB,depth_buffer_float} */ Depth32FloatStencil8 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV + #endif }; /*@}*/ diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index d53ad29b7..e8fd69658 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -44,11 +44,13 @@ void AbstractShaderProgram::bindAttributeLocation(GLuint location, const string& glBindAttribLocation(program, location, name.c_str()); } +#ifndef MAGNUM_TARGET_GLES void AbstractShaderProgram::bindFragmentDataLocation(GLuint location, const std::string& name) { CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", ) glBindFragDataLocation(program, location, name.c_str()); } +#endif void AbstractShaderProgram::link() { /* Already compiled or failed, exit */ diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index 4ce901791..5027984ca 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -82,6 +82,8 @@ layout(location = 0) in vec4 vertex; layout(location = 1) in vec3 normal; layout(location = 2) in vec2 textureCoords; @endcode +@requires_gl (for explicit attribute location instead of using + bindAttributeLocation()) @requires_gl33 Extension @extension{ARB,explicit_attrib_location} (for explicit attribute location instead of using bindAttributeLocation()) @@ -105,6 +107,8 @@ code, e.g.: layout(binding = 0) uniform sampler2D diffuseTexture; layout(binding = 1) uniform sampler2D specularTexture; @endcode +@requires_gl (for explicit texture layer binding instead of using + setUniform(GLint, GLint)) @requires_gl42 Extension @extension{ARB,shading_language_420pack} (for explicit texture layer binding instead of using setUniform(GLint, GLint)) @@ -180,10 +184,12 @@ class MAGNUM_EXPORT AbstractShaderProgram { bool use(); protected: + #ifndef MAGNUM_TARGET_GLES /** * @brief Allow retrieving program binary * * Disabled by default. + * @requires_gl * @requires_gl41 Extension @extension{ARB,get_program_binary} * @note This function should be called after attachShader() calls and * before link(). @@ -196,6 +202,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @brief Allow the program to be bound to individual pipeline stages * * Disabled by default. + * @requires_gl * @requires_gl41 Extension @extension{ARB,separate_shader_objects} * @note This function should be called after attachShader() calls and * before link(). @@ -203,6 +210,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { inline void setSeparable(bool enabled) { glProgramParameteri(program, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE); } + #endif /** * @brief Load shader @@ -235,6 +243,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { */ void bindAttributeLocation(GLuint location, const std::string& name); + #ifndef MAGNUM_TARGET_GLES /** * @brief Bind fragment data to given location * @param location Location @@ -246,10 +255,11 @@ class MAGNUM_EXPORT AbstractShaderProgram { * explicitly in the shader instead of using this function. See * @ref AbstractShaderProgramAttributeLocation "class documentation" * for more information. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,gpu_shader4} */ void bindFragmentDataLocation(GLuint location, const std::string& name); + #endif /** * @brief Link the shader @@ -313,9 +323,10 @@ class MAGNUM_EXPORT AbstractShaderProgram { glUniform4iv(location, 1, value.data()); } + #ifndef MAGNUM_TARGET_GLES /** * @copydoc setUniform(GLint, GLint) - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,gpu_shader4} */ inline void setUniform(GLint location, GLuint value) { @@ -324,7 +335,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { /** * @copydoc setUniform(GLint, GLint) - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,gpu_shader4} */ inline void setUniform(GLint location, const Math::Vector2& value) { @@ -333,7 +344,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { /** * @copydoc setUniform(GLint, GLint) - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,gpu_shader4} */ inline void setUniform(GLint location, const Math::Vector3& value) { @@ -342,12 +353,13 @@ class MAGNUM_EXPORT AbstractShaderProgram { /** * @copydoc setUniform(GLint, GLuint) - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,gpu_shader4} */ inline void setUniform(GLint location, const Math::Vector4& value) { glUniform4uiv(location, 1, value.data()); } + #endif /** @copydoc setUniform(GLint, GLint) */ inline void setUniform(GLint location, const Matrix3& value) { diff --git a/src/AbstractTexture.cpp b/src/AbstractTexture.cpp index a0ba88f96..625359b7f 100644 --- a/src/AbstractTexture.cpp +++ b/src/AbstractTexture.cpp @@ -40,14 +40,18 @@ GLint AbstractTexture::maxSupportedLayerCount() { return value; } +#ifndef MAGNUM_TARGET_GLES GLfloat AbstractTexture::maxSupportedAnisotropy() { GLfloat value; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &value); return value; } +#endif void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) { + #ifndef MAGNUM_TARGET_GLES CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::BaseLevel, "AbstractTexture: rectangle textures cannot have mipmaps", ) + #endif bind(); glTexParameteri(_target, GL_TEXTURE_MIN_FILTER, @@ -55,12 +59,15 @@ void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) { } void AbstractTexture::generateMipmap() { + #ifndef MAGNUM_TARGET_GLES CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", ) + #endif bind(); glGenerateMipmap(_target); } +#ifndef MAGNUM_TARGET_GLES AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components components, AbstractTexture::ComponentType type) { #define internalFormatSwitch(c) switch(type) { \ case ComponentType::UnsignedByte: \ @@ -98,10 +105,13 @@ AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components comp internalFormatSwitch(RGBA) #undef internalFormatSwitch } +#endif #ifndef DOXYGEN_GENERATING_OUTPUT void AbstractTexture::DataHelper<2>::setWrapping(GLenum target, const Math::Vector<2, Wrapping>& wrapping) { + #ifndef MAGNUM_TARGET_GLES CORRADE_ASSERT(target != GL_TEXTURE_RECTANGLE || ((wrapping[0] == Wrapping::ClampToEdge || wrapping[0] == Wrapping::ClampToBorder) && (wrapping[0] == Wrapping::ClampToEdge || wrapping[1] == Wrapping::ClampToEdge)), "AbstractTexture: rectangle texture wrapping must either clamp to border or to edge", ) + #endif glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); @@ -110,7 +120,9 @@ void AbstractTexture::DataHelper<2>::setWrapping(GLenum target, const Math::Vect void AbstractTexture::DataHelper<3>::setWrapping(GLenum target, const Math::Vector<3, Wrapping>& wrapping) { glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); + #ifndef MAGNUM_TARGET_GLES glTexParameteri(target, GL_TEXTURE_WRAP_R, static_cast(wrapping[2])); + #endif } #endif diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index 506c97e38..252160a2b 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -97,18 +97,26 @@ class MAGNUM_EXPORT AbstractTexture { * Clamp to edge. Coordinates out of the range will be clamped to * first / last column / row in given direction. */ - ClampToEdge = GL_CLAMP_TO_EDGE, + ClampToEdge = GL_CLAMP_TO_EDGE + #ifndef MAGNUM_TARGET_GLES + , /** * Clamp to border color. Coordinates out of range will be clamped * to border color (set with setBorderColor()). + * @requires_gl */ ClampToBorder = GL_CLAMP_TO_BORDER + #endif }; /** @{ @name Internal texture formats */ - /** @brief Color components */ + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Color components + * @requires_gl + */ enum class Components { /** * Red component only. Green and blue are set to `0`, alpha is set @@ -131,6 +139,7 @@ class MAGNUM_EXPORT AbstractTexture { * * `NormalizedUnsignedByte` and `NormalizedUnsignedShort` are the * main ones for general usage. + * @requires_gl */ enum class ComponentType { /** @@ -217,6 +226,7 @@ class MAGNUM_EXPORT AbstractTexture { */ NormalizedShort }; + #endif /** * @brief Internal format @@ -225,10 +235,11 @@ class MAGNUM_EXPORT AbstractTexture { * normalization see enums Components and ComponentType. */ enum class Format: GLenum { + #ifndef MAGNUM_TARGET_GLES /** * One-component (red channel), unsigned normalized, probably * 8bit. - * + * @requires_gl * @requires_gl30 (no extension providing this functionality) */ Red = GL_RED, @@ -236,10 +247,11 @@ class MAGNUM_EXPORT AbstractTexture { /** * Two-component (red and green channel), unsigned normalized, * each component probably 8bit, 16bit total. - * + * @requires_gl * @requires_gl30 (no extension providing this functionality) */ RedGreen = GL_RG, + #endif /** * Three-component RGB, unsigned normalized, each component @@ -259,43 +271,50 @@ class MAGNUM_EXPORT AbstractTexture { */ RGBA = GL_RGBA, + #ifndef MAGNUM_TARGET_GLES /** * Three-component BGR, unsigned normalized, each component * probably 8bit, 24bit total. + * @requires_gl */ BGR = GL_BGR, /** * Four-component BGRA, unsigned normalized, each component * probably 8bit, 24bit total. + * @requires_gl */ BGRA = GL_BGRA, /** * Four-component sRGBA, unsigned normalized, each component * 8bit, 32bit total. + * @requires_gl */ SRGBA8 = GL_SRGB8_ALPHA8, /** * Three-component sRGB, unsigned normalized, each component * 8bit, 24bit total. + * @requires_gl */ SRGB8 = GL_SRGB8, /** * Four-component RGBA, unsigned normalized, each RGB component * 10bit, alpha 2bit, 32bit total. + * @requires_gl */ RGB10Alpha2 = GL_RGB10_A2, /** * Four-component RGBA, unsigned non-normalized, each RGB * component 10bit, alpha channel 2bit, 32bit total. - * + * @requires_gl * @requires_gl33 Extension @extension{ARB,texture_rgb10_a2ui} */ RGB10Alpha2Unsigned = GL_RGB10_A2UI, + #endif /** * Four-component RGBA, unsigned normalized, each RGB component @@ -309,13 +328,15 @@ class MAGNUM_EXPORT AbstractTexture { */ RGBA4 = GL_RGBA4, + #ifndef MAGNUM_TARGET_GLES /** * Three-component RGB, float, red and green 11bit, blue 10bit, * 32bit total. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,packed_float} */ RG11B10Float = GL_R11F_G11F_B10F, + #endif #if defined(GL_RGB565) || defined(DOXYGEN_GENERATING_OUTPUT) /** @@ -325,79 +346,93 @@ class MAGNUM_EXPORT AbstractTexture { RGB565 = GL_RGB565, #endif + #ifndef MAGNUM_TARGET_GLES /** * Three-component RGB, unsigned with exponent, each component * 9bit, exponent 5bit, 32bit total. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_shared_exponent} */ RGB9Exponent5 = GL_RGB9_E5, - /** Compressed red channel, unsigned normalized. */ + /** + * Compressed red channel, unsigned normalized. + * @requires_gl + */ CompressedRed = GL_COMPRESSED_RED, - /** Compressed red and green channel, unsigned normalized. */ + /** + * Compressed red and green channel, unsigned normalized. + * @requires_gl + */ CompressedRedGreen = GL_COMPRESSED_RG, - /** Compressed RGB, unsigned normalized. */ + /** + * Compressed RGB, unsigned normalized. + * @requires_gl + */ CompressedRGB = GL_COMPRESSED_RGB, - /** Compressed RGBA, unsigned normalized. */ + /** + * Compressed RGBA, unsigned normalized. + * @requires_gl + */ CompressedRGBA = GL_COMPRESSED_RGBA, /** * RTGC compressed red channel, unsigned normalized. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} */ CompressedRtgcRed = GL_COMPRESSED_RED_RGTC1, /** * RTGC compressed red channel, signed normalized. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} */ CompressedRtgcSignedRed = GL_COMPRESSED_SIGNED_RED_RGTC1, /** * RTGC compressed red and green channel, unsigned normalized. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} */ CompressedRtgcRedGreen = GL_COMPRESSED_RG_RGTC2, /** * RTGC compressed red and green channel, signed normalized. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} */ CompressedRtgcSignedRedGreen = GL_COMPRESSED_SIGNED_RG_RGTC2, + #endif #if defined(GL_COMPRESSED_RGBA_BPTC_UNORM) || defined(DOXYGEN_GENERATING_OUTPUT) /** * BPTC compressed RGBA, unsigned normalized. - * + * @requires_gl * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} */ CompressedBptcRGBA = GL_COMPRESSED_RGBA_BPTC_UNORM, /** * BPTC compressed sRGBA, unsigned normalized. - * + * @requires_gl * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} */ CompressedBptcSRGBA = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, /** * BPTC compressed RGB, signed float. - * + * @requires_gl * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} */ CompressedBptcRGBSignedFloat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, /** * BPTC compressed RGB, unsigned float. - * + * @requires_gl * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} */ CompressedBptcRGBUnsignedFloat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, @@ -406,35 +441,47 @@ class MAGNUM_EXPORT AbstractTexture { /** Depth component. */ Depth = GL_DEPTH_COMPONENT, - /** Depth and stencil component. */ + #ifndef MAGNUM_TARGET_GLES + /** + * Depth and stencil component. + * @requires_gl + */ DepthStencil = GL_DEPTH_STENCIL, + #endif /** 16bit depth component. */ - Depth16 = GL_DEPTH_COMPONENT16, + Depth16 = GL_DEPTH_COMPONENT16 - /** 24bit depth component. */ + #ifndef MAGNUM_TARGET_GLES + , + + /** + * 24bit depth component. + * @requires_gl + */ Depth24 = GL_DEPTH_COMPONENT24, /** * 32bit float depth component. - * + * @requires_gl * @requires_gl30 Extension @extension{ARB,depth_buffer_float} */ Depth32Float = GL_DEPTH_COMPONENT32F, /** * 24bit depth and 8bit stencil component. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,packed_depth_stencil} */ Depth24Stencil8 = GL_DEPTH24_STENCIL8, /** * 32bit float depth component and 8bit stencil component. - * + * @requires_gl * @requires_gl30 Extension @extension{ARB,depth_buffer_float} */ Depth32FloatStencil8 = GL_DEPTH32F_STENCIL8 + #endif }; /** @@ -455,8 +502,14 @@ class MAGNUM_EXPORT AbstractTexture { */ class MAGNUM_EXPORT InternalFormat { public: - /** @brief Constructor from component count and data type per component */ + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Constructor from component count and data type per component + * + * @requires_gl + */ InternalFormat(Components components, ComponentType type); + #endif /** @brief Constructor from named internal format */ inline constexpr InternalFormat(Format format): internalFormat(static_cast(format)) {} @@ -478,6 +531,7 @@ class MAGNUM_EXPORT AbstractTexture { */ static GLint maxSupportedLayerCount(); + #ifndef MAGNUM_TARGET_GLES /** * @brief Max supported anisotropy * @@ -485,6 +539,7 @@ class MAGNUM_EXPORT AbstractTexture { * @requires_extension @extension{EXT,texture_filter_anisotropic} */ static GLfloat maxSupportedAnisotropy(); + #endif /** * @brief Constructor @@ -546,11 +601,13 @@ class MAGNUM_EXPORT AbstractTexture { glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, static_cast(filter)); } + #ifndef MAGNUM_TARGET_GLES /** * @brief Set border color * * Border color when @ref AbstractTexture::Wrapping "wrapping" is set * to `ClampToBorder`. + * @requires_gl */ inline void setBorderColor(const Vector4& color) { bind(); @@ -569,6 +626,7 @@ class MAGNUM_EXPORT AbstractTexture { bind(); glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); } + #endif /** * @brief Generate mipmap @@ -602,8 +660,11 @@ class MAGNUM_EXPORT AbstractTexture { inline AbstractTexture::~AbstractTexture() { glDeleteTextures(1, &texture); } +#ifndef MAGNUM_TARGET_GLES /** @relates AbstractTexture @brief Convertor of component count and data type to InternalFormat + +@requires_gl */ inline AbstractTexture::InternalFormat operator|(AbstractTexture::Components components, AbstractTexture::ComponentType type) { return AbstractTexture::InternalFormat(components, type); @@ -615,8 +676,10 @@ inline AbstractTexture::InternalFormat operator|(AbstractTexture::Components com inline AbstractTexture::InternalFormat operator|(AbstractTexture::ComponentType type, AbstractTexture::Components components) { return AbstractTexture::InternalFormat(components, type); } +#endif #ifndef DOXYGEN_GENERATING_OUTPUT +#ifndef MAGNUM_TARGET_GLES template<> struct AbstractTexture::DataHelper<1> { enum class Target: GLenum { Texture1D = GL_TEXTURE_1D @@ -636,11 +699,15 @@ template<> struct AbstractTexture::DataHelper<1> { glTexSubImage1D(target, mipLevel, offset[0], image->dimensions()[0], static_cast(image->components()), static_cast(image->type()), image->data()); } }; +#endif template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { enum class Target: GLenum { - Texture2D = GL_TEXTURE_2D, + Texture2D = GL_TEXTURE_2D + #ifndef MAGNUM_TARGET_GLES + , Texture1DArray = GL_TEXTURE_1D_ARRAY, Rectangle = GL_TEXTURE_RECTANGLE + #endif }; inline constexpr static Target target() { return Target::Texture2D; } @@ -661,14 +728,19 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { }; template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { enum class Target: GLenum { + #ifndef MAGNUM_TARGET_GLES Texture3D = GL_TEXTURE_3D, Texture2DArray = GL_TEXTURE_2D_ARRAY + #endif }; + #ifndef MAGNUM_TARGET_GLES inline constexpr static Target target() { return Target::Texture3D; } + #endif static void setWrapping(GLenum target, const Math::Vector<3, Wrapping>& wrapping); + #ifndef MAGNUM_TARGET_GLES template inline static void set(GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image, const Math::Vector<3, GLsizei>& = (Math::Vector())) { glTexImage3D(target, mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], 0, static_cast(image->components()), static_cast(image->type()), image->data()); } @@ -680,6 +752,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { template inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector<3, GLint>& offset, Image* image, const Math::Vector<2, GLsizei>& = (Math::Vector())) { glTexSubImage3D(target, mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], 1, static_cast(image->components()), static_cast(image->type()), image->data()); } + #endif }; #endif diff --git a/src/Buffer.h b/src/Buffer.h index 43e505278..940dcaae5 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -41,24 +41,32 @@ class Buffer { /** Used for storing vertex attributes. */ Array = GL_ARRAY_BUFFER, + #ifndef MAGNUM_TARGET_GLES /** * Source for copies. - * + * @requires_gl * @requires_gl31 Extension @extension{ARB,copy_buffer} */ CopyRead = GL_COPY_READ_BUFFER, /** * Target for copies. - * + * @requires_gl * @requires_gl31 Extension @extension{ARB,copy_buffer} */ CopyWrite = GL_COPY_WRITE_BUFFER, + #endif /** Used for storing vertex indices. */ - ElementArray = GL_ELEMENT_ARRAY_BUFFER, + ElementArray = GL_ELEMENT_ARRAY_BUFFER + + #ifndef MAGNUM_TARGET_GLES + , - /** Source for texture update operations. */ + /** + * Source for texture update operations. + * @requires_gl + */ PixelUnpack = GL_PIXEL_UNPACK_BUFFER, /** Target for pixel pack operations. */ @@ -68,30 +76,32 @@ class Buffer { * Source for texel fetches. * * @see BufferedTexture + * @requires_gl * @requires_gl31 Extension @extension{ARB,texture_buffer_object} */ Texture = GL_TEXTURE_BUFFER, /** * Target for transform feedback. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,transform_feedback} */ TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER, /** * Used for storing uniforms. - * + * @requires_gl * @requires_gl31 Extension @extension{ARB,uniform_buffer_object} */ Uniform = GL_UNIFORM_BUFFER, /** * Used for supplying arguments for instanced drawing. - * + * @requires_gl * @requires_gl40 Extension @extension{ARB,draw_indirect} */ DrawIndirect = GL_DRAW_INDIRECT_BUFFER + #endif }; /** @brief Buffer usage */ @@ -101,52 +111,66 @@ class Buffer { */ StreamDraw = GL_STREAM_DRAW, + #ifndef MAGNUM_TARGET_GLES /** * Set once as output from an OpenGL command and used infequently * for drawing. + * @requires_gl */ StreamRead = GL_STREAM_READ, /** * Set once as output from an OpenGL command and used infrequently * for drawing or copying to other buffers. + * @requires_gl */ StreamCopy = GL_STREAM_COPY, + #endif /** * Set once by the application and used frequently for drawing. */ StaticDraw = GL_STATIC_DRAW, + #ifndef MAGNUM_TARGET_GLES /** * Set once as output from an OpenGL command and queried many * times by the application. + * @requires_gl */ StaticRead = GL_STATIC_READ, /** * Set once as output from an OpenGL command and used frequently * for drawing or copying to other buffers. + * @requires_gl */ StaticCopy = GL_STATIC_COPY, + #endif /** * Updated frequently by the application and used frequently * for drawing or copying to other images. */ - DynamicDraw = GL_DYNAMIC_DRAW, + DynamicDraw = GL_DYNAMIC_DRAW + + #ifndef MAGNUM_TARGET_GLES + , /** * Updated frequently as output from OpenGL command and queried * many times from the application. + * @requires_gl */ DynamicRead = GL_DYNAMIC_READ, /** * Updated frequently as output from OpenGL command and used * frequently for drawing or copying to other images. + * @requires_gl */ DynamicCopy = GL_DYNAMIC_COPY + #endif }; /** diff --git a/src/BufferedImage.h b/src/BufferedImage.h index d7691f077..74cd8b408 100644 --- a/src/BufferedImage.h +++ b/src/BufferedImage.h @@ -25,6 +25,7 @@ namespace Magnum { +#ifndef MAGNUM_TARGET_GLES /** @addtogroup textures * @{ */ @@ -34,6 +35,7 @@ namespace Magnum { Class for storing image data in GPU memory. Can be replaced with Image, which stores image data in client memory, or for example with Trade::ImageData. +@requires_gl */ template class BufferedImage: public AbstractImage { public: @@ -115,6 +117,7 @@ typedef BufferedImage<2> BufferedImage2D; typedef BufferedImage<3> BufferedImage3D; /*@}*/ +#endif } diff --git a/src/BufferedTexture.cpp b/src/BufferedTexture.cpp index edd88e000..ffd5a6d20 100644 --- a/src/BufferedTexture.cpp +++ b/src/BufferedTexture.cpp @@ -17,6 +17,7 @@ namespace Magnum { +#ifndef MAGNUM_TARGET_GLES BufferedTexture::InternalFormat::InternalFormat(Components components, ComponentType type) { #define internalFormatSwitch(c) switch(type) { \ case ComponentType::UnsignedByte: \ @@ -48,5 +49,6 @@ BufferedTexture::InternalFormat::InternalFormat(Components components, Component internalFormatSwitch(RGBA) #undef internalFormatSwitch } +#endif } diff --git a/src/BufferedTexture.h b/src/BufferedTexture.h index 5d69f7b8d..591ef3c11 100644 --- a/src/BufferedTexture.h +++ b/src/BufferedTexture.h @@ -24,6 +24,7 @@ namespace Magnum { +#ifndef MAGNUM_TARGET_GLES /** @ingroup textures @brief Buffered texture @@ -36,6 +37,7 @@ using data setting functions in Buffer itself. When using buffered texture in the shader, use `samplerBuffer` and fetch the data using integer coordinates in `texelFetch()`. +@requires_gl @requires_gl31 Extension @extension{ARB,texture_buffer_object} */ class BufferedTexture { @@ -161,6 +163,7 @@ inline BufferedTexture::InternalFormat operator|(BufferedTexture::Components com inline BufferedTexture::InternalFormat operator|(BufferedTexture::ComponentType type, BufferedTexture::Components components) { return BufferedTexture::InternalFormat(components, type); } +#endif } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0033d1d2e..ae9300666 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,13 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -std=c++0x -fvisibility=hidden") -include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CORRADE_INCLUDE_DIR}) +if(TARGET_GLES) + set(MAGNUM_TARGET_GLES 1) +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configureMagnum.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configureMagnum.h) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CORRADE_INCLUDE_DIR}) # Files shared between main library and unit test library set(Magnum_SRCS @@ -45,9 +52,17 @@ add_library(Magnum SHARED $ ${Magnum_GracefulAssert_SRCS} ) -target_link_libraries(Magnum ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY} ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY}) +target_link_libraries(Magnum ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY}) +if(NOT TARGET_GLES) + target_link_libraries(Magnum ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY}) +else() + target_link_libraries(Magnum ${OPENGLES2_LIBRARY}) +endif() install(TARGETS Magnum DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) +# Install also configure file +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/configureMagnum.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}) + add_subdirectory(Contexts) add_subdirectory(Math) add_subdirectory(MeshTools) @@ -64,7 +79,12 @@ if(BUILD_TESTS) ${Magnum_GracefulAssert_SRCS} ) set_target_properties(MagnumTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) - target_link_libraries(MagnumTestLib ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY} ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY}) + target_link_libraries(MagnumTestLib ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY}) + if(NOT TARGET_GLES) + target_link_libraries(MagnumTestLib ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY}) + else() + target_link_libraries(MagnumTestLib ${OPENGLES2_LIBRARY}) + endif() include_directories(${QT_INCLUDE_DIR}) add_subdirectory(Test) diff --git a/src/Camera.h b/src/Camera.h index b5c352d9f..4bdcbf929 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -42,12 +42,14 @@ class MAGNUM_EXPORT Camera: public Object { enum class Feature: GLenum { AlphaBlending = GL_BLEND, /**< Alpha blending */ + #ifndef MAGNUM_TARGET_GLES /** * Depth clamping. If enabled, ignores near and far clipping plane. - * + * @requires_gl * @requires_gl32 Extension @extension{ARB,depth_clamp} */ DepthClamp = GL_DEPTH_CLAMP, + #endif DepthTest = GL_DEPTH_TEST, /**< Depth test */ StencilTest = GL_STENCIL_TEST, /**< Stencil test */ @@ -78,12 +80,15 @@ class MAGNUM_EXPORT Camera: public Object { glClearColor(color.r(), color.g(), color.b(), color.a()); } + #ifndef MAGNUM_TARGET_GLES /** * @brief Set clear depth * * Initial value is `1.0`. + * @requires_gl See setClearDepth(GLfloat), which is supported in OpenGL ES. */ inline static void setClearDepth(GLdouble depth) { glClearDepth(depth); } + #endif /** * @overload diff --git a/src/Contexts/CMakeLists.txt b/src/Contexts/CMakeLists.txt index 155eda326..a72c3ef83 100644 --- a/src/Contexts/CMakeLists.txt +++ b/src/Contexts/CMakeLists.txt @@ -1,13 +1,15 @@ install(FILES AbstractContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) # GLUT context -find_package(GLUT) -if(GLUT_FOUND) - add_library(MagnumGlutContext STATIC GlutContext.cpp) - install(FILES GlutContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) - install(TARGETS MagnumGlutContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) -else() - message(WARNING "GLUT library was not found. GLUT context library will not be generated.") +if(NOT TARGET_GLES) + find_package(GLUT) + if(GLUT_FOUND) + add_library(MagnumGlutContext STATIC GlutContext.cpp) + install(FILES GlutContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + install(TARGETS MagnumGlutContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) + else() + message(WARNING "GLUT library was not found. GLUT context library will not be generated.") + endif() endif() # SDL2 context diff --git a/src/Contexts/Sdl2Context.cpp b/src/Contexts/Sdl2Context.cpp index b772c609c..3959db0ee 100644 --- a/src/Contexts/Sdl2Context.cpp +++ b/src/Contexts/Sdl2Context.cpp @@ -40,6 +40,7 @@ Sdl2Context::Sdl2Context(int argc, char** argv, const std::string& name, const M context = SDL_GL_CreateContext(window); + #ifndef MAGNUM_TARGET_GLES /* This must be enabled, otherwise (on my NVidia) it crashes when creating VAO. WTF. */ glewExperimental = true; @@ -50,6 +51,7 @@ Sdl2Context::Sdl2Context(int argc, char** argv, const std::string& name, const M Error() << "Sdl2Context: cannot initialize GLEW:" << glewGetErrorString(err); exit(1); } + #endif /* Push resize event, so viewportEvent() is called at startup */ SDL_Event* sizeEvent = new SDL_Event; diff --git a/src/CubeMapTexture.h b/src/CubeMapTexture.h index 1ca43134a..7a8edbdfa 100644 --- a/src/CubeMapTexture.h +++ b/src/CubeMapTexture.h @@ -59,14 +59,17 @@ class CubeMapTexture: public AbstractTexture { NegativeZ = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z /**< -Z cube side */ }; + #ifndef MAGNUM_TARGET_GLES /** * @brief Enable/disable seamless cube map textures * + * @requires_gl * @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); } + #endif /** * @brief Constructor diff --git a/src/Framebuffer.cpp b/src/Framebuffer.cpp index 36da9af2c..e6117caec 100644 --- a/src/Framebuffer.cpp +++ b/src/Framebuffer.cpp @@ -17,6 +17,7 @@ namespace Magnum { +#ifndef MAGNUM_TARGET_GLES void Framebuffer::mapDefaultForDraw(std::initializer_list attachments) { GLenum* _attachments = new GLenum[attachments.size()]; for(auto it = attachments.begin(); it != attachments.end(); ++it) @@ -36,6 +37,7 @@ void Framebuffer::mapForDraw(std::initializer_list colorAttachments) { glDrawBuffers(colorAttachments.size(), attachments); delete[] attachments; } +#endif void Framebuffer::read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image) { char* data = new char[AbstractImage::pixelSize(components, type)*dimensions.product()]; @@ -43,6 +45,7 @@ void Framebuffer::read(const Math::Vector2& offset, const Math::Vector2setData(dimensions, components, type, data); } +#ifndef MAGNUM_TARGET_GLES void Framebuffer::read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage) { /* If the buffer doesn't have sufficient size, resize it */ /** @todo Explicitly reset also when buffer usage changes */ @@ -52,5 +55,6 @@ void Framebuffer::read(const Math::Vector2& offset, const Math::Vector2buffer()->bind(Buffer::Target::PixelPack); glReadPixels(offset.x(), offset.y(), dimensions.x(), dimensions.y(), static_cast(components), static_cast(type), nullptr); } +#endif } diff --git a/src/Framebuffer.h b/src/Framebuffer.h index af4eb14c3..4ad6fa4cb 100644 --- a/src/Framebuffer.h +++ b/src/Framebuffer.h @@ -44,26 +44,31 @@ class MAGNUM_EXPORT Framebuffer { * @see bind(), bindDefault() */ enum class Target: GLenum { + #ifndef MAGNUM_TARGET_GLES /** * For reading only. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_blit} */ Read = GL_READ_FRAMEBUFFER, /** * For drawing only. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_blit} */ Draw = GL_DRAW_FRAMEBUFFER, + #endif + ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */ }; + #ifndef MAGNUM_TARGET_GLES /** * @brief Draw attachment for default framebuffer * * @see mapDefaultForDraw() + * @requires_gl */ enum class DefaultDrawAttachment: GLenum { None = GL_NONE, /**< Don't use the output. */ @@ -77,6 +82,7 @@ class MAGNUM_EXPORT Framebuffer { * @brief Read attachment for default framebuffer * * @see mapDefaultForRead() + * @requires_gl */ enum class DefaultReadAttachment: GLenum { FrontLeft = GL_FRONT_LEFT, /**< Read from front left framebuffer. */ @@ -89,6 +95,7 @@ class MAGNUM_EXPORT Framebuffer { Back = GL_BACK, /**< Read from back framebuffers. */ FrontAndBack = GL_FRONT_AND_BACK /**< Read from front and back framebuffers. */ }; + #endif /** * @brief Attachment for depth/stencil part of fragment shader output @@ -101,8 +108,16 @@ class MAGNUM_EXPORT Framebuffer { */ enum class DepthStencilAttachment: GLenum { Depth = GL_DEPTH_ATTACHMENT, /**< Depth output only. */ - Stencil = GL_STENCIL_ATTACHMENT, /**< Stencil output only. */ - DepthStencil = GL_DEPTH_STENCIL_ATTACHMENT /**< Both depth and stencil output. */ + + Stencil = GL_STENCIL_ATTACHMENT /**< Stencil output only. */ + + #ifndef MAGNUM_TARGET_GLES + , + /** + * Both depth and stencil output. + */ + DepthStencil = GL_DEPTH_STENCIL_ATTACHMENT + #endif }; /** @@ -139,6 +154,7 @@ class MAGNUM_EXPORT Framebuffer { glBindFramebuffer(static_cast(target), 0); } + #ifndef MAGNUM_TARGET_GLES /** * @brief Map given attachments of default framebuffer for drawing * @param attachments Default attachments. If any value is @@ -150,6 +166,7 @@ class MAGNUM_EXPORT Framebuffer { * should have either renderbuffer or texture attached for writing to * work properly. * @see mapForDraw(), mapDefaultForRead() + * @requires_gl */ static void mapDefaultForDraw(std::initializer_list attachments); @@ -160,12 +177,15 @@ class MAGNUM_EXPORT Framebuffer { * Each used attachment should have either renderbuffer or texture * attached to work properly. * @see mapForRead(), mapDefaultForDraw() + * @requires_gl */ inline static void mapDefaultForRead(DefaultReadAttachment attachment) { bindDefault(Target::Read); glReadBuffer(static_cast(attachment)); } + #endif + #ifndef MAGNUM_TARGET_GLES /** * @brief Copy block of pixels from read to draw framebuffer * @param bottomLeft Bottom left coordinates of source rectangle @@ -181,7 +201,7 @@ class MAGNUM_EXPORT Framebuffer { * mapDefaultForDraw() for binding particular framebuffer for reading * and drawing. If multiple attachments are specified in mapForDraw() * / mapDefaultForDraw(), the data are written to each of them. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_blit} */ inline static void blit(const Math::Vector2& bottomLeft, const Math::Vector2& topRight, const Math::Vector2& destinationBottomLeft, const Math::Vector2& destinationTopRight, BlitMask blitMask, AbstractTexture::Filter filter) { @@ -201,12 +221,13 @@ class MAGNUM_EXPORT Framebuffer { * no interpolation is needed and thus * AbstractTexture::Filter::NearestNeighbor filtering is used by * default. - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_blit} */ inline static void blit(const Math::Vector2& bottomLeft, const Math::Vector2& topRight, BlitMask blitMask) { glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast(blitMask), static_cast(AbstractTexture::Filter::NearestNeighbor)); } + #endif /** * @brief Read block of pixels from framebuffer to image @@ -218,6 +239,7 @@ class MAGNUM_EXPORT Framebuffer { */ static void read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image); + #ifndef MAGNUM_TARGET_GLES /** * @brief Read block of pixels from framebuffer to buffered image * @param offset Offset in the framebuffer @@ -226,8 +248,11 @@ class MAGNUM_EXPORT Framebuffer { * @param type Data type * @param image Buffered image where to put the data * @param usage %Buffer usage + * + * @requires_gl */ static void read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage); + #endif /** * @brief Constructor @@ -248,6 +273,7 @@ class MAGNUM_EXPORT Framebuffer { glBindFramebuffer(static_cast(target), framebuffer); } + #ifndef MAGNUM_TARGET_GLES /** * @brief Map given color attachments of current framebuffer for drawing * @param colorAttachments Color attachment IDs. If any value is -1, @@ -259,6 +285,7 @@ class MAGNUM_EXPORT Framebuffer { * should have either renderbuffer or texture attached for writing to * work properly. * @see mapDefaultForDraw(), mapForRead() + * @requires_gl */ void mapForDraw(std::initializer_list colorAttachments); @@ -269,11 +296,13 @@ class MAGNUM_EXPORT Framebuffer { * The color attachment should have either renderbuffer or texture * attached for reading to work properly. * @see mapDefaultForRead(), mapForDraw() + * @requires_gl */ inline void mapForRead(unsigned int colorAttachment) { bind(Target::Read); glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachment); } + #endif /** * @brief Attach renderbuffer to given framebuffer depth/stencil attachment @@ -299,12 +328,15 @@ class MAGNUM_EXPORT Framebuffer { glFramebufferRenderbuffer(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, GL_RENDERBUFFER, renderbuffer->id()); } + #ifndef MAGNUM_TARGET_GLES /** * @brief Attach 1D texture to given framebuffer depth/stencil attachment * @param target %Target * @param depthStencilAttachment Depth/stencil attachment * @param texture 1D texture * @param mipLevel Mip level + * + * @requires_gl */ inline void attachTexture1D(Target target, DepthStencilAttachment depthStencilAttachment, Texture1D* texture, GLint mipLevel) { /** @todo Check for internal format compatibility */ @@ -319,6 +351,8 @@ class MAGNUM_EXPORT Framebuffer { * @param colorAttachment Color attachment ID (number between 0 and 15) * @param texture 1D texture * @param mipLevel Mip level + * + * @requires_gl */ inline void attachTexture1D(Target target, unsigned int colorAttachment, Texture1D* texture, GLint mipLevel) { /** @todo Check for internal format compatibility */ @@ -326,6 +360,7 @@ class MAGNUM_EXPORT Framebuffer { bind(target); glFramebufferTexture1D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel); } + #endif /** * @brief Attach 2D texture to given framebuffer depth/stencil attachment @@ -393,6 +428,7 @@ class MAGNUM_EXPORT Framebuffer { glFramebufferTexture2D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(coordinate), texture->id(), mipLevel); } + #ifndef MAGNUM_TARGET_GLES /** * @brief Attach 3D texture to given framebuffer depth/stencil attachment * @param target %Target @@ -400,6 +436,8 @@ class MAGNUM_EXPORT Framebuffer { * @param texture 3D texture * @param mipLevel Mip level * @param layer Layer of 2D image within a 3D texture + * + * @requires_gl */ inline void attachTexture3D(Target target, DepthStencilAttachment depthStencilAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { /** @todo Check for internal format compatibility */ @@ -415,6 +453,8 @@ class MAGNUM_EXPORT Framebuffer { * @param texture 3D texture * @param mipLevel Mip level * @param layer Layer of 2D image within a 3D texture. + * + * @requires_gl */ inline void attachTexture3D(Target target, unsigned int colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { /** @todo Check for internal format compatibility */ @@ -422,6 +462,7 @@ class MAGNUM_EXPORT Framebuffer { bind(target); glFramebufferTexture3D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel, layer); } + #endif private: GLuint framebuffer; diff --git a/src/IndexedMesh.cpp b/src/IndexedMesh.cpp index 45679d166..76d1b5040 100644 --- a/src/IndexedMesh.cpp +++ b/src/IndexedMesh.cpp @@ -18,11 +18,19 @@ namespace Magnum { void IndexedMesh::draw() { + /* Vertex array must be bound before finalization */ + #ifndef MAGNUM_TARGET_GLES bind(); + #endif - /* Finalize the mesh, if it is not already */ finalize(); + /* Buffers must be bound after initialization */ + #ifdef MAGNUM_TARGET_GLES + bind(); + _indexBuffer.bind(); + #endif + /** @todo Start at given index */ glDrawElements(static_cast(primitive()), _indexCount, static_cast(_indexType), nullptr); @@ -38,8 +46,10 @@ void IndexedMesh::finalize() { /* Finalize attribute positions */ Mesh::finalize(); - /* Bind index buffer */ + /* Bind index buffer to VAO too */ + #ifndef MAGNUM_TARGET_GLES _indexBuffer.bind(); + #endif } #endif diff --git a/src/IndexedMesh.h b/src/IndexedMesh.h index 948b36d51..a400d7f55 100644 --- a/src/IndexedMesh.h +++ b/src/IndexedMesh.h @@ -69,12 +69,6 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh { */ inline Buffer* indexBuffer() { return &_indexBuffer; } - /** - * @brief Draw the mesh - * - * Binds attributes to buffers, bind index buffer and draws the mesh. - * Expects an active shader with all uniforms set. - */ void draw(); protected: diff --git a/src/Magnum.h b/src/Magnum.h index 4ff5a1099..ed448078b 100644 --- a/src/Magnum.h +++ b/src/Magnum.h @@ -19,7 +19,13 @@ * @brief Basic definitions */ +#include "configureMagnum.h" + +#ifndef MAGNUM_TARGET_GLES #include +#else +#include +#endif #include "Math/Math.h" #include "Math/Matrix4.h" diff --git a/src/Mesh.cpp b/src/Mesh.cpp index d703b3bb7..fde21c538 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -21,10 +21,12 @@ using namespace std; namespace Magnum { Mesh::~Mesh() { - for(auto it: _buffers) + for(auto& it: _buffers) delete it.first; + #ifndef MAGNUM_TARGET_GLES glDeleteVertexArrays(1, &vao); + #endif } Buffer* Mesh::addBuffer(BufferType interleaved) { @@ -35,17 +37,42 @@ Buffer* Mesh::addBuffer(BufferType interleaved) { } void Mesh::draw() { + /* Vertex array must be bound before finalization */ + #ifndef MAGNUM_TARGET_GLES bind(); + #endif - /* Finalize the mesh, if it is not already */ + /* Finalize, if not already */ finalize(); + /* Buffers must be bound after initialization */ + #ifdef MAGNUM_TARGET_GLES + bind(); + #endif + /** @todo Start at given index */ glDrawArrays(static_cast(_primitive), 0, _vertexCount); unbind(); } +void Mesh::bind() { + #ifndef MAGNUM_TARGET_GLES + glBindVertexArray(vao); + #else + bindBuffers(); + #endif +} + +void Mesh::unbind() { + #ifndef MAGNUM_TARGET_GLES + glBindVertexArray(0); + #else + for(set::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it) + glDisableVertexAttribArray(*it); + #endif +} + #ifndef DOXYGEN_GENERATING_OUTPUT void Mesh::finalize() { /* Already finalized */ @@ -53,12 +80,8 @@ void Mesh::finalize() { CORRADE_ASSERT(_vertexCount, "Mesh: the mesh has zero vertex count!", ) - /* Enable vertex arrays for all attributes */ - for(set::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it) - glEnableVertexAttribArray(*it); - /* Finalize attribute positions for every buffer */ - for(auto it: _buffers) { + for(auto& it: _buffers) { /* Avoid confustion */ bool interleaved = it.second.first == BufferType::Interleaved; vector& attributes = it.second.second; @@ -91,19 +114,37 @@ void Mesh::finalize() { position += ait->size*TypeInfo::sizeOf(ait->type)*_vertexCount; } } + } + + /* Mesh is now finalized, attribute binding is not allowed */ + finalized = true; + + #ifndef MAGNUM_TARGET_GLES + bindBuffers(); + #endif +} + +void Mesh::bindBuffers() { + /* Enable vertex arrays for all attributes */ + for(set::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it) + glEnableVertexAttribArray(*it); + + for(auto& it: _buffers) { + /* Avoid confusion */ + vector& attributes = it.second.second; /* Bind buffer */ it.first->bind(); /* Bind all attributes to this buffer */ for(vector::const_iterator ait = attributes.begin(); ait != attributes.end(); ++ait) + #ifndef MAGNUM_TARGET_GLES if(TypeInfo::isIntegral(ait->type)) glVertexAttribIPointer(ait->attribute, ait->size, static_cast(ait->type), ait->stride, ait->pointer); - else glVertexAttribPointer(ait->attribute, ait->size, static_cast(ait->type), GL_FALSE, ait->stride, ait->pointer); + else + #endif + glVertexAttribPointer(ait->attribute, ait->size, static_cast(ait->type), GL_FALSE, ait->stride, ait->pointer); } - - /* Mesh is now finalized, attribute binding is not allowed */ - finalized = true; } #endif diff --git a/src/Mesh.h b/src/Mesh.h index 458676ed9..7985bdd68 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -33,12 +33,12 @@ class Buffer; /** @ingroup rendering mesh @brief Base class for managing non-indexed meshes -@todo Support for normalized values (e.g. for color as char[4] passed to - shader as floating-point vec4) - +VAOs are used for desktop OpenGL (not in OpenGL ES). @requires_gl30 Extension @extension{APPLE,vertex_array_object} @requires_gl30 Extension @extension{EXT,gpu_shader4} (for unsigned integer attributes) +@todo Support for normalized values (e.g. for color as char[4] passed to + shader as floating-point vec4) @todo Support for provoking vertex (OpenGL 3.2, @extension{ARB,provoking_vertex}) @todo Support for packed unsigned integer types for attributes (OpenGL 3.3, @extension{ARB,vertex_type_2_10_10_10_rev}) @todo Support for fixed precision type for attributes (OpenGL 4.1, @extension{ARB,ES2_compatibility}) @@ -53,10 +53,12 @@ class MAGNUM_EXPORT Mesh { Mesh& operator=(Mesh&& other) = delete; public: + #ifndef MAGNUM_TARGET_GLES /** * @brief Polygon mode * * @see setPolygonMode() + * @requires_gl */ enum class PolygonMode: GLenum { /** @@ -75,6 +77,7 @@ class MAGNUM_EXPORT Mesh { */ Point = GL_POINT }; + #endif /** * @brief Primitive type @@ -135,14 +138,17 @@ class MAGNUM_EXPORT Mesh { NonInterleaved /**< Non-interleaved buffer */ }; + #ifndef MAGNUM_TARGET_GLES /** * @brief Set polygon drawing mode * * Initial value is PolygonMode::Fill. + * @requires_gl */ inline static void setPolygonMode(PolygonMode mode) { glPolygonMode(GL_FRONT_AND_BACK, static_cast(mode)); } + #endif /** * @brief Set line width @@ -153,10 +159,12 @@ class MAGNUM_EXPORT Mesh { glLineWidth(width); } + #ifndef MAGNUM_TARGET_GLES /** * @brief Set point size * * @see setProgramPointSize() + * @requires_gl */ inline static void setPointSize(GLfloat size) { glPointSize(size); @@ -168,10 +176,12 @@ class MAGNUM_EXPORT Mesh { * If enabled, the point size is taken from vertex/geometry shader * builtin `gl_PointSize`. * @see setPointSize() + * @requires_gl */ inline static void setProgramPointSize(bool enabled) { enabled ? glEnable(GL_PROGRAM_POINT_SIZE) : glDisable(GL_PROGRAM_POINT_SIZE); } + #endif /** * @brief Implicit constructor @@ -182,7 +192,9 @@ class MAGNUM_EXPORT Mesh { * to draw properly. */ inline Mesh(Primitive primitive = Primitive::Triangles): _primitive(primitive), _vertexCount(0), finalized(false) { + #ifndef MAGNUM_TARGET_GLES glGenVertexArrays(1, &vao); + #endif } /** @@ -191,7 +203,9 @@ class MAGNUM_EXPORT Mesh { * @param vertexCount Vertex count */ inline Mesh(Primitive primitive, GLsizei vertexCount): _primitive(primitive), _vertexCount(vertexCount), finalized(false) { + #ifndef MAGNUM_TARGET_GLES glGenVertexArrays(1, &vao); + #endif } /** @@ -268,18 +282,20 @@ class MAGNUM_EXPORT Mesh { /** * @brief Draw the mesh * - * Binds attributes to buffers and draws the mesh. Expects an active - * shader with all uniforms set. + * Expects an active shader with all uniforms set. */ virtual void draw(); protected: #ifndef DOXYGEN_GENERATING_OUTPUT - /** @brief Unbind any vertex array object */ - inline static void unbind() { glBindVertexArray(0); } + /** @brief Bind all buffers */ + void bindBuffers(); - /** @brief Bind vertex array object of current mesh */ - inline void bind() { glBindVertexArray(vao); } + /** @brief Bind vertex array or all buffers */ + void bind(); + + /** @brief Unbind vertex array or all buffers */ + void unbind(); /** * @brief Finalize the mesh @@ -300,7 +316,9 @@ class MAGNUM_EXPORT Mesh { const GLvoid* pointer; /**< @brief Pointer to first attribute of this type in the buffer */ }; + #ifndef MAGNUM_TARGET_GLES GLuint vao; + #endif Primitive _primitive; GLsizei _vertexCount; bool finalized; diff --git a/src/Query.cpp b/src/Query.cpp index 058b88e31..e0889ac68 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -17,6 +17,7 @@ namespace Magnum { +#ifndef MAGNUM_TARGET_GLES bool AbstractQuery::resultAvailable() { GLuint result; glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &result); @@ -78,5 +79,6 @@ void SampleQuery::end() { delete target; target = nullptr; } +#endif } diff --git a/src/Query.h b/src/Query.h index b238e7d28..a9780572b 100644 --- a/src/Query.h +++ b/src/Query.h @@ -23,6 +23,7 @@ namespace Magnum { +#ifndef MAGNUM_TARGET_GLES /** @addtogroup rendering * @{ */ @@ -32,6 +33,7 @@ namespace Magnum { See Query, SampleQuery, TimeQuery documentation for more information. @todo Support for AMD's query buffer (@extension{AMD,query_buffer_object}) +@requires_gl */ class MAGNUM_EXPORT AbstractQuery { public: @@ -98,6 +100,7 @@ if(!q.resultAvailable()) { // ...or block until the result is available GLuint primitiveCount = q.result(); @endcode +@requires_gl */ class MAGNUM_EXPORT Query: public AbstractQuery { public: @@ -176,6 +179,7 @@ q.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait); // render full version of the object only if the query returns nonzero result q.endConditionalRender(); @endcode +@requires_gl */ class MAGNUM_EXPORT SampleQuery: public AbstractQuery { public: @@ -273,7 +277,7 @@ GLuint timeElapsed1 = tmp-q1.result(); GLuint timeElapsed2 = q3.result()-tmp; @endcode Using this query results in fewer OpenGL calls when doing more measures. - +@requires_gl @requires_gl33 Extension @extension{ARB,timer_query} */ class TimeQuery: public AbstractQuery { @@ -285,6 +289,7 @@ class TimeQuery: public AbstractQuery { }; /*@}*/ +#endif } diff --git a/src/Renderbuffer.cpp b/src/Renderbuffer.cpp index b0b2f30e6..f7d2c4f11 100644 --- a/src/Renderbuffer.cpp +++ b/src/Renderbuffer.cpp @@ -17,6 +17,7 @@ namespace Magnum { +#ifndef MAGNUM_TARGET_GLES Renderbuffer::InternalFormat::InternalFormat(Components components, ComponentType type) { #define internalFormatSwitch(c) switch(type) { \ case ComponentType::UnsignedByte: \ @@ -48,5 +49,6 @@ Renderbuffer::InternalFormat::InternalFormat(Components components, ComponentTyp internalFormatSwitch(RGBA) #undef internalFormatSwitch } +#endif } diff --git a/src/Renderbuffer.h b/src/Renderbuffer.h index 670f45af5..94b75a915 100644 --- a/src/Renderbuffer.h +++ b/src/Renderbuffer.h @@ -39,10 +39,12 @@ class Renderbuffer { public: /** @{ @name Internal renderbuffer formats */ + #ifndef MAGNUM_TARGET_GLES /** * @copydoc AbstractTexture::Components * * Like AbstractTexture::Components, without three-component RGB. + * @requires_gl */ enum class Components { Red, RedGreen, RGBA @@ -53,11 +55,13 @@ class Renderbuffer { * * Like AbstractTexture::ComponentType, without normalized signed * types. + * @requires_gl */ enum class ComponentType { UnsignedByte, Byte, UnsignedShort, Short, UnsignedInt, Int, Half, Float, NormalizedUnsignedByte, NormalizedUnsignedShort }; + #endif /** * @copydoc AbstractTexture::Format @@ -67,21 +71,43 @@ class Renderbuffer { * compressed formats. */ enum class Format: GLenum { - Red = GL_RED, RedGreen = GL_RG, RGBA = GL_RGBA, BGRA = GL_BGRA, - SRGBA = GL_SRGB8_ALPHA8, + #ifndef MAGNUM_TARGET_GLES + Red = GL_RED, RedGreen = GL_RG, + #endif + + RGBA = GL_RGBA, + + #ifndef MAGNUM_TARGET_GLES + BGRA = GL_BGRA, SRGBA = GL_SRGB8_ALPHA8, RGB10Alpha2 = GL_RGB10_A2, RGB10AlphaUnsigned2 = GL_RGB10_A2UI, + #endif + RGB5Alpha1 = GL_RGB5_A1, RGBA4 = GL_RGBA4, + + #ifndef MAGNUM_TARGET_GLES RFloat11GFloat11BFloat10 = GL_R11F_G11F_B10F, + #endif #if defined(GL_RGB565) || defined(DOXYGEN_GENERATING_OUTPUT) RGB565 = GL_RGB565, #endif - Depth = GL_DEPTH_COMPONENT, DepthStencil = GL_DEPTH_STENCIL, - Depth16 = GL_DEPTH_COMPONENT16, Depth24 = GL_DEPTH_COMPONENT24, + Depth = GL_DEPTH_COMPONENT, + + #ifndef MAGNUM_TARGET_GLES + DepthStencil = GL_DEPTH_STENCIL, + #endif + + #ifdef MAGNUM_TARGET_GLES + Depth16 = GL_DEPTH_COMPONENT16 + #else + Depth16 = GL_DEPTH_COMPONENT16, + + Depth24 = GL_DEPTH_COMPONENT24, DepthFloat = GL_DEPTH_COMPONENT32F, Depth24Stencil8 = GL_DEPTH24_STENCIL8, DepthFloatStencil8 = GL_DEPTH32F_STENCIL8 + #endif /** @todo GL_STENCIL_INDEX1 - GL_STENCIL_INDEX16 (renderbuffer only) */ }; @@ -89,8 +115,10 @@ class Renderbuffer { /** @copydoc AbstractTexture::InternalFormat */ class MAGNUM_EXPORT InternalFormat { public: + #ifndef MAGNUM_TARGET_GLES /** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components, AbstractTexture::ComponentType) */ InternalFormat(Components components, ComponentType type); + #endif /** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Format) */ inline constexpr InternalFormat(Format format): internalFormat(static_cast(format)) {} @@ -148,8 +176,11 @@ class Renderbuffer { GLuint renderbuffer; }; +#ifndef MAGNUM_TARGET_GLES /** @relates Renderbuffer @brief Convertor of component count and data type to InternalFormat + +@requires_gl */ inline Renderbuffer::InternalFormat operator|(Renderbuffer::Components components, Renderbuffer::ComponentType type) { return Renderbuffer::InternalFormat(components, type); @@ -160,6 +191,7 @@ inline Renderbuffer::InternalFormat operator|(Renderbuffer::Components component inline Renderbuffer::InternalFormat operator|(Renderbuffer::ComponentType type, Renderbuffer::Components components) { return Renderbuffer::InternalFormat(components, type); } +#endif } diff --git a/src/Shader.cpp b/src/Shader.cpp index 8671ef71d..2ffc80738 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -98,10 +98,14 @@ GLuint Shader::compile() { switch(_type) { case Type::Vertex: err << "vertex"; break; + #ifndef MAGNUM_TARGET_GLES case Type::Geometry: err << "geometry"; break; + #endif case Type::Fragment: err << "fragment"; break; + #ifndef MAGNUM_TARGET_GLES case Type::TessellationControl: err << "tessellation control"; break; case Type::TessellationEvaluation: err << "tessellation evaluation"; break; + #endif } /* Show error log and delete shader */ diff --git a/src/Shader.h b/src/Shader.h index d7a54ee3d..4b5639604 100644 --- a/src/Shader.h +++ b/src/Shader.h @@ -42,26 +42,28 @@ class MAGNUM_EXPORT Shader { enum class Type: GLenum { Vertex = GL_VERTEX_SHADER, /**< Vertex shader */ + #ifndef MAGNUM_TARGET_GLES /** * Tessellation control shader - * + * @requires_gl * @requires_gl40 Extension @extension{ARB,tessellation_shader} */ TessellationControl = GL_TESS_CONTROL_SHADER, /** * Tessellation evaluation shader - * + * @requires_gl * @requires_gl40 Extension @extension{ARB,tessellation_shader} */ TessellationEvaluation = GL_TESS_EVALUATION_SHADER, /** * Geometry shader - * + * @requires_gl * @requires_gl32 Extension @extension{ARB,geometry_shader4} */ Geometry = GL_GEOMETRY_SHADER, + #endif Fragment = GL_FRAGMENT_SHADER /**< Fragment shader */ }; diff --git a/src/Texture.h b/src/Texture.h index b3447976c..b36bfa049 100644 --- a/src/Texture.h +++ b/src/Texture.h @@ -47,6 +47,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_gl31 Extension @extension{ARB,texture_rectangle} (rectangle textures) @see CubeMapTexture, CubeMapTextureArray @@ -62,27 +63,37 @@ template class Texture: public AbstractTexture { * Each dimension has its own unique subset of these targets. */ enum class Target: GLenum { - Texture1D = GL_TEXTURE_1D, /**< One-dimensional texture */ + /** + * One-dimensional texture + * @requires_gl + */ + Texture1D = GL_TEXTURE_1D, + Texture2D = GL_TEXTURE_2D, /**< Two-dimensional texture */ - Texture3D = GL_TEXTURE_3D, /**< Three-dimensional texture */ + + /** + * Three-dimensional texture + * @requires_gl + */ + Texture3D = GL_TEXTURE_3D, /** * One-dimensional texture array (i.e. two dimensions in total) - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_array} */ Texture1DArray = GL_TEXTURE_1D_ARRAY, /** * Two-dimensional texture array (i.e. three dimensions in total) - * + * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_array} */ Texture2DArray = GL_TEXTURE_2D_ARRAY, /** * Rectangle texture (i.e. two dimensions) - * + * @requires_gl * @requires_gl31 Extension @extension{ARB,texture_rectangle} */ Rectangle = GL_TEXTURE_RECTANGLE @@ -157,14 +168,26 @@ template class Texture: public AbstractTexture { } }; -/** @brief One-dimensional texture */ +#ifndef MAGNUM_TARGET_GLES +/** +@brief One-dimensional texture + +@requires_gl +*/ typedef Texture<1> Texture1D; +#endif /** @brief Two-dimensional texture */ typedef Texture<2> Texture2D; -/** @brief Three-dimensional texture */ +#ifndef MAGNUM_TARGET_GLES +/** +@brief Three-dimensional texture + +@requires_gl +*/ typedef Texture<3> Texture3D; +#endif /*@}*/ diff --git a/src/TypeTraits.cpp b/src/TypeTraits.cpp index 5d0663156..f9936e742 100644 --- a/src/TypeTraits.cpp +++ b/src/TypeTraits.cpp @@ -25,8 +25,10 @@ static_assert(sizeof(GLshort) == sizeof(short), "GLshort is not the same as shor static_assert(sizeof(GLuint) == sizeof(unsigned int), "GLuint is not the same as unsigned int"); static_assert(sizeof(GLint) == sizeof(int), "GLint is not the same as int"); static_assert(sizeof(GLfloat) == sizeof(float), "GLfloat is not the same as float"); +#ifndef MAGNUM_TARGET_GLES static_assert(sizeof(GLdouble) == sizeof(double), "GLdouble is not the same as double"); #endif +#endif size_t TypeInfo::sizeOf(Type type) { switch(type) { @@ -37,7 +39,9 @@ size_t TypeInfo::sizeOf(Type type) { val(Short) val(UnsignedInt) val(Int) + #ifndef MAGNUM_TARGET_GLES val(Double) + #endif val(Float) #undef val diff --git a/src/TypeTraits.h b/src/TypeTraits.h index 112d1cd52..54ec54324 100644 --- a/src/TypeTraits.h +++ b/src/TypeTraits.h @@ -89,8 +89,16 @@ enum class Type: GLenum { Short = GL_SHORT, /**< Short */ UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */ Int = GL_INT, /**< Int */ - Float = GL_FLOAT, /**< Float */ - Double = GL_DOUBLE /**< Double */ + Float = GL_FLOAT /**< Float */ + + #ifndef MAGNUM_TARGET_GLES + , + /** + * Double + * @requires_gl + */ + Double = GL_DOUBLE + #endif }; /** @@ -150,7 +158,9 @@ template<> struct TypeOf { typedef GLshort Type; }; template<> struct TypeOf { typedef GLuint Type; }; template<> struct TypeOf { typedef GLint Type; }; template<> struct TypeOf { typedef GLfloat Type; }; +#ifndef MAGNUM_TARGET_GLES template<> struct TypeOf { typedef GLdouble Type; }; +#endif template<> struct TypeTraits: public Math::MathTypeTraits { inline constexpr static Type type() { return Type::UnsignedByte; } @@ -208,6 +218,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits { inline constexpr static size_t count() { return 1; } }; +#ifndef MAGNUM_TARGET_GLES template<> struct TypeTraits: public Math::MathTypeTraits { inline constexpr static Type type() { return Type::Double; } /* Can not be used for indices */ @@ -215,6 +226,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits { inline constexpr static size_t size() { return sizeof(GLdouble); } inline constexpr static size_t count() { return 1; } }; +#endif template struct TypeTraits> { inline constexpr static Type type() { return TypeTraits::type(); } diff --git a/src/configureMagnum.h.cmake b/src/configureMagnum.h.cmake new file mode 100644 index 000000000..9e8a3c7e8 --- /dev/null +++ b/src/configureMagnum.h.cmake @@ -0,0 +1 @@ +#cmakedefine MAGNUM_TARGET_GLES