Browse Source

Port to OpenGL ES 2.

Desktop OpenGL and OpenGL ES 2 support can be switched using CMake
TARGET_GLES option. All functionality not supported in ES is marked in
documentation.

If targetting OpenGL ES, GLES2/gl2.h is included instead of GLEW.

Mesh class now uses VAOs only in desktop OpenGL, in ES the buffers are
bound on each draw call.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
c7bb153d0a
  1. 2
      CMakeLists.txt
  2. 1
      Doxyfile
  3. 6
      doc/building.dox
  4. 4
      doc/mainpage.dox
  5. 18
      doc/required-extensions.dox
  6. 9
      modules/FindMagnum.cmake
  7. 18
      src/AbstractImage.cpp
  8. 74
      src/AbstractImage.h
  9. 2
      src/AbstractShaderProgram.cpp
  10. 22
      src/AbstractShaderProgram.h
  11. 12
      src/AbstractTexture.cpp
  12. 127
      src/AbstractTexture.h
  13. 40
      src/Buffer.h
  14. 3
      src/BufferedImage.h
  15. 2
      src/BufferedTexture.cpp
  16. 3
      src/BufferedTexture.h
  17. 26
      src/CMakeLists.txt
  18. 7
      src/Camera.h
  19. 16
      src/Contexts/CMakeLists.txt
  20. 2
      src/Contexts/Sdl2Context.cpp
  21. 3
      src/CubeMapTexture.h
  22. 4
      src/Framebuffer.cpp
  23. 53
      src/Framebuffer.h
  24. 14
      src/IndexedMesh.cpp
  25. 6
      src/IndexedMesh.h
  26. 6
      src/Magnum.h
  27. 63
      src/Mesh.cpp
  28. 36
      src/Mesh.h
  29. 2
      src/Query.cpp
  30. 7
      src/Query.h
  31. 2
      src/Renderbuffer.cpp
  32. 40
      src/Renderbuffer.h
  33. 4
      src/Shader.cpp
  34. 8
      src/Shader.h
  35. 37
      src/Texture.h
  36. 4
      src/TypeTraits.cpp
  37. 16
      src/TypeTraits.h
  38. 1
      src/configureMagnum.h.cmake

2
CMakeLists.txt

@ -2,6 +2,8 @@
cmake_minimum_required(VERSION 2.8.8) cmake_minimum_required(VERSION 2.8.8)
project(Magnum) project(Magnum)
option(TARGET_GLES "Build for OpenGL ES 2 instead of desktop OpenGL" OFF)
option(BUILD_TESTS "Build unit tests (requires Qt4)." OFF) option(BUILD_TESTS "Build unit tests (requires Qt4)." OFF)
if(BUILD_TESTS) if(BUILD_TESTS)

1
Doxyfile

@ -198,6 +198,7 @@ ALIASES = \
"debugoperator{1}=@relates \1\n@brief Debug output operator" \ "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" \ "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\"" \ "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_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_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\"" \ "requires_gl32=@xrefitem requires-gl32 \"Requires OpenGL 3.2\" \"Functionality requiring OpenGL 3.2\"" \

6
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** which are tested to support everything needed: **GCC** >= 4.6 and **Clang**
>= 3.1. >= 3.1.
- **CMake** >= 2.8.8 (needed for `OBJECT` library target) - **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 - **GLEW** - OpenGL extension wrangler
- **Corrade** - Plugin management and utility library. You can get it at - **Corrade** - Plugin management and utility library. You can get it at
http://github.com/mosra/corrade or at http://mosra.cz/blog/corrade.php. 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 cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make
make install 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 If you want to build with another compiler (e.g. Clang), pass
`-DCMAKE_CXX_COMPILER=clang++` to CMake. `-DCMAKE_CXX_COMPILER=clang++` to CMake.

4
doc/mainpage.dox

@ -25,8 +25,8 @@ Features:
covered with unit tests. covered with unit tests.
The engine is meant to be run on OpenGL 3 capable hardware, but most of the 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 functionality is working on OpenGL 2.1 hardware too. The engine can be built
@ref required-extensions. also for OpenGL ES 2 with limited functionality. See also @ref required-extensions.
@section download-build Downloading and building Magnum @section download-build Downloading and building Magnum

18
doc/required-extensions.dox

@ -1,15 +1,18 @@
/** @page required-extensions Functionality requiring specific OpenGL version or extensions /** @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 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 functionality is working in OpenGL 2.1 hardware too (i.e. integrated Intel
GPUs), unless stated otherwise. Following are lists of functionality requiring GPUs), unless stated otherwise. OpenGL ES 2 is also supported, see
specific OpenGL version. In most cases it is also specified which extension is @ref building for guide how to build the engine for it.
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).
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-gl30
- @subpage requires-gl31 - @subpage requires-gl31
- @subpage requires-gl32 - @subpage requires-gl32
@ -19,6 +22,7 @@ capable of OpenGL 2.1 only).
- @subpage requires-gl42 - @subpage requires-gl42
- @subpage requires-extension - @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-gl30 Functionality requiring OpenGL 3.0
@page requires-gl31 Functionality requiring OpenGL 3.1 @page requires-gl31 Functionality requiring OpenGL 3.1
@page requires-gl32 Functionality requiring OpenGL 3.2 @page requires-gl32 Functionality requiring OpenGL 3.2

9
modules/FindMagnum.cmake

@ -43,8 +43,13 @@
# Dependencies # Dependencies
find_package(Corrade REQUIRED) 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 # Magnum library
find_library(MAGNUM_LIBRARY Magnum) find_library(MAGNUM_LIBRARY Magnum)

18
src/AbstractImage.cpp

@ -21,16 +21,25 @@ namespace Magnum {
size_t AbstractImage::pixelSize(Components format, ComponentType type) { size_t AbstractImage::pixelSize(Components format, ComponentType type) {
size_t size = 0; size_t size = 0;
switch(type) { switch(type) {
#ifndef MAGNUM_TARGET_GLES
case ComponentType::RGB332: case ComponentType::RGB332:
case ComponentType::BGR233: case ComponentType::BGR233:
return 1; return 1;
#endif
case ComponentType::RGB565: case ComponentType::RGB565:
#ifndef MAGNUM_TARGET_GLES
case ComponentType::BGR565: case ComponentType::BGR565:
#endif
case ComponentType::RGBA4: case ComponentType::RGBA4:
#ifndef MAGNUM_TARGET_GLES
case ComponentType::ABGR4: case ComponentType::ABGR4:
#endif
case ComponentType::RGB5Alpha1: case ComponentType::RGB5Alpha1:
#ifndef MAGNUM_TARGET_GLES
case ComponentType::Alpha1BGR5: case ComponentType::Alpha1BGR5:
#endif
return 2; return 2;
#ifndef MAGNUM_TARGET_GLES
case ComponentType::RGBA8: case ComponentType::RGBA8:
case ComponentType::ABGR8: case ComponentType::ABGR8:
case ComponentType::RGB10Alpha2: case ComponentType::RGB10Alpha2:
@ -41,13 +50,16 @@ size_t AbstractImage::pixelSize(Components format, ComponentType type) {
return 4; return 4;
case ComponentType::Depth32FloatStencil8: case ComponentType::Depth32FloatStencil8:
return 8; return 8;
#endif
case ComponentType::UnsignedByte: case ComponentType::UnsignedByte:
case ComponentType::Byte: case ComponentType::Byte:
size = 1; break; size = 1; break;
case ComponentType::UnsignedShort: case ComponentType::UnsignedShort:
case ComponentType::Short: case ComponentType::Short:
#ifndef MAGNUM_TARGET_GLES
case ComponentType::HalfFloat: case ComponentType::HalfFloat:
size = 2; break; size = 2; break;
#endif
case ComponentType::UnsignedInt: case ComponentType::UnsignedInt:
case ComponentType::Int: case ComponentType::Int:
case ComponentType::Float: case ComponentType::Float:
@ -55,15 +67,21 @@ size_t AbstractImage::pixelSize(Components format, ComponentType type) {
} }
switch(format) { switch(format) {
#ifndef MAGNUM_TARGET_GLES
case Components::Red: case Components::Red:
return 1*size; return 1*size;
case Components::RedGreen: case Components::RedGreen:
return 2*size; return 2*size;
#endif
case Components::RGB: case Components::RGB:
#ifndef MAGNUM_TARGET_GLES
case Components::BGR: case Components::BGR:
#endif
return 3*size; return 3*size;
case Components::RGBA: case Components::RGBA:
#ifndef MAGNUM_TARGET_GLES
case Components::BGRA: case Components::BGRA:
#endif
return 4*size; return 4*size;
default: default:
return 0; return 0;

74
src/AbstractImage.h

@ -45,34 +45,64 @@ class MAGNUM_EXPORT AbstractImage {
/** @brief Color components */ /** @brief Color components */
enum class Components: GLenum { 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, Green = GL_GREEN,
/** One-component (green channel). For framebuffer reading only. */ /**
* One-component (green channel). For framebuffer reading only.
* @requires_gl
*/
Blue = GL_BLUE, 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, RedGreen = GL_RG,
#endif
RGB = GL_RGB, /**< Three-component RGB */ RGB = GL_RGB, /**< Three-component RGB */
BGR = GL_BGR, /**< Three-component BGR */
RGBA = GL_RGBA, /**< Four-component RGBA */ 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 component. For framebuffer reading only. */
Depth = GL_DEPTH_COMPONENT, Depth = GL_DEPTH_COMPONENT,
/** Stencil index. For framebuffer reading only. */ /** 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. * Depth and stencil component. For framebuffer reading only.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,packed_depth_stencil} * @requires_gl30 Extension @extension{EXT,packed_depth_stencil}
*/ */
DepthStencil = GL_DEPTH_STENCIL DepthStencil = GL_DEPTH_STENCIL
#endif
}; };
/** @brief Data type */ /** @brief Data type */
@ -84,26 +114,33 @@ class MAGNUM_EXPORT AbstractImage {
UnsignedInt = GL_UNSIGNED_INT, /**< Each component unsigned int */ UnsignedInt = GL_UNSIGNED_INT, /**< Each component unsigned int */
Int = GL_INT, /**< Each component int */ Int = GL_INT, /**< Each component int */
#ifndef MAGNUM_TARGET_GLES
/** /**
* Each component half float (16bit). For framebuffer reading only. * Each component half float (16bit). For framebuffer reading only.
* *
* @requires_gl
* @requires_gl30 Extension @extension{NV,half_float} / @extension{ARB,half_float_pixel} * @requires_gl30 Extension @extension{NV,half_float} / @extension{ARB,half_float_pixel}
*/ */
HalfFloat = GL_HALF_FLOAT, HalfFloat = GL_HALF_FLOAT,
#endif
Float = GL_FLOAT, /**< Each component float (32bit) */ Float = GL_FLOAT, /**< Each component float (32bit) */
#ifndef MAGNUM_TARGET_GLES
/** /**
* Three-component RGB, unsigned normalized, red and green 3bit, * Three-component RGB, unsigned normalized, red and green 3bit,
* blue 2bit, 8bit total. * blue 2bit, 8bit total.
* @requires_gl
*/ */
RGB332 = GL_UNSIGNED_BYTE_3_3_2, RGB332 = GL_UNSIGNED_BYTE_3_3_2,
/** /**
* Three-component BGR, unsigned normalized, red and green 3bit, * Three-component BGR, unsigned normalized, red and green 3bit,
* blue 2bit, 8bit total. * blue 2bit, 8bit total.
* @requires_gl
*/ */
BGR233 = GL_UNSIGNED_BYTE_2_3_3_REV, BGR233 = GL_UNSIGNED_BYTE_2_3_3_REV,
#endif
/** /**
* Three-component RGB, unsigned normalized, red and blue 5bit, * Three-component RGB, unsigned normalized, red and blue 5bit,
@ -111,11 +148,14 @@ class MAGNUM_EXPORT AbstractImage {
*/ */
RGB565 = GL_UNSIGNED_SHORT_5_6_5, RGB565 = GL_UNSIGNED_SHORT_5_6_5,
#ifndef MAGNUM_TARGET_GLES
/** /**
* Three-component BGR, unsigned normalized, red and blue 5bit, * Three-component BGR, unsigned normalized, red and blue 5bit,
* green 6bit, 16bit total. * green 6bit, 16bit total.
* @requires_gl
*/ */
BGR565 = GL_UNSIGNED_SHORT_5_6_5_REV, BGR565 = GL_UNSIGNED_SHORT_5_6_5_REV,
#endif
/** /**
* Four-component RGBA, unsigned normalized, each component 4bit, * Four-component RGBA, unsigned normalized, each component 4bit,
@ -123,11 +163,14 @@ class MAGNUM_EXPORT AbstractImage {
*/ */
RGBA4 = GL_UNSIGNED_SHORT_4_4_4_4, RGBA4 = GL_UNSIGNED_SHORT_4_4_4_4,
#ifndef MAGNUM_TARGET_GLES
/** /**
* Four-component ABGR, unsigned normalized, each component 4bit, * Four-component ABGR, unsigned normalized, each component 4bit,
* 16bit total. * 16bit total.
* @requires_gl
*/ */
ABGR4 = GL_UNSIGNED_SHORT_4_4_4_4_REV, ABGR4 = GL_UNSIGNED_SHORT_4_4_4_4_REV,
#endif
/** /**
* Four-component RGBA, unsigned normalized, each RGB component * Four-component RGBA, unsigned normalized, each RGB component
@ -135,40 +178,46 @@ class MAGNUM_EXPORT AbstractImage {
*/ */
RGB5Alpha1 = GL_UNSIGNED_SHORT_5_5_5_1, RGB5Alpha1 = GL_UNSIGNED_SHORT_5_5_5_1,
#ifndef MAGNUM_TARGET_GLES
/** /**
* Four-component ABGR, unsigned normalized, each RGB component * Four-component ABGR, unsigned normalized, each RGB component
* 5bit, alpha 1bit, 16bit total. * 5bit, alpha 1bit, 16bit total.
* @requires_gl
*/ */
Alpha1BGR5 = GL_UNSIGNED_SHORT_1_5_5_5_REV, Alpha1BGR5 = GL_UNSIGNED_SHORT_1_5_5_5_REV,
/** /**
* Four-component RGBA, unsigned normalized, each component 8bit, * Four-component RGBA, unsigned normalized, each component 8bit,
* 32bit total. * 32bit total.
* @requires_gl
*/ */
RGBA8 = GL_UNSIGNED_INT_8_8_8_8, RGBA8 = GL_UNSIGNED_INT_8_8_8_8,
/** /**
* Four-component ABGR, unsigned normalized, each component 8bit, * Four-component ABGR, unsigned normalized, each component 8bit,
* 32bit total. * 32bit total.
* @requires_gl
*/ */
ABGR8 = GL_UNSIGNED_INT_8_8_8_8_REV, ABGR8 = GL_UNSIGNED_INT_8_8_8_8_REV,
/** /**
* Four-component RGBA, unsigned normalized, each RGB component * Four-component RGBA, unsigned normalized, each RGB component
* 10bit, alpha 2bit, 32bit total. * 10bit, alpha 2bit, 32bit total.
* @requires_gl
*/ */
RGB10Alpha2 = GL_UNSIGNED_INT_10_10_10_2, RGB10Alpha2 = GL_UNSIGNED_INT_10_10_10_2,
/** /**
* Four-component ABGR, unsigned normalized, each RGB component * Four-component ABGR, unsigned normalized, each RGB component
* 10bit, alpha 2bit, 32bit total. * 10bit, alpha 2bit, 32bit total.
* @requires_gl
*/ */
Alpha2RGB10 = GL_UNSIGNED_INT_2_10_10_10_REV, Alpha2RGB10 = GL_UNSIGNED_INT_2_10_10_10_REV,
/** /**
* Three-component BGR, float, red and green 11bit, blue 10bit, * Three-component BGR, float, red and green 11bit, blue 10bit,
* 32bit total. For framebuffer reading only. * 32bit total. For framebuffer reading only.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,packed_float} * @requires_gl30 Extension @extension{EXT,packed_float}
*/ */
B10GR11Float = GL_UNSIGNED_INT_10F_11F_11F_REV, B10GR11Float = GL_UNSIGNED_INT_10F_11F_11F_REV,
@ -177,7 +226,7 @@ class MAGNUM_EXPORT AbstractImage {
* Three-component BGR, unsigned integers with exponent, each * Three-component BGR, unsigned integers with exponent, each
* component 9bit, exponent 5bit, 32bit total. For framebuffer * component 9bit, exponent 5bit, 32bit total. For framebuffer
* reading only. * reading only.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_shared_exponent} * @requires_gl30 Extension @extension{EXT,texture_shared_exponent}
*/ */
Exponent5RGB9 = GL_UNSIGNED_INT_5_9_9_9_REV, 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 * 24bit depth and 8bit stencil component, 32bit total. For
* framebuffer reading only. * framebuffer reading only.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,packed_depth_stencil} * @requires_gl30 Extension @extension{EXT,packed_depth_stencil}
*/ */
Depth24Stencil8 = GL_UNSIGNED_INT_24_8, Depth24Stencil8 = GL_UNSIGNED_INT_24_8,
@ -193,10 +242,11 @@ class MAGNUM_EXPORT AbstractImage {
/** /**
* 32bit float depth component and 8bit stencil component, 64bit * 32bit float depth component and 8bit stencil component, 64bit
* total. For framebuffer reading only. * total. For framebuffer reading only.
* * @requires_gl
* @requires_gl30 Extension @extension{ARB,depth_buffer_float} * @requires_gl30 Extension @extension{ARB,depth_buffer_float}
*/ */
Depth32FloatStencil8 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV Depth32FloatStencil8 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
#endif
}; };
/*@}*/ /*@}*/

2
src/AbstractShaderProgram.cpp

@ -44,11 +44,13 @@ void AbstractShaderProgram::bindAttributeLocation(GLuint location, const string&
glBindAttribLocation(program, location, name.c_str()); glBindAttribLocation(program, location, name.c_str());
} }
#ifndef MAGNUM_TARGET_GLES
void AbstractShaderProgram::bindFragmentDataLocation(GLuint location, const std::string& name) { void AbstractShaderProgram::bindFragmentDataLocation(GLuint location, const std::string& name) {
CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", ) CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", )
glBindFragDataLocation(program, location, name.c_str()); glBindFragDataLocation(program, location, name.c_str());
} }
#endif
void AbstractShaderProgram::link() { void AbstractShaderProgram::link() {
/* Already compiled or failed, exit */ /* Already compiled or failed, exit */

22
src/AbstractShaderProgram.h

@ -82,6 +82,8 @@ layout(location = 0) in vec4 vertex;
layout(location = 1) in vec3 normal; layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 textureCoords; layout(location = 2) in vec2 textureCoords;
@endcode @endcode
@requires_gl (for explicit attribute location instead of using
bindAttributeLocation())
@requires_gl33 Extension @extension{ARB,explicit_attrib_location} (for @requires_gl33 Extension @extension{ARB,explicit_attrib_location} (for
explicit attribute location instead of using bindAttributeLocation()) explicit attribute location instead of using bindAttributeLocation())
@ -105,6 +107,8 @@ code, e.g.:
layout(binding = 0) uniform sampler2D diffuseTexture; layout(binding = 0) uniform sampler2D diffuseTexture;
layout(binding = 1) uniform sampler2D specularTexture; layout(binding = 1) uniform sampler2D specularTexture;
@endcode @endcode
@requires_gl (for explicit texture layer binding instead of using
setUniform(GLint, GLint))
@requires_gl42 Extension @extension{ARB,shading_language_420pack} (for explicit @requires_gl42 Extension @extension{ARB,shading_language_420pack} (for explicit
texture layer binding instead of using setUniform(GLint, GLint)) texture layer binding instead of using setUniform(GLint, GLint))
@ -180,10 +184,12 @@ class MAGNUM_EXPORT AbstractShaderProgram {
bool use(); bool use();
protected: protected:
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Allow retrieving program binary * @brief Allow retrieving program binary
* *
* Disabled by default. * Disabled by default.
* @requires_gl
* @requires_gl41 Extension @extension{ARB,get_program_binary} * @requires_gl41 Extension @extension{ARB,get_program_binary}
* @note This function should be called after attachShader() calls and * @note This function should be called after attachShader() calls and
* before link(). * before link().
@ -196,6 +202,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @brief Allow the program to be bound to individual pipeline stages * @brief Allow the program to be bound to individual pipeline stages
* *
* Disabled by default. * Disabled by default.
* @requires_gl
* @requires_gl41 Extension @extension{ARB,separate_shader_objects} * @requires_gl41 Extension @extension{ARB,separate_shader_objects}
* @note This function should be called after attachShader() calls and * @note This function should be called after attachShader() calls and
* before link(). * before link().
@ -203,6 +210,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
inline void setSeparable(bool enabled) { inline void setSeparable(bool enabled) {
glProgramParameteri(program, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE); glProgramParameteri(program, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE);
} }
#endif
/** /**
* @brief Load shader * @brief Load shader
@ -235,6 +243,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
*/ */
void bindAttributeLocation(GLuint location, const std::string& name); void bindAttributeLocation(GLuint location, const std::string& name);
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Bind fragment data to given location * @brief Bind fragment data to given location
* @param location Location * @param location Location
@ -246,10 +255,11 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* explicitly in the shader instead of using this function. See * explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgramAttributeLocation "class documentation" * @ref AbstractShaderProgramAttributeLocation "class documentation"
* for more information. * for more information.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gl30 Extension @extension{EXT,gpu_shader4}
*/ */
void bindFragmentDataLocation(GLuint location, const std::string& name); void bindFragmentDataLocation(GLuint location, const std::string& name);
#endif
/** /**
* @brief Link the shader * @brief Link the shader
@ -313,9 +323,10 @@ class MAGNUM_EXPORT AbstractShaderProgram {
glUniform4iv(location, 1, value.data()); glUniform4iv(location, 1, value.data());
} }
#ifndef MAGNUM_TARGET_GLES
/** /**
* @copydoc setUniform(GLint, GLint) * @copydoc setUniform(GLint, GLint)
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gl30 Extension @extension{EXT,gpu_shader4}
*/ */
inline void setUniform(GLint location, GLuint value) { inline void setUniform(GLint location, GLuint value) {
@ -324,7 +335,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
/** /**
* @copydoc setUniform(GLint, GLint) * @copydoc setUniform(GLint, GLint)
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gl30 Extension @extension{EXT,gpu_shader4}
*/ */
inline void setUniform(GLint location, const Math::Vector2<GLuint>& value) { inline void setUniform(GLint location, const Math::Vector2<GLuint>& value) {
@ -333,7 +344,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
/** /**
* @copydoc setUniform(GLint, GLint) * @copydoc setUniform(GLint, GLint)
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gl30 Extension @extension{EXT,gpu_shader4}
*/ */
inline void setUniform(GLint location, const Math::Vector3<GLuint>& value) { inline void setUniform(GLint location, const Math::Vector3<GLuint>& value) {
@ -342,12 +353,13 @@ class MAGNUM_EXPORT AbstractShaderProgram {
/** /**
* @copydoc setUniform(GLint, GLuint) * @copydoc setUniform(GLint, GLuint)
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gl30 Extension @extension{EXT,gpu_shader4}
*/ */
inline void setUniform(GLint location, const Math::Vector4<GLuint>& value) { inline void setUniform(GLint location, const Math::Vector4<GLuint>& value) {
glUniform4uiv(location, 1, value.data()); glUniform4uiv(location, 1, value.data());
} }
#endif
/** @copydoc setUniform(GLint, GLint) */ /** @copydoc setUniform(GLint, GLint) */
inline void setUniform(GLint location, const Matrix3& value) { inline void setUniform(GLint location, const Matrix3& value) {

12
src/AbstractTexture.cpp

@ -40,14 +40,18 @@ GLint AbstractTexture::maxSupportedLayerCount() {
return value; return value;
} }
#ifndef MAGNUM_TARGET_GLES
GLfloat AbstractTexture::maxSupportedAnisotropy() { GLfloat AbstractTexture::maxSupportedAnisotropy() {
GLfloat value; GLfloat value;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &value); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &value);
return value; return value;
} }
#endif
void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) { 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", ) CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::BaseLevel, "AbstractTexture: rectangle textures cannot have mipmaps", )
#endif
bind(); bind();
glTexParameteri(_target, GL_TEXTURE_MIN_FILTER, glTexParameteri(_target, GL_TEXTURE_MIN_FILTER,
@ -55,12 +59,15 @@ void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) {
} }
void AbstractTexture::generateMipmap() { void AbstractTexture::generateMipmap() {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", ) CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", )
#endif
bind(); bind();
glGenerateMipmap(_target); glGenerateMipmap(_target);
} }
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components components, AbstractTexture::ComponentType type) { AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components components, AbstractTexture::ComponentType type) {
#define internalFormatSwitch(c) switch(type) { \ #define internalFormatSwitch(c) switch(type) { \
case ComponentType::UnsignedByte: \ case ComponentType::UnsignedByte: \
@ -98,10 +105,13 @@ AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components comp
internalFormatSwitch(RGBA) internalFormatSwitch(RGBA)
#undef internalFormatSwitch #undef internalFormatSwitch
} }
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractTexture::DataHelper<2>::setWrapping(GLenum target, const Math::Vector<2, Wrapping>& wrapping) { 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", ) 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<GLint>(wrapping[0])); glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping[1])); glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast<GLint>(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) { void AbstractTexture::DataHelper<3>::setWrapping(GLenum target, const Math::Vector<3, Wrapping>& wrapping) {
glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0])); glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping[0]));
glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping[1])); glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping[1]));
#ifndef MAGNUM_TARGET_GLES
glTexParameteri(target, GL_TEXTURE_WRAP_R, static_cast<GLint>(wrapping[2])); glTexParameteri(target, GL_TEXTURE_WRAP_R, static_cast<GLint>(wrapping[2]));
#endif
} }
#endif #endif

127
src/AbstractTexture.h

@ -97,18 +97,26 @@ class MAGNUM_EXPORT AbstractTexture {
* Clamp to edge. Coordinates out of the range will be clamped to * Clamp to edge. Coordinates out of the range will be clamped to
* first / last column / row in given direction. * 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 * Clamp to border color. Coordinates out of range will be clamped
* to border color (set with setBorderColor()). * to border color (set with setBorderColor()).
* @requires_gl
*/ */
ClampToBorder = GL_CLAMP_TO_BORDER ClampToBorder = GL_CLAMP_TO_BORDER
#endif
}; };
/** @{ @name Internal texture formats */ /** @{ @name Internal texture formats */
/** @brief Color components */ #ifndef MAGNUM_TARGET_GLES
/**
* @brief Color components
* @requires_gl
*/
enum class Components { enum class Components {
/** /**
* Red component only. Green and blue are set to `0`, alpha is set * 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 * `NormalizedUnsignedByte` and `NormalizedUnsignedShort` are the
* main ones for general usage. * main ones for general usage.
* @requires_gl
*/ */
enum class ComponentType { enum class ComponentType {
/** /**
@ -217,6 +226,7 @@ class MAGNUM_EXPORT AbstractTexture {
*/ */
NormalizedShort NormalizedShort
}; };
#endif
/** /**
* @brief Internal format * @brief Internal format
@ -225,10 +235,11 @@ class MAGNUM_EXPORT AbstractTexture {
* normalization see enums Components and ComponentType. * normalization see enums Components and ComponentType.
*/ */
enum class Format: GLenum { enum class Format: GLenum {
#ifndef MAGNUM_TARGET_GLES
/** /**
* One-component (red channel), unsigned normalized, probably * One-component (red channel), unsigned normalized, probably
* 8bit. * 8bit.
* * @requires_gl
* @requires_gl30 (no extension providing this functionality) * @requires_gl30 (no extension providing this functionality)
*/ */
Red = GL_RED, Red = GL_RED,
@ -236,10 +247,11 @@ class MAGNUM_EXPORT AbstractTexture {
/** /**
* Two-component (red and green channel), unsigned normalized, * Two-component (red and green channel), unsigned normalized,
* each component probably 8bit, 16bit total. * each component probably 8bit, 16bit total.
* * @requires_gl
* @requires_gl30 (no extension providing this functionality) * @requires_gl30 (no extension providing this functionality)
*/ */
RedGreen = GL_RG, RedGreen = GL_RG,
#endif
/** /**
* Three-component RGB, unsigned normalized, each component * Three-component RGB, unsigned normalized, each component
@ -259,43 +271,50 @@ class MAGNUM_EXPORT AbstractTexture {
*/ */
RGBA = GL_RGBA, RGBA = GL_RGBA,
#ifndef MAGNUM_TARGET_GLES
/** /**
* Three-component BGR, unsigned normalized, each component * Three-component BGR, unsigned normalized, each component
* probably 8bit, 24bit total. * probably 8bit, 24bit total.
* @requires_gl
*/ */
BGR = GL_BGR, BGR = GL_BGR,
/** /**
* Four-component BGRA, unsigned normalized, each component * Four-component BGRA, unsigned normalized, each component
* probably 8bit, 24bit total. * probably 8bit, 24bit total.
* @requires_gl
*/ */
BGRA = GL_BGRA, BGRA = GL_BGRA,
/** /**
* Four-component sRGBA, unsigned normalized, each component * Four-component sRGBA, unsigned normalized, each component
* 8bit, 32bit total. * 8bit, 32bit total.
* @requires_gl
*/ */
SRGBA8 = GL_SRGB8_ALPHA8, SRGBA8 = GL_SRGB8_ALPHA8,
/** /**
* Three-component sRGB, unsigned normalized, each component * Three-component sRGB, unsigned normalized, each component
* 8bit, 24bit total. * 8bit, 24bit total.
* @requires_gl
*/ */
SRGB8 = GL_SRGB8, SRGB8 = GL_SRGB8,
/** /**
* Four-component RGBA, unsigned normalized, each RGB component * Four-component RGBA, unsigned normalized, each RGB component
* 10bit, alpha 2bit, 32bit total. * 10bit, alpha 2bit, 32bit total.
* @requires_gl
*/ */
RGB10Alpha2 = GL_RGB10_A2, RGB10Alpha2 = GL_RGB10_A2,
/** /**
* Four-component RGBA, unsigned non-normalized, each RGB * Four-component RGBA, unsigned non-normalized, each RGB
* component 10bit, alpha channel 2bit, 32bit total. * component 10bit, alpha channel 2bit, 32bit total.
* * @requires_gl
* @requires_gl33 Extension @extension{ARB,texture_rgb10_a2ui} * @requires_gl33 Extension @extension{ARB,texture_rgb10_a2ui}
*/ */
RGB10Alpha2Unsigned = GL_RGB10_A2UI, RGB10Alpha2Unsigned = GL_RGB10_A2UI,
#endif
/** /**
* Four-component RGBA, unsigned normalized, each RGB component * Four-component RGBA, unsigned normalized, each RGB component
@ -309,13 +328,15 @@ class MAGNUM_EXPORT AbstractTexture {
*/ */
RGBA4 = GL_RGBA4, RGBA4 = GL_RGBA4,
#ifndef MAGNUM_TARGET_GLES
/** /**
* Three-component RGB, float, red and green 11bit, blue 10bit, * Three-component RGB, float, red and green 11bit, blue 10bit,
* 32bit total. * 32bit total.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,packed_float} * @requires_gl30 Extension @extension{EXT,packed_float}
*/ */
RG11B10Float = GL_R11F_G11F_B10F, RG11B10Float = GL_R11F_G11F_B10F,
#endif
#if defined(GL_RGB565) || defined(DOXYGEN_GENERATING_OUTPUT) #if defined(GL_RGB565) || defined(DOXYGEN_GENERATING_OUTPUT)
/** /**
@ -325,79 +346,93 @@ class MAGNUM_EXPORT AbstractTexture {
RGB565 = GL_RGB565, RGB565 = GL_RGB565,
#endif #endif
#ifndef MAGNUM_TARGET_GLES
/** /**
* Three-component RGB, unsigned with exponent, each component * Three-component RGB, unsigned with exponent, each component
* 9bit, exponent 5bit, 32bit total. * 9bit, exponent 5bit, 32bit total.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_shared_exponent} * @requires_gl30 Extension @extension{EXT,texture_shared_exponent}
*/ */
RGB9Exponent5 = GL_RGB9_E5, RGB9Exponent5 = GL_RGB9_E5,
/** Compressed red channel, unsigned normalized. */ /**
* Compressed red channel, unsigned normalized.
* @requires_gl
*/
CompressedRed = GL_COMPRESSED_RED, CompressedRed = GL_COMPRESSED_RED,
/** Compressed red and green channel, unsigned normalized. */ /**
* Compressed red and green channel, unsigned normalized.
* @requires_gl
*/
CompressedRedGreen = GL_COMPRESSED_RG, CompressedRedGreen = GL_COMPRESSED_RG,
/** Compressed RGB, unsigned normalized. */ /**
* Compressed RGB, unsigned normalized.
* @requires_gl
*/
CompressedRGB = GL_COMPRESSED_RGB, CompressedRGB = GL_COMPRESSED_RGB,
/** Compressed RGBA, unsigned normalized. */ /**
* Compressed RGBA, unsigned normalized.
* @requires_gl
*/
CompressedRGBA = GL_COMPRESSED_RGBA, CompressedRGBA = GL_COMPRESSED_RGBA,
/** /**
* RTGC compressed red channel, unsigned normalized. * RTGC compressed red channel, unsigned normalized.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc}
*/ */
CompressedRtgcRed = GL_COMPRESSED_RED_RGTC1, CompressedRtgcRed = GL_COMPRESSED_RED_RGTC1,
/** /**
* RTGC compressed red channel, signed normalized. * RTGC compressed red channel, signed normalized.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc}
*/ */
CompressedRtgcSignedRed = GL_COMPRESSED_SIGNED_RED_RGTC1, CompressedRtgcSignedRed = GL_COMPRESSED_SIGNED_RED_RGTC1,
/** /**
* RTGC compressed red and green channel, unsigned normalized. * RTGC compressed red and green channel, unsigned normalized.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc}
*/ */
CompressedRtgcRedGreen = GL_COMPRESSED_RG_RGTC2, CompressedRtgcRedGreen = GL_COMPRESSED_RG_RGTC2,
/** /**
* RTGC compressed red and green channel, signed normalized. * RTGC compressed red and green channel, signed normalized.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_compression_rgtc} * @requires_gl30 Extension @extension{EXT,texture_compression_rgtc}
*/ */
CompressedRtgcSignedRedGreen = GL_COMPRESSED_SIGNED_RG_RGTC2, CompressedRtgcSignedRedGreen = GL_COMPRESSED_SIGNED_RG_RGTC2,
#endif
#if defined(GL_COMPRESSED_RGBA_BPTC_UNORM) || defined(DOXYGEN_GENERATING_OUTPUT) #if defined(GL_COMPRESSED_RGBA_BPTC_UNORM) || defined(DOXYGEN_GENERATING_OUTPUT)
/** /**
* BPTC compressed RGBA, unsigned normalized. * BPTC compressed RGBA, unsigned normalized.
* * @requires_gl
* @requires_gl42 Extension @extension{ARB,texture_compression_bptc} * @requires_gl42 Extension @extension{ARB,texture_compression_bptc}
*/ */
CompressedBptcRGBA = GL_COMPRESSED_RGBA_BPTC_UNORM, CompressedBptcRGBA = GL_COMPRESSED_RGBA_BPTC_UNORM,
/** /**
* BPTC compressed sRGBA, unsigned normalized. * BPTC compressed sRGBA, unsigned normalized.
* * @requires_gl
* @requires_gl42 Extension @extension{ARB,texture_compression_bptc} * @requires_gl42 Extension @extension{ARB,texture_compression_bptc}
*/ */
CompressedBptcSRGBA = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, CompressedBptcSRGBA = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
/** /**
* BPTC compressed RGB, signed float. * BPTC compressed RGB, signed float.
* * @requires_gl
* @requires_gl42 Extension @extension{ARB,texture_compression_bptc} * @requires_gl42 Extension @extension{ARB,texture_compression_bptc}
*/ */
CompressedBptcRGBSignedFloat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, CompressedBptcRGBSignedFloat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT,
/** /**
* BPTC compressed RGB, unsigned float. * BPTC compressed RGB, unsigned float.
* * @requires_gl
* @requires_gl42 Extension @extension{ARB,texture_compression_bptc} * @requires_gl42 Extension @extension{ARB,texture_compression_bptc}
*/ */
CompressedBptcRGBUnsignedFloat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, CompressedBptcRGBUnsignedFloat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
@ -406,35 +441,47 @@ class MAGNUM_EXPORT AbstractTexture {
/** Depth component. */ /** Depth component. */
Depth = GL_DEPTH_COMPONENT, Depth = GL_DEPTH_COMPONENT,
/** Depth and stencil component. */ #ifndef MAGNUM_TARGET_GLES
/**
* Depth and stencil component.
* @requires_gl
*/
DepthStencil = GL_DEPTH_STENCIL, DepthStencil = GL_DEPTH_STENCIL,
#endif
/** 16bit depth component. */ /** 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, Depth24 = GL_DEPTH_COMPONENT24,
/** /**
* 32bit float depth component. * 32bit float depth component.
* * @requires_gl
* @requires_gl30 Extension @extension{ARB,depth_buffer_float} * @requires_gl30 Extension @extension{ARB,depth_buffer_float}
*/ */
Depth32Float = GL_DEPTH_COMPONENT32F, Depth32Float = GL_DEPTH_COMPONENT32F,
/** /**
* 24bit depth and 8bit stencil component. * 24bit depth and 8bit stencil component.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,packed_depth_stencil} * @requires_gl30 Extension @extension{EXT,packed_depth_stencil}
*/ */
Depth24Stencil8 = GL_DEPTH24_STENCIL8, Depth24Stencil8 = GL_DEPTH24_STENCIL8,
/** /**
* 32bit float depth component and 8bit stencil component. * 32bit float depth component and 8bit stencil component.
* * @requires_gl
* @requires_gl30 Extension @extension{ARB,depth_buffer_float} * @requires_gl30 Extension @extension{ARB,depth_buffer_float}
*/ */
Depth32FloatStencil8 = GL_DEPTH32F_STENCIL8 Depth32FloatStencil8 = GL_DEPTH32F_STENCIL8
#endif
}; };
/** /**
@ -455,8 +502,14 @@ class MAGNUM_EXPORT AbstractTexture {
*/ */
class MAGNUM_EXPORT InternalFormat { class MAGNUM_EXPORT InternalFormat {
public: 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); InternalFormat(Components components, ComponentType type);
#endif
/** @brief Constructor from named internal format */ /** @brief Constructor from named internal format */
inline constexpr InternalFormat(Format format): internalFormat(static_cast<GLint>(format)) {} inline constexpr InternalFormat(Format format): internalFormat(static_cast<GLint>(format)) {}
@ -478,6 +531,7 @@ class MAGNUM_EXPORT AbstractTexture {
*/ */
static GLint maxSupportedLayerCount(); static GLint maxSupportedLayerCount();
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Max supported anisotropy * @brief Max supported anisotropy
* *
@ -485,6 +539,7 @@ class MAGNUM_EXPORT AbstractTexture {
* @requires_extension @extension{EXT,texture_filter_anisotropic} * @requires_extension @extension{EXT,texture_filter_anisotropic}
*/ */
static GLfloat maxSupportedAnisotropy(); static GLfloat maxSupportedAnisotropy();
#endif
/** /**
* @brief Constructor * @brief Constructor
@ -546,11 +601,13 @@ class MAGNUM_EXPORT AbstractTexture {
glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, static_cast<GLint>(filter)); glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, static_cast<GLint>(filter));
} }
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Set border color * @brief Set border color
* *
* Border color when @ref AbstractTexture::Wrapping "wrapping" is set * Border color when @ref AbstractTexture::Wrapping "wrapping" is set
* to `ClampToBorder`. * to `ClampToBorder`.
* @requires_gl
*/ */
inline void setBorderColor(const Vector4& color) { inline void setBorderColor(const Vector4& color) {
bind(); bind();
@ -569,6 +626,7 @@ class MAGNUM_EXPORT AbstractTexture {
bind(); bind();
glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
} }
#endif
/** /**
* @brief Generate mipmap * @brief Generate mipmap
@ -602,8 +660,11 @@ class MAGNUM_EXPORT AbstractTexture {
inline AbstractTexture::~AbstractTexture() { glDeleteTextures(1, &texture); } inline AbstractTexture::~AbstractTexture() { glDeleteTextures(1, &texture); }
#ifndef MAGNUM_TARGET_GLES
/** @relates AbstractTexture /** @relates AbstractTexture
@brief Convertor of component count and data type to InternalFormat @brief Convertor of component count and data type to InternalFormat
@requires_gl
*/ */
inline AbstractTexture::InternalFormat operator|(AbstractTexture::Components components, AbstractTexture::ComponentType type) { inline AbstractTexture::InternalFormat operator|(AbstractTexture::Components components, AbstractTexture::ComponentType type) {
return AbstractTexture::InternalFormat(components, 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) { inline AbstractTexture::InternalFormat operator|(AbstractTexture::ComponentType type, AbstractTexture::Components components) {
return AbstractTexture::InternalFormat(components, type); return AbstractTexture::InternalFormat(components, type);
} }
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES
template<> struct AbstractTexture::DataHelper<1> { template<> struct AbstractTexture::DataHelper<1> {
enum class Target: GLenum { enum class Target: GLenum {
Texture1D = GL_TEXTURE_1D Texture1D = GL_TEXTURE_1D
@ -636,11 +699,15 @@ template<> struct AbstractTexture::DataHelper<1> {
glTexSubImage1D(target, mipLevel, offset[0], image->dimensions()[0], static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data()); glTexSubImage1D(target, mipLevel, offset[0], image->dimensions()[0], static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
} }
}; };
#endif
template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
enum class Target: GLenum { enum class Target: GLenum {
Texture2D = GL_TEXTURE_2D, Texture2D = GL_TEXTURE_2D
#ifndef MAGNUM_TARGET_GLES
,
Texture1DArray = GL_TEXTURE_1D_ARRAY, Texture1DArray = GL_TEXTURE_1D_ARRAY,
Rectangle = GL_TEXTURE_RECTANGLE Rectangle = GL_TEXTURE_RECTANGLE
#endif
}; };
inline constexpr static Target target() { return Target::Texture2D; } 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> { template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
enum class Target: GLenum { enum class Target: GLenum {
#ifndef MAGNUM_TARGET_GLES
Texture3D = GL_TEXTURE_3D, Texture3D = GL_TEXTURE_3D,
Texture2DArray = GL_TEXTURE_2D_ARRAY Texture2DArray = GL_TEXTURE_2D_ARRAY
#endif
}; };
#ifndef MAGNUM_TARGET_GLES
inline constexpr static Target target() { return Target::Texture3D; } inline constexpr static Target target() { return Target::Texture3D; }
#endif
static void setWrapping(GLenum target, const Math::Vector<3, Wrapping>& wrapping); static void setWrapping(GLenum target, const Math::Vector<3, Wrapping>& wrapping);
#ifndef MAGNUM_TARGET_GLES
template<class Image> inline static void set(GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image, const Math::Vector<3, GLsizei>& = (Math::Vector<Image::Dimensions, GLsizei>())) { template<class Image> inline static void set(GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image, const Math::Vector<3, GLsizei>& = (Math::Vector<Image::Dimensions, GLsizei>())) {
glTexImage3D(target, mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data()); glTexImage3D(target, mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], 0, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
} }
@ -680,6 +752,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
template<class Image> inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector<3, GLint>& offset, Image* image, const Math::Vector<2, GLsizei>& = (Math::Vector<Image::Dimensions, GLsizei>())) { template<class Image> inline static void setSub(GLenum target, GLint mipLevel, const Math::Vector<3, GLint>& offset, Image* image, const Math::Vector<2, GLsizei>& = (Math::Vector<Image::Dimensions, GLsizei>())) {
glTexSubImage3D(target, mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], 1, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data()); glTexSubImage3D(target, mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], 1, static_cast<GLenum>(image->components()), static_cast<GLenum>(image->type()), image->data());
} }
#endif
}; };
#endif #endif

40
src/Buffer.h

@ -41,24 +41,32 @@ class Buffer {
/** Used for storing vertex attributes. */ /** Used for storing vertex attributes. */
Array = GL_ARRAY_BUFFER, Array = GL_ARRAY_BUFFER,
#ifndef MAGNUM_TARGET_GLES
/** /**
* Source for copies. * Source for copies.
* * @requires_gl
* @requires_gl31 Extension @extension{ARB,copy_buffer} * @requires_gl31 Extension @extension{ARB,copy_buffer}
*/ */
CopyRead = GL_COPY_READ_BUFFER, CopyRead = GL_COPY_READ_BUFFER,
/** /**
* Target for copies. * Target for copies.
* * @requires_gl
* @requires_gl31 Extension @extension{ARB,copy_buffer} * @requires_gl31 Extension @extension{ARB,copy_buffer}
*/ */
CopyWrite = GL_COPY_WRITE_BUFFER, CopyWrite = GL_COPY_WRITE_BUFFER,
#endif
/** Used for storing vertex indices. */ /** 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, PixelUnpack = GL_PIXEL_UNPACK_BUFFER,
/** Target for pixel pack operations. */ /** Target for pixel pack operations. */
@ -68,30 +76,32 @@ class Buffer {
* Source for texel fetches. * Source for texel fetches.
* *
* @see BufferedTexture * @see BufferedTexture
* @requires_gl
* @requires_gl31 Extension @extension{ARB,texture_buffer_object} * @requires_gl31 Extension @extension{ARB,texture_buffer_object}
*/ */
Texture = GL_TEXTURE_BUFFER, Texture = GL_TEXTURE_BUFFER,
/** /**
* Target for transform feedback. * Target for transform feedback.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,transform_feedback} * @requires_gl30 Extension @extension{EXT,transform_feedback}
*/ */
TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER, TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER,
/** /**
* Used for storing uniforms. * Used for storing uniforms.
* * @requires_gl
* @requires_gl31 Extension @extension{ARB,uniform_buffer_object} * @requires_gl31 Extension @extension{ARB,uniform_buffer_object}
*/ */
Uniform = GL_UNIFORM_BUFFER, Uniform = GL_UNIFORM_BUFFER,
/** /**
* Used for supplying arguments for instanced drawing. * Used for supplying arguments for instanced drawing.
* * @requires_gl
* @requires_gl40 Extension @extension{ARB,draw_indirect} * @requires_gl40 Extension @extension{ARB,draw_indirect}
*/ */
DrawIndirect = GL_DRAW_INDIRECT_BUFFER DrawIndirect = GL_DRAW_INDIRECT_BUFFER
#endif
}; };
/** @brief Buffer usage */ /** @brief Buffer usage */
@ -101,52 +111,66 @@ class Buffer {
*/ */
StreamDraw = GL_STREAM_DRAW, StreamDraw = GL_STREAM_DRAW,
#ifndef MAGNUM_TARGET_GLES
/** /**
* Set once as output from an OpenGL command and used infequently * Set once as output from an OpenGL command and used infequently
* for drawing. * for drawing.
* @requires_gl
*/ */
StreamRead = GL_STREAM_READ, StreamRead = GL_STREAM_READ,
/** /**
* Set once as output from an OpenGL command and used infrequently * Set once as output from an OpenGL command and used infrequently
* for drawing or copying to other buffers. * for drawing or copying to other buffers.
* @requires_gl
*/ */
StreamCopy = GL_STREAM_COPY, StreamCopy = GL_STREAM_COPY,
#endif
/** /**
* Set once by the application and used frequently for drawing. * Set once by the application and used frequently for drawing.
*/ */
StaticDraw = GL_STATIC_DRAW, StaticDraw = GL_STATIC_DRAW,
#ifndef MAGNUM_TARGET_GLES
/** /**
* Set once as output from an OpenGL command and queried many * Set once as output from an OpenGL command and queried many
* times by the application. * times by the application.
* @requires_gl
*/ */
StaticRead = GL_STATIC_READ, StaticRead = GL_STATIC_READ,
/** /**
* Set once as output from an OpenGL command and used frequently * Set once as output from an OpenGL command and used frequently
* for drawing or copying to other buffers. * for drawing or copying to other buffers.
* @requires_gl
*/ */
StaticCopy = GL_STATIC_COPY, StaticCopy = GL_STATIC_COPY,
#endif
/** /**
* Updated frequently by the application and used frequently * Updated frequently by the application and used frequently
* for drawing or copying to other images. * 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 * Updated frequently as output from OpenGL command and queried
* many times from the application. * many times from the application.
* @requires_gl
*/ */
DynamicRead = GL_DYNAMIC_READ, DynamicRead = GL_DYNAMIC_READ,
/** /**
* Updated frequently as output from OpenGL command and used * Updated frequently as output from OpenGL command and used
* frequently for drawing or copying to other images. * frequently for drawing or copying to other images.
* @requires_gl
*/ */
DynamicCopy = GL_DYNAMIC_COPY DynamicCopy = GL_DYNAMIC_COPY
#endif
}; };
/** /**

3
src/BufferedImage.h

@ -25,6 +25,7 @@
namespace Magnum { namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
/** @addtogroup textures /** @addtogroup textures
* @{ * @{
*/ */
@ -34,6 +35,7 @@ namespace Magnum {
Class for storing image data in GPU memory. Can be replaced with Image, which 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. stores image data in client memory, or for example with Trade::ImageData.
@requires_gl
*/ */
template<size_t imageDimensions> class BufferedImage: public AbstractImage { template<size_t imageDimensions> class BufferedImage: public AbstractImage {
public: public:
@ -115,6 +117,7 @@ typedef BufferedImage<2> BufferedImage2D;
typedef BufferedImage<3> BufferedImage3D; typedef BufferedImage<3> BufferedImage3D;
/*@}*/ /*@}*/
#endif
} }

2
src/BufferedTexture.cpp

@ -17,6 +17,7 @@
namespace Magnum { namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
BufferedTexture::InternalFormat::InternalFormat(Components components, ComponentType type) { BufferedTexture::InternalFormat::InternalFormat(Components components, ComponentType type) {
#define internalFormatSwitch(c) switch(type) { \ #define internalFormatSwitch(c) switch(type) { \
case ComponentType::UnsignedByte: \ case ComponentType::UnsignedByte: \
@ -48,5 +49,6 @@ BufferedTexture::InternalFormat::InternalFormat(Components components, Component
internalFormatSwitch(RGBA) internalFormatSwitch(RGBA)
#undef internalFormatSwitch #undef internalFormatSwitch
} }
#endif
} }

3
src/BufferedTexture.h

@ -24,6 +24,7 @@
namespace Magnum { namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
/** @ingroup textures /** @ingroup textures
@brief Buffered texture @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 When using buffered texture in the shader, use `samplerBuffer` and fetch the
data using integer coordinates in `texelFetch()`. data using integer coordinates in `texelFetch()`.
@requires_gl
@requires_gl31 Extension @extension{ARB,texture_buffer_object} @requires_gl31 Extension @extension{ARB,texture_buffer_object}
*/ */
class BufferedTexture { class BufferedTexture {
@ -161,6 +163,7 @@ inline BufferedTexture::InternalFormat operator|(BufferedTexture::Components com
inline BufferedTexture::InternalFormat operator|(BufferedTexture::ComponentType type, BufferedTexture::Components components) { inline BufferedTexture::InternalFormat operator|(BufferedTexture::ComponentType type, BufferedTexture::Components components) {
return BufferedTexture::InternalFormat(components, type); return BufferedTexture::InternalFormat(components, type);
} }
#endif
} }

26
src/CMakeLists.txt

@ -1,6 +1,13 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -std=c++0x -fvisibility=hidden") 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 # Files shared between main library and unit test library
set(Magnum_SRCS set(Magnum_SRCS
@ -45,9 +52,17 @@ add_library(Magnum SHARED
$<TARGET_OBJECTS:MagnumMathObjects> $<TARGET_OBJECTS:MagnumMathObjects>
${Magnum_GracefulAssert_SRCS} ${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(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(Contexts)
add_subdirectory(Math) add_subdirectory(Math)
add_subdirectory(MeshTools) add_subdirectory(MeshTools)
@ -64,7 +79,12 @@ if(BUILD_TESTS)
${Magnum_GracefulAssert_SRCS} ${Magnum_GracefulAssert_SRCS}
) )
set_target_properties(MagnumTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) 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}) include_directories(${QT_INCLUDE_DIR})
add_subdirectory(Test) add_subdirectory(Test)

7
src/Camera.h

@ -42,12 +42,14 @@ class MAGNUM_EXPORT Camera: public Object {
enum class Feature: GLenum { enum class Feature: GLenum {
AlphaBlending = GL_BLEND, /**< Alpha blending */ AlphaBlending = GL_BLEND, /**< Alpha blending */
#ifndef MAGNUM_TARGET_GLES
/** /**
* Depth clamping. If enabled, ignores near and far clipping plane. * Depth clamping. If enabled, ignores near and far clipping plane.
* * @requires_gl
* @requires_gl32 Extension @extension{ARB,depth_clamp} * @requires_gl32 Extension @extension{ARB,depth_clamp}
*/ */
DepthClamp = GL_DEPTH_CLAMP, DepthClamp = GL_DEPTH_CLAMP,
#endif
DepthTest = GL_DEPTH_TEST, /**< Depth test */ DepthTest = GL_DEPTH_TEST, /**< Depth test */
StencilTest = GL_STENCIL_TEST, /**< Stencil 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()); glClearColor(color.r(), color.g(), color.b(), color.a());
} }
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Set clear depth * @brief Set clear depth
* *
* Initial value is `1.0`. * Initial value is `1.0`.
* @requires_gl See setClearDepth(GLfloat), which is supported in OpenGL ES.
*/ */
inline static void setClearDepth(GLdouble depth) { glClearDepth(depth); } inline static void setClearDepth(GLdouble depth) { glClearDepth(depth); }
#endif
/** /**
* @overload * @overload

16
src/Contexts/CMakeLists.txt

@ -1,13 +1,15 @@
install(FILES AbstractContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) install(FILES AbstractContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts)
# GLUT context # GLUT context
find_package(GLUT) if(NOT TARGET_GLES)
if(GLUT_FOUND) find_package(GLUT)
add_library(MagnumGlutContext STATIC GlutContext.cpp) if(GLUT_FOUND)
install(FILES GlutContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) add_library(MagnumGlutContext STATIC GlutContext.cpp)
install(TARGETS MagnumGlutContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES GlutContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts)
else() install(TARGETS MagnumGlutContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
message(WARNING "GLUT library was not found. GLUT context library will not be generated.") else()
message(WARNING "GLUT library was not found. GLUT context library will not be generated.")
endif()
endif() endif()
# SDL2 context # SDL2 context

2
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); context = SDL_GL_CreateContext(window);
#ifndef MAGNUM_TARGET_GLES
/* This must be enabled, otherwise (on my NVidia) it crashes when creating /* This must be enabled, otherwise (on my NVidia) it crashes when creating
VAO. WTF. */ VAO. WTF. */
glewExperimental = true; 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); Error() << "Sdl2Context: cannot initialize GLEW:" << glewGetErrorString(err);
exit(1); exit(1);
} }
#endif
/* Push resize event, so viewportEvent() is called at startup */ /* Push resize event, so viewportEvent() is called at startup */
SDL_Event* sizeEvent = new SDL_Event; SDL_Event* sizeEvent = new SDL_Event;

3
src/CubeMapTexture.h

@ -59,14 +59,17 @@ class CubeMapTexture: public AbstractTexture {
NegativeZ = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z /**< -Z cube side */ NegativeZ = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z /**< -Z cube side */
}; };
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Enable/disable seamless cube map textures * @brief Enable/disable seamless cube map textures
* *
* @requires_gl
* @requires_gl32 Extension @extension{ARB,seamless_cube_map} * @requires_gl32 Extension @extension{ARB,seamless_cube_map}
*/ */
inline static void setSeamless(bool enabled) { inline static void setSeamless(bool enabled) {
enabled ? glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) : glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); enabled ? glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) : glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
} }
#endif
/** /**
* @brief Constructor * @brief Constructor

4
src/Framebuffer.cpp

@ -17,6 +17,7 @@
namespace Magnum { namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
void Framebuffer::mapDefaultForDraw(std::initializer_list<DefaultDrawAttachment> attachments) { void Framebuffer::mapDefaultForDraw(std::initializer_list<DefaultDrawAttachment> attachments) {
GLenum* _attachments = new GLenum[attachments.size()]; GLenum* _attachments = new GLenum[attachments.size()];
for(auto it = attachments.begin(); it != attachments.end(); ++it) for(auto it = attachments.begin(); it != attachments.end(); ++it)
@ -36,6 +37,7 @@ void Framebuffer::mapForDraw(std::initializer_list<int> colorAttachments) {
glDrawBuffers(colorAttachments.size(), attachments); glDrawBuffers(colorAttachments.size(), attachments);
delete[] attachments; delete[] attachments;
} }
#endif
void Framebuffer::read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image) { void Framebuffer::read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image) {
char* data = new char[AbstractImage::pixelSize(components, type)*dimensions.product()]; char* data = new char[AbstractImage::pixelSize(components, type)*dimensions.product()];
@ -43,6 +45,7 @@ void Framebuffer::read(const Math::Vector2<GLint>& offset, const Math::Vector2<G
image->setData(dimensions, components, type, data); image->setData(dimensions, components, type, data);
} }
#ifndef MAGNUM_TARGET_GLES
void Framebuffer::read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage) { void Framebuffer::read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage) {
/* If the buffer doesn't have sufficient size, resize it */ /* If the buffer doesn't have sufficient size, resize it */
/** @todo Explicitly reset also when buffer usage changes */ /** @todo Explicitly reset also when buffer usage changes */
@ -52,5 +55,6 @@ void Framebuffer::read(const Math::Vector2<GLint>& offset, const Math::Vector2<G
image->buffer()->bind(Buffer::Target::PixelPack); image->buffer()->bind(Buffer::Target::PixelPack);
glReadPixels(offset.x(), offset.y(), dimensions.x(), dimensions.y(), static_cast<GLenum>(components), static_cast<GLenum>(type), nullptr); glReadPixels(offset.x(), offset.y(), dimensions.x(), dimensions.y(), static_cast<GLenum>(components), static_cast<GLenum>(type), nullptr);
} }
#endif
} }

53
src/Framebuffer.h

@ -44,26 +44,31 @@ class MAGNUM_EXPORT Framebuffer {
* @see bind(), bindDefault() * @see bind(), bindDefault()
*/ */
enum class Target: GLenum { enum class Target: GLenum {
#ifndef MAGNUM_TARGET_GLES
/** /**
* For reading only. * For reading only.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,framebuffer_blit} * @requires_gl30 Extension @extension{EXT,framebuffer_blit}
*/ */
Read = GL_READ_FRAMEBUFFER, Read = GL_READ_FRAMEBUFFER,
/** /**
* For drawing only. * For drawing only.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,framebuffer_blit} * @requires_gl30 Extension @extension{EXT,framebuffer_blit}
*/ */
Draw = GL_DRAW_FRAMEBUFFER, Draw = GL_DRAW_FRAMEBUFFER,
#endif
ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */ ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */
}; };
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Draw attachment for default framebuffer * @brief Draw attachment for default framebuffer
* *
* @see mapDefaultForDraw() * @see mapDefaultForDraw()
* @requires_gl
*/ */
enum class DefaultDrawAttachment: GLenum { enum class DefaultDrawAttachment: GLenum {
None = GL_NONE, /**< Don't use the output. */ None = GL_NONE, /**< Don't use the output. */
@ -77,6 +82,7 @@ class MAGNUM_EXPORT Framebuffer {
* @brief Read attachment for default framebuffer * @brief Read attachment for default framebuffer
* *
* @see mapDefaultForRead() * @see mapDefaultForRead()
* @requires_gl
*/ */
enum class DefaultReadAttachment: GLenum { enum class DefaultReadAttachment: GLenum {
FrontLeft = GL_FRONT_LEFT, /**< Read from front left framebuffer. */ FrontLeft = GL_FRONT_LEFT, /**< Read from front left framebuffer. */
@ -89,6 +95,7 @@ class MAGNUM_EXPORT Framebuffer {
Back = GL_BACK, /**< Read from back framebuffers. */ Back = GL_BACK, /**< Read from back framebuffers. */
FrontAndBack = GL_FRONT_AND_BACK /**< Read from front and back framebuffers. */ FrontAndBack = GL_FRONT_AND_BACK /**< Read from front and back framebuffers. */
}; };
#endif
/** /**
* @brief Attachment for depth/stencil part of fragment shader output * @brief Attachment for depth/stencil part of fragment shader output
@ -101,8 +108,16 @@ class MAGNUM_EXPORT Framebuffer {
*/ */
enum class DepthStencilAttachment: GLenum { enum class DepthStencilAttachment: GLenum {
Depth = GL_DEPTH_ATTACHMENT, /**< Depth output only. */ 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<GLenum>(target), 0); glBindFramebuffer(static_cast<GLenum>(target), 0);
} }
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Map given attachments of default framebuffer for drawing * @brief Map given attachments of default framebuffer for drawing
* @param attachments Default attachments. If any value is * @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 * should have either renderbuffer or texture attached for writing to
* work properly. * work properly.
* @see mapForDraw(), mapDefaultForRead() * @see mapForDraw(), mapDefaultForRead()
* @requires_gl
*/ */
static void mapDefaultForDraw(std::initializer_list<DefaultDrawAttachment> attachments); static void mapDefaultForDraw(std::initializer_list<DefaultDrawAttachment> attachments);
@ -160,12 +177,15 @@ class MAGNUM_EXPORT Framebuffer {
* Each used attachment should have either renderbuffer or texture * Each used attachment should have either renderbuffer or texture
* attached to work properly. * attached to work properly.
* @see mapForRead(), mapDefaultForDraw() * @see mapForRead(), mapDefaultForDraw()
* @requires_gl
*/ */
inline static void mapDefaultForRead(DefaultReadAttachment attachment) { inline static void mapDefaultForRead(DefaultReadAttachment attachment) {
bindDefault(Target::Read); bindDefault(Target::Read);
glReadBuffer(static_cast<GLenum>(attachment)); glReadBuffer(static_cast<GLenum>(attachment));
} }
#endif
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Copy block of pixels from read to draw framebuffer * @brief Copy block of pixels from read to draw framebuffer
* @param bottomLeft Bottom left coordinates of source rectangle * @param bottomLeft Bottom left coordinates of source rectangle
@ -181,7 +201,7 @@ class MAGNUM_EXPORT Framebuffer {
* mapDefaultForDraw() for binding particular framebuffer for reading * mapDefaultForDraw() for binding particular framebuffer for reading
* and drawing. If multiple attachments are specified in mapForDraw() * and drawing. If multiple attachments are specified in mapForDraw()
* / mapDefaultForDraw(), the data are written to each of them. * / mapDefaultForDraw(), the data are written to each of them.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,framebuffer_blit} * @requires_gl30 Extension @extension{EXT,framebuffer_blit}
*/ */
inline static void blit(const Math::Vector2<GLint>& bottomLeft, const Math::Vector2<GLint>& topRight, const Math::Vector2<GLint>& destinationBottomLeft, const Math::Vector2<GLint>& destinationTopRight, BlitMask blitMask, AbstractTexture::Filter filter) { inline static void blit(const Math::Vector2<GLint>& bottomLeft, const Math::Vector2<GLint>& topRight, const Math::Vector2<GLint>& destinationBottomLeft, const Math::Vector2<GLint>& destinationTopRight, BlitMask blitMask, AbstractTexture::Filter filter) {
@ -201,12 +221,13 @@ class MAGNUM_EXPORT Framebuffer {
* no interpolation is needed and thus * no interpolation is needed and thus
* AbstractTexture::Filter::NearestNeighbor filtering is used by * AbstractTexture::Filter::NearestNeighbor filtering is used by
* default. * default.
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,framebuffer_blit} * @requires_gl30 Extension @extension{EXT,framebuffer_blit}
*/ */
inline static void blit(const Math::Vector2<GLint>& bottomLeft, const Math::Vector2<GLint>& topRight, BlitMask blitMask) { inline static void blit(const Math::Vector2<GLint>& bottomLeft, const Math::Vector2<GLint>& topRight, BlitMask blitMask) {
glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast<GLbitfield>(blitMask), static_cast<GLenum>(AbstractTexture::Filter::NearestNeighbor)); glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast<GLbitfield>(blitMask), static_cast<GLenum>(AbstractTexture::Filter::NearestNeighbor));
} }
#endif
/** /**
* @brief Read block of pixels from framebuffer to image * @brief Read block of pixels from framebuffer to image
@ -218,6 +239,7 @@ class MAGNUM_EXPORT Framebuffer {
*/ */
static void read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image); static void read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image);
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Read block of pixels from framebuffer to buffered image * @brief Read block of pixels from framebuffer to buffered image
* @param offset Offset in the framebuffer * @param offset Offset in the framebuffer
@ -226,8 +248,11 @@ class MAGNUM_EXPORT Framebuffer {
* @param type Data type * @param type Data type
* @param image Buffered image where to put the data * @param image Buffered image where to put the data
* @param usage %Buffer usage * @param usage %Buffer usage
*
* @requires_gl
*/ */
static void read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage); static void read(const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage);
#endif
/** /**
* @brief Constructor * @brief Constructor
@ -248,6 +273,7 @@ class MAGNUM_EXPORT Framebuffer {
glBindFramebuffer(static_cast<GLenum>(target), framebuffer); glBindFramebuffer(static_cast<GLenum>(target), framebuffer);
} }
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Map given color attachments of current framebuffer for drawing * @brief Map given color attachments of current framebuffer for drawing
* @param colorAttachments Color attachment IDs. If any value is -1, * @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 * should have either renderbuffer or texture attached for writing to
* work properly. * work properly.
* @see mapDefaultForDraw(), mapForRead() * @see mapDefaultForDraw(), mapForRead()
* @requires_gl
*/ */
void mapForDraw(std::initializer_list<int> colorAttachments); void mapForDraw(std::initializer_list<int> colorAttachments);
@ -269,11 +296,13 @@ class MAGNUM_EXPORT Framebuffer {
* The color attachment should have either renderbuffer or texture * The color attachment should have either renderbuffer or texture
* attached for reading to work properly. * attached for reading to work properly.
* @see mapDefaultForRead(), mapForDraw() * @see mapDefaultForRead(), mapForDraw()
* @requires_gl
*/ */
inline void mapForRead(unsigned int colorAttachment) { inline void mapForRead(unsigned int colorAttachment) {
bind(Target::Read); bind(Target::Read);
glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachment); glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachment);
} }
#endif
/** /**
* @brief Attach renderbuffer to given framebuffer depth/stencil attachment * @brief Attach renderbuffer to given framebuffer depth/stencil attachment
@ -299,12 +328,15 @@ class MAGNUM_EXPORT Framebuffer {
glFramebufferRenderbuffer(static_cast<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, GL_RENDERBUFFER, renderbuffer->id()); glFramebufferRenderbuffer(static_cast<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, GL_RENDERBUFFER, renderbuffer->id());
} }
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Attach 1D texture to given framebuffer depth/stencil attachment * @brief Attach 1D texture to given framebuffer depth/stencil attachment
* @param target %Target * @param target %Target
* @param depthStencilAttachment Depth/stencil attachment * @param depthStencilAttachment Depth/stencil attachment
* @param texture 1D texture * @param texture 1D texture
* @param mipLevel Mip level * @param mipLevel Mip level
*
* @requires_gl
*/ */
inline void attachTexture1D(Target target, DepthStencilAttachment depthStencilAttachment, Texture1D* texture, GLint mipLevel) { inline void attachTexture1D(Target target, DepthStencilAttachment depthStencilAttachment, Texture1D* texture, GLint mipLevel) {
/** @todo Check for internal format compatibility */ /** @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 colorAttachment Color attachment ID (number between 0 and 15)
* @param texture 1D texture * @param texture 1D texture
* @param mipLevel Mip level * @param mipLevel Mip level
*
* @requires_gl
*/ */
inline void attachTexture1D(Target target, unsigned int colorAttachment, Texture1D* texture, GLint mipLevel) { inline void attachTexture1D(Target target, unsigned int colorAttachment, Texture1D* texture, GLint mipLevel) {
/** @todo Check for internal format compatibility */ /** @todo Check for internal format compatibility */
@ -326,6 +360,7 @@ class MAGNUM_EXPORT Framebuffer {
bind(target); bind(target);
glFramebufferTexture1D(static_cast<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(texture->target()), texture->id(), mipLevel); glFramebufferTexture1D(static_cast<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(texture->target()), texture->id(), mipLevel);
} }
#endif
/** /**
* @brief Attach 2D texture to given framebuffer depth/stencil attachment * @brief Attach 2D texture to given framebuffer depth/stencil attachment
@ -393,6 +428,7 @@ class MAGNUM_EXPORT Framebuffer {
glFramebufferTexture2D(static_cast<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(coordinate), texture->id(), mipLevel); glFramebufferTexture2D(static_cast<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(coordinate), texture->id(), mipLevel);
} }
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Attach 3D texture to given framebuffer depth/stencil attachment * @brief Attach 3D texture to given framebuffer depth/stencil attachment
* @param target %Target * @param target %Target
@ -400,6 +436,8 @@ class MAGNUM_EXPORT Framebuffer {
* @param texture 3D texture * @param texture 3D texture
* @param mipLevel Mip level * @param mipLevel Mip level
* @param layer Layer of 2D image within a 3D texture * @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) { inline void attachTexture3D(Target target, DepthStencilAttachment depthStencilAttachment, Texture3D* texture, GLint mipLevel, GLint layer) {
/** @todo Check for internal format compatibility */ /** @todo Check for internal format compatibility */
@ -415,6 +453,8 @@ class MAGNUM_EXPORT Framebuffer {
* @param texture 3D texture * @param texture 3D texture
* @param mipLevel Mip level * @param mipLevel Mip level
* @param layer Layer of 2D image within a 3D texture. * @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) { inline void attachTexture3D(Target target, unsigned int colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer) {
/** @todo Check for internal format compatibility */ /** @todo Check for internal format compatibility */
@ -422,6 +462,7 @@ class MAGNUM_EXPORT Framebuffer {
bind(target); bind(target);
glFramebufferTexture3D(static_cast<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(texture->target()), texture->id(), mipLevel, layer); glFramebufferTexture3D(static_cast<GLenum>(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast<GLenum>(texture->target()), texture->id(), mipLevel, layer);
} }
#endif
private: private:
GLuint framebuffer; GLuint framebuffer;

14
src/IndexedMesh.cpp

@ -18,11 +18,19 @@
namespace Magnum { namespace Magnum {
void IndexedMesh::draw() { void IndexedMesh::draw() {
/* Vertex array must be bound before finalization */
#ifndef MAGNUM_TARGET_GLES
bind(); bind();
#endif
/* Finalize the mesh, if it is not already */
finalize(); finalize();
/* Buffers must be bound after initialization */
#ifdef MAGNUM_TARGET_GLES
bind();
_indexBuffer.bind();
#endif
/** @todo Start at given index */ /** @todo Start at given index */
glDrawElements(static_cast<GLenum>(primitive()), _indexCount, static_cast<GLenum>(_indexType), nullptr); glDrawElements(static_cast<GLenum>(primitive()), _indexCount, static_cast<GLenum>(_indexType), nullptr);
@ -38,8 +46,10 @@ void IndexedMesh::finalize() {
/* Finalize attribute positions */ /* Finalize attribute positions */
Mesh::finalize(); Mesh::finalize();
/* Bind index buffer */ /* Bind index buffer to VAO too */
#ifndef MAGNUM_TARGET_GLES
_indexBuffer.bind(); _indexBuffer.bind();
#endif
} }
#endif #endif

6
src/IndexedMesh.h

@ -69,12 +69,6 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
*/ */
inline Buffer* indexBuffer() { return &_indexBuffer; } 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(); void draw();
protected: protected:

6
src/Magnum.h

@ -19,7 +19,13 @@
* @brief Basic definitions * @brief Basic definitions
*/ */
#include "configureMagnum.h"
#ifndef MAGNUM_TARGET_GLES
#include <GL/glew.h> #include <GL/glew.h>
#else
#include <GLES2/gl2.h>
#endif
#include "Math/Math.h" #include "Math/Math.h"
#include "Math/Matrix4.h" #include "Math/Matrix4.h"

63
src/Mesh.cpp

@ -21,10 +21,12 @@ using namespace std;
namespace Magnum { namespace Magnum {
Mesh::~Mesh() { Mesh::~Mesh() {
for(auto it: _buffers) for(auto& it: _buffers)
delete it.first; delete it.first;
#ifndef MAGNUM_TARGET_GLES
glDeleteVertexArrays(1, &vao); glDeleteVertexArrays(1, &vao);
#endif
} }
Buffer* Mesh::addBuffer(BufferType interleaved) { Buffer* Mesh::addBuffer(BufferType interleaved) {
@ -35,17 +37,42 @@ Buffer* Mesh::addBuffer(BufferType interleaved) {
} }
void Mesh::draw() { void Mesh::draw() {
/* Vertex array must be bound before finalization */
#ifndef MAGNUM_TARGET_GLES
bind(); bind();
#endif
/* Finalize the mesh, if it is not already */ /* Finalize, if not already */
finalize(); finalize();
/* Buffers must be bound after initialization */
#ifdef MAGNUM_TARGET_GLES
bind();
#endif
/** @todo Start at given index */ /** @todo Start at given index */
glDrawArrays(static_cast<GLenum>(_primitive), 0, _vertexCount); glDrawArrays(static_cast<GLenum>(_primitive), 0, _vertexCount);
unbind(); 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<GLuint>::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it)
glDisableVertexAttribArray(*it);
#endif
}
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
void Mesh::finalize() { void Mesh::finalize() {
/* Already finalized */ /* Already finalized */
@ -53,12 +80,8 @@ void Mesh::finalize() {
CORRADE_ASSERT(_vertexCount, "Mesh: the mesh has zero vertex count!", ) CORRADE_ASSERT(_vertexCount, "Mesh: the mesh has zero vertex count!", )
/* Enable vertex arrays for all attributes */
for(set<GLuint>::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it)
glEnableVertexAttribArray(*it);
/* Finalize attribute positions for every buffer */ /* Finalize attribute positions for every buffer */
for(auto it: _buffers) { for(auto& it: _buffers) {
/* Avoid confustion */ /* Avoid confustion */
bool interleaved = it.second.first == BufferType::Interleaved; bool interleaved = it.second.first == BufferType::Interleaved;
vector<Attribute>& attributes = it.second.second; vector<Attribute>& attributes = it.second.second;
@ -91,19 +114,37 @@ void Mesh::finalize() {
position += ait->size*TypeInfo::sizeOf(ait->type)*_vertexCount; 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<GLuint>::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it)
glEnableVertexAttribArray(*it);
for(auto& it: _buffers) {
/* Avoid confusion */
vector<Attribute>& attributes = it.second.second;
/* Bind buffer */ /* Bind buffer */
it.first->bind(); it.first->bind();
/* Bind all attributes to this buffer */ /* Bind all attributes to this buffer */
for(vector<Attribute>::const_iterator ait = attributes.begin(); ait != attributes.end(); ++ait) for(vector<Attribute>::const_iterator ait = attributes.begin(); ait != attributes.end(); ++ait)
#ifndef MAGNUM_TARGET_GLES
if(TypeInfo::isIntegral(ait->type)) if(TypeInfo::isIntegral(ait->type))
glVertexAttribIPointer(ait->attribute, ait->size, static_cast<GLenum>(ait->type), ait->stride, ait->pointer); glVertexAttribIPointer(ait->attribute, ait->size, static_cast<GLenum>(ait->type), ait->stride, ait->pointer);
else glVertexAttribPointer(ait->attribute, ait->size, static_cast<GLenum>(ait->type), GL_FALSE, ait->stride, ait->pointer); else
#endif
glVertexAttribPointer(ait->attribute, ait->size, static_cast<GLenum>(ait->type), GL_FALSE, ait->stride, ait->pointer);
} }
/* Mesh is now finalized, attribute binding is not allowed */
finalized = true;
} }
#endif #endif

36
src/Mesh.h

@ -33,12 +33,12 @@ class Buffer;
/** @ingroup rendering mesh /** @ingroup rendering mesh
@brief Base class for managing non-indexed meshes @brief Base class for managing non-indexed meshes
@todo Support for normalized values (e.g. for color as char[4] passed to VAOs are used for desktop OpenGL (not in OpenGL ES).
shader as floating-point vec4)
@requires_gl30 Extension @extension{APPLE,vertex_array_object} @requires_gl30 Extension @extension{APPLE,vertex_array_object}
@requires_gl30 Extension @extension{EXT,gpu_shader4} (for unsigned integer attributes) @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 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 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}) @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; Mesh& operator=(Mesh&& other) = delete;
public: public:
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Polygon mode * @brief Polygon mode
* *
* @see setPolygonMode() * @see setPolygonMode()
* @requires_gl
*/ */
enum class PolygonMode: GLenum { enum class PolygonMode: GLenum {
/** /**
@ -75,6 +77,7 @@ class MAGNUM_EXPORT Mesh {
*/ */
Point = GL_POINT Point = GL_POINT
}; };
#endif
/** /**
* @brief Primitive type * @brief Primitive type
@ -135,14 +138,17 @@ class MAGNUM_EXPORT Mesh {
NonInterleaved /**< Non-interleaved buffer */ NonInterleaved /**< Non-interleaved buffer */
}; };
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Set polygon drawing mode * @brief Set polygon drawing mode
* *
* Initial value is PolygonMode::Fill. * Initial value is PolygonMode::Fill.
* @requires_gl
*/ */
inline static void setPolygonMode(PolygonMode mode) { inline static void setPolygonMode(PolygonMode mode) {
glPolygonMode(GL_FRONT_AND_BACK, static_cast<GLenum>(mode)); glPolygonMode(GL_FRONT_AND_BACK, static_cast<GLenum>(mode));
} }
#endif
/** /**
* @brief Set line width * @brief Set line width
@ -153,10 +159,12 @@ class MAGNUM_EXPORT Mesh {
glLineWidth(width); glLineWidth(width);
} }
#ifndef MAGNUM_TARGET_GLES
/** /**
* @brief Set point size * @brief Set point size
* *
* @see setProgramPointSize() * @see setProgramPointSize()
* @requires_gl
*/ */
inline static void setPointSize(GLfloat size) { inline static void setPointSize(GLfloat size) {
glPointSize(size); glPointSize(size);
@ -168,10 +176,12 @@ class MAGNUM_EXPORT Mesh {
* If enabled, the point size is taken from vertex/geometry shader * If enabled, the point size is taken from vertex/geometry shader
* builtin `gl_PointSize`. * builtin `gl_PointSize`.
* @see setPointSize() * @see setPointSize()
* @requires_gl
*/ */
inline static void setProgramPointSize(bool enabled) { inline static void setProgramPointSize(bool enabled) {
enabled ? glEnable(GL_PROGRAM_POINT_SIZE) : glDisable(GL_PROGRAM_POINT_SIZE); enabled ? glEnable(GL_PROGRAM_POINT_SIZE) : glDisable(GL_PROGRAM_POINT_SIZE);
} }
#endif
/** /**
* @brief Implicit constructor * @brief Implicit constructor
@ -182,7 +192,9 @@ class MAGNUM_EXPORT Mesh {
* to draw properly. * to draw properly.
*/ */
inline Mesh(Primitive primitive = Primitive::Triangles): _primitive(primitive), _vertexCount(0), finalized(false) { inline Mesh(Primitive primitive = Primitive::Triangles): _primitive(primitive), _vertexCount(0), finalized(false) {
#ifndef MAGNUM_TARGET_GLES
glGenVertexArrays(1, &vao); glGenVertexArrays(1, &vao);
#endif
} }
/** /**
@ -191,7 +203,9 @@ class MAGNUM_EXPORT Mesh {
* @param vertexCount Vertex count * @param vertexCount Vertex count
*/ */
inline Mesh(Primitive primitive, GLsizei vertexCount): _primitive(primitive), _vertexCount(vertexCount), finalized(false) { inline Mesh(Primitive primitive, GLsizei vertexCount): _primitive(primitive), _vertexCount(vertexCount), finalized(false) {
#ifndef MAGNUM_TARGET_GLES
glGenVertexArrays(1, &vao); glGenVertexArrays(1, &vao);
#endif
} }
/** /**
@ -268,18 +282,20 @@ class MAGNUM_EXPORT Mesh {
/** /**
* @brief Draw the mesh * @brief Draw the mesh
* *
* Binds attributes to buffers and draws the mesh. Expects an active * Expects an active shader with all uniforms set.
* shader with all uniforms set.
*/ */
virtual void draw(); virtual void draw();
protected: protected:
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/** @brief Unbind any vertex array object */ /** @brief Bind all buffers */
inline static void unbind() { glBindVertexArray(0); } void bindBuffers();
/** @brief Bind vertex array object of current mesh */ /** @brief Bind vertex array or all buffers */
inline void bind() { glBindVertexArray(vao); } void bind();
/** @brief Unbind vertex array or all buffers */
void unbind();
/** /**
* @brief Finalize the mesh * @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 */ const GLvoid* pointer; /**< @brief Pointer to first attribute of this type in the buffer */
}; };
#ifndef MAGNUM_TARGET_GLES
GLuint vao; GLuint vao;
#endif
Primitive _primitive; Primitive _primitive;
GLsizei _vertexCount; GLsizei _vertexCount;
bool finalized; bool finalized;

2
src/Query.cpp

@ -17,6 +17,7 @@
namespace Magnum { namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
bool AbstractQuery::resultAvailable() { bool AbstractQuery::resultAvailable() {
GLuint result; GLuint result;
glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &result); glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &result);
@ -78,5 +79,6 @@ void SampleQuery::end() {
delete target; delete target;
target = nullptr; target = nullptr;
} }
#endif
} }

7
src/Query.h

@ -23,6 +23,7 @@
namespace Magnum { namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
/** @addtogroup rendering /** @addtogroup rendering
* @{ * @{
*/ */
@ -32,6 +33,7 @@ namespace Magnum {
See Query, SampleQuery, TimeQuery documentation for more information. See Query, SampleQuery, TimeQuery documentation for more information.
@todo Support for AMD's query buffer (@extension{AMD,query_buffer_object}) @todo Support for AMD's query buffer (@extension{AMD,query_buffer_object})
@requires_gl
*/ */
class MAGNUM_EXPORT AbstractQuery { class MAGNUM_EXPORT AbstractQuery {
public: public:
@ -98,6 +100,7 @@ if(!q.resultAvailable()) {
// ...or block until the result is available // ...or block until the result is available
GLuint primitiveCount = q.result<GLuint>(); GLuint primitiveCount = q.result<GLuint>();
@endcode @endcode
@requires_gl
*/ */
class MAGNUM_EXPORT Query: public AbstractQuery { class MAGNUM_EXPORT Query: public AbstractQuery {
public: public:
@ -176,6 +179,7 @@ q.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait);
// render full version of the object only if the query returns nonzero result // render full version of the object only if the query returns nonzero result
q.endConditionalRender(); q.endConditionalRender();
@endcode @endcode
@requires_gl
*/ */
class MAGNUM_EXPORT SampleQuery: public AbstractQuery { class MAGNUM_EXPORT SampleQuery: public AbstractQuery {
public: public:
@ -273,7 +277,7 @@ GLuint timeElapsed1 = tmp-q1.result<GLuint>();
GLuint timeElapsed2 = q3.result<GLuint>()-tmp; GLuint timeElapsed2 = q3.result<GLuint>()-tmp;
@endcode @endcode
Using this query results in fewer OpenGL calls when doing more measures. Using this query results in fewer OpenGL calls when doing more measures.
@requires_gl
@requires_gl33 Extension @extension{ARB,timer_query} @requires_gl33 Extension @extension{ARB,timer_query}
*/ */
class TimeQuery: public AbstractQuery { class TimeQuery: public AbstractQuery {
@ -285,6 +289,7 @@ class TimeQuery: public AbstractQuery {
}; };
/*@}*/ /*@}*/
#endif
} }

2
src/Renderbuffer.cpp

@ -17,6 +17,7 @@
namespace Magnum { namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
Renderbuffer::InternalFormat::InternalFormat(Components components, ComponentType type) { Renderbuffer::InternalFormat::InternalFormat(Components components, ComponentType type) {
#define internalFormatSwitch(c) switch(type) { \ #define internalFormatSwitch(c) switch(type) { \
case ComponentType::UnsignedByte: \ case ComponentType::UnsignedByte: \
@ -48,5 +49,6 @@ Renderbuffer::InternalFormat::InternalFormat(Components components, ComponentTyp
internalFormatSwitch(RGBA) internalFormatSwitch(RGBA)
#undef internalFormatSwitch #undef internalFormatSwitch
} }
#endif
} }

40
src/Renderbuffer.h

@ -39,10 +39,12 @@ class Renderbuffer {
public: public:
/** @{ @name Internal renderbuffer formats */ /** @{ @name Internal renderbuffer formats */
#ifndef MAGNUM_TARGET_GLES
/** /**
* @copydoc AbstractTexture::Components * @copydoc AbstractTexture::Components
* *
* Like AbstractTexture::Components, without three-component RGB. * Like AbstractTexture::Components, without three-component RGB.
* @requires_gl
*/ */
enum class Components { enum class Components {
Red, RedGreen, RGBA Red, RedGreen, RGBA
@ -53,11 +55,13 @@ class Renderbuffer {
* *
* Like AbstractTexture::ComponentType, without normalized signed * Like AbstractTexture::ComponentType, without normalized signed
* types. * types.
* @requires_gl
*/ */
enum class ComponentType { enum class ComponentType {
UnsignedByte, Byte, UnsignedShort, Short, UnsignedInt, Int, Half, UnsignedByte, Byte, UnsignedShort, Short, UnsignedInt, Int, Half,
Float, NormalizedUnsignedByte, NormalizedUnsignedShort Float, NormalizedUnsignedByte, NormalizedUnsignedShort
}; };
#endif
/** /**
* @copydoc AbstractTexture::Format * @copydoc AbstractTexture::Format
@ -67,21 +71,43 @@ class Renderbuffer {
* compressed formats. * compressed formats.
*/ */
enum class Format: GLenum { enum class Format: GLenum {
Red = GL_RED, RedGreen = GL_RG, RGBA = GL_RGBA, BGRA = GL_BGRA, #ifndef MAGNUM_TARGET_GLES
SRGBA = GL_SRGB8_ALPHA8, 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, RGB10Alpha2 = GL_RGB10_A2, RGB10AlphaUnsigned2 = GL_RGB10_A2UI,
#endif
RGB5Alpha1 = GL_RGB5_A1, RGBA4 = GL_RGBA4, RGB5Alpha1 = GL_RGB5_A1, RGBA4 = GL_RGBA4,
#ifndef MAGNUM_TARGET_GLES
RFloat11GFloat11BFloat10 = GL_R11F_G11F_B10F, RFloat11GFloat11BFloat10 = GL_R11F_G11F_B10F,
#endif
#if defined(GL_RGB565) || defined(DOXYGEN_GENERATING_OUTPUT) #if defined(GL_RGB565) || defined(DOXYGEN_GENERATING_OUTPUT)
RGB565 = GL_RGB565, RGB565 = GL_RGB565,
#endif #endif
Depth = GL_DEPTH_COMPONENT, DepthStencil = GL_DEPTH_STENCIL, Depth = GL_DEPTH_COMPONENT,
Depth16 = GL_DEPTH_COMPONENT16, Depth24 = GL_DEPTH_COMPONENT24,
#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, DepthFloat = GL_DEPTH_COMPONENT32F,
Depth24Stencil8 = GL_DEPTH24_STENCIL8, Depth24Stencil8 = GL_DEPTH24_STENCIL8,
DepthFloatStencil8 = GL_DEPTH32F_STENCIL8 DepthFloatStencil8 = GL_DEPTH32F_STENCIL8
#endif
/** @todo GL_STENCIL_INDEX1 - GL_STENCIL_INDEX16 (renderbuffer only) */ /** @todo GL_STENCIL_INDEX1 - GL_STENCIL_INDEX16 (renderbuffer only) */
}; };
@ -89,8 +115,10 @@ class Renderbuffer {
/** @copydoc AbstractTexture::InternalFormat */ /** @copydoc AbstractTexture::InternalFormat */
class MAGNUM_EXPORT InternalFormat { class MAGNUM_EXPORT InternalFormat {
public: public:
#ifndef MAGNUM_TARGET_GLES
/** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components, AbstractTexture::ComponentType) */ /** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components, AbstractTexture::ComponentType) */
InternalFormat(Components components, ComponentType type); InternalFormat(Components components, ComponentType type);
#endif
/** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Format) */ /** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Format) */
inline constexpr InternalFormat(Format format): internalFormat(static_cast<GLenum>(format)) {} inline constexpr InternalFormat(Format format): internalFormat(static_cast<GLenum>(format)) {}
@ -148,8 +176,11 @@ class Renderbuffer {
GLuint renderbuffer; GLuint renderbuffer;
}; };
#ifndef MAGNUM_TARGET_GLES
/** @relates Renderbuffer /** @relates Renderbuffer
@brief Convertor of component count and data type to InternalFormat @brief Convertor of component count and data type to InternalFormat
@requires_gl
*/ */
inline Renderbuffer::InternalFormat operator|(Renderbuffer::Components components, Renderbuffer::ComponentType type) { inline Renderbuffer::InternalFormat operator|(Renderbuffer::Components components, Renderbuffer::ComponentType type) {
return Renderbuffer::InternalFormat(components, 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) { inline Renderbuffer::InternalFormat operator|(Renderbuffer::ComponentType type, Renderbuffer::Components components) {
return Renderbuffer::InternalFormat(components, type); return Renderbuffer::InternalFormat(components, type);
} }
#endif
} }

4
src/Shader.cpp

@ -98,10 +98,14 @@ GLuint Shader::compile() {
switch(_type) { switch(_type) {
case Type::Vertex: err << "vertex"; break; case Type::Vertex: err << "vertex"; break;
#ifndef MAGNUM_TARGET_GLES
case Type::Geometry: err << "geometry"; break; case Type::Geometry: err << "geometry"; break;
#endif
case Type::Fragment: err << "fragment"; break; case Type::Fragment: err << "fragment"; break;
#ifndef MAGNUM_TARGET_GLES
case Type::TessellationControl: err << "tessellation control"; break; case Type::TessellationControl: err << "tessellation control"; break;
case Type::TessellationEvaluation: err << "tessellation evaluation"; break; case Type::TessellationEvaluation: err << "tessellation evaluation"; break;
#endif
} }
/* Show error log and delete shader */ /* Show error log and delete shader */

8
src/Shader.h

@ -42,26 +42,28 @@ class MAGNUM_EXPORT Shader {
enum class Type: GLenum { enum class Type: GLenum {
Vertex = GL_VERTEX_SHADER, /**< Vertex shader */ Vertex = GL_VERTEX_SHADER, /**< Vertex shader */
#ifndef MAGNUM_TARGET_GLES
/** /**
* Tessellation control shader * Tessellation control shader
* * @requires_gl
* @requires_gl40 Extension @extension{ARB,tessellation_shader} * @requires_gl40 Extension @extension{ARB,tessellation_shader}
*/ */
TessellationControl = GL_TESS_CONTROL_SHADER, TessellationControl = GL_TESS_CONTROL_SHADER,
/** /**
* Tessellation evaluation shader * Tessellation evaluation shader
* * @requires_gl
* @requires_gl40 Extension @extension{ARB,tessellation_shader} * @requires_gl40 Extension @extension{ARB,tessellation_shader}
*/ */
TessellationEvaluation = GL_TESS_EVALUATION_SHADER, TessellationEvaluation = GL_TESS_EVALUATION_SHADER,
/** /**
* Geometry shader * Geometry shader
* * @requires_gl
* @requires_gl32 Extension @extension{ARB,geometry_shader4} * @requires_gl32 Extension @extension{ARB,geometry_shader4}
*/ */
Geometry = GL_GEOMETRY_SHADER, Geometry = GL_GEOMETRY_SHADER,
#endif
Fragment = GL_FRAGMENT_SHADER /**< Fragment shader */ Fragment = GL_FRAGMENT_SHADER /**< Fragment shader */
}; };

37
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 "Filter", @ref Texture::Mipmap "Mipmap" and generateMipmap() documentation
for more information. for more information.
@requires_gl (rectangle textures)
@requires_gl31 Extension @extension{ARB,texture_rectangle} (rectangle textures) @requires_gl31 Extension @extension{ARB,texture_rectangle} (rectangle textures)
@see CubeMapTexture, CubeMapTextureArray @see CubeMapTexture, CubeMapTextureArray
@ -62,27 +63,37 @@ template<size_t textureDimensions> class Texture: public AbstractTexture {
* Each dimension has its own unique subset of these targets. * Each dimension has its own unique subset of these targets.
*/ */
enum class Target: GLenum { 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 */ 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) * One-dimensional texture array (i.e. two dimensions in total)
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_array} * @requires_gl30 Extension @extension{EXT,texture_array}
*/ */
Texture1DArray = GL_TEXTURE_1D_ARRAY, Texture1DArray = GL_TEXTURE_1D_ARRAY,
/** /**
* Two-dimensional texture array (i.e. three dimensions in total) * Two-dimensional texture array (i.e. three dimensions in total)
* * @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_array} * @requires_gl30 Extension @extension{EXT,texture_array}
*/ */
Texture2DArray = GL_TEXTURE_2D_ARRAY, Texture2DArray = GL_TEXTURE_2D_ARRAY,
/** /**
* Rectangle texture (i.e. two dimensions) * Rectangle texture (i.e. two dimensions)
* * @requires_gl
* @requires_gl31 Extension @extension{ARB,texture_rectangle} * @requires_gl31 Extension @extension{ARB,texture_rectangle}
*/ */
Rectangle = GL_TEXTURE_RECTANGLE Rectangle = GL_TEXTURE_RECTANGLE
@ -157,14 +168,26 @@ template<size_t textureDimensions> class Texture: public AbstractTexture {
} }
}; };
/** @brief One-dimensional texture */ #ifndef MAGNUM_TARGET_GLES
/**
@brief One-dimensional texture
@requires_gl
*/
typedef Texture<1> Texture1D; typedef Texture<1> Texture1D;
#endif
/** @brief Two-dimensional texture */ /** @brief Two-dimensional texture */
typedef Texture<2> Texture2D; typedef Texture<2> Texture2D;
/** @brief Three-dimensional texture */ #ifndef MAGNUM_TARGET_GLES
/**
@brief Three-dimensional texture
@requires_gl
*/
typedef Texture<3> Texture3D; typedef Texture<3> Texture3D;
#endif
/*@}*/ /*@}*/

4
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(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(GLint) == sizeof(int), "GLint is not the same as int");
static_assert(sizeof(GLfloat) == sizeof(float), "GLfloat is not the same as float"); 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"); static_assert(sizeof(GLdouble) == sizeof(double), "GLdouble is not the same as double");
#endif #endif
#endif
size_t TypeInfo::sizeOf(Type type) { size_t TypeInfo::sizeOf(Type type) {
switch(type) { switch(type) {
@ -37,7 +39,9 @@ size_t TypeInfo::sizeOf(Type type) {
val(Short) val(Short)
val(UnsignedInt) val(UnsignedInt)
val(Int) val(Int)
#ifndef MAGNUM_TARGET_GLES
val(Double) val(Double)
#endif
val(Float) val(Float)
#undef val #undef val

16
src/TypeTraits.h

@ -89,8 +89,16 @@ enum class Type: GLenum {
Short = GL_SHORT, /**< Short */ Short = GL_SHORT, /**< Short */
UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */ UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */
Int = GL_INT, /**< Int */ Int = GL_INT, /**< Int */
Float = GL_FLOAT, /**< Float */ Float = GL_FLOAT /**< Float */
Double = GL_DOUBLE /**< Double */
#ifndef MAGNUM_TARGET_GLES
,
/**
* Double
* @requires_gl
*/
Double = GL_DOUBLE
#endif
}; };
/** /**
@ -150,7 +158,9 @@ template<> struct TypeOf<Type::Short> { typedef GLshort Type; };
template<> struct TypeOf<Type::UnsignedInt> { typedef GLuint Type; }; template<> struct TypeOf<Type::UnsignedInt> { typedef GLuint Type; };
template<> struct TypeOf<Type::Int> { typedef GLint Type; }; template<> struct TypeOf<Type::Int> { typedef GLint Type; };
template<> struct TypeOf<Type::Float> { typedef GLfloat Type; }; template<> struct TypeOf<Type::Float> { typedef GLfloat Type; };
#ifndef MAGNUM_TARGET_GLES
template<> struct TypeOf<Type::Double> { typedef GLdouble Type; }; template<> struct TypeOf<Type::Double> { typedef GLdouble Type; };
#endif
template<> struct TypeTraits<GLubyte>: public Math::MathTypeTraits<unsigned char> { template<> struct TypeTraits<GLubyte>: public Math::MathTypeTraits<unsigned char> {
inline constexpr static Type type() { return Type::UnsignedByte; } inline constexpr static Type type() { return Type::UnsignedByte; }
@ -208,6 +218,7 @@ template<> struct TypeTraits<GLfloat>: public Math::MathTypeTraits<float> {
inline constexpr static size_t count() { return 1; } inline constexpr static size_t count() { return 1; }
}; };
#ifndef MAGNUM_TARGET_GLES
template<> struct TypeTraits<GLdouble>: public Math::MathTypeTraits<double> { template<> struct TypeTraits<GLdouble>: public Math::MathTypeTraits<double> {
inline constexpr static Type type() { return Type::Double; } inline constexpr static Type type() { return Type::Double; }
/* Can not be used for indices */ /* Can not be used for indices */
@ -215,6 +226,7 @@ template<> struct TypeTraits<GLdouble>: public Math::MathTypeTraits<double> {
inline constexpr static size_t size() { return sizeof(GLdouble); } inline constexpr static size_t size() { return sizeof(GLdouble); }
inline constexpr static size_t count() { return 1; } inline constexpr static size_t count() { return 1; }
}; };
#endif
template<class T, size_t vectorSize> struct TypeTraits<Math::Vector<vectorSize, T>> { template<class T, size_t vectorSize> struct TypeTraits<Math::Vector<vectorSize, T>> {
inline constexpr static Type type() { return TypeTraits<T>::type(); } inline constexpr static Type type() { return TypeTraits<T>::type(); }

1
src/configureMagnum.h.cmake

@ -0,0 +1 @@
#cmakedefine MAGNUM_TARGET_GLES
Loading…
Cancel
Save