Browse Source

Deinlined heavy functions and removed redundant `inline` everywhere else.

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
f7aa2c05a6
  1. 2
      doc/coding-style.dox
  2. 2
      src/AbstractFramebuffer.cpp
  3. 6
      src/AbstractFramebuffer.h
  4. 2
      src/AbstractImage.cpp
  5. 12
      src/AbstractImage.h
  6. 46
      src/AbstractResourceLoader.h
  7. 104
      src/AbstractShaderProgram.h
  8. 50
      src/AbstractTexture.h
  9. 70
      src/Array.h
  10. 42
      src/Buffer.h
  11. 6
      src/BufferImage.h
  12. 8
      src/BufferTexture.h
  13. 80
      src/Color.h
  14. 36
      src/Context.h
  15. 28
      src/CubeMapTexture.h
  16. 30
      src/CubeMapTextureArray.h
  17. 2
      src/DebugMarker.h
  18. 6
      src/DefaultFramebuffer.h
  19. 36
      src/Framebuffer.h
  20. 12
      src/Image.h
  21. 12
      src/ImageWrapper.h
  22. 2
      src/Implementation/BufferState.h
  23. 2
      src/Implementation/FramebufferState.h
  24. 2
      src/Implementation/MeshState.h
  25. 2
      src/Implementation/RendererState.h
  26. 2
      src/Implementation/ShaderProgramState.h
  27. 31
      src/Mesh.h
  28. 14
      src/Query.h
  29. 10
      src/Renderbuffer.h
  30. 12
      src/Renderer.h
  31. 154
      src/Resource.h
  32. 443
      src/ResourceManager.h
  33. 2
      src/Shader.h
  34. 2
      src/Swizzle.h
  35. 4
      src/Test/ResourceManagerTest.cpp
  36. 30
      src/Texture.h
  37. 8
      src/Timeline.h

2
doc/coding-style.dox

@ -139,7 +139,7 @@ in @c \@see block with @c \@fn_gl command. If only specific definition is used
in the function, document it with @c \@def_gl command. Example usage: in the function, document it with @c \@def_gl command. Example usage:
@code @code
// @see @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS} // @see @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS}
inline static void setSeamless(bool enabled) { 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);
} }
@endcode @endcode

2
src/AbstractFramebuffer.cpp

@ -43,6 +43,8 @@ AbstractFramebuffer::ReadBufferImplementation AbstractFramebuffer::readBufferImp
FramebufferTarget AbstractFramebuffer::readTarget = FramebufferTarget::ReadDraw; FramebufferTarget AbstractFramebuffer::readTarget = FramebufferTarget::ReadDraw;
FramebufferTarget AbstractFramebuffer::drawTarget = FramebufferTarget::ReadDraw; FramebufferTarget AbstractFramebuffer::drawTarget = FramebufferTarget::ReadDraw;
AbstractFramebuffer::~AbstractFramebuffer() {}
void AbstractFramebuffer::bind(FramebufferTarget target) { void AbstractFramebuffer::bind(FramebufferTarget target) {
bindInternal(target); bindInternal(target);
setViewportInternal(); setViewportInternal();

6
src/AbstractFramebuffer.h

@ -186,7 +186,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit} * @es_extension{NV,framebuffer_blit}
*/ */
inline static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& rectangle, FramebufferBlitMask mask) { static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& rectangle, FramebufferBlitMask mask) {
blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest); blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest);
} }
@ -205,7 +205,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
void bind(FramebufferTarget target); void bind(FramebufferTarget target);
/** @brief Viewport rectangle */ /** @brief Viewport rectangle */
inline Rectanglei viewport() const { return _viewport; } Rectanglei viewport() const { return _viewport; }
/** /**
* @brief Set viewport * @brief Set viewport
@ -316,8 +316,6 @@ class MAGNUM_EXPORT AbstractFramebuffer {
static ReadImplementation MAGNUM_LOCAL readImplementation; static ReadImplementation MAGNUM_LOCAL readImplementation;
}; };
inline AbstractFramebuffer::~AbstractFramebuffer() {}
CORRADE_ENUMSET_OPERATORS(FramebufferClearMask) CORRADE_ENUMSET_OPERATORS(FramebufferClearMask)
CORRADE_ENUMSET_OPERATORS(FramebufferBlitMask) CORRADE_ENUMSET_OPERATORS(FramebufferBlitMask)

2
src/AbstractImage.cpp

@ -30,6 +30,8 @@
namespace Magnum { namespace Magnum {
AbstractImage::~AbstractImage() {}
std::size_t AbstractImage::pixelSize(ImageFormat format, ImageType type) { std::size_t AbstractImage::pixelSize(ImageFormat format, ImageType type) {
std::size_t size = 0; std::size_t size = 0;
switch(type) { switch(type) {

12
src/AbstractImage.h

@ -66,25 +66,23 @@ class MAGNUM_EXPORT AbstractImage {
* @param format Format of pixel data * @param format Format of pixel data
* @param type Data type of pixel data * @param type Data type of pixel data
*/ */
inline explicit AbstractImage(ImageFormat format, ImageType type): _format(format), _type(type) {} explicit AbstractImage(ImageFormat format, ImageType type): _format(format), _type(type) {}
/** @brief Destructor */ /** @brief Destructor */
virtual ~AbstractImage() = 0; virtual ~AbstractImage() = 0;
/** @brief Format of pixel data */ /** @brief Format of pixel data */
inline ImageFormat format() const { return _format; } ImageFormat format() const { return _format; }
/** @brief Data type of pixel data */ /** @brief Data type of pixel data */
inline ImageType type() const { return _type; } ImageType type() const { return _type; }
/** /**
* @brief Pixel size (in bytes) * @brief Pixel size (in bytes)
* *
* Convenience member alternative for pixelSize(Format, Type). * Convenience member alternative for pixelSize(Format, Type).
*/ */
inline std::size_t pixelSize() const { std::size_t pixelSize() const { return pixelSize(_format, _type); }
return pixelSize(_format, _type);
}
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
private: private:
@ -95,8 +93,6 @@ class MAGNUM_EXPORT AbstractImage {
ImageType _type; ImageType _type;
}; };
inline AbstractImage::~AbstractImage() {}
} }
#endif #endif

46
src/AbstractResourceLoader.h

@ -98,18 +98,16 @@ template<class T> class AbstractResourceLoader {
friend class Implementation::ResourceManagerData<T>; friend class Implementation::ResourceManagerData<T>;
public: public:
inline explicit AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {} explicit AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {}
inline virtual ~AbstractResourceLoader() { virtual ~AbstractResourceLoader();
if(manager) manager->_loader = nullptr;
}
/** /**
* @brief Count of requested resources * @brief Count of requested resources
* *
* Count of resources requested by calling load(). * Count of resources requested by calling load().
*/ */
inline std::size_t requestedCount() const { return _requestedCount; } std::size_t requestedCount() const { return _requestedCount; }
/** /**
* @brief Count of not found resources * @brief Count of not found resources
@ -117,7 +115,7 @@ template<class T> class AbstractResourceLoader {
* Count of resources requested by calling load(), but not found by * Count of resources requested by calling load(), but not found by
* the loader. * the loader.
*/ */
inline std::size_t notFoundCount() const { return _notFoundCount; } std::size_t notFoundCount() const { return _notFoundCount; }
/** /**
* @brief Count of loaded resources * @brief Count of loaded resources
@ -125,7 +123,7 @@ template<class T> class AbstractResourceLoader {
* Count of resources requested by calling load(), but not found by * Count of resources requested by calling load(), but not found by
* the loader. * the loader.
*/ */
inline std::size_t loadedCount() const { return _loadedCount; } std::size_t loadedCount() const { return _loadedCount; }
/** /**
* @brief %Resource name corresponding to given key * @brief %Resource name corresponding to given key
@ -160,12 +158,7 @@ template<class T> class AbstractResourceLoader {
* ResourceManager::set() for more information. * ResourceManager::set() for more information.
* @see loadedCount() * @see loadedCount()
*/ */
inline void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy);
CORRADE_ASSERT(state == ResourceDataState::Mutable || state == ResourceDataState::Final,
"AbstractResourceLoader::set(): state must be either Mutable or Final", );
++_loadedCount;
manager->set(key, data, state, policy);
}
/** /**
* @brief Mark resource as not found * @brief Mark resource as not found
@ -174,11 +167,7 @@ template<class T> class AbstractResourceLoader {
* ResourceManager::setNotFound() for more information. * ResourceManager::setNotFound() for more information.
* @see notFountCount() * @see notFountCount()
*/ */
inline void setNotFound(ResourceKey key) { void setNotFound(ResourceKey key);
++_notFoundCount;
/** @todo What policy for notfound resources? */
manager->set(key, nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
}
private: private:
Implementation::ResourceManagerData<T>* manager; Implementation::ResourceManagerData<T>* manager;
@ -187,14 +176,31 @@ template<class T> class AbstractResourceLoader {
std::size_t _notFoundCount; std::size_t _notFoundCount;
}; };
template<class T> inline std::string AbstractResourceLoader<T>::name(ResourceKey) const { return {}; } template<class T> AbstractResourceLoader<T>::~AbstractResourceLoader() {
if(manager) manager->_loader = nullptr;
}
template<class T> std::string AbstractResourceLoader<T>::name(ResourceKey) const { return {}; }
template<class T> inline void AbstractResourceLoader<T>::load(ResourceKey key) { template<class T> void AbstractResourceLoader<T>::load(ResourceKey key) {
++_requestedCount; ++_requestedCount;
/** @todo What policy for loading resources? */ /** @todo What policy for loading resources? */
manager->set(key, nullptr, ResourceDataState::Loading, ResourcePolicy::Resident); manager->set(key, nullptr, ResourceDataState::Loading, ResourcePolicy::Resident);
} }
template<class T> void AbstractResourceLoader<T>::set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
CORRADE_ASSERT(state == ResourceDataState::Mutable || state == ResourceDataState::Final,
"AbstractResourceLoader::set(): state must be either Mutable or Final", );
++_loadedCount;
manager->set(key, data, state, policy);
}
template<class T> inline void AbstractResourceLoader<T>::setNotFound(ResourceKey key) {
++_notFoundCount;
/** @todo What policy for notfound resources? */
manager->set(key, nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
}
} }
#endif #endif

104
src/AbstractShaderProgram.h

@ -320,7 +320,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
virtual ~AbstractShaderProgram() = 0; virtual ~AbstractShaderProgram() = 0;
/** @brief OpenGL program ID */ /** @brief OpenGL program ID */
inline GLuint id() const { return _id; } GLuint id() const { return _id; }
/** /**
* @brief Validate program * @brief Validate program
@ -349,7 +349,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl41 %Extension @extension{ARB,get_program_binary} * @requires_gl41 %Extension @extension{ARB,get_program_binary}
* @requires_gles30 Always allowed in OpenGL ES 2.0. * @requires_gles30 Always allowed in OpenGL ES 2.0.
*/ */
inline void setRetrievableBinary(bool enabled) { void setRetrievableBinary(bool enabled) {
glProgramParameteri(_id, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, enabled ? GL_TRUE : GL_FALSE); glProgramParameteri(_id, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, enabled ? GL_TRUE : GL_FALSE);
} }
#endif #endif
@ -362,7 +362,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl41 %Extension @extension{ARB,separate_shader_objects} * @requires_gl41 %Extension @extension{ARB,separate_shader_objects}
* @requires_es_extension %Extension @es_extension{EXT,separate_shader_objects} * @requires_es_extension %Extension @es_extension{EXT,separate_shader_objects}
*/ */
inline void setSeparable(bool enabled) { void setSeparable(bool enabled) {
/** @todo Remove when extension wrangler is available for ES */ /** @todo Remove when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
glProgramParameteri(_id, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE); glProgramParameteri(_id, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE);
@ -464,26 +464,26 @@ class MAGNUM_EXPORT AbstractShaderProgram {
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline void setUniform(Int location, const T& value); template<class T> inline void setUniform(Int location, const T& value);
#else #else
inline void setUniform(Int location, Float value) { void setUniform(Int location, Float value) {
setUniform(location, 1, &value); setUniform(location, 1, &value);
} }
inline void setUniform(Int location, Int value) { void setUniform(Int location, Int value) {
setUniform(location, 1, &value); setUniform(location, 1, &value);
} }
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
inline void setUniform(Int location, UnsignedInt value) { void setUniform(Int location, UnsignedInt value) {
setUniform(location, 1, &value); setUniform(location, 1, &value);
} }
#endif #endif
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
inline void setUniform(Int location, Double value) { void setUniform(Int location, Double value) {
setUniform(location, 1, &value); setUniform(location, 1, &value);
} }
#endif #endif
template<std::size_t size, class T> inline void setUniform(Int location, const Math::Vector<size, T>& value) { template<std::size_t size, class T> void setUniform(Int location, const Math::Vector<size, T>& value) {
setUniform(location, 1, &value); setUniform(location, 1, &value);
} }
template<std::size_t cols, std::size_t rows, class T> inline void setUniform(Int location, const Math::RectangularMatrix<cols, rows, T>& value) { template<std::size_t cols, std::size_t rows, class T> void setUniform(Int location, const Math::RectangularMatrix<cols, rows, T>& value) {
setUniform(location, 1, &value); setUniform(location, 1, &value);
} }
#endif #endif
@ -500,42 +500,42 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @see setUniform(Int, const T&), @fn_gl{UseProgram}, @fn_gl{Uniform} * @see setUniform(Int, const T&), @fn_gl{UseProgram}, @fn_gl{Uniform}
* or @fn_gl{ProgramUniform}/@fn_gl_extension{ProgramUniform,EXT,direct_state_access}. * or @fn_gl{ProgramUniform}/@fn_gl_extension{ProgramUniform,EXT,direct_state_access}.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Float* values) { void setUniform(Int location, UnsignedInt count, const Float* values) {
(this->*uniform1fvImplementation)(location, count, values); (this->*uniform1fvImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Float>* values) {
(this->*uniform2fvImplementation)(location, count, values); (this->*uniform2fvImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Float>* values) {
(this->*uniform3fvImplementation)(location, count, values); (this->*uniform3fvImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Float>* values) {
(this->*uniform4fvImplementation)(location, count, values); (this->*uniform4fvImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Int* values) { void setUniform(Int location, UnsignedInt count, const Int* values) {
(this->*uniform1ivImplementation)(location, count, values); (this->*uniform1ivImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Int>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Int>* values) {
(this->*uniform2ivImplementation)(location, count, values); (this->*uniform2ivImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Int>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Int>* values) {
(this->*uniform3ivImplementation)(location, count, values); (this->*uniform3ivImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Int>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Int>* values) {
(this->*uniform4ivImplementation)(location, count, values); (this->*uniform4ivImplementation)(location, count, values);
} }
@ -545,7 +545,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0. * @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const UnsignedInt* values) { void setUniform(Int location, UnsignedInt count, const UnsignedInt* values) {
(this->*uniform1uivImplementation)(location, count, values); (this->*uniform1uivImplementation)(location, count, values);
} }
@ -554,7 +554,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0. * @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, UnsignedInt>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<2, UnsignedInt>* values) {
(this->*uniform2uivImplementation)(location, count, values); (this->*uniform2uivImplementation)(location, count, values);
} }
@ -563,7 +563,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0. * @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, UnsignedInt>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<3, UnsignedInt>* values) {
(this->*uniform3uivImplementation)(location, count, values); (this->*uniform3uivImplementation)(location, count, values);
} }
@ -572,7 +572,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl30 %Extension @extension{EXT,gpu_shader4} * @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0. * @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, UnsignedInt>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<4, UnsignedInt>* values) {
(this->*uniform4uivImplementation)(location, count, values); (this->*uniform4uivImplementation)(location, count, values);
} }
#endif #endif
@ -583,7 +583,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Double* values) { void setUniform(Int location, UnsignedInt count, const Double* values) {
(this->*uniform1dvImplementation)(location, count, values); (this->*uniform1dvImplementation)(location, count, values);
} }
@ -592,7 +592,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Double>* values) {
(this->*uniform2dvImplementation)(location, count, values); (this->*uniform2dvImplementation)(location, count, values);
} }
@ -601,7 +601,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Double>* values) {
(this->*uniform3dvImplementation)(location, count, values); (this->*uniform3dvImplementation)(location, count, values);
} }
@ -610,23 +610,23 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Double>* values) {
(this->*uniform4dvImplementation)(location, count, values); (this->*uniform4dvImplementation)(location, count, values);
} }
#endif #endif
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Float>* values) {
(this->*uniformMatrix2fvImplementation)(location, count, values); (this->*uniformMatrix2fvImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Float>* values) {
(this->*uniformMatrix3fvImplementation)(location, count, values); (this->*uniformMatrix3fvImplementation)(location, count, values);
} }
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */ /** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Float>* values) {
(this->*uniformMatrix4fvImplementation)(location, count, values); (this->*uniformMatrix4fvImplementation)(location, count, values);
} }
@ -635,7 +635,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*) * @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0. * @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Float>* values) {
(this->*uniformMatrix2x3fvImplementation)(location, count, values); (this->*uniformMatrix2x3fvImplementation)(location, count, values);
} }
@ -643,7 +643,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*) * @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0. * @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Float>* values) {
(this->*uniformMatrix3x2fvImplementation)(location, count, values); (this->*uniformMatrix3x2fvImplementation)(location, count, values);
} }
@ -651,7 +651,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*) * @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0. * @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Float>* values) {
(this->*uniformMatrix2x4fvImplementation)(location, count, values); (this->*uniformMatrix2x4fvImplementation)(location, count, values);
} }
@ -659,7 +659,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*) * @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0. * @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Float>* values) {
(this->*uniformMatrix4x2fvImplementation)(location, count, values); (this->*uniformMatrix4x2fvImplementation)(location, count, values);
} }
@ -667,7 +667,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*) * @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0. * @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Float>* values) {
(this->*uniformMatrix3x4fvImplementation)(location, count, values); (this->*uniformMatrix3x4fvImplementation)(location, count, values);
} }
@ -675,7 +675,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*) * @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0. * @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Float>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Float>* values) {
(this->*uniformMatrix4x3fvImplementation)(location, count, values); (this->*uniformMatrix4x3fvImplementation)(location, count, values);
} }
#endif #endif
@ -686,7 +686,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Double>* values) {
(this->*uniformMatrix2dvImplementation)(location, count, values); (this->*uniformMatrix2dvImplementation)(location, count, values);
} }
@ -695,7 +695,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Double>* values) {
(this->*uniformMatrix3dvImplementation)(location, count, values); (this->*uniformMatrix3dvImplementation)(location, count, values);
} }
@ -704,7 +704,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Double>* values) {
(this->*uniformMatrix4dvImplementation)(location, count, values); (this->*uniformMatrix4dvImplementation)(location, count, values);
} }
@ -713,7 +713,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Double>* values) {
(this->*uniformMatrix2x3dvImplementation)(location, count, values); (this->*uniformMatrix2x3dvImplementation)(location, count, values);
} }
@ -722,7 +722,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Double>* values) {
(this->*uniformMatrix3x2dvImplementation)(location, count, values); (this->*uniformMatrix3x2dvImplementation)(location, count, values);
} }
@ -731,7 +731,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Double>* values) {
(this->*uniformMatrix2x4dvImplementation)(location, count, values); (this->*uniformMatrix2x4dvImplementation)(location, count, values);
} }
@ -740,7 +740,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Double>* values) {
(this->*uniformMatrix4x2dvImplementation)(location, count, values); (this->*uniformMatrix4x2dvImplementation)(location, count, values);
} }
@ -749,7 +749,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Double>* values) {
(this->*uniformMatrix3x4dvImplementation)(location, count, values); (this->*uniformMatrix3x4dvImplementation)(location, count, values);
} }
@ -758,7 +758,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64} * @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES. * @requires_gl Only floats are available in OpenGL ES.
*/ */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Double>* values) { void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Double>* values) {
(this->*uniformMatrix4x3dvImplementation)(location, count, values); (this->*uniformMatrix4x3dvImplementation)(location, count, values);
} }
#endif #endif
@ -1108,7 +1108,7 @@ template<UnsignedInt location, class T> class AbstractShaderProgram::Attribute {
* type used in shader (e.g. DataType::Integer for Vector4i). * type used in shader (e.g. DataType::Integer for Vector4i).
* @param dataOptions Data options. Default is no options. * @param dataOptions Data options. Default is no options.
*/ */
inline constexpr Attribute(Components components, DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(components), _dataType(dataType), _dataOptions(dataOptions) {} constexpr Attribute(Components components, DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(components), _dataType(dataType), _dataOptions(dataOptions) {}
/** /**
* @brief Constructor * @brief Constructor
@ -1119,21 +1119,21 @@ template<UnsignedInt location, class T> class AbstractShaderProgram::Attribute {
* Component count is set to the same value as in type used in shader * Component count is set to the same value as in type used in shader
* (e.g. @ref Components "Components::Three" for Vector3). * (e.g. @ref Components "Components::Three" for Vector3).
*/ */
inline constexpr Attribute(DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(Implementation::Attribute<T>::DefaultComponents), _dataType(dataType), _dataOptions(dataOptions) {} constexpr Attribute(DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(Implementation::Attribute<T>::DefaultComponents), _dataType(dataType), _dataOptions(dataOptions) {}
/** @brief Component count of passed data */ /** @brief Component count of passed data */
inline constexpr Components components() const { return _components; } constexpr Components components() const { return _components; }
/** @brief Type of passed data */ /** @brief Type of passed data */
inline constexpr DataType dataType() const { return _dataType; } constexpr DataType dataType() const { return _dataType; }
/** @brief Size of passed data */ /** @brief Size of passed data */
inline std::size_t dataSize() const { std::size_t dataSize() const {
return Implementation::Attribute<T>::size(GLint(_components)*Implementation::Attribute<T>::vectorCount(), _dataType); return Implementation::Attribute<T>::size(GLint(_components)*Implementation::Attribute<T>::vectorCount(), _dataType);
} }
/** @brief Data options */ /** @brief Data options */
inline constexpr DataOptions dataOptions() const { return _dataOptions; } constexpr DataOptions dataOptions() const { return _dataOptions; }
private: private:
const Components _components; const Components _components;
@ -1156,7 +1156,7 @@ template<std::size_t cols, std::size_t rows> struct SizedAttribute;
/* Vector attribute sizes */ /* Vector attribute sizes */
template<std::size_t cols> struct SizedVectorAttribute { template<std::size_t cols> struct SizedVectorAttribute {
inline constexpr static std::size_t vectorCount() { return cols; } constexpr static std::size_t vectorCount() { return cols; }
}; };
template<> struct SizedAttribute<1, 1>: SizedVectorAttribute<1> { template<> struct SizedAttribute<1, 1>: SizedVectorAttribute<1> {
enum class Components: GLint { One = 1 }; enum class Components: GLint { One = 1 };
@ -1281,7 +1281,7 @@ struct UnsignedIntAttribute {
typedef IntAttribute::DataOption DataOption; typedef IntAttribute::DataOption DataOption;
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions; typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
inline static std::size_t size(GLint components, DataType dataType) { static std::size_t size(GLint components, DataType dataType) {
return IntAttribute::size(components, dataType); return IntAttribute::size(components, dataType);
} }
}; };
@ -1352,7 +1352,7 @@ template<> struct Attribute<Math::Vector<4, Float>> {
}; };
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions; typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
inline constexpr static std::size_t vectorCount() { return 1; } constexpr static std::size_t vectorCount() { return 1; }
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType); static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
}; };

50
src/AbstractTexture.h

@ -104,7 +104,7 @@ class MAGNUM_EXPORT AbstractTexture {
static Int maxSupportedLayerCount(); static Int maxSupportedLayerCount();
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline explicit AbstractTexture(GLenum target): _target(target) { explicit AbstractTexture(GLenum target): _target(target) {
glGenTextures(1, &_id); glGenTextures(1, &_id);
} }
#endif #endif
@ -124,7 +124,7 @@ class MAGNUM_EXPORT AbstractTexture {
AbstractTexture& operator=(AbstractTexture&& other); AbstractTexture& operator=(AbstractTexture&& other);
/** @brief OpenGL texture ID */ /** @brief OpenGL texture ID */
inline GLuint id() const { return _id; } GLuint id() const { return _id; }
/** /**
* @brief Bind texture for rendering * @brief Bind texture for rendering
@ -174,7 +174,7 @@ class MAGNUM_EXPORT AbstractTexture {
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access} * or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MAG_FILTER} * with @def_gl{TEXTURE_MAG_FILTER}
*/ */
inline AbstractTexture* setMagnificationFilter(Sampler::Filter filter) { AbstractTexture* setMagnificationFilter(Sampler::Filter filter) {
(this->*parameteriImplementation)(GL_TEXTURE_MAG_FILTER, static_cast<GLint>(filter)); (this->*parameteriImplementation)(GL_TEXTURE_MAG_FILTER, static_cast<GLint>(filter));
return this; return this;
} }
@ -193,7 +193,7 @@ class MAGNUM_EXPORT AbstractTexture {
* with @def_gl{TEXTURE_BORDER_COLOR} * with @def_gl{TEXTURE_BORDER_COLOR}
* @requires_es_extension %Extension @es_extension{NV,texture_border_clamp} * @requires_es_extension %Extension @es_extension{NV,texture_border_clamp}
*/ */
inline AbstractTexture* setBorderColor(const Color4<>& color) { AbstractTexture* setBorderColor(const Color4<>& color) {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
(this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data()); (this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data());
#else #else
@ -217,7 +217,7 @@ class MAGNUM_EXPORT AbstractTexture {
* @requires_extension %Extension @extension{EXT,texture_filter_anisotropic} * @requires_extension %Extension @extension{EXT,texture_filter_anisotropic}
* @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic} * @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic}
*/ */
inline AbstractTexture* setMaxAnisotropy(Float anisotropy) { AbstractTexture* setMaxAnisotropy(Float anisotropy) {
(this->*parameterfImplementation)(GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); (this->*parameterfImplementation)(GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
return this; return this;
} }
@ -232,7 +232,7 @@ class MAGNUM_EXPORT AbstractTexture {
* @see @ref Texture::invalidateSubImage() "invalidateSubImage()", * @see @ref Texture::invalidateSubImage() "invalidateSubImage()",
* @fn_gl{InvalidateTexImage} * @fn_gl{InvalidateTexImage}
*/ */
inline void invalidateImage(Int level) { void invalidateImage(Int level) {
(this->*invalidateImageImplementation)(level); (this->*invalidateImageImplementation)(level);
} }
@ -406,7 +406,7 @@ class MAGNUM_EXPORT AbstractTexture {
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation { namespace Implementation {
template<class Image> struct ImageHelper { template<class Image> struct ImageHelper {
inline static const GLvoid* dataOrPixelUnpackBuffer(Image* image) { static const GLvoid* dataOrPixelUnpackBuffer(Image* image) {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
Buffer::unbind(Buffer::Target::PixelUnpack); Buffer::unbind(Buffer::Target::PixelUnpack);
#endif #endif
@ -427,27 +427,27 @@ template<> struct AbstractTexture::DataHelper<1> {
Texture1D = GL_TEXTURE_1D Texture1D = GL_TEXTURE_1D
}; };
inline constexpr static Target target() { return Target::Texture1D; } constexpr static Target target() { return Target::Texture1D; }
static Math::Vector<1, GLint> imageSize(AbstractTexture* texture, GLenum target, GLint level); static Math::Vector<1, GLint> imageSize(AbstractTexture* texture, GLenum target, GLint level);
inline static void setWrapping(AbstractTexture* texture, const Array1D<Sampler::Wrapping>& wrapping) { static void setWrapping(AbstractTexture* texture, const Array1D<Sampler::Wrapping>& wrapping) {
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping.x())); (texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping.x()));
} }
inline static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
(texture->*storage1DImplementation)(target, levels, internalFormat, size); (texture->*storage1DImplementation)(target, levels, internalFormat, size);
} }
template<class Image> inline static typename std::enable_if<Image::Dimensions == 1, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { template<class Image> static typename std::enable_if<Image::Dimensions == 1, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) {
(texture->*image1DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); (texture->*image1DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
} }
template<class Image> inline static typename std::enable_if<Image::Dimensions == 1, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, Image* image) { template<class Image> static typename std::enable_if<Image::Dimensions == 1, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Math::Vector<1, GLint>& offset, Image* image) {
(texture->*subImage1DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); (texture->*subImage1DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
} }
inline static void invalidateSubImage(AbstractTexture* texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size) { static void invalidateSubImage(AbstractTexture* texture, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLint>& size) {
(texture->*invalidateSubImageImplementation)(level, {offset[0], 0, 0}, {size[0], 1, 1}); (texture->*invalidateSubImageImplementation)(level, {offset[0], 0, 0}, {size[0], 1, 1});
} }
}; };
@ -462,7 +462,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
#endif #endif
}; };
inline constexpr static Target target() { return Target::Texture2D; } constexpr static Target target() { return Target::Texture2D; }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
static Vector2i imageSize(AbstractTexture* texture, GLenum target, GLint level); static Vector2i imageSize(AbstractTexture* texture, GLenum target, GLint level);
@ -470,23 +470,23 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
static void setWrapping(AbstractTexture* texture, const Array2D<Sampler::Wrapping>& wrapping); static void setWrapping(AbstractTexture* texture, const Array2D<Sampler::Wrapping>& wrapping);
inline static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
(texture->*storage2DImplementation)(target, levels, internalFormat, size); (texture->*storage2DImplementation)(target, levels, internalFormat, size);
} }
template<class Image> inline static typename std::enable_if<Image::Dimensions == 2, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { template<class Image> static typename std::enable_if<Image::Dimensions == 2, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) {
(texture->*image2DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); (texture->*image2DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
} }
template<class Image> inline static typename std::enable_if<Image::Dimensions == 2, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) { template<class Image> static typename std::enable_if<Image::Dimensions == 2, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) {
(texture->*subImage2DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); (texture->*subImage2DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
} }
template<class Image> inline static typename std::enable_if<Image::Dimensions == 1, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) { template<class Image> static typename std::enable_if<Image::Dimensions == 1, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector2i& offset, Image* image) {
(texture->*subImage2DImplementation)(target, level, offset, Vector2i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); (texture->*subImage2DImplementation)(target, level, offset, Vector2i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
} }
inline static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector2i& offset, const Vector2i& size) { static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector2i& offset, const Vector2i& size) {
(texture->*invalidateSubImageImplementation)(level, {offset, 0}, {size, 1}); (texture->*invalidateSubImageImplementation)(level, {offset, 0}, {size, 1});
} }
}; };
@ -503,7 +503,7 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
#endif #endif
}; };
inline constexpr static Target target() { return Target::Texture3D; } constexpr static Target target() { return Target::Texture3D; }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
static Vector3i imageSize(AbstractTexture* texture, GLenum target, GLint level); static Vector3i imageSize(AbstractTexture* texture, GLenum target, GLint level);
@ -511,23 +511,23 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
static void setWrapping(AbstractTexture* texture, const Array3D<Sampler::Wrapping>& wrapping); static void setWrapping(AbstractTexture* texture, const Array3D<Sampler::Wrapping>& wrapping);
inline static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { static void setStorage(AbstractTexture* texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
(texture->*storage3DImplementation)(target, levels, internalFormat, size); (texture->*storage3DImplementation)(target, levels, internalFormat, size);
} }
template<class Image> inline static typename std::enable_if<Image::Dimensions == 3, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) { template<class Image> static typename std::enable_if<Image::Dimensions == 3, void>::type setImage(AbstractTexture* texture, GLenum target, GLint level, TextureFormat internalFormat, Image* image) {
(texture->*image3DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); (texture->*image3DImplementation)(target, level, internalFormat, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
} }
template<class Image> inline static typename std::enable_if<Image::Dimensions == 3, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) { template<class Image> static typename std::enable_if<Image::Dimensions == 3, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) {
(texture->*subImage3DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); (texture->*subImage3DImplementation)(target, level, offset, image->size(), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
} }
template<class Image> inline static typename std::enable_if<Image::Dimensions == 2, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) { template<class Image> static typename std::enable_if<Image::Dimensions == 2, void>::type setSubImage(AbstractTexture* texture, GLenum target, GLint level, const Vector3i& offset, Image* image) {
(texture->*subImage3DImplementation)(target, level, offset, Vector3i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image)); (texture->*subImage3DImplementation)(target, level, offset, Vector3i(image->size(), 1), image->format(), image->type(), Implementation::ImageHelper<Image>::dataOrPixelUnpackBuffer(image));
} }
inline static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector3i& offset, const Vector3i& size) { static void invalidateSubImage(AbstractTexture* texture, GLint level, const Vector3i& offset, const Vector3i& size) {
(texture->*invalidateSubImageImplementation)(level, offset, size); (texture->*invalidateSubImageImplementation)(level, offset, size);
} }
}; };

70
src/Array.h

@ -55,7 +55,7 @@ template<UnsignedInt dimensions, class T> class Array {
* *
* Sets all components to their default-constructed values * Sets all components to their default-constructed values
*/ */
inline constexpr /*implicit*/ Array(): _data() {} constexpr /*implicit*/ Array(): _data() {}
/** /**
* @brief Initializer-list constructor * @brief Initializer-list constructor
@ -63,45 +63,45 @@ template<UnsignedInt dimensions, class T> class Array {
* @param next Next values * @param next Next values
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
template<class ...U> inline constexpr /*implicit*/ Array(T first, T second, U... next): _data{first, second, next...} { template<class ...U> constexpr /*implicit*/ Array(T first, T second, U... next): _data{first, second, next...} {
static_assert(sizeof...(next)+2 == dimensions, "Improper number of arguments passed to Array constructor"); static_assert(sizeof...(next)+2 == dimensions, "Improper number of arguments passed to Array constructor");
} }
template<class U = T> inline constexpr /*implicit*/ Array(typename std::enable_if<std::is_same<T, U>::value && dimensions == 1, U>::type first): _data{first} {} template<class U = T> constexpr /*implicit*/ Array(typename std::enable_if<std::is_same<T, U>::value && dimensions == 1, U>::type first): _data{first} {}
#else #else
template<class ...U> inline constexpr /*implicit*/ Array(T first, U... next); template<class ...U> constexpr /*implicit*/ Array(T first, U... next);
#endif #endif
/** /**
* @brief Constructor * @brief Constructor
* @param value Value for all fields * @param value Value for all fields
*/ */
template<class U, class = typename std::enable_if<std::is_same<T, U>::value && dimensions != 1, U>::type> inline /*implicit*/ Array(U value) { template<class U, class = typename std::enable_if<std::is_same<T, U>::value && dimensions != 1, U>::type> /*implicit*/ Array(U value) {
for(UnsignedInt i = 0; i != dimensions; ++i) for(UnsignedInt i = 0; i != dimensions; ++i)
_data[i] = value; _data[i] = value;
} }
/** @brief Equality */ /** @brief Equality */
inline bool operator==(const Array<dimensions, T>& other) const { bool operator==(const Array<dimensions, T>& other) const {
for(UnsignedInt i = 0; i != dimensions; ++i) for(UnsignedInt i = 0; i != dimensions; ++i)
if(_data[i] != other._data[i]) return false; if(_data[i] != other._data[i]) return false;
return true; return true;
} }
/** @brief Non-equality */ /** @brief Non-equality */
inline bool operator!=(const Array<dimensions, T>& other) const { bool operator!=(const Array<dimensions, T>& other) const {
return !operator==(other); return !operator==(other);
} }
/** @brief Value at given position */ /** @brief Value at given position */
inline T& operator[](UnsignedInt pos) { return _data[pos]; } T& operator[](UnsignedInt pos) { return _data[pos]; }
inline constexpr T operator[](UnsignedInt pos) const { return _data[pos]; } /**< @overload */ constexpr T operator[](UnsignedInt pos) const { return _data[pos]; } /**< @overload */
/** /**
* @brief Raw data * @brief Raw data
* @return One-dimensional array of `dimensions` length * @return One-dimensional array of `dimensions` length
*/ */
inline T* data() { return _data; } T* data() { return _data; }
inline constexpr const T* data() const { return _data; } /**< @overload */ constexpr const T* data() const { return _data; } /**< @overload */
private: private:
T _data[dimensions]; T _data[dimensions];
@ -114,19 +114,19 @@ template<UnsignedInt dimensions, class T> class Array {
template<class T> class Array1D: public Array<1, T> { template<class T> class Array1D: public Array<1, T> {
public: public:
/** @copydoc Array::Array() */ /** @copydoc Array::Array() */
inline constexpr /*implicit*/ Array1D() = default; constexpr /*implicit*/ Array1D() = default;
/** /**
* @brief Constructor * @brief Constructor
* @param x X component * @param x X component
*/ */
inline constexpr /*implicit*/ Array1D(T x): Array<1, T>(x) {} constexpr /*implicit*/ Array1D(T x): Array<1, T>(x) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
inline constexpr Array1D(const Array<1, T>& other): Array<1, T>(other) {} constexpr Array1D(const Array<1, T>& other): Array<1, T>(other) {}
inline T& x() { return (*this)[0]; } /**< @brief X component */ T& x() { return (*this)[0]; } /**< @brief X component */
inline constexpr T x() const { return (*this)[0]; } /**< @overload */ constexpr T x() const { return (*this)[0]; } /**< @overload */
}; };
/** /**
@ -136,25 +136,25 @@ template<class T> class Array1D: public Array<1, T> {
template<class T> class Array2D: public Array<2, T> { template<class T> class Array2D: public Array<2, T> {
public: public:
/** @copydoc Array::Array() */ /** @copydoc Array::Array() */
inline constexpr /*implicit*/ Array2D() = default; constexpr /*implicit*/ Array2D() = default;
/** /**
* @brief Constructor * @brief Constructor
* @param x X component * @param x X component
* @param y Y component * @param y Y component
*/ */
inline constexpr /*implicit*/ Array2D(T x, T y): Array<2, T>(x, y) {} constexpr /*implicit*/ Array2D(T x, T y): Array<2, T>(x, y) {}
/** @copydoc Array::Array(U) */ /** @copydoc Array::Array(U) */
inline constexpr /*implicit*/ Array2D(T value): Array<2, T>(value, value) {} constexpr /*implicit*/ Array2D(T value): Array<2, T>(value, value) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
inline constexpr Array2D(const Array<2, T>& other): Array<2, T>(other) {} constexpr Array2D(const Array<2, T>& other): Array<2, T>(other) {}
inline T& x() { return (*this)[0]; } /**< @brief X component */ T& x() { return (*this)[0]; } /**< @brief X component */
inline constexpr T x() const { return (*this)[0]; } /**< @overload */ constexpr T x() const { return (*this)[0]; } /**< @overload */
inline T& y() { return (*this)[1]; } /**< @brief Y component */ T& y() { return (*this)[1]; } /**< @brief Y component */
inline constexpr T y() const { return (*this)[1]; } /**< @overload */ constexpr T y() const { return (*this)[1]; } /**< @overload */
}; };
/** /**
@ -164,7 +164,7 @@ template<class T> class Array2D: public Array<2, T> {
template<class T> class Array3D: public Array<3, T> { template<class T> class Array3D: public Array<3, T> {
public: public:
/** @copydoc Array::Array() */ /** @copydoc Array::Array() */
inline constexpr /*implicit*/ Array3D() {} constexpr /*implicit*/ Array3D() {}
/** /**
* @brief Constructor * @brief Constructor
@ -172,20 +172,20 @@ template<class T> class Array3D: public Array<3, T> {
* @param y Y component * @param y Y component
* @param z Z component * @param z Z component
*/ */
inline constexpr /*implicit*/ Array3D(T x, T y, T z): Array<3, T>(x, y, z) {} constexpr /*implicit*/ Array3D(T x, T y, T z): Array<3, T>(x, y, z) {}
/** @copydoc Array::Array(U) */ /** @copydoc Array::Array(U) */
inline constexpr /*implicit*/ Array3D(T value): Array<3, T>(value, value, value) {} constexpr /*implicit*/ Array3D(T value): Array<3, T>(value, value, value) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
inline constexpr Array3D(const Array<3, T>& other): Array<3, T>(other) {} constexpr Array3D(const Array<3, T>& other): Array<3, T>(other) {}
inline T& x() { return (*this)[0]; } /**< @brief X component */ T& x() { return (*this)[0]; } /**< @brief X component */
inline constexpr T x() const { return (*this)[0]; } /**< @overload */ constexpr T x() const { return (*this)[0]; } /**< @overload */
inline T& y() { return (*this)[1]; } /**< @brief Y component */ T& y() { return (*this)[1]; } /**< @brief Y component */
inline constexpr T y() const { return (*this)[1]; } /**< @overload */ constexpr T y() const { return (*this)[1]; } /**< @overload */
inline T& z() { return (*this)[2]; } /**< @brief Z component */ T& z() { return (*this)[2]; } /**< @brief Z component */
inline constexpr T z() const { return (*this)[2]; } /**< @overload */ constexpr T z() const { return (*this)[2]; } /**< @overload */
}; };
/** @debugoperator{Magnum::Array} */ /** @debugoperator{Magnum::Array} */

42
src/Buffer.h

@ -437,7 +437,7 @@ class MAGNUM_EXPORT Buffer {
* *
* @see @fn_gl{BindBuffer} * @see @fn_gl{BindBuffer}
*/ */
inline static void unbind(Target target) { bind(target, 0); } static void unbind(Target target) { bind(target, 0); }
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/** /**
@ -457,7 +457,7 @@ class MAGNUM_EXPORT Buffer {
* @requires_gl31 %Extension @extension{ARB,copy_buffer} * @requires_gl31 %Extension @extension{ARB,copy_buffer}
* @requires_gles30 %Buffer copying is not available in OpenGL ES 2.0. * @requires_gles30 %Buffer copying is not available in OpenGL ES 2.0.
*/ */
inline static void copy(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { static void copy(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
copyImplementation(read, write, readOffset, writeOffset, size); copyImplementation(read, write, readOffset, writeOffset, size);
} }
#endif #endif
@ -470,7 +470,7 @@ class MAGNUM_EXPORT Buffer {
* Generates new OpenGL buffer. * Generates new OpenGL buffer.
* @see @fn_gl{GenBuffers} * @see @fn_gl{GenBuffers}
*/ */
inline explicit Buffer(Target targetHint = Target::Array): _targetHint(targetHint) { explicit Buffer(Target targetHint = Target::Array): _targetHint(targetHint) {
glGenBuffers(1, &_id); glGenBuffers(1, &_id);
} }
@ -483,10 +483,10 @@ class MAGNUM_EXPORT Buffer {
virtual ~Buffer(); virtual ~Buffer();
/** @brief OpenGL buffer ID */ /** @brief OpenGL buffer ID */
inline GLuint id() const { return _id; } GLuint id() const { return _id; }
/** @brief Target hint */ /** @brief Target hint */
inline Target targetHint() const { return _targetHint; } Target targetHint() const { return _targetHint; }
/** /**
* @brief Set target hint * @brief Set target hint
@ -503,7 +503,7 @@ class MAGNUM_EXPORT Buffer {
* http://www.opengl.org/wiki/Vertex_Specification#Index_buffers * http://www.opengl.org/wiki/Vertex_Specification#Index_buffers
* ... damned GL state * ... damned GL state
*/ */
inline Buffer* setTargetHint(Target hint) { Buffer* setTargetHint(Target hint) {
_targetHint = hint; _targetHint = hint;
return this; return this;
} }
@ -518,7 +518,7 @@ class MAGNUM_EXPORT Buffer {
* @todo Don't allow user to bind buffers? * @todo Don't allow user to bind buffers?
* @see @fn_gl{BindBuffer} * @see @fn_gl{BindBuffer}
*/ */
inline void bind(Target target) { bind(target, _id); } void bind(Target target) { bind(target, _id); }
/** /**
* @brief Buffer size * @brief Buffer size
@ -571,7 +571,7 @@ class MAGNUM_EXPORT Buffer {
* @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferData} or * @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferData} or
* @fn_gl_extension{NamedBufferData,EXT,direct_state_access} * @fn_gl_extension{NamedBufferData,EXT,direct_state_access}
*/ */
inline Buffer* setData(GLsizeiptr size, const GLvoid* data, Usage usage) { Buffer* setData(GLsizeiptr size, const GLvoid* data, Usage usage) {
(this->*dataImplementation)(size, data, usage); (this->*dataImplementation)(size, data, usage);
return this; return this;
} }
@ -584,7 +584,7 @@ class MAGNUM_EXPORT Buffer {
* *
* @see setData(GLsizeiptr, const GLvoid*, Usage). * @see setData(GLsizeiptr, const GLvoid*, Usage).
*/ */
template<std::size_t size, class T> inline Buffer* setData(const T(&data)[size], Usage usage) { template<std::size_t size, class T> Buffer* setData(const T(&data)[size], Usage usage) {
setData(size*sizeof(T), data, usage); setData(size*sizeof(T), data, usage);
return this; return this;
} }
@ -597,13 +597,13 @@ class MAGNUM_EXPORT Buffer {
* *
* @see setData(GLsizeiptr, const GLvoid*, Usage) * @see setData(GLsizeiptr, const GLvoid*, Usage)
*/ */
template<class T> inline Buffer* setData(const std::vector<T>& data, Usage usage) { template<class T> Buffer* setData(const std::vector<T>& data, Usage usage) {
setData(data.size()*sizeof(T), data.data(), usage); setData(data.size()*sizeof(T), data.data(), usage);
return this; return this;
} }
/** @overload */ /** @overload */
template<std::size_t size, class T> inline void setData(const std::array<T, size>& data, Usage usage) { template<std::size_t size, class T> void setData(const std::array<T, size>& data, Usage usage) {
setData(data.size()*sizeof(T), data.data(), usage); setData(data.size()*sizeof(T), data.data(), usage);
} }
@ -620,7 +620,7 @@ class MAGNUM_EXPORT Buffer {
* @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferSubData} * @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferSubData}
* or @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access} * or @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access}
*/ */
inline Buffer* setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) { Buffer* setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
(this->*subDataImplementation)(offset, size, data); (this->*subDataImplementation)(offset, size, data);
return this; return this;
} }
@ -633,7 +633,7 @@ class MAGNUM_EXPORT Buffer {
* *
* @see setSubData(GLintptr, GLsizeiptr, const GLvoid*) * @see setSubData(GLintptr, GLsizeiptr, const GLvoid*)
*/ */
template<std::size_t size, class T> inline Buffer* setSubData(GLintptr offset, const T(&data)[size]) { template<std::size_t size, class T> Buffer* setSubData(GLintptr offset, const T(&data)[size]) {
setSubData(offset, size*sizeof(T), data); setSubData(offset, size*sizeof(T), data);
return this; return this;
} }
@ -646,13 +646,13 @@ class MAGNUM_EXPORT Buffer {
* *
* @see setSubData(GLintptr, GLsizeiptr, const GLvoid*) * @see setSubData(GLintptr, GLsizeiptr, const GLvoid*)
*/ */
template<class T> inline Buffer* setSubData(GLintptr offset, const std::vector<T>& data) { template<class T> Buffer* setSubData(GLintptr offset, const std::vector<T>& data) {
setSubData(offset, data.size()*sizeof(T), data.data()); setSubData(offset, data.size()*sizeof(T), data.data());
return this; return this;
} }
/** @overload */ /** @overload */
template<std::size_t size, class T> inline Buffer* setSubData(GLintptr offset, const std::array<T, size>& data) { template<std::size_t size, class T> Buffer* setSubData(GLintptr offset, const std::array<T, size>& data) {
setSubData(offset, data.size()*sizeof(T), data.data()); setSubData(offset, data.size()*sizeof(T), data.data());
return this; return this;
} }
@ -666,7 +666,7 @@ class MAGNUM_EXPORT Buffer {
* is not available, this function does nothing. * is not available, this function does nothing.
* @see @ref MapFlag "MapFlag::InvalidateBuffer", @fn_gl{InvalidateBufferData} * @see @ref MapFlag "MapFlag::InvalidateBuffer", @fn_gl{InvalidateBufferData}
*/ */
inline Buffer* invalidateData() { Buffer* invalidateData() {
(this->*invalidateImplementation)(); (this->*invalidateImplementation)();
return this; return this;
} }
@ -681,7 +681,7 @@ class MAGNUM_EXPORT Buffer {
* is not available, this function does nothing. * is not available, this function does nothing.
* @see @ref MapFlag "MapFlag::InvalidateRange", @fn_gl{InvalidateBufferData} * @see @ref MapFlag "MapFlag::InvalidateRange", @fn_gl{InvalidateBufferData}
*/ */
inline Buffer* invalidateSubData(GLintptr offset, GLsizeiptr length) { Buffer* invalidateSubData(GLintptr offset, GLsizeiptr length) {
(this->*invalidateSubImplementation)(offset, length); (this->*invalidateSubImplementation)(offset, length);
return this; return this;
} }
@ -704,7 +704,7 @@ class MAGNUM_EXPORT Buffer {
* OpenGL ES 2.0, use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * OpenGL ES 2.0, use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* in OpenGL ES 3.0 instead. * in OpenGL ES 3.0 instead.
*/ */
inline void* map(MapAccess access) { void* map(MapAccess access) {
return (this->*mapImplementation)(access); return (this->*mapImplementation)(access);
} }
#endif #endif
@ -725,7 +725,7 @@ class MAGNUM_EXPORT Buffer {
* @requires_gl30 %Extension @extension{ARB,map_buffer_range} * @requires_gl30 %Extension @extension{ARB,map_buffer_range}
* @requires_gles30 %Extension @es_extension{EXT,map_buffer_range} * @requires_gles30 %Extension @es_extension{EXT,map_buffer_range}
*/ */
inline void* map(GLintptr offset, GLsizeiptr length, MapFlags flags) { void* map(GLintptr offset, GLsizeiptr length, MapFlags flags) {
return (this->*mapRangeImplementation)(offset, length, flags); return (this->*mapRangeImplementation)(offset, length, flags);
} }
@ -747,7 +747,7 @@ class MAGNUM_EXPORT Buffer {
* @requires_gl30 %Extension @extension{ARB,map_buffer_range} * @requires_gl30 %Extension @extension{ARB,map_buffer_range}
* @requires_gles30 %Extension @es_extension{EXT,map_buffer_range} * @requires_gles30 %Extension @es_extension{EXT,map_buffer_range}
*/ */
inline Buffer* flushMappedRange(GLintptr offset, GLsizeiptr length) { Buffer* flushMappedRange(GLintptr offset, GLsizeiptr length) {
(this->*flushMappedRangeImplementation)(offset, length); (this->*flushMappedRangeImplementation)(offset, length);
return this; return this;
} }
@ -766,7 +766,7 @@ class MAGNUM_EXPORT Buffer {
* @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access} * @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension{OES,mapbuffer} * @requires_gles30 %Extension @es_extension{OES,mapbuffer}
*/ */
inline bool unmap() { bool unmap() {
return (this->*unmapImplementation)(); return (this->*unmapImplementation)();
} }

6
src/BufferImage.h

@ -58,15 +58,15 @@ template<UnsignedInt dimensions> class MAGNUM_EXPORT BufferImage: public Abstrac
* Dimensions and buffer are empty, call setData() to fill the image * Dimensions and buffer are empty, call setData() to fill the image
* with data. * with data.
*/ */
inline explicit BufferImage(ImageFormat format, ImageType type): AbstractImage(format, type) { explicit BufferImage(ImageFormat format, ImageType type): AbstractImage(format, type) {
_buffer.setTargetHint(Buffer::Target::PixelPack); _buffer.setTargetHint(Buffer::Target::PixelPack);
} }
/** @brief %Image size */ /** @brief %Image size */
inline typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; } typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
/** @brief %Image buffer */ /** @brief %Image buffer */
inline Buffer* buffer() { return &_buffer; } Buffer* buffer() { return &_buffer; }
/** /**
* @brief Set image data * @brief Set image data

8
src/BufferTexture.h

@ -90,10 +90,10 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
BufferTexture& operator=(BufferTexture&&) = delete; BufferTexture& operator=(BufferTexture&&) = delete;
public: public:
inline explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {} explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {}
/** @copydoc AbstractTexture::bind() */ /** @copydoc AbstractTexture::bind() */
inline void bind(Int layer) { AbstractTexture::bind(layer); } void bind(Int layer) { AbstractTexture::bind(layer); }
/** /**
* @brief Set texture buffer * @brief Set texture buffer
@ -106,7 +106,7 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBuffer} * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBuffer}
* or @fn_gl_extension{TextureBuffer,EXT,direct_state_access} * or @fn_gl_extension{TextureBuffer,EXT,direct_state_access}
*/ */
inline void setBuffer(BufferTextureFormat internalFormat, Buffer* buffer) { void setBuffer(BufferTextureFormat internalFormat, Buffer* buffer) {
(this->*setBufferImplementation)(internalFormat, buffer); (this->*setBufferImplementation)(internalFormat, buffer);
} }
@ -124,7 +124,7 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBufferRange} * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBufferRange}
* or @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} * or @fn_gl_extension{TextureBufferRange,EXT,direct_state_access}
*/ */
inline void setBuffer(BufferTextureFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size) { void setBuffer(BufferTextureFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size) {
(this->*setBufferRangeImplementation)(internalFormat, buffer, offset, size); (this->*setBufferRangeImplementation)(internalFormat, buffer, offset, size);
} }

80
src/Color.h

@ -39,7 +39,7 @@ namespace Magnum {
namespace Implementation { namespace Implementation {
/* Convert color from HSV */ /* Convert color from HSV */
template<class T> inline typename std::enable_if<std::is_floating_point<T>::value, Color3<T>>::type fromHSV(typename Color3<T>::HSV hsv) { template<class T> typename std::enable_if<std::is_floating_point<T>::value, Color3<T>>::type fromHSV(typename Color3<T>::HSV hsv) {
Math::Deg<T> hue; Math::Deg<T> hue;
T saturation, value; T saturation, value;
std::tie(hue, saturation, value) = hsv; std::tie(hue, saturation, value) = hsv;
@ -172,11 +172,11 @@ class Color3: public Math::Vector3<T> {
* *
* Hue can overflow the range @f$ [0.0, 360.0] @f$. * Hue can overflow the range @f$ [0.0, 360.0] @f$.
*/ */
inline constexpr static Color3<T> fromHSV(HSV hsv) { constexpr static Color3<T> fromHSV(HSV hsv) {
return Implementation::fromHSV<T>(hsv); return Implementation::fromHSV<T>(hsv);
} }
/** @overload */ /** @overload */
inline constexpr static Color3<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) { constexpr static Color3<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) {
return fromHSV(std::make_tuple(hue, saturation, value)); return fromHSV(std::make_tuple(hue, saturation, value));
} }
@ -185,13 +185,13 @@ class Color3: public Math::Vector3<T> {
* *
* All components are set to zero. * All components are set to zero.
*/ */
inline constexpr /*implicit*/ Color3() {} constexpr /*implicit*/ Color3() {}
/** /**
* @brief Gray constructor * @brief Gray constructor
* @param rgb RGB value * @param rgb RGB value
*/ */
inline constexpr explicit Color3(T rgb): Math::Vector3<T>(rgb) {} constexpr explicit Color3(T rgb): Math::Vector3<T>(rgb) {}
/** /**
* @brief Constructor * @brief Constructor
@ -199,20 +199,20 @@ class Color3: public Math::Vector3<T> {
* @param g G value * @param g G value
* @param b B value * @param b B value
*/ */
inline constexpr /*implicit*/ Color3(T r, T g, T b): Math::Vector3<T>(r, g, b) {} constexpr /*implicit*/ Color3(T r, T g, T b): Math::Vector3<T>(r, g, b) {}
/** @copydoc Math::Vector::Vector(const Vector<size, U>&) */ /** @copydoc Math::Vector::Vector(const Vector<size, U>&) */
template<class U> inline constexpr explicit Color3(const Math::Vector<3, U>& other): Math::Vector3<T>(other) {} template<class U> constexpr explicit Color3(const Math::Vector<3, U>& other): Math::Vector3<T>(other) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
inline constexpr Color3(const Math::Vector<3, T>& other): Math::Vector3<T>(other) {} constexpr Color3(const Math::Vector<3, T>& other): Math::Vector3<T>(other) {}
inline T& r() { return Math::Vector3<T>::x(); } /**< @brief R component */ T& r() { return Math::Vector3<T>::x(); } /**< @brief R component */
inline constexpr T r() const { return Math::Vector3<T>::x(); } /**< @overload */ constexpr T r() const { return Math::Vector3<T>::x(); } /**< @overload */
inline T& g() { return Math::Vector3<T>::y(); } /**< @brief G component */ T& g() { return Math::Vector3<T>::y(); } /**< @brief G component */
inline constexpr T g() const { return Math::Vector3<T>::y(); } /**< @overload */ constexpr T g() const { return Math::Vector3<T>::y(); } /**< @overload */
inline T& b() { return Math::Vector3<T>::z(); } /**< @brief B component */ T& b() { return Math::Vector3<T>::z(); } /**< @brief B component */
inline constexpr T b() const { return Math::Vector3<T>::z(); } /**< @overload */ constexpr T b() const { return Math::Vector3<T>::z(); } /**< @overload */
/** /**
* @brief Convert to HSV * @brief Convert to HSV
@ -225,7 +225,7 @@ class Color3: public Math::Vector3<T> {
* *
* @see hue(), saturation(), value(), fromHSV() * @see hue(), saturation(), value(), fromHSV()
*/ */
inline constexpr HSV toHSV() const { constexpr HSV toHSV() const {
return Implementation::toHSV<T>(*this); return Implementation::toHSV<T>(*this);
} }
@ -235,7 +235,7 @@ class Color3: public Math::Vector3<T> {
* *
* @see saturation(), value(), toHSV(), fromHSV() * @see saturation(), value(), toHSV(), fromHSV()
*/ */
inline constexpr Math::Deg<FloatingPointType> hue() const { constexpr Math::Deg<FloatingPointType> hue() const {
return Math::Deg<FloatingPointType>(Implementation::hue<T>(*this)); return Math::Deg<FloatingPointType>(Implementation::hue<T>(*this));
} }
@ -245,7 +245,7 @@ class Color3: public Math::Vector3<T> {
* *
* @see hue(), value(), toHSV(), fromHSV() * @see hue(), value(), toHSV(), fromHSV()
*/ */
inline constexpr FloatingPointType saturation() const { constexpr FloatingPointType saturation() const {
return Implementation::saturation<T>(*this); return Implementation::saturation<T>(*this);
} }
@ -255,7 +255,7 @@ class Color3: public Math::Vector3<T> {
* *
* @see hue(), saturation(), toHSV(), fromHSV() * @see hue(), saturation(), toHSV(), fromHSV()
*/ */
inline constexpr FloatingPointType value() const { constexpr FloatingPointType value() const {
return Implementation::value<T>(*this); return Implementation::value<T>(*this);
} }
@ -289,11 +289,11 @@ class Color4: public Math::Vector4<T> {
* @param a Alpha value, defaults to 1.0 for floating-point types * @param a Alpha value, defaults to 1.0 for floating-point types
* and maximum positive value for integral types. * and maximum positive value for integral types.
*/ */
inline constexpr static Color4<T> fromHSV(HSV hsv, T a = Implementation::defaultAlpha<T>()) { constexpr static Color4<T> fromHSV(HSV hsv, T a = Implementation::defaultAlpha<T>()) {
return Color4<T>(Implementation::fromHSV<T>(hsv), a); return Color4<T>(Implementation::fromHSV<T>(hsv), a);
} }
/** @overload */ /** @overload */
inline constexpr static Color4<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha) { constexpr static Color4<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha) {
return fromHSV(std::make_tuple(hue, saturation, value), alpha); return fromHSV(std::make_tuple(hue, saturation, value), alpha);
} }
@ -303,14 +303,14 @@ class Color4: public Math::Vector4<T> {
* RGB components are set to zero, A component is set to 1.0 for * RGB components are set to zero, A component is set to 1.0 for
* floating-point types and maximum positive value for integral types. * floating-point types and maximum positive value for integral types.
*/ */
inline constexpr /*implicit*/ Color4(): Math::Vector4<T>(T(0), T(0), T(0), Implementation::defaultAlpha<T>()) {} constexpr /*implicit*/ Color4(): Math::Vector4<T>(T(0), T(0), T(0), Implementation::defaultAlpha<T>()) {}
/** /**
* @copydoc Color3::Color3(T) * @copydoc Color3::Color3(T)
* @param alpha Alpha value, defaults to 1.0 for floating-point types * @param alpha Alpha value, defaults to 1.0 for floating-point types
* and maximum positive value for integral types. * and maximum positive value for integral types.
*/ */
inline constexpr explicit Color4(T rgb, T alpha = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb, rgb, rgb, alpha) {} constexpr explicit Color4(T rgb, T alpha = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb, rgb, rgb, alpha) {}
/** /**
* @brief Constructor * @brief Constructor
@ -320,7 +320,7 @@ class Color4: public Math::Vector4<T> {
* @param a A value, defaults to 1.0 for floating-point types and * @param a A value, defaults to 1.0 for floating-point types and
* maximum positive value for integral types. * maximum positive value for integral types.
*/ */
inline constexpr /*implicit*/ Color4(T r, T g, T b, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(r, g, b, a) {} constexpr /*implicit*/ Color4(T r, T g, T b, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(r, g, b, a) {}
/** /**
* @brief Constructor * @brief Constructor
@ -329,22 +329,22 @@ class Color4: public Math::Vector4<T> {
*/ */
/* Not marked as explicit, because conversion from Color3 to Color4 /* Not marked as explicit, because conversion from Color3 to Color4
is fairly common, nearly always with A set to 1 */ is fairly common, nearly always with A set to 1 */
inline constexpr /*implicit*/ Color4(const Math::Vector3<T>& rgb, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb[0], rgb[1], rgb[2], a) {} constexpr /*implicit*/ Color4(const Math::Vector3<T>& rgb, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb[0], rgb[1], rgb[2], a) {}
/** @copydoc Math::Vector::Vector(const Vector<size, U>&) */ /** @copydoc Math::Vector::Vector(const Vector<size, U>&) */
template<class U> inline constexpr explicit Color4(const Math::Vector<4, U>& other): Math::Vector4<T>(other) {} template<class U> constexpr explicit Color4(const Math::Vector<4, U>& other): Math::Vector4<T>(other) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
inline constexpr Color4(const Math::Vector<4, T>& other): Math::Vector4<T>(other) {} constexpr Color4(const Math::Vector<4, T>& other): Math::Vector4<T>(other) {}
inline T& r() { return Math::Vector4<T>::x(); } /**< @brief R component */ T& r() { return Math::Vector4<T>::x(); } /**< @brief R component */
inline constexpr T r() const { return Math::Vector4<T>::x(); } /**< @overload */ constexpr T r() const { return Math::Vector4<T>::x(); } /**< @overload */
inline T& g() { return Math::Vector4<T>::y(); } /**< @brief G component */ T& g() { return Math::Vector4<T>::y(); } /**< @brief G component */
inline constexpr T g() const { return Math::Vector4<T>::y(); } /**< @overload */ constexpr T g() const { return Math::Vector4<T>::y(); } /**< @overload */
inline T& b() { return Math::Vector4<T>::z(); } /**< @brief B component */ T& b() { return Math::Vector4<T>::z(); } /**< @brief B component */
inline constexpr T b() const { return Math::Vector4<T>::z(); } /**< @overload */ constexpr T b() const { return Math::Vector4<T>::z(); } /**< @overload */
inline T& a() { return Math::Vector4<T>::w(); } /**< @brief A component */ T& a() { return Math::Vector4<T>::w(); } /**< @brief A component */
inline constexpr T a() const { return Math::Vector4<T>::w(); } /**< @overload */ constexpr T a() const { return Math::Vector4<T>::w(); } /**< @overload */
/** /**
* @brief RGB part of the vector * @brief RGB part of the vector
@ -352,26 +352,26 @@ class Color4: public Math::Vector4<T> {
* *
* @see swizzle() * @see swizzle()
*/ */
inline Color3<T>& rgb() { return Color3<T>::from(Math::Vector4<T>::data()); } Color3<T>& rgb() { return Color3<T>::from(Math::Vector4<T>::data()); }
inline constexpr Color3<T> rgb() const { return Color3<T>::from(Math::Vector4<T>::data()); } /**< @overload */ constexpr Color3<T> rgb() const { return Color3<T>::from(Math::Vector4<T>::data()); } /**< @overload */
/** @copydoc Color3::toHSV() */ /** @copydoc Color3::toHSV() */
inline constexpr HSV toHSV() const { constexpr HSV toHSV() const {
return Implementation::toHSV<T>(rgb()); return Implementation::toHSV<T>(rgb());
} }
/** @copydoc Color3::hue() */ /** @copydoc Color3::hue() */
inline constexpr Math::Deg<FloatingPointType> hue() const { constexpr Math::Deg<FloatingPointType> hue() const {
return Implementation::hue<T>(rgb()); return Implementation::hue<T>(rgb());
} }
/** @copydoc Color3::saturation() */ /** @copydoc Color3::saturation() */
inline constexpr FloatingPointType saturation() const { constexpr FloatingPointType saturation() const {
return Implementation::saturation<T>(rgb()); return Implementation::saturation<T>(rgb());
} }
/** @copydoc Color3::value() */ /** @copydoc Color3::value() */
inline constexpr FloatingPointType value() const { constexpr FloatingPointType value() const {
return Implementation::value<T>(rgb()); return Implementation::value<T>(rgb());
} }

36
src/Context.h

@ -109,13 +109,13 @@ class MAGNUM_EXPORT Extension {
static const std::vector<Extension>& extensions(Version version); static const std::vector<Extension>& extensions(Version version);
/** @brief Minimal version required by this extension */ /** @brief Minimal version required by this extension */
inline constexpr Version requiredVersion() const { return _requiredVersion; } constexpr Version requiredVersion() const { return _requiredVersion; }
/** @brief Version in which this extension was adopted to core */ /** @brief Version in which this extension was adopted to core */
inline constexpr Version coreVersion() const { return _coreVersion; } constexpr Version coreVersion() const { return _coreVersion; }
/** @brief %Extension string */ /** @brief %Extension string */
inline constexpr const char* string() const { return _string; } constexpr const char* string() const { return _string; }
private: private:
/* GCC 4.6 doesn't like const members, as std::vector doesn't have /* GCC 4.6 doesn't like const members, as std::vector doesn't have
@ -125,7 +125,7 @@ class MAGNUM_EXPORT Extension {
Version _coreVersion; Version _coreVersion;
const char* _string; const char* _string;
inline constexpr Extension(std::size_t index, Version requiredVersion, Version coreVersion, const char* string): _index(index), _requiredVersion(requiredVersion), _coreVersion(coreVersion), _string(string) {} constexpr Extension(std::size_t index, Version requiredVersion, Version coreVersion, const char* string): _index(index), _requiredVersion(requiredVersion), _coreVersion(coreVersion), _string(string) {}
}; };
/** /**
@ -197,7 +197,7 @@ class MAGNUM_EXPORT Context {
~Context(); ~Context();
/** @brief Current context */ /** @brief Current context */
inline static Context* current() { return _current; } static Context* current() { return _current; }
/** /**
* @brief OpenGL version * @brief OpenGL version
@ -205,7 +205,7 @@ class MAGNUM_EXPORT Context {
* @see majorVersion(), minorVersion(), versionString(), * @see majorVersion(), minorVersion(), versionString(),
* shadingLanguageVersionString() * shadingLanguageVersionString()
*/ */
inline Version version() const { return _version; } Version version() const { return _version; }
/** /**
* @brief Major OpenGL version (e.g. `4`) * @brief Major OpenGL version (e.g. `4`)
@ -213,7 +213,7 @@ class MAGNUM_EXPORT Context {
* @see minorVersion(), version(), versionString(), * @see minorVersion(), version(), versionString(),
* shadingLanguageVersionString() * shadingLanguageVersionString()
*/ */
inline Int majorVersion() const { return _majorVersion; } Int majorVersion() const { return _majorVersion; }
/** /**
* @brief Minor OpenGL version (e.g. `3`) * @brief Minor OpenGL version (e.g. `3`)
@ -221,7 +221,7 @@ class MAGNUM_EXPORT Context {
* @see majorVersion(), version(), versionString(), * @see majorVersion(), version(), versionString(),
* shadingLanguageVersionString() * shadingLanguageVersionString()
*/ */
inline Int minorVersion() const { return _minorVersion; } Int minorVersion() const { return _minorVersion; }
/** /**
* @brief Vendor string * @brief Vendor string
@ -230,7 +230,7 @@ class MAGNUM_EXPORT Context {
* OpenGL calls. * OpenGL calls.
* @see rendererString(), @fn_gl{GetString} with @def_gl{VENDOR} * @see rendererString(), @fn_gl{GetString} with @def_gl{VENDOR}
*/ */
inline std::string vendorString() const { std::string vendorString() const {
return reinterpret_cast<const char*>(glGetString(GL_VENDOR)); return reinterpret_cast<const char*>(glGetString(GL_VENDOR));
} }
@ -241,7 +241,7 @@ class MAGNUM_EXPORT Context {
* OpenGL calls. * OpenGL calls.
* @see vendorString(), @fn_gl{GetString} with @def_gl{RENDERER} * @see vendorString(), @fn_gl{GetString} with @def_gl{RENDERER}
*/ */
inline std::string rendererString() const { std::string rendererString() const {
return reinterpret_cast<const char*>(glGetString(GL_RENDERER)); return reinterpret_cast<const char*>(glGetString(GL_RENDERER));
} }
@ -253,7 +253,7 @@ class MAGNUM_EXPORT Context {
* @see shadingLanguageVersionString(), version(), @fn_gl{GetString} * @see shadingLanguageVersionString(), version(), @fn_gl{GetString}
* with @def_gl{VERSION} * with @def_gl{VERSION}
*/ */
inline std::string versionString() const { std::string versionString() const {
return reinterpret_cast<const char*>(glGetString(GL_VERSION)); return reinterpret_cast<const char*>(glGetString(GL_VERSION));
} }
@ -265,7 +265,7 @@ class MAGNUM_EXPORT Context {
* @see versionString(), version(), @fn_gl{GetString} with * @see versionString(), version(), @fn_gl{GetString} with
* @def_gl{SHADING_LANGUAGE_VERSION} * @def_gl{SHADING_LANGUAGE_VERSION}
*/ */
inline std::string shadingLanguageVersionString() const { std::string shadingLanguageVersionString() const {
return reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)); return reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
} }
@ -280,7 +280,7 @@ class MAGNUM_EXPORT Context {
std::vector<std::string> shadingLanguageVersionStrings() const; std::vector<std::string> shadingLanguageVersionStrings() const;
/** @brief Context flags */ /** @brief Context flags */
inline Flags flags() const { return _flags; } Flags flags() const { return _flags; }
/** /**
* @brief Supported extensions * @brief Supported extensions
@ -290,7 +290,7 @@ class MAGNUM_EXPORT Context {
* *
* @see isExtensionSupported(), Extension::extensions() * @see isExtensionSupported(), Extension::extensions()
*/ */
inline const std::vector<Extension>& supportedExtensions() const { const std::vector<Extension>& supportedExtensions() const {
return _supportedExtensions; return _supportedExtensions;
} }
@ -299,7 +299,7 @@ class MAGNUM_EXPORT Context {
* *
* @see supportedVersion(), MAGNUM_ASSERT_VERSION_SUPPORTED() * @see supportedVersion(), MAGNUM_ASSERT_VERSION_SUPPORTED()
*/ */
inline bool isVersionSupported(Version version) const { bool isVersionSupported(Version version) const {
return _version >= version; return _version >= version;
} }
@ -335,7 +335,7 @@ class MAGNUM_EXPORT Context {
* @see isExtensionSupported(const Extension&) const, * @see isExtensionSupported(const Extension&) const,
* MAGNUM_ASSERT_EXTENSION_SUPPORTED() * MAGNUM_ASSERT_EXTENSION_SUPPORTED()
*/ */
template<class T> inline bool isExtensionSupported() const { template<class T> bool isExtensionSupported() const {
return isVersionSupported(T::coreVersion()) || (isVersionSupported(T::requiredVersion()) && extensionStatus[T::Index]); return isVersionSupported(T::coreVersion()) || (isVersionSupported(T::requiredVersion()) && extensionStatus[T::Index]);
} }
@ -349,12 +349,12 @@ class MAGNUM_EXPORT Context {
* @see supportedExtensions(), Extension::extensions(), * @see supportedExtensions(), Extension::extensions(),
* MAGNUM_ASSERT_EXTENSION_SUPPORTED() * MAGNUM_ASSERT_EXTENSION_SUPPORTED()
*/ */
inline bool isExtensionSupported(const Extension& extension) const { bool isExtensionSupported(const Extension& extension) const {
return isVersionSupported(extension._coreVersion) || (isVersionSupported(extension._requiredVersion) && extensionStatus[extension._index]); return isVersionSupported(extension._coreVersion) || (isVersionSupported(extension._requiredVersion) && extensionStatus[extension._index]);
} }
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline Implementation::State* state() { return _state; } Implementation::State* state() { return _state; }
#endif #endif
private: private:

28
src/CubeMapTexture.h

@ -94,14 +94,14 @@ class CubeMapTexture: public AbstractTexture {
* Creates one cube map OpenGL texture. * Creates one cube map OpenGL texture.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP} * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
*/ */
inline explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {} explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
/** /**
* @brief Set wrapping * @brief Set wrapping
* *
* See Texture::setWrapping() for more information. * See Texture::setWrapping() for more information.
*/ */
inline CubeMapTexture* setWrapping(const Array3D<Sampler::Wrapping>& wrapping) { CubeMapTexture* setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(this, wrapping); DataHelper<3>::setWrapping(this, wrapping);
return this; return this;
} }
@ -115,7 +115,7 @@ class CubeMapTexture: public AbstractTexture {
* See Texture::imageSize() for more information. * See Texture::imageSize() for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES. * @requires_gl %Texture image queries are not available in OpenGL ES.
*/ */
inline Vector2i imageSize(Coordinate coordinate, Int level) { Vector2i imageSize(Coordinate coordinate, Int level) {
return DataHelper<2>::imageSize(this, static_cast<GLenum>(coordinate), level); return DataHelper<2>::imageSize(this, static_cast<GLenum>(coordinate), level);
} }
#endif #endif
@ -125,7 +125,7 @@ class CubeMapTexture: public AbstractTexture {
* *
* See Texture::setStorage() for more information. * See Texture::setStorage() for more information.
*/ */
inline CubeMapTexture* setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) { CubeMapTexture* setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(this, _target, levels, internalFormat, size); DataHelper<2>::setStorage(this, _target, levels, internalFormat, size);
return this; return this;
} }
@ -140,7 +140,7 @@ class CubeMapTexture: public AbstractTexture {
* See Texture::image(Int, Image*) for more information. * See Texture::image(Int, Image*) for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES. * @requires_gl %Texture image queries are not available in OpenGL ES.
*/ */
inline void image(Coordinate coordinate, Int level, Image2D* image) { void image(Coordinate coordinate, Int level, Image2D* image) {
AbstractTexture::image<2>(GLenum(coordinate), level, image); AbstractTexture::image<2>(GLenum(coordinate), level, image);
} }
@ -155,7 +155,7 @@ class CubeMapTexture: public AbstractTexture {
* information. * information.
* @requires_gl %Texture image queries are not available in OpenGL ES. * @requires_gl %Texture image queries are not available in OpenGL ES.
*/ */
inline void image(Coordinate coordinate, Int level, BufferImage2D* image, Buffer::Usage usage) { void image(Coordinate coordinate, Int level, BufferImage2D* image, Buffer::Usage usage) {
AbstractTexture::image<2>(GLenum(coordinate), level, image, usage); AbstractTexture::image<2>(GLenum(coordinate), level, image, usage);
} }
#endif #endif
@ -171,7 +171,7 @@ class CubeMapTexture: public AbstractTexture {
* *
* See Texture::setImage() for more information. * See Texture::setImage() for more information.
*/ */
template<class Image> inline CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, Image* image) { template<class Image> CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, Image* image) {
DataHelper<2>::setImage(this, static_cast<GLenum>(coordinate), level, internalFormat, image); DataHelper<2>::setImage(this, static_cast<GLenum>(coordinate), level, internalFormat, image);
return this; return this;
} }
@ -187,7 +187,7 @@ class CubeMapTexture: public AbstractTexture {
* *
* See Texture::setSubImage() for more information. * See Texture::setSubImage() for more information.
*/ */
template<class Image> inline CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) { template<class Image> CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) {
DataHelper<2>::setSubImage(this, static_cast<GLenum>(coordinate), level, offset, image); DataHelper<2>::setSubImage(this, static_cast<GLenum>(coordinate), level, offset, image);
return this; return this;
} }
@ -204,31 +204,31 @@ class CubeMapTexture: public AbstractTexture {
* *
* See Texture::invalidateSubImage() for more information. * See Texture::invalidateSubImage() for more information.
*/ */
inline void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) { void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) {
DataHelper<3>::invalidateSubImage(this, level, offset, size); DataHelper<3>::invalidateSubImage(this, level, offset, size);
} }
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline CubeMapTexture* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { CubeMapTexture* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap); AbstractTexture::setMinificationFilter(filter, mipmap);
return this; return this;
} }
inline CubeMapTexture* setMagnificationFilter(Sampler::Filter filter) { CubeMapTexture* setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter); AbstractTexture::setMagnificationFilter(filter);
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES3
inline CubeMapTexture* setBorderColor(const Color4<>& color) { CubeMapTexture* setBorderColor(const Color4<>& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return this; return this;
} }
inline CubeMapTexture* setMaxAnisotropy(Float anisotropy) { CubeMapTexture* setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy); AbstractTexture::setMaxAnisotropy(anisotropy);
return this; return this;
} }
#endif #endif
inline CubeMapTexture* generateMipmap() { CubeMapTexture* generateMipmap() {
AbstractTexture::generateMipmap(); AbstractTexture::generateMipmap();
return this; return this;
} }

30
src/CubeMapTextureArray.h

@ -98,14 +98,14 @@ class CubeMapTextureArray: public AbstractTexture {
* Creates one cube map OpenGL texture. * Creates one cube map OpenGL texture.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP} * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
*/ */
inline explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {} explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {}
/** /**
* @brief Set wrapping * @brief Set wrapping
* *
* See Texture::setWrapping() for more information. * See Texture::setWrapping() for more information.
*/ */
inline CubeMapTextureArray* setWrapping(const Array3D<Sampler::Wrapping>& wrapping) { CubeMapTextureArray* setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(this, wrapping); DataHelper<3>::setWrapping(this, wrapping);
return this; return this;
} }
@ -117,7 +117,7 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* See Texture::imageSize() for more information. * See Texture::imageSize() for more information.
*/ */
inline Vector3i imageSize(Coordinate coordinate, Int level) { Vector3i imageSize(Coordinate coordinate, Int level) {
return DataHelper<3>::imageSize(this, GL_TEXTURE_CUBE_MAP_POSITIVE_X + static_cast<GLenum>(coordinate), level); return DataHelper<3>::imageSize(this, GL_TEXTURE_CUBE_MAP_POSITIVE_X + static_cast<GLenum>(coordinate), level);
} }
@ -126,7 +126,7 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* See Texture::setStorage() for more information. * See Texture::setStorage() for more information.
*/ */
inline CubeMapTextureArray* setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) { CubeMapTextureArray* setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) {
DataHelper<3>::setStorage(this, _target, levels, internalFormat, size); DataHelper<3>::setStorage(this, _target, levels, internalFormat, size);
return this; return this;
} }
@ -141,7 +141,7 @@ class CubeMapTextureArray: public AbstractTexture {
* See Texture::image(Int, Image*) for more information. * See Texture::image(Int, Image*) for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES. * @requires_gl %Texture image queries are not available in OpenGL ES.
*/ */
inline void image(Coordinate coordinate, Int level, Image3D* image) { void image(Coordinate coordinate, Int level, Image3D* image) {
AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + GLenum(coordinate), level, image); AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + GLenum(coordinate), level, image);
} }
@ -156,7 +156,7 @@ class CubeMapTextureArray: public AbstractTexture {
* information. * information.
* @requires_gl %Texture image queries are not available in OpenGL ES. * @requires_gl %Texture image queries are not available in OpenGL ES.
*/ */
inline void image(Coordinate coordinate, Int level, BufferImage3D* image, Buffer::Usage usage) { void image(Coordinate coordinate, Int level, BufferImage3D* image, Buffer::Usage usage) {
AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + GLenum(coordinate), level, image, usage); AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + GLenum(coordinate), level, image, usage);
} }
#endif #endif
@ -175,7 +175,7 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* See Texture::setImage() for more information. * See Texture::setImage() for more information.
*/ */
template<class T> inline CubeMapTextureArray* setImage(Int level, TextureFormat internalFormat, T* image) { template<class T> CubeMapTextureArray* setImage(Int level, TextureFormat internalFormat, T* image) {
DataHelper<3>::setImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image); DataHelper<3>::setImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image);
return this; return this;
} }
@ -199,7 +199,7 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* @see setSubImage(Int, Coordinate, Int, const Math::Vector<2, Int>&, const Image*) * @see setSubImage(Int, Coordinate, Int, const Math::Vector<2, Int>&, const Image*)
*/ */
template<class Image> inline CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const Image* image) { template<class Image> CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const Image* image) {
DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image, Vector3i(Math::Vector<Image::Dimensions, GLsizei>())); DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image, Vector3i(Math::Vector<Image::Dimensions, GLsizei>()));
return this; return this;
} }
@ -218,7 +218,7 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* @see setSubImage(Int, const Math::Vector<3, Int>&, const Image*) * @see setSubImage(Int, const Math::Vector<3, Int>&, const Image*)
*/ */
template<class Image> inline CubeMapTextureArray* setSubImage(Int layer, Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) { template<class Image> CubeMapTextureArray* setSubImage(Int layer, Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) {
DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, Vector3i(offset, layer*6+static_cast<GLsizei>(coordinate)), image, Vector2i(Math::Vector<Image::Dimensions, GLsizei>())); DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, Vector3i(offset, layer*6+static_cast<GLsizei>(coordinate)), image, Vector2i(Math::Vector<Image::Dimensions, GLsizei>()));
return this; return this;
} }
@ -235,31 +235,31 @@ class CubeMapTextureArray: public AbstractTexture {
* *
* See Texture::invalidateSubImage() for more information. * See Texture::invalidateSubImage() for more information.
*/ */
inline void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) { void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) {
DataHelper<3>::invalidateSubImage(this, level, offset, size); DataHelper<3>::invalidateSubImage(this, level, offset, size);
} }
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline CubeMapTextureArray* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { CubeMapTextureArray* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap); AbstractTexture::setMinificationFilter(filter, mipmap);
return this; return this;
} }
inline CubeMapTextureArray* setMagnificationFilter(Sampler::Filter filter) { CubeMapTextureArray* setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter); AbstractTexture::setMagnificationFilter(filter);
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES3
inline CubeMapTextureArray* setBorderColor(const Color4<>& color) { CubeMapTextureArray* setBorderColor(const Color4<>& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return this; return this;
} }
inline CubeMapTextureArray* setMaxAnisotropy(Float anisotropy) { CubeMapTextureArray* setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy); AbstractTexture::setMaxAnisotropy(anisotropy);
return this; return this;
} }
#endif #endif
inline CubeMapTextureArray* generateMipmap() { CubeMapTextureArray* generateMipmap() {
AbstractTexture::generateMipmap(); AbstractTexture::generateMipmap();
return this; return this;
} }

2
src/DebugMarker.h

@ -53,7 +53,7 @@ class MAGNUM_EXPORT DebugMarker {
DebugMarker() = delete; DebugMarker() = delete;
/** @brief Put string mark into OpenGL command stream */ /** @brief Put string mark into OpenGL command stream */
inline static void mark(const std::string& string) { static void mark(const std::string& string) {
markImplementation(string); markImplementation(string);
} }

6
src/DefaultFramebuffer.h

@ -311,7 +311,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @requires_gles30 Draw attachments for default framebuffer are * @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0. * available only in OpenGL ES 3.0.
*/ */
inline DefaultFramebuffer* mapForDraw(DrawAttachment attachment) { DefaultFramebuffer* mapForDraw(DrawAttachment attachment) {
(this->*drawBufferImplementation)(static_cast<GLenum>(attachment)); (this->*drawBufferImplementation)(static_cast<GLenum>(attachment));
return this; return this;
} }
@ -329,7 +329,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} * @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/ */
inline DefaultFramebuffer* mapForRead(ReadAttachment attachment) { DefaultFramebuffer* mapForRead(ReadAttachment attachment) {
(this->*readBufferImplementation)(static_cast<GLenum>(attachment)); (this->*readBufferImplementation)(static_cast<GLenum>(attachment));
return this; return this;
} }
@ -367,7 +367,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline DefaultFramebuffer* setViewport(const Rectanglei& rectangle) { DefaultFramebuffer* setViewport(const Rectanglei& rectangle) {
AbstractFramebuffer::setViewport(rectangle); AbstractFramebuffer::setViewport(rectangle);
return this; return this;
} }

36
src/Framebuffer.h

@ -114,10 +114,10 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @brief Constructor * @brief Constructor
* @param id Color attachment id * @param id Color attachment id
*/ */
inline constexpr explicit ColorAttachment(UnsignedInt id): attachment(GL_COLOR_ATTACHMENT0 + id) {} constexpr explicit ColorAttachment(UnsignedInt id): attachment(GL_COLOR_ATTACHMENT0 + id) {}
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit operator GLenum() const { return attachment; } constexpr explicit operator GLenum() const { return attachment; }
#endif #endif
private: private:
@ -135,14 +135,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
static const DrawAttachment None; static const DrawAttachment None;
/** @brief Color attachment */ /** @brief Color attachment */
inline constexpr /*implicit*/ DrawAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {} constexpr /*implicit*/ DrawAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit operator GLenum() const { return attachment; } constexpr explicit operator GLenum() const { return attachment; }
#endif #endif
private: private:
inline constexpr explicit DrawAttachment(GLenum attachment): attachment(attachment) {} constexpr explicit DrawAttachment(GLenum attachment): attachment(attachment) {}
GLenum attachment; GLenum attachment;
}; };
@ -172,14 +172,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
#endif #endif
/** @brief Color buffer */ /** @brief Color buffer */
inline constexpr /*implicit*/ BufferAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {} constexpr /*implicit*/ BufferAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit operator GLenum() const { return attachment; } constexpr explicit operator GLenum() const { return attachment; }
#endif #endif
private: private:
inline constexpr explicit BufferAttachment(GLenum attachment): attachment(attachment) {} constexpr explicit BufferAttachment(GLenum attachment): attachment(attachment) {}
GLenum attachment; GLenum attachment;
}; };
@ -200,14 +200,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
static const InvalidationAttachment Stencil; static const InvalidationAttachment Stencil;
/** @brief Invalidate color buffer */ /** @brief Invalidate color buffer */
inline constexpr /*implicit*/ InvalidationAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {} constexpr /*implicit*/ InvalidationAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit operator GLenum() const { return attachment; } constexpr explicit operator GLenum() const { return attachment; }
#endif #endif
private: private:
inline constexpr explicit InvalidationAttachment(GLenum attachment): attachment(attachment) {} constexpr explicit InvalidationAttachment(GLenum attachment): attachment(attachment) {}
GLenum attachment; GLenum attachment;
}; };
@ -266,7 +266,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl{DrawBuffers} in OpenGL ES 3.0 * @fn_gl{DrawBuffers} in OpenGL ES 3.0
* @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} * @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
*/ */
inline Framebuffer* mapForDraw(DrawAttachment attachment) { Framebuffer* mapForDraw(DrawAttachment attachment) {
(this->*drawBufferImplementation)(GLenum(attachment)); (this->*drawBufferImplementation)(GLenum(attachment));
return this; return this;
} }
@ -314,7 +314,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} * @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/ */
inline Framebuffer* mapForRead(ColorAttachment attachment) { Framebuffer* mapForRead(ColorAttachment attachment) {
(this->*readBufferImplementation)(GLenum(attachment)); (this->*readBufferImplementation)(GLenum(attachment));
return this; return this;
} }
@ -331,7 +331,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} or * @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} or
* @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access} * @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access}
*/ */
inline Framebuffer* attachRenderbuffer(BufferAttachment attachment, Renderbuffer* renderbuffer) { Framebuffer* attachRenderbuffer(BufferAttachment attachment, Renderbuffer* renderbuffer) {
(this->*renderbufferImplementation)(attachment, renderbuffer); (this->*renderbufferImplementation)(attachment, renderbuffer);
return this; return this;
} }
@ -351,7 +351,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access} * @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}
* @requires_gl Only 2D and 3D textures are available in OpenGL ES. * @requires_gl Only 2D and 3D textures are available in OpenGL ES.
*/ */
inline Framebuffer* attachTexture1D(BufferAttachment attachment, Texture1D* texture, Int level) { Framebuffer* attachTexture1D(BufferAttachment attachment, Texture1D* texture, Int level) {
(this->*texture1DImplementation)(attachment, texture, level); (this->*texture1DImplementation)(attachment, texture, level);
return this; return this;
} }
@ -386,7 +386,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see attachTexture2D(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture} * @see attachTexture2D(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access} * or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
*/ */
inline Framebuffer* attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, Int level) { Framebuffer* attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, Int level) {
(this->*texture2DImplementation)(attachment, GLenum(coordinate), texture->id(), level); (this->*texture2DImplementation)(attachment, GLenum(coordinate), texture->id(), level);
return this; return this;
} }
@ -406,7 +406,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{NamedFramebufferTexture3D,EXT,direct_state_access} * @fn_gl_extension{NamedFramebufferTexture3D,EXT,direct_state_access}
* @requires_es_extension %Extension @es_extension{OES,texture_3D} * @requires_es_extension %Extension @es_extension{OES,texture_3D}
*/ */
inline Framebuffer* attachTexture3D(BufferAttachment attachment, Texture3D* texture, Int level, Int layer) { Framebuffer* attachTexture3D(BufferAttachment attachment, Texture3D* texture, Int level, Int layer) {
/** @todo Check for texture target compatibility */ /** @todo Check for texture target compatibility */
(this->*texture3DImplementation)(attachment, texture, level, layer); (this->*texture3DImplementation)(attachment, texture, level, layer);
return this; return this;
@ -414,7 +414,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline Framebuffer* setViewport(const Rectanglei& rectangle) { Framebuffer* setViewport(const Rectanglei& rectangle) {
AbstractFramebuffer::setViewport(rectangle); AbstractFramebuffer::setViewport(rectangle);
return this; return this;
} }

12
src/Image.h

@ -55,7 +55,7 @@ template<UnsignedInt dimensions> class Image: public AbstractImage {
* Note that the image data are not copied on construction, but they * Note that the image data are not copied on construction, but they
* are deleted on class destruction. * are deleted on class destruction.
*/ */
inline explicit Image(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {} explicit Image(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {}
/** /**
* @brief Constructor * @brief Constructor
@ -65,17 +65,17 @@ template<UnsignedInt dimensions> class Image: public AbstractImage {
* Dimensions and data pointer are set to zero, call setData() to fill * Dimensions and data pointer are set to zero, call setData() to fill
* the image with data. * the image with data.
*/ */
inline explicit Image(ImageFormat format, ImageType type): AbstractImage(format, type), _data(nullptr) {} explicit Image(ImageFormat format, ImageType type): AbstractImage(format, type), _data(nullptr) {}
/** @brief Destructor */ /** @brief Destructor */
inline ~Image() { delete[] _data; } ~Image() { delete[] _data; }
/** @brief %Image size */ /** @brief %Image size */
inline typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; } typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
/** @brief Pointer to raw data */ /** @brief Pointer to raw data */
inline unsigned char* data() { return _data; } unsigned char* data() { return _data; }
inline const unsigned char* data() const { return _data; } /**< @overload */ const unsigned char* data() const { return _data; } /**< @overload */
/** /**
* @brief Set image data * @brief Set image data

12
src/ImageWrapper.h

@ -62,7 +62,7 @@ template<UnsignedInt dimensions> class ImageWrapper: public AbstractImage {
* Note that the image data are not copied on construction, but they * Note that the image data are not copied on construction, but they
* are deleted on class destruction. * are deleted on class destruction.
*/ */
inline explicit ImageWrapper(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {} explicit ImageWrapper(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {}
/** /**
* @brief Constructor * @brief Constructor
@ -73,14 +73,14 @@ template<UnsignedInt dimensions> class ImageWrapper: public AbstractImage {
* Data pointer is set to zero, call setData() to fill the image with * Data pointer is set to zero, call setData() to fill the image with
* data. * data.
*/ */
inline explicit ImageWrapper(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type): AbstractImage(format, type), _size(size), _data(nullptr) {} explicit ImageWrapper(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type): AbstractImage(format, type), _size(size), _data(nullptr) {}
/** @brief %Image size */ /** @brief %Image size */
inline typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; } typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
/** @brief Pointer to raw data */ /** @brief Pointer to raw data */
inline unsigned char* data() { return _data; } unsigned char* data() { return _data; }
inline const unsigned char* data() const { return _data; } /**< @overload */ const unsigned char* data() const { return _data; } /**< @overload */
/** /**
* @brief Set image data * @brief Set image data
@ -90,7 +90,7 @@ template<UnsignedInt dimensions> class ImageWrapper: public AbstractImage {
* passed in constructor. The data are not copied nor deleted on * passed in constructor. The data are not copied nor deleted on
* destruction. * destruction.
*/ */
inline void setData(void* data) { void setData(void* data) {
_data = reinterpret_cast<unsigned char*>(data); _data = reinterpret_cast<unsigned char*>(data);
} }

2
src/Implementation/BufferState.h

@ -43,7 +43,7 @@ struct BufferState {
static std::size_t indexForTarget(Buffer::Target target); static std::size_t indexForTarget(Buffer::Target target);
static const Buffer::Target targetForIndex[TargetCount-1]; static const Buffer::Target targetForIndex[TargetCount-1];
inline constexpr BufferState(): bindings() {} constexpr BufferState(): bindings() {}
/* Currently bound buffer for all targets */ /* Currently bound buffer for all targets */
GLuint bindings[TargetCount]; GLuint bindings[TargetCount];

2
src/Implementation/FramebufferState.h

@ -31,7 +31,7 @@
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
struct FramebufferState { struct FramebufferState {
inline constexpr FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {} constexpr FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {}
GLuint readBinding, drawBinding, renderbufferBinding; GLuint readBinding, drawBinding, renderbufferBinding;
Rectanglei viewport; Rectanglei viewport;

2
src/Implementation/MeshState.h

@ -29,7 +29,7 @@
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
struct MeshState { struct MeshState {
inline constexpr MeshState(): currentVAO(0) {} constexpr MeshState(): currentVAO(0) {}
GLuint currentVAO; GLuint currentVAO;
}; };

2
src/Implementation/RendererState.h

@ -29,7 +29,7 @@
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
struct RendererState { struct RendererState {
inline constexpr RendererState() constexpr RendererState()
#ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES3
: resetNotificationStrategy() : resetNotificationStrategy()
#endif #endif

2
src/Implementation/ShaderProgramState.h

@ -29,7 +29,7 @@
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
struct ShaderProgramState { struct ShaderProgramState {
inline constexpr ShaderProgramState(): current(0), maxSupportedVertexAttributeCount(0) {} constexpr ShaderProgramState(): current(0), maxSupportedVertexAttributeCount(0) {}
/* Currently used program */ /* Currently used program */
GLuint current; GLuint current;

31
src/Mesh.h

@ -362,7 +362,7 @@ class MAGNUM_EXPORT Mesh {
Mesh& operator=(Mesh&& other); Mesh& operator=(Mesh&& other);
/** @brief Primitive type */ /** @brief Primitive type */
inline Primitive primitive() const { return _primitive; } Primitive primitive() const { return _primitive; }
/** /**
* @brief Set primitive type * @brief Set primitive type
@ -372,13 +372,13 @@ class MAGNUM_EXPORT Mesh {
* @see setVertexCount(), addVertexBuffer(), * @see setVertexCount(), addVertexBuffer(),
* addInterleavedVertexBuffer(), addVertexBufferStride() * addInterleavedVertexBuffer(), addVertexBufferStride()
*/ */
inline Mesh* setPrimitive(Primitive primitive) { Mesh* setPrimitive(Primitive primitive) {
_primitive = primitive; _primitive = primitive;
return this; return this;
} }
/** @brief Vertex count */ /** @brief Vertex count */
inline Int vertexCount() const { return _vertexCount; } Int vertexCount() const { return _vertexCount; }
/** /**
* @brief Set vertex count * @brief Set vertex count
@ -388,13 +388,13 @@ class MAGNUM_EXPORT Mesh {
* @see setPrimitive(), addVertexBuffer(), addInterleavedVertexBuffer(), * @see setPrimitive(), addVertexBuffer(), addInterleavedVertexBuffer(),
* addVertexBufferStride(), MeshTools::interleave() * addVertexBufferStride(), MeshTools::interleave()
*/ */
inline Mesh* setVertexCount(Int vertexCount) { Mesh* setVertexCount(Int vertexCount) {
_vertexCount = vertexCount; _vertexCount = vertexCount;
return this; return this;
} }
/** @brief Index count */ /** @brief Index count */
inline Int indexCount() const { return _indexCount; } Int indexCount() const { return _indexCount; }
/** /**
* @brief Set index count * @brief Set index count
@ -403,7 +403,7 @@ class MAGNUM_EXPORT Mesh {
* Default is zero. * Default is zero.
* @see setIndexBuffer(), MeshTools::compressIndices() * @see setIndexBuffer(), MeshTools::compressIndices()
*/ */
inline Mesh* setIndexCount(Int count) { Mesh* setIndexCount(Int count) {
_indexCount = count; _indexCount = count;
return this; return this;
} }
@ -457,13 +457,7 @@ class MAGNUM_EXPORT Mesh {
* @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access} * @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access}
* if @extension{APPLE,vertex_array_object} is available * if @extension{APPLE,vertex_array_object} is available
*/ */
template<class ...T> inline Mesh* addVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes) { template<class ...T> Mesh* addVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes);
CORRADE_ASSERT(sizeof...(attributes) == 1 || _vertexCount != 0,
"Mesh::addVertexBuffer(): vertex count must be set before binding attributes", this);
addVertexBufferInternal(buffer, offset, attributes...);
return this;
}
/** /**
* @brief Add buffer with interleaved vertex attributes for use with given shader * @brief Add buffer with interleaved vertex attributes for use with given shader
@ -574,7 +568,7 @@ class MAGNUM_EXPORT Mesh {
* @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if * @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if
* @extension{APPLE,vertex_array_object} is available) * @extension{APPLE,vertex_array_object} is available)
*/ */
inline Mesh* setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type) { Mesh* setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type) {
return setIndexBuffer(buffer, offset, type, 0, 0); return setIndexBuffer(buffer, offset, type, 0, 0);
} }
@ -789,6 +783,15 @@ Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::Primitive value);
/** @debugoperator{Magnum::Mesh} */ /** @debugoperator{Magnum::Mesh} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::IndexType value); Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::IndexType value);
template<class ...T> inline Mesh* Mesh::addVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes) {
CORRADE_ASSERT(sizeof...(attributes) == 1 || _vertexCount != 0,
"Mesh::addVertexBuffer(): vertex count must be set before binding attributes", this);
addVertexBufferInternal(buffer, offset, attributes...);
return this;
}
} }
namespace Corrade { namespace Utility { namespace Corrade { namespace Utility {

14
src/Query.h

@ -66,7 +66,7 @@ class MAGNUM_EXPORT AbstractQuery {
#endif #endif
/** @brief OpenGL query ID */ /** @brief OpenGL query ID */
inline GLuint id() const { return _id; } GLuint id() const { return _id; }
/** /**
* @brief Whether the result is available * @brief Whether the result is available
@ -172,7 +172,7 @@ class PrimitiveQuery: public AbstractQuery {
* Begins counting of given @p target until end() is called. * Begins counting of given @p target until end() is called.
* @see @fn_gl{BeginQuery} * @see @fn_gl{BeginQuery}
*/ */
inline void begin(Target target) { void begin(Target target) {
AbstractQuery::begin(GLenum(target)); AbstractQuery::begin(GLenum(target));
} }
}; };
@ -285,7 +285,7 @@ class SampleQuery: public AbstractQuery {
#endif #endif
/** @copydoc PrimitiveQuery::begin() */ /** @copydoc PrimitiveQuery::begin() */
inline void begin(Target target) { void begin(Target target) {
AbstractQuery::begin(GLenum(target)); AbstractQuery::begin(GLenum(target));
} }
@ -297,7 +297,7 @@ class SampleQuery: public AbstractQuery {
* @requires_gl30 %Extension @extension{NV,conditional_render} * @requires_gl30 %Extension @extension{NV,conditional_render}
* @requires_gl Conditional rendering is not available in OpenGL ES. * @requires_gl Conditional rendering is not available in OpenGL ES.
*/ */
inline void beginConditionalRender(ConditionalRenderMode mode) { void beginConditionalRender(ConditionalRenderMode mode) {
glBeginConditionalRender(id(), static_cast<GLenum>(mode)); glBeginConditionalRender(id(), static_cast<GLenum>(mode));
} }
@ -308,7 +308,7 @@ class SampleQuery: public AbstractQuery {
* @requires_gl30 %Extension @extension{NV,conditional_render} * @requires_gl30 %Extension @extension{NV,conditional_render}
* @requires_gl Conditional rendering is not available in OpenGL ES. * @requires_gl Conditional rendering is not available in OpenGL ES.
*/ */
inline void endConditionalRender() { void endConditionalRender() {
glEndConditionalRender(); glEndConditionalRender();
} }
#endif #endif
@ -366,7 +366,7 @@ class TimeQuery: public AbstractQuery {
* *
* @see @fn_gl{QueryCounter} with @def_gl{TIMESTAMP} * @see @fn_gl{QueryCounter} with @def_gl{TIMESTAMP}
*/ */
inline void timestamp() { void timestamp() {
/** @todo Enable when extension wrangler for ES is available */ /** @todo Enable when extension wrangler for ES is available */
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
glQueryCounter(id(), GL_TIMESTAMP); glQueryCounter(id(), GL_TIMESTAMP);
@ -377,7 +377,7 @@ class TimeQuery: public AbstractQuery {
} }
/** @copydoc PrimitiveQuery::begin() */ /** @copydoc PrimitiveQuery::begin() */
inline void begin(Target target) { void begin(Target target) {
AbstractQuery::begin(GLenum(target)); AbstractQuery::begin(GLenum(target));
} }
}; };

10
src/Renderbuffer.h

@ -66,9 +66,7 @@ class MAGNUM_EXPORT Renderbuffer {
* Generates new OpenGL renderbuffer. * Generates new OpenGL renderbuffer.
* @see @fn_gl{GenRenderbuffers} * @see @fn_gl{GenRenderbuffers}
*/ */
inline explicit Renderbuffer() { explicit Renderbuffer() { glGenRenderbuffers(1, &_id); }
glGenRenderbuffers(1, &_id);
}
/** /**
* @brief Destructor * @brief Destructor
@ -79,7 +77,7 @@ class MAGNUM_EXPORT Renderbuffer {
~Renderbuffer(); ~Renderbuffer();
/** @brief OpenGL internal renderbuffer ID */ /** @brief OpenGL internal renderbuffer ID */
inline GLuint id() const { return _id; } GLuint id() const { return _id; }
/** /**
* @brief Set renderbuffer storage * @brief Set renderbuffer storage
@ -92,7 +90,7 @@ class MAGNUM_EXPORT Renderbuffer {
* @see @fn_gl{BindRenderbuffer}, @fn_gl{RenderbufferStorage} or * @see @fn_gl{BindRenderbuffer}, @fn_gl{RenderbufferStorage} or
* @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access} * @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access}
*/ */
inline void setStorage(RenderbufferFormat internalFormat, const Vector2i& size) { void setStorage(RenderbufferFormat internalFormat, const Vector2i& size) {
(this->*storageImplementation)(internalFormat, size); (this->*storageImplementation)(internalFormat, size);
} }
@ -112,7 +110,7 @@ class MAGNUM_EXPORT Renderbuffer {
* or @es_extension{NV,framebuffer_multisample} * or @es_extension{NV,framebuffer_multisample}
* @todo How about @es_extension{APPLE,framebuffer_multisample}? * @todo How about @es_extension{APPLE,framebuffer_multisample}?
*/ */
inline void setStorageMultisample(Int samples, RenderbufferFormat internalFormat, const Vector2i& size) { void setStorageMultisample(Int samples, RenderbufferFormat internalFormat, const Vector2i& size) {
(this->*storageMultisampleImplementation)(samples, internalFormat, size); (this->*storageMultisampleImplementation)(samples, internalFormat, size);
} }

12
src/Renderer.h

@ -231,7 +231,7 @@ class MAGNUM_EXPORT Renderer {
* If OpenGL ES, OpenGL 4.1 or extension @extension{ARB,ES2_compatibility} * If OpenGL ES, OpenGL 4.1 or extension @extension{ARB,ES2_compatibility}
* is not available, this function behaves exactly as setClearDepth(Double). * is not available, this function behaves exactly as setClearDepth(Double).
*/ */
inline static void setClearDepth(Float depth) { static void setClearDepth(Float depth) {
clearDepthfImplementation(depth); clearDepthfImplementation(depth);
} }
@ -824,9 +824,7 @@ class MAGNUM_EXPORT Renderer {
* *
* @see finish(), @fn_gl{Flush} * @see finish(), @fn_gl{Flush}
*/ */
inline static void flush() { static void flush() { glFlush(); }
glFlush();
}
/** /**
* @brief Finish the pipeline * @brief Finish the pipeline
@ -834,9 +832,7 @@ class MAGNUM_EXPORT Renderer {
* Blocks until all commands in the pipeline are finished. * Blocks until all commands in the pipeline are finished.
* @see flush(), @fn_gl{Finish} * @see flush(), @fn_gl{Finish}
*/ */
inline static void finish() { static void finish() { glFinish(); }
glFinish();
}
#ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES3
/** /**
@ -922,7 +918,7 @@ class MAGNUM_EXPORT Renderer {
* @ref GraphicsResetStatus "GraphicsResetStatus::NoError". * @ref GraphicsResetStatus "GraphicsResetStatus::NoError".
* @see resetNotificationStrategy(), @fn_gl_extension{GetGraphicsResetStatus,ARB,robustness} * @see resetNotificationStrategy(), @fn_gl_extension{GetGraphicsResetStatus,ARB,robustness}
*/ */
inline static GraphicsResetStatus graphicsResetStatus() { static GraphicsResetStatus graphicsResetStatus() {
return graphicsResetStatusImplementation(); return graphicsResetStatusImplementation();
} }
#endif #endif

154
src/Resource.h

@ -86,16 +86,16 @@ class ResourceKey: public Utility::MurmurHash2::Digest {
* Creates zero key. Note that it is not the same as calling other * Creates zero key. Note that it is not the same as calling other
* constructors with empty string. * constructors with empty string.
*/ */
inline constexpr ResourceKey() {} constexpr ResourceKey() {}
/** @brief Constructor */ /** @brief Constructor */
inline ResourceKey(const std::string& key): Utility::MurmurHash2::Digest(Utility::MurmurHash2()(key)) {} ResourceKey(const std::string& key): Utility::MurmurHash2::Digest(Utility::MurmurHash2()(key)) {}
/** /**
* @brief Constructor * @brief Constructor
* @todo constexpr * @todo constexpr
*/ */
template<std::size_t size> inline constexpr ResourceKey(const char(&key)[size]): Utility::MurmurHash2::Digest(Utility::MurmurHash2()(key)) {} template<std::size_t size> constexpr ResourceKey(const char(&key)[size]): Utility::MurmurHash2::Digest(Utility::MurmurHash2()(key)) {}
}; };
/** @debugoperator{Magnum::ResourceKey} */ /** @debugoperator{Magnum::ResourceKey} */
@ -112,10 +112,10 @@ namespace Implementation {
See ResourceManager for more information. See ResourceManager for more information.
*/ */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T, class U>
#else
template<class T, class U = T> template<class T, class U = T>
#else
template<class T, class U>
#endif #endif
class Resource { class Resource {
friend class Implementation::ResourceManagerData<T>; friend class Implementation::ResourceManagerData<T>;
@ -127,60 +127,39 @@ class Resource {
* Creates empty resource. Resources are acquired from the manager by * Creates empty resource. Resources are acquired from the manager by
* calling ResourceManager::get(). * calling ResourceManager::get().
*/ */
inline explicit Resource(): manager(nullptr), lastCheck(0), _state(ResourceState::Final), data(nullptr) {} explicit Resource(): manager(nullptr), lastCheck(0), _state(ResourceState::Final), data(nullptr) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
inline Resource(const Resource<T, U>& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { Resource(const Resource<T, U>& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) {
if(manager) manager->incrementReferenceCount(_key); if(manager) manager->incrementReferenceCount(_key);
} }
/** @brief Move constructor */ /** @brief Move constructor */
inline Resource(Resource<T, U>&& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { Resource(Resource<T, U>&& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) {
/** @brief Make other's state well-defined */
other.manager = nullptr; other.manager = nullptr;
} }
/** @brief Destructor */ /** @brief Destructor */
inline ~Resource() { ~Resource() {
if(manager) manager->decrementReferenceCount(_key); if(manager) manager->decrementReferenceCount(_key);
} }
/** @brief Assignment operator */ /** @brief Copy assignment */
Resource<T, U>& operator=(const Resource<T, U>& other) { Resource<T, U>& operator=(const Resource<T, U>& other);
if(manager) manager->decrementReferenceCount(_key);
manager = other.manager; /** @brief Move assignment */
_key = other._key; Resource<T, U>& operator=(Resource<T, U>&& other);
lastCheck = other.lastCheck;
_state = other._state;
data = other.data;
if(manager) manager->incrementReferenceCount(_key);
return *this;
}
/** @brief Assignment move operator */
Resource<T, U>& operator=(Resource<T, U>&& other) {
if(manager) manager->decrementReferenceCount(_key);
manager = other.manager;
_key = other._key;
lastCheck = other.lastCheck;
_state = other._state;
data = other.data;
other.manager = nullptr;
return *this;
}
/** @brief Resource key */ /** @brief Resource key */
inline ResourceKey key() const { return _key; } ResourceKey key() const { return _key; }
/** /**
* @brief %Resource state * @brief %Resource state
* *
* @see operator bool(), ResourceManager::state() * @see operator bool(), ResourceManager::state()
*/ */
inline ResourceState state() { ResourceState state() {
acquire(); acquire();
return _state; return _state;
} }
@ -193,7 +172,7 @@ class Resource {
* @ref ResourceState "ResourceState::Loading" or * @ref ResourceState "ResourceState::Loading" or
* @ref ResourceState "ResourceState::NotFound"), true otherwise. * @ref ResourceState "ResourceState::NotFound"), true otherwise.
*/ */
inline operator bool() { operator bool() {
acquire(); acquire();
return data; return data;
} }
@ -204,61 +183,32 @@ class Resource {
* The resource must be loaded before accessing it. Use boolean * The resource must be loaded before accessing it. Use boolean
* conversion operator or state() for testing whether it is loaded. * conversion operator or state() for testing whether it is loaded.
*/ */
inline operator U*() { operator U*() {
acquire(); acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr); CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr);
return static_cast<U*>(data); return static_cast<U*>(data);
} }
/** @overload */ /** @overload */
inline U* operator->() { U* operator->() {
acquire(); acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr); CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), nullptr);
return static_cast<U*>(data); return static_cast<U*>(data);
} }
/** @overload */ /** @overload */
inline U& operator*() { U& operator*() {
acquire(); acquire();
CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), *static_cast<U*>(data)); CORRADE_ASSERT(data, "Resource: accessing not loaded data with key" << key(), *static_cast<U*>(data));
return *static_cast<U*>(data); return *static_cast<U*>(data);
} }
private: private:
inline Resource(Implementation::ResourceManagerData<T>* manager, ResourceKey key): manager(manager), _key(key), lastCheck(0), _state(ResourceState::NotLoaded), data(nullptr) { Resource(Implementation::ResourceManagerData<T>* manager, ResourceKey key): manager(manager), _key(key), lastCheck(0), _state(ResourceState::NotLoaded), data(nullptr) {
manager->incrementReferenceCount(key); manager->incrementReferenceCount(key);
} }
void acquire() { void acquire();
/* The data are already final, nothing to do */
if(_state == ResourceState::Final) return;
/* Nothing changed since last check */
if(manager->lastChange() < lastCheck) return;
/* Acquire new data and save last check time */
const typename Implementation::ResourceManagerData<T>::Data& d = manager->data(_key);
lastCheck = manager->lastChange();
/* Try to get the data */
data = d.data;
_state = static_cast<ResourceState>(d.state);
/* Data are not available */
if(!data) {
/* Fallback found, add *Fallback to state */
if((data = manager->fallback())) {
if(_state == ResourceState::Loading)
_state = ResourceState::LoadingFallback;
else if(_state == ResourceState::NotFound)
_state = ResourceState::NotFoundFallback;
else _state = ResourceState::NotLoadedFallback;
/* Fallback not found and loading didn't start yet */
} else if(_state != ResourceState::Loading && _state != ResourceState::NotFound)
_state = ResourceState::NotLoaded;
}
}
Implementation::ResourceManagerData<T>* manager; Implementation::ResourceManagerData<T>* manager;
ResourceKey _key; ResourceKey _key;
@ -267,6 +217,64 @@ class Resource {
T* data; T* data;
}; };
template<class T, class U> Resource<T, U>& Resource<T, U>::operator=(const Resource<T, U>& other) {
if(manager) manager->decrementReferenceCount(_key);
manager = other.manager;
_key = other._key;
lastCheck = other.lastCheck;
_state = other._state;
data = other.data;
if(manager) manager->incrementReferenceCount(_key);
return *this;
}
template<class T, class U> Resource<T, U>& Resource<T, U>::operator=(Resource<T, U>&& other) {
/** @todo Just swap the values */
if(manager) manager->decrementReferenceCount(_key);
manager = other.manager;
_key = other._key;
lastCheck = other.lastCheck;
_state = other._state;
data = other.data;
other.manager = nullptr;
return *this;
}
template<class T, class U> void Resource<T, U>::acquire() {
/* The data are already final, nothing to do */
if(_state == ResourceState::Final) return;
/* Nothing changed since last check */
if(manager->lastChange() < lastCheck) return;
/* Acquire new data and save last check time */
const typename Implementation::ResourceManagerData<T>::Data& d = manager->data(_key);
lastCheck = manager->lastChange();
/* Try to get the data */
data = d.data;
_state = static_cast<ResourceState>(d.state);
/* Data are not available */
if(!data) {
/* Fallback found, add *Fallback to state */
if((data = manager->fallback())) {
if(_state == ResourceState::Loading)
_state = ResourceState::LoadingFallback;
else if(_state == ResourceState::NotFound)
_state = ResourceState::NotFoundFallback;
else _state = ResourceState::NotLoadedFallback;
/* Fallback not found and loading didn't start yet */
} else if(_state != ResourceState::Loading && _state != ResourceState::NotFound)
_state = ResourceState::NotLoaded;
}
}
} }
/* Make the definition complete */ /* Make the definition complete */

443
src/ResourceManager.h

@ -90,185 +90,69 @@ enum class ResourcePolicy: UnsignedByte {
template<class> class AbstractResourceLoader; template<class> class AbstractResourceLoader;
namespace Implementation { namespace Implementation {
struct ResourceKeyHash {
inline std::size_t operator()(ResourceKey key) const { struct ResourceKeyHash {
return *reinterpret_cast<const std::size_t*>(key.byteArray()); std::size_t operator()(ResourceKey key) const {
return *reinterpret_cast<const std::size_t*>(key.byteArray());
}
};
template<class T> class ResourceManagerData {
template<class, class> friend class Magnum::Resource;
friend class AbstractResourceLoader<T>;
ResourceManagerData(const ResourceManagerData<T>&) = delete;
ResourceManagerData(ResourceManagerData<T>&&) = delete;
ResourceManagerData<T>& operator=(const ResourceManagerData<T>&) = delete;
ResourceManagerData<T>& operator=(ResourceManagerData<T>&&) = delete;
public:
virtual ~ResourceManagerData();
std::size_t lastChange() const { return _lastChange; }
std::size_t count() const { return _data.size(); }
std::size_t referenceCount(ResourceKey key) const;
ResourceState state(ResourceKey key) const;
template<class U> Resource<T, U> get(ResourceKey key);
void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy);
T* fallback() { return _fallback; }
const T* fallback() const { return _fallback; }
void setFallback(T* data);
void free();
AbstractResourceLoader<T>* loader() { return _loader; }
const AbstractResourceLoader<T>* loader() const { return _loader; }
void setLoader(AbstractResourceLoader<T>* loader);
protected:
ResourceManagerData(): _fallback(nullptr), _loader(nullptr), _lastChange(0) {}
private:
struct Data;
const Data& data(ResourceKey key) { return _data[key]; }
void incrementReferenceCount(ResourceKey key) {
++_data[key].referenceCount;
} }
};
void decrementReferenceCount(ResourceKey key);
template<class T> class ResourceManagerData {
template<class, class> friend class Magnum::Resource; std::unordered_map<ResourceKey, Data, ResourceKeyHash> _data;
friend class AbstractResourceLoader<T>; T* _fallback;
AbstractResourceLoader<T>* _loader;
ResourceManagerData(const ResourceManagerData<T>&) = delete; std::size_t _lastChange;
ResourceManagerData(ResourceManagerData<T>&&) = delete; };
ResourceManagerData<T>& operator=(const ResourceManagerData<T>&) = delete;
ResourceManagerData<T>& operator=(ResourceManagerData<T>&&) = delete;
public:
inline virtual ~ResourceManagerData() {
delete _fallback;
if(_loader) {
_loader->manager = nullptr;
delete _loader;
}
}
inline std::size_t lastChange() const { return _lastChange; }
inline std::size_t count() const { return _data.size(); }
std::size_t referenceCount(ResourceKey key) const {
auto it = _data.find(key);
if(it == _data.end()) return 0;
return it->second.referenceCount;
}
ResourceState state(ResourceKey key) const {
auto it = _data.find(key);
/* Resource not loaded */
if(it == _data.end() || !it->second.data) {
/* Fallback found, add *Fallback to state */
if(_fallback) {
if(it != _data.end() && it->second.state == ResourceDataState::Loading)
return ResourceState::LoadingFallback;
else if(it != _data.end() && it->second.state == ResourceDataState::NotFound)
return ResourceState::NotFoundFallback;
else return ResourceState::NotLoadedFallback;
}
/* Fallback not found, loading didn't start yet */
if(it == _data.end() || (it->second.state != ResourceDataState::Loading && it->second.state != ResourceDataState::NotFound))
return ResourceState::NotLoaded;
}
/* Loading / NotFound without fallback, Mutable / Final */
return static_cast<ResourceState>(it->second.state);
}
template<class U> inline Resource<T, U> get(ResourceKey key) {
/* Ask loader for the data, if they aren't there yet */
if(_loader && _data.find(key) == _data.end())
_loader->load(key);
return Resource<T, U>(this, key);
}
void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
auto it = _data.find(key);
/* NotFound / Loading state shouldn't have any data */
CORRADE_ASSERT((data == nullptr) == (state == ResourceDataState::NotFound || state == ResourceDataState::Loading),
"ResourceManager::set(): data should be null if and only if state is NotFound or Loading", );
/* Cannot change resource with already final state */
CORRADE_ASSERT(it == _data.end() || it->second.state != ResourceDataState::Final,
"ResourceManager::set(): cannot change already final resource" << key, );
/* If nothing is referencing reference-counted resource, we're done */
if(policy == ResourcePolicy::ReferenceCounted && (it == _data.end() || it->second.referenceCount == 0)) {
Warning() << "ResourceManager: Reference-counted resource with key" << key << "isn't referenced from anywhere, deleting it immediately";
delete data;
/* Delete also already present resource (it could be here
because previous policy could be other than
ReferenceCounted) */
if(it != _data.end()) _data.erase(it);
return;
/* Insert it, if not already here */
} else if(it == _data.end())
it = _data.insert(std::make_pair(key, Data())).first;
/* Replace previous data */
delete it->second.data;
it->second.data = data;
it->second.state = state;
it->second.policy = policy;
++_lastChange;
}
inline T* fallback() { return _fallback; }
inline const T* fallback() const { return _fallback; }
inline void setFallback(T* data) {
delete _fallback;
_fallback = data;
}
void free() {
/* Delete all non-referenced non-resident resources */
for(auto it = _data.begin(); it != _data.end(); ) {
if(it->second.policy != ResourcePolicy::Resident && !it->second.referenceCount)
it = _data.erase(it);
else ++it;
}
}
inline AbstractResourceLoader<T>* loader() { return _loader; }
inline const AbstractResourceLoader<T>* loader() const { return _loader; }
inline void setLoader(AbstractResourceLoader<T>* loader) {
/* Delete previous loader */
delete _loader;
/* Add new loader */
_loader = loader;
if(_loader) _loader->manager = this;
}
protected:
inline ResourceManagerData(): _fallback(nullptr), _loader(nullptr), _lastChange(0) {}
private:
struct Data {
Data(const Data&) = delete;
Data& operator=(const Data&) = delete;
Data& operator=(Data&&) = delete;
inline Data(): data(nullptr), state(ResourceDataState::Mutable), policy(ResourcePolicy::Manual), referenceCount(0) {}
inline Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
other.data = nullptr;
other.referenceCount = 0;
}
inline ~Data() {
CORRADE_ASSERT(referenceCount == 0,
"ResourceManager::~ResourceManager(): destroyed while data are still referenced", );
delete data;
}
T* data;
ResourceDataState state;
ResourcePolicy policy;
std::size_t referenceCount;
};
inline const Data& data(ResourceKey key) {
return _data[key];
}
inline void incrementReferenceCount(ResourceKey key) {
++_data[key].referenceCount;
}
inline void decrementReferenceCount(ResourceKey key) {
auto it = _data.find(key);
/* Free the resource if it is reference counted */
if(--it->second.referenceCount == 0 && it->second.policy == ResourcePolicy::ReferenceCounted)
_data.erase(it);
}
std::unordered_map<ResourceKey, Data, ResourceKeyHash> _data;
T* _fallback;
AbstractResourceLoader<T>* _loader;
std::size_t _lastChange;
};
} }
/** /**
@ -342,10 +226,7 @@ cube->draw();
template<class... Types> class ResourceManager: private Implementation::ResourceManagerData<Types>... { template<class... Types> class ResourceManager: private Implementation::ResourceManagerData<Types>... {
public: public:
/** @brief Global instance */ /** @brief Global instance */
inline static ResourceManager<Types...>* instance() { static ResourceManager<Types...>* instance();
CORRADE_ASSERT(internalInstance(), "ResourceManager::instance(): no instance exists", nullptr);
return internalInstance();
}
/** /**
* @brief Constructor * @brief Constructor
@ -355,10 +236,7 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* created. * created.
* @see instance() * @see instance()
*/ */
inline ResourceManager() { explicit ResourceManager();
CORRADE_ASSERT(!internalInstance(), "ResourceManager::ResourceManager(): another instance is already created", );
internalInstance() = this;
}
/** /**
* @brief Destructor * @brief Destructor
@ -366,13 +244,10 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* Sets global instance pointer to `nullptr`. * Sets global instance pointer to `nullptr`.
* @see instance() * @see instance()
*/ */
inline ~ResourceManager() { ~ResourceManager();
CORRADE_INTERNAL_ASSERT(internalInstance() == this);
internalInstance() = nullptr;
}
/** @brief Count of resources of given type */ /** @brief Count of resources of given type */
template<class T> inline std::size_t count() { template<class T> std::size_t count() {
return this->Implementation::ResourceManagerData<T>::count(); return this->Implementation::ResourceManagerData<T>::count();
} }
@ -388,7 +263,7 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* Resource<AbstractShaderProgram, MyShader> shader = manager->get<AbstractShaderProgram, MyShader>("shader"); * Resource<AbstractShaderProgram, MyShader> shader = manager->get<AbstractShaderProgram, MyShader>("shader");
* @endcode * @endcode
*/ */
template<class T, class U = T> inline Resource<T, U> get(ResourceKey key) { template<class T, class U = T> Resource<T, U> get(ResourceKey key) {
return this->Implementation::ResourceManagerData<T>::template get<U>(key); return this->Implementation::ResourceManagerData<T>::template get<U>(key);
} }
@ -397,7 +272,7 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* *
* @see set() * @see set()
*/ */
template<class T> inline std::size_t referenceCount(ResourceKey key) const { template<class T> std::size_t referenceCount(ResourceKey key) const {
return this->Implementation::ResourceManagerData<T>::referenceCount(key); return this->Implementation::ResourceManagerData<T>::referenceCount(key);
} }
@ -406,7 +281,7 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* *
* @see set(), Resource::state() * @see set(), Resource::state()
*/ */
template<class T> inline ResourceState state(ResourceKey key) const { template<class T> ResourceState state(ResourceKey key) const {
return this->Implementation::ResourceManagerData<T>::state(key); return this->Implementation::ResourceManagerData<T>::state(key);
} }
@ -429,7 +304,7 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* subsequent updates are not possible. * subsequent updates are not possible.
* @see referenceCount(), state() * @see referenceCount(), state()
*/ */
template<class T> inline ResourceManager<Types...>* set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { template<class T> ResourceManager<Types...>* set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
this->Implementation::ResourceManagerData<T>::set(key, data, state, policy); this->Implementation::ResourceManagerData<T>::set(key, data, state, policy);
return this; return this;
} }
@ -441,18 +316,18 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* Same as above function with state set to @ref ResourceDataState "ResourceDataState::Final" * Same as above function with state set to @ref ResourceDataState "ResourceDataState::Final"
* and policy to @ref ResourcePolicy "ResourcePolicy::Resident". * and policy to @ref ResourcePolicy "ResourcePolicy::Resident".
*/ */
template<class T> inline ResourceManager<Types...>* set(ResourceKey key, T* data) { template<class T> ResourceManager<Types...>* set(ResourceKey key, T* data) {
this->Implementation::ResourceManagerData<T>::set(key, data, ResourceDataState::Final, ResourcePolicy::Resident); this->Implementation::ResourceManagerData<T>::set(key, data, ResourceDataState::Final, ResourcePolicy::Resident);
return this; return this;
} }
/** @brief Fallback for not found resources */ /** @brief Fallback for not found resources */
template<class T> inline T* fallback() { template<class T> T* fallback() {
return this->Implementation::ResourceManagerData<T>::fallback(); return this->Implementation::ResourceManagerData<T>::fallback();
} }
/** @overload */ /** @overload */
template<class T> inline const T* fallback() const { template<class T> const T* fallback() const {
return this->Implementation::ResourceManagerData<T>::fallback(); return this->Implementation::ResourceManagerData<T>::fallback();
} }
@ -460,7 +335,7 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* @brief Set fallback for not found resources * @brief Set fallback for not found resources
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
template<class T> inline ResourceManager<Types...>* setFallback(T* data) { template<class T> ResourceManager<Types...>* setFallback(T* data) {
this->Implementation::ResourceManagerData<T>::setFallback(data); this->Implementation::ResourceManagerData<T>::setFallback(data);
return this; return this;
} }
@ -469,7 +344,7 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* @brief Free all resources of given type which are not referenced * @brief Free all resources of given type which are not referenced
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
template<class T> inline ResourceManager<Types...>* free() { template<class T> ResourceManager<Types...>* free() {
this->Implementation::ResourceManagerData<T>::free(); this->Implementation::ResourceManagerData<T>::free();
return this; return this;
} }
@ -478,18 +353,18 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* @brief Free all resources which are not referenced * @brief Free all resources which are not referenced
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
*/ */
inline ResourceManager<Types...>* free() { ResourceManager<Types...>* free() {
freeInternal(std::common_type<Types>()...); freeInternal(std::common_type<Types>()...);
return this; return this;
} }
/** @brief Loader for given type of resources */ /** @brief Loader for given type of resources */
template<class T> inline AbstractResourceLoader<T>* loader() { template<class T> AbstractResourceLoader<T>* loader() {
return this->Implementation::ResourceManagerData<T>::loader(); return this->Implementation::ResourceManagerData<T>::loader();
} }
/** @overload */ /** @overload */
template<class T> inline const AbstractResourceLoader<T>* loader() const { template<class T> const AbstractResourceLoader<T>* loader() const {
return this->Implementation::ResourceManagerData<T>::loader(); return this->Implementation::ResourceManagerData<T>::loader();
} }
@ -499,17 +374,17 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* *
* See AbstractResourceLoader documentation for more information. * See AbstractResourceLoader documentation for more information.
*/ */
template<class T> inline ResourceManager<Types...>* setLoader(AbstractResourceLoader<T>* loader) { template<class T> ResourceManager<Types...>* setLoader(AbstractResourceLoader<T>* loader) {
this->Implementation::ResourceManagerData<T>::setLoader(loader); this->Implementation::ResourceManagerData<T>::setLoader(loader);
return this; return this;
} }
private: private:
template<class FirstType, class ...NextTypes> inline void freeInternal(std::common_type<FirstType>, std::common_type<NextTypes>... t) { template<class FirstType, class ...NextTypes> void freeInternal(std::common_type<FirstType>, std::common_type<NextTypes>... t) {
free<FirstType>(); free<FirstType>();
freeInternal(t...); freeInternal(t...);
} }
inline void freeInternal() const {} void freeInternal() const {}
static ResourceManager<Types...>*& internalInstance(); static ResourceManager<Types...>*& internalInstance();
}; };
@ -521,6 +396,162 @@ template<class ...Types> ResourceManager<Types...>*& ResourceManager<Types...>::
} }
#endif #endif
namespace Implementation {
template<class T> ResourceManagerData<T>::~ResourceManagerData() {
delete _fallback;
if(_loader) {
_loader->manager = nullptr;
delete _loader;
}
}
template<class T> std::size_t ResourceManagerData<T>::referenceCount(const ResourceKey key) const {
auto it = _data.find(key);
if(it == _data.end()) return 0;
return it->second.referenceCount;
}
template<class T> ResourceState ResourceManagerData<T>::state(const ResourceKey key) const {
const auto it = _data.find(key);
/* Resource not loaded */
if(it == _data.end() || !it->second.data) {
/* Fallback found, add *Fallback to state */
if(_fallback) {
if(it != _data.end() && it->second.state == ResourceDataState::Loading)
return ResourceState::LoadingFallback;
else if(it != _data.end() && it->second.state == ResourceDataState::NotFound)
return ResourceState::NotFoundFallback;
else return ResourceState::NotLoadedFallback;
}
/* Fallback not found, loading didn't start yet */
if(it == _data.end() || (it->second.state != ResourceDataState::Loading && it->second.state != ResourceDataState::NotFound))
return ResourceState::NotLoaded;
}
/* Loading / NotFound without fallback, Mutable / Final */
return static_cast<ResourceState>(it->second.state);
}
template<class T> template<class U> Resource<T, U> ResourceManagerData<T>::get(ResourceKey key) {
/* Ask loader for the data, if they aren't there yet */
if(_loader && _data.find(key) == _data.end())
_loader->load(key);
return Resource<T, U>(this, key);
}
template<class T> void ResourceManagerData<T>::set(const ResourceKey key, T* const data, const ResourceDataState state, const ResourcePolicy policy) {
auto it = _data.find(key);
/* NotFound / Loading state shouldn't have any data */
CORRADE_ASSERT((data == nullptr) == (state == ResourceDataState::NotFound || state == ResourceDataState::Loading),
"ResourceManager::set(): data should be null if and only if state is NotFound or Loading", );
/* Cannot change resource with already final state */
CORRADE_ASSERT(it == _data.end() || it->second.state != ResourceDataState::Final,
"ResourceManager::set(): cannot change already final resource" << key, );
/* If nothing is referencing reference-counted resource, we're done */
if(policy == ResourcePolicy::ReferenceCounted && (it == _data.end() || it->second.referenceCount == 0)) {
Warning() << "ResourceManager: Reference-counted resource with key" << key << "isn't referenced from anywhere, deleting it immediately";
delete data;
/* Delete also already present resource (it could be here
because previous policy could be other than
ReferenceCounted) */
if(it != _data.end()) _data.erase(it);
return;
/* Insert it, if not already here */
} else if(it == _data.end())
it = _data.insert(std::make_pair(key, Data())).first;
/* Replace previous data */
delete it->second.data;
it->second.data = data;
it->second.state = state;
it->second.policy = policy;
++_lastChange;
}
template<class T> void ResourceManagerData<T>::setFallback(T* const data) {
delete _fallback;
_fallback = data;
}
template<class T> void ResourceManagerData<T>::free() {
/* Delete all non-referenced non-resident resources */
for(auto it = _data.begin(); it != _data.end(); ) {
if(it->second.policy != ResourcePolicy::Resident && !it->second.referenceCount)
it = _data.erase(it);
else ++it;
}
}
template<class T> void ResourceManagerData<T>::setLoader(AbstractResourceLoader<T>* const loader) {
/* Delete previous loader */
delete _loader;
/* Add new loader */
if((_loader = loader)) _loader->manager = this;
}
template<class T> void ResourceManagerData<T>::decrementReferenceCount(ResourceKey key) {
auto it = _data.find(key);
/* Free the resource if it is reference counted */
if(--it->second.referenceCount == 0 && it->second.policy == ResourcePolicy::ReferenceCounted)
_data.erase(it);
}
template<class T> struct ResourceManagerData<T>::Data {
Data(const Data&) = delete;
Data& operator=(const Data&) = delete;
Data& operator=(Data&&) = delete;
Data(): data(nullptr), state(ResourceDataState::Mutable), policy(ResourcePolicy::Manual), referenceCount(0) {}
Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) {
other.data = nullptr;
other.referenceCount = 0;
}
~Data();
T* data;
ResourceDataState state;
ResourcePolicy policy;
std::size_t referenceCount;
};
template<class T> inline ResourceManagerData<T>::Data::~Data() {
CORRADE_ASSERT(referenceCount == 0,
"ResourceManager::~ResourceManager(): destroyed while data are still referenced", );
delete data;
}
}
template<class ...Types> ResourceManager<Types...>* ResourceManager<Types...>::instance() {
CORRADE_ASSERT(internalInstance(), "ResourceManager::instance(): no instance exists", nullptr);
return internalInstance();
}
template<class ...Types> ResourceManager<Types...>::ResourceManager() {
CORRADE_ASSERT(!internalInstance(), "ResourceManager::ResourceManager(): another instance is already created", );
internalInstance() = this;
}
template<class ...Types> ResourceManager<Types...>::~ResourceManager() {
CORRADE_INTERNAL_ASSERT(internalInstance() == this);
internalInstance() = nullptr;
}
} }
/* Make the definition complete */ /* Make the definition complete */

2
src/Shader.h

@ -111,7 +111,7 @@ class MAGNUM_EXPORT Shader {
Shader& operator=(Shader&& other); Shader& operator=(Shader&& other);
/** @brief OpenGL shader ID */ /** @brief OpenGL shader ID */
inline GLuint id() const { return _id; } GLuint id() const { return _id; }
/** /**
* @brief Add shader source * @brief Add shader source

2
src/Swizzle.h

@ -72,7 +72,7 @@ Color3 or Color4 specialization is returned.
@see @ref matrix-vector-component-access, Math::swizzle(), Vector4::xyz(), @see @ref matrix-vector-component-access, Math::swizzle(), Vector4::xyz(),
Color4::rgb(), Vector4::xy(), Vector3::xy() Color4::rgb(), Vector4::xy(), Vector3::xy()
*/ */
template<char ...components, class T> inline constexpr typename Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const T& vector) { template<char ...components, class T> constexpr typename Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const T& vector) {
return {Math::Implementation::Component<T::Size, components>::value(vector)...}; return {Math::Implementation::Component<T::Size, components>::value(vector)...};
} }

4
src/Test/ResourceManagerTest.cpp

@ -50,8 +50,8 @@ class Data {
public: public:
static std::size_t count; static std::size_t count;
inline Data() { ++count; } Data() { ++count; }
inline ~Data() { --count; } ~Data() { --count; }
}; };
typedef Magnum::ResourceManager<Int, Data> ResourceManager; typedef Magnum::ResourceManager<Int, Data> ResourceManager;

30
src/Texture.h

@ -224,10 +224,10 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* Creates one OpenGL texture. * Creates one OpenGL texture.
* @see @fn_gl{GenTextures} * @see @fn_gl{GenTextures}
*/ */
inline explicit Texture(Target target = DataHelper<Dimensions>::target()): AbstractTexture(static_cast<GLenum>(target)) {} explicit Texture(Target target = DataHelper<Dimensions>::target()): AbstractTexture(static_cast<GLenum>(target)) {}
/** @brief %Texture target */ /** @brief %Texture target */
inline constexpr Target target() const { return static_cast<Target>(_target); } constexpr Target target() const { return static_cast<Target>(_target); }
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
/** /**
@ -241,7 +241,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or @def_gl{TEXTURE_DEPTH}. * with @def_gl{TEXTURE_WIDTH}, @def_gl{TEXTURE_HEIGHT} or @def_gl{TEXTURE_DEPTH}.
* @requires_gl %Texture image queries are not available in OpenGL ES. * @requires_gl %Texture image queries are not available in OpenGL ES.
*/ */
inline typename DimensionTraits<Dimensions, Int>::VectorType imageSize(Int level) { typename DimensionTraits<Dimensions, Int>::VectorType imageSize(Int level) {
return DataHelper<Dimensions>::imageSize(this, _target, level); return DataHelper<Dimensions>::imageSize(this, _target, level);
} }
#endif #endif
@ -264,7 +264,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* with @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, * with @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T},
* @def_gl{TEXTURE_WRAP_R} * @def_gl{TEXTURE_WRAP_R}
*/ */
inline Texture<Dimensions>* setWrapping(const Array<Dimensions, Sampler::Wrapping>& wrapping) { Texture<Dimensions>* setWrapping(const Array<Dimensions, Sampler::Wrapping>& wrapping) {
DataHelper<Dimensions>::setWrapping(this, wrapping); DataHelper<Dimensions>::setWrapping(this, wrapping);
return this; return this;
} }
@ -291,7 +291,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @requires_gl42 %Extension @extension{ARB,texture_storage} * @requires_gl42 %Extension @extension{ARB,texture_storage}
* @requires_gles30 %Extension @es_extension{EXT,texture_storage} * @requires_gles30 %Extension @es_extension{EXT,texture_storage}
*/ */
inline Texture<Dimensions>* setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits<Dimensions, Int>::VectorType& size) { Texture<Dimensions>* setStorage(Int levels, TextureFormat internalFormat, const typename DimensionTraits<Dimensions, Int>::VectorType& size) {
DataHelper<Dimensions>::setStorage(this, _target, levels, internalFormat, size); DataHelper<Dimensions>::setStorage(this, _target, levels, internalFormat, size);
return this; return this;
} }
@ -319,7 +319,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* then @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access} * then @fn_gl{GetTexImage}, @fn_gl_extension{GetTextureImage,EXT,direct_state_access}
* or @fn_gl_extension{GetnTexImage,ARB,robustness} * or @fn_gl_extension{GetnTexImage,ARB,robustness}
*/ */
inline void image(Int level, Image<dimensions>* image) { void image(Int level, Image<dimensions>* image) {
AbstractTexture::image<dimensions>(_target, level, image); AbstractTexture::image<dimensions>(_target, level, image);
} }
@ -332,7 +332,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* See image(Int, Image*) for more information. * See image(Int, Image*) for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES. * @requires_gl %Texture image queries are not available in OpenGL ES.
*/ */
inline void image(Int level, BufferImage<dimensions>* image, Buffer::Usage usage) { void image(Int level, BufferImage<dimensions>* image, Buffer::Usage usage) {
AbstractTexture::image<dimensions>(_target, level, image, usage); AbstractTexture::image<dimensions>(_target, level, image, usage);
} }
#endif #endif
@ -359,7 +359,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access} * @fn_gl_extension{TextureImage3D,EXT,direct_state_access}
*/ */
template<class Image> inline Texture<Dimensions>* setImage(Int level, TextureFormat internalFormat, Image* image) { template<class Image> Texture<Dimensions>* setImage(Int level, TextureFormat internalFormat, Image* image) {
DataHelper<Dimensions>::setImage(this, _target, level, internalFormat, image); DataHelper<Dimensions>::setImage(this, _target, level, internalFormat, image);
return this; return this;
} }
@ -389,7 +389,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}
*/ */
template<class Image> inline Texture<Dimensions>* setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, Image* image) { template<class Image> Texture<Dimensions>* setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, Image* image) {
DataHelper<Dimensions>::setSubImage(this, _target, level, offset, image); DataHelper<Dimensions>::setSubImage(this, _target, level, offset, image);
return this; return this;
} }
@ -404,31 +404,31 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* is not available, this function does nothing. * is not available, this function does nothing.
* @see invalidateImage(), @fn_gl{InvalidateTexSubImage} * @see invalidateImage(), @fn_gl{InvalidateTexSubImage}
*/ */
inline void invalidateSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, const typename DimensionTraits<Dimensions, Int>::VectorType& size) { void invalidateSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, const typename DimensionTraits<Dimensions, Int>::VectorType& size) {
DataHelper<dimensions>::invalidateSubImage(this, level, offset, size); DataHelper<dimensions>::invalidateSubImage(this, level, offset, size);
} }
/* Overloads to remove WTF-factor from method chaining order */ /* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
inline Texture<Dimensions>* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) { Texture<Dimensions>* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap); AbstractTexture::setMinificationFilter(filter, mipmap);
return this; return this;
} }
inline Texture<Dimensions>* setMagnificationFilter(Sampler::Filter filter) { Texture<Dimensions>* setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter); AbstractTexture::setMagnificationFilter(filter);
return this; return this;
} }
#ifndef MAGNUM_TARGET_GLES3 #ifndef MAGNUM_TARGET_GLES3
inline Texture<Dimensions>* setBorderColor(const Color4<>& color) { Texture<Dimensions>* setBorderColor(const Color4<>& color) {
AbstractTexture::setBorderColor(color); AbstractTexture::setBorderColor(color);
return this; return this;
} }
inline Texture<Dimensions>* setMaxAnisotropy(Float anisotropy) { Texture<Dimensions>* setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy); AbstractTexture::setMaxAnisotropy(anisotropy);
return this; return this;
} }
#endif #endif
inline Texture<Dimensions>* generateMipmap() { Texture<Dimensions>* generateMipmap() {
AbstractTexture::generateMipmap(); AbstractTexture::generateMipmap();
return this; return this;
} }

8
src/Timeline.h

@ -89,10 +89,10 @@ class MAGNUM_EXPORT Timeline {
* Creates stopped timeline. * Creates stopped timeline.
* @see start() * @see start()
*/ */
inline explicit Timeline(): _minimalFrameTime(0), _previousFrameDuration(0), running(false) {} explicit Timeline(): _minimalFrameTime(0), _previousFrameDuration(0), running(false) {}
/** @brief Minimal frame time (in seconds) */ /** @brief Minimal frame time (in seconds) */
inline Float minimalFrameTime() const { return _minimalFrameTime; } Float minimalFrameTime() const { return _minimalFrameTime; }
/** /**
* @brief Set minimal frame time * @brief Set minimal frame time
@ -101,7 +101,7 @@ class MAGNUM_EXPORT Timeline {
* Default value is 0. * Default value is 0.
* @see nextFrame() * @see nextFrame()
*/ */
inline Timeline* setMinimalFrameTime(Float seconds) { Timeline* setMinimalFrameTime(Float seconds) {
_minimalFrameTime = seconds; _minimalFrameTime = seconds;
return this; return this;
} }
@ -144,7 +144,7 @@ class MAGNUM_EXPORT Timeline {
* *
* If the timeline is stopped, the function returns `0.0f`. * If the timeline is stopped, the function returns `0.0f`.
*/ */
inline Float previousFrameDuration() const { return _previousFrameDuration; } Float previousFrameDuration() const { return _previousFrameDuration; }
private: private:
std::chrono::high_resolution_clock::time_point _startTime; std::chrono::high_resolution_clock::time_point _startTime;

Loading…
Cancel
Save