Browse Source

Reducing pointer chasings, part 1: method chaining via references.

Makes some cases less consistent (and some convenience shortcuts
impossible), but goes well with the attitude "don't use pointer when it
can't be null".
pull/277/head
Vladimír Vondruš 13 years ago
parent
commit
d04b308aa3
  1. 2
      doc/debug-tools.dox
  2. 45
      doc/method-chaining.dox
  3. 4
      doc/scenegraph.dox
  4. 4
      src/AbstractFramebuffer.cpp
  5. 4
      src/AbstractFramebuffer.h
  6. 18
      src/AbstractShaderProgram.h
  7. 12
      src/AbstractTexture.cpp
  8. 26
      src/AbstractTexture.h
  9. 67
      src/Buffer.h
  10. 54
      src/CubeMapTexture.h
  11. 50
      src/CubeMapTextureArray.h
  12. 12
      src/DebugTools/ForceRenderer.cpp
  13. 18
      src/DebugTools/ForceRenderer.h
  14. 8
      src/DebugTools/Implementation/AbstractShapeRenderer.cpp
  15. 4
      src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp
  16. 4
      src/DebugTools/Implementation/BoxRenderer.cpp
  17. 4
      src/DebugTools/Implementation/LineSegmentRenderer.cpp
  18. 4
      src/DebugTools/Implementation/PointRenderer.cpp
  19. 4
      src/DebugTools/Implementation/SphereRenderer.cpp
  20. 8
      src/DebugTools/ObjectRenderer.cpp
  21. 9
      src/DebugTools/ObjectRenderer.h
  22. 22
      src/DebugTools/ShapeRenderer.h
  23. 4
      src/DefaultFramebuffer.cpp
  24. 20
      src/DefaultFramebuffer.h
  25. 8
      src/Framebuffer.cpp
  26. 48
      src/Framebuffer.h
  27. 4
      src/Mesh.cpp
  28. 114
      src/Mesh.h
  29. 2
      src/MeshTools/CompressIndices.cpp
  30. 4
      src/Platform/AbstractXApplication.h
  31. 46
      src/ResourceManager.h
  32. 4
      src/SceneGraph/AbstractCamera.h
  33. 4
      src/SceneGraph/AbstractCamera.hpp
  34. 6
      src/SceneGraph/AbstractTransformation.h
  35. 16
      src/SceneGraph/AbstractTranslationRotation2D.h
  36. 34
      src/SceneGraph/AbstractTranslationRotation3D.h
  37. 18
      src/SceneGraph/AbstractTranslationRotationScaling2D.h
  38. 30
      src/SceneGraph/AbstractTranslationRotationScaling3D.h
  39. 22
      src/SceneGraph/Animable.h
  40. 8
      src/SceneGraph/Animable.hpp
  41. 14
      src/SceneGraph/Camera2D.h
  42. 4
      src/SceneGraph/Camera2D.hpp
  43. 22
      src/SceneGraph/Camera3D.h
  44. 12
      src/SceneGraph/Camera3D.hpp
  45. 12
      src/SceneGraph/Drawable.h
  46. 42
      src/SceneGraph/DualComplexTransformation.h
  47. 42
      src/SceneGraph/DualQuaternionTransformation.h
  48. 18
      src/SceneGraph/FeatureGroup.h
  49. 40
      src/SceneGraph/MatrixTransformation2D.h
  50. 52
      src/SceneGraph/MatrixTransformation3D.h
  51. 8
      src/SceneGraph/Object.h
  52. 14
      src/SceneGraph/Object.hpp
  53. 48
      src/SceneGraph/RigidMatrixTransformation2D.h
  54. 60
      src/SceneGraph/RigidMatrixTransformation3D.h
  55. 7
      src/SceneGraph/Test/AnimableTest.cpp
  56. 12
      src/SceneGraph/Test/DualQuaternionTransformationTest.cpp
  57. 12
      src/SceneGraph/Test/MatrixTransformation3DTest.cpp
  58. 12
      src/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp
  59. 33
      src/Shaders/DistanceFieldVector.h
  60. 12
      src/Shaders/Flat.h
  61. 38
      src/Shaders/MeshVisualizer.h
  62. 60
      src/Shaders/Phong.h
  63. 12
      src/Shaders/Vector.h
  64. 6
      src/Shaders/VertexColor.h
  65. 8
      src/Shapes/Shape.h
  66. 6
      src/Text/DistanceFieldGlyphCache.cpp
  67. 6
      src/Text/GlyphCache.cpp
  68. 6
      src/Text/TextRenderer.cpp
  69. 22
      src/Text/TextRenderer.h
  70. 66
      src/Texture.h
  71. 18
      src/TextureTools/DistanceField.cpp
  72. 8
      src/Timeline.h

2
doc/debug-tools.dox

@ -63,7 +63,7 @@ SceneGraph::DrawableGroup3D debugDrawables;
// Create renderer options which will be referenced later by "my" resource key
DebugTools::ResourceManager::instance()->set("my",
(new DebugTools::ObjectRendererOptions)->setSize(0.3f));
DebugTools::ObjectRendererOptions().setSize(0.3f));
// Create debug renderer for given object, use "my" options for it. The
// renderer is automatically added to the object features and also to

45
doc/method-chaining.dox

@ -42,17 +42,17 @@ bound somewhere. Method chaining encourages you to configure whole object in
one run, effectively reducing the number of needed bindings. Consider the
following example:
@code
Texture2D *carDiffuseTexture, *carSpecularTexture, *carBumpTexture;
Texture2D carDiffuseTexture, carSpecularTexture, carBumpTexture;
carDiffuseTexture->setStorage(5, TextureFormat::SRGB8);
carSpecularTexture->setStorage(3, TextureFormat::R8);
carBumpTexture->setStorage(5, TextureFormat::RGB8);
carDiffuseTexture->setSubImage(0, {}, diffuse);
carSpecularTexture->setSubImage(0, {}, specular;
carBumpTexture->setSubImage(0, {}, bump);
carDiffuseTexture->generateMipmap();
carSpecularTexture->generateMipmap();
carBumpTexture->generateMipmap();
carDiffuseTexture.setStorage(5, TextureFormat::SRGB8);
carSpecularTexture.setStorage(3, TextureFormat::R8);
carBumpTexture.setStorage(5, TextureFormat::RGB8);
carDiffuseTexture.setSubImage(0, {}, diffuse);
carSpecularTexture.setSubImage(0, {}, specular;
carBumpTexture.setSubImage(0, {}, bump);
carDiffuseTexture.generateMipmap();
carSpecularTexture.generateMipmap();
carBumpTexture.generateMipmap();
@endcode
This code is written that similar configuration steps are grouped together,
@ -62,15 +62,15 @@ names and after each configuration step the texture must be rebound to another.
With method chaining used the code looks much lighter and each object is
configured in one run, reducing count of bind calls from 9 to 3.
@code
carDiffuseTexture->setStorage(5, TextureFormat::SRGB8)
->setSubImage(0, {}, diffuse)
->generateMipmap();
carSpecularTexture->setStorage(3, TextureFormat::R8)
->setSubImage(0, {}, diffuse)
->generateMipmap();
carBumpTexture->setStorage(5, TextureFormat::RGB8)
->setSubImage(0, {}, bump)
->generateMipmap();
carDiffuseTexture.setStorage(5, TextureFormat::SRGB8)
.setSubImage(0, {}, diffuse)
.generateMipmap();
carSpecularTexture.setStorage(3, TextureFormat::R8)
.setSubImage(0, {}, diffuse)
.generateMipmap();
carBumpTexture.setStorage(5, TextureFormat::RGB8)
.setSubImage(0, {}, bump)
.generateMipmap();
@endcode
Method chaining is not used on non-configuring functions, such as Framebuffer::clear()
@ -85,12 +85,7 @@ Scene3D scene;
(new MyObject(&scene))
->rotateX(90.0_degf)
->translate({-1.5f, 0.5f, 7.0f});
.translate({-1.5f, 0.5f, 7.0f});
@endcode
In most cases method chaining methods return pointer to the object, because
most of the objects are commonly created on the heap. The only exception are
Shader methods, which return reference, because the class is commonly created
as local variable in shader constructors.
*/
}

4
doc/scenegraph.dox

@ -109,8 +109,8 @@ transformation. For convenience you can use method chaining:
@code
Object3D* next = new Object3D;
next->setParent(another)
->translate(Vector3::yAxis(3.0f))
->rotateY(35.0_degf);
.translate(Vector3::yAxis(3.0f))
.rotateY(35.0_degf);
@endcode
@section scenegraph-features Object features

4
src/AbstractFramebuffer.cpp

@ -108,14 +108,14 @@ void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer&
#endif
}
AbstractFramebuffer* AbstractFramebuffer::setViewport(const Rectanglei& rectangle) {
AbstractFramebuffer& AbstractFramebuffer::setViewport(const Rectanglei& rectangle) {
_viewport = rectangle;
/* Update the viewport if the framebuffer is currently bound */
if(Context::current()->state()->framebuffer->drawBinding == _id)
setViewportInternal();
return this;
return *this;
}
void AbstractFramebuffer::setViewportInternal() {

4
src/AbstractFramebuffer.h

@ -207,14 +207,14 @@ class MAGNUM_EXPORT AbstractFramebuffer {
/**
* @brief Set viewport
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Saves the viewport to be used at later time in bind(). If the
* framebuffer is currently bound, updates the viewport to given
* rectangle.
* @see @fn_gl{Viewport}
*/
AbstractFramebuffer* setViewport(const Rectanglei& rectangle);
AbstractFramebuffer& setViewport(const Rectanglei& rectangle);
/**
* @brief Clear specified buffers in framebuffer

18
src/AbstractShaderProgram.h

@ -101,13 +101,13 @@ MyShader() {
protected setUniform() functions. For usability purposes you can implement
also method chaining. Example:
@code
MyShader* setTransformation(const Matrix4& matrix) {
MyShader& setTransformation(const Matrix4& matrix) {
setUniform(TransformationUniform, matrix);
return this;
return *this;
}
MyShader* setProjection(const Matrix4& matrix) {
MyShader& setProjection(const Matrix4& matrix) {
setUniform(ProjectionUniform, matrix);
return this;
return *this;
}
@endcode
@ -219,12 +219,12 @@ specific framebuffer (if needed) and bind required textures to their
respective layers using AbstractTexture::bind(Int). Then call Mesh::draw().
Example:
@code
shader->setTransformation(transformation)
->setProjection(projection)
->use();
shader.setTransformation(transformation)
.setProjection(projection)
.use();
diffuseTexture->bind(MyShader::DiffuseTextureLayer);
specularTexture->bind(MyShader::SpecularTextureLayer);
diffuseTexture.bind(MyShader::DiffuseTextureLayer);
specularTexture.bind(MyShader::SpecularTextureLayer);
mesh.draw();
@endcode

12
src/AbstractTexture.cpp

@ -145,23 +145,23 @@ void AbstractTexture::bindImplementationDSA(GLint layer) {
}
#endif
AbstractTexture* AbstractTexture::setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap) {
AbstractTexture& AbstractTexture::setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap) {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Sampler::Mipmap::Base, "AbstractTexture: rectangle textures cannot have mipmaps", this);
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Sampler::Mipmap::Base, "AbstractTexture: rectangle textures cannot have mipmaps", *this);
#endif
(this->*parameteriImplementation)(GL_TEXTURE_MIN_FILTER,
static_cast<GLint>(filter)|static_cast<GLint>(mipmap));
return this;
return *this;
}
AbstractTexture* AbstractTexture::generateMipmap() {
AbstractTexture& AbstractTexture::generateMipmap() {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", this);
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", *this);
#endif
(this->*mipmapImplementation)();
return this;
return *this;
}
void AbstractTexture::mipmapImplementationDefault() {

26
src/AbstractTexture.h

@ -141,7 +141,7 @@ class MAGNUM_EXPORT AbstractTexture {
* @param mipmap Mipmap filtering. If set to anything else than
* BaseMipLevel, make sure textures for all mip levels are set or
* call generateMipmap().
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is smaller than the
* texture size. If @extension{EXT,direct_state_access} is not
@ -155,12 +155,12 @@ class MAGNUM_EXPORT AbstractTexture {
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MIN_FILTER}
*/
AbstractTexture* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base);
AbstractTexture& setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base);
/**
* @brief Set magnification filter
* @param filter Filter
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Sets filter used when the object pixel size is larger than largest
* texture size. If @extension{EXT,direct_state_access} is not
@ -170,15 +170,15 @@ class MAGNUM_EXPORT AbstractTexture {
* or @fn_gl_extension{TextureParameter,EXT,direct_state_access}
* with @def_gl{TEXTURE_MAG_FILTER}
*/
AbstractTexture* setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture& setMagnificationFilter(Sampler::Filter filter) {
(this->*parameteriImplementation)(GL_TEXTURE_MAG_FILTER, static_cast<GLint>(filter));
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES3
/**
* @brief Set border color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Border color when wrapping is set to @ref Sampler::Wrapping "Sampler::Wrapping::ClampToBorder".
* If @extension{EXT,direct_state_access} is not available, the texture
@ -189,18 +189,18 @@ class MAGNUM_EXPORT AbstractTexture {
* with @def_gl{TEXTURE_BORDER_COLOR}
* @requires_es_extension %Extension @es_extension{NV,texture_border_clamp}
*/
AbstractTexture* setBorderColor(const Color4& color) {
AbstractTexture& setBorderColor(const Color4& color) {
#ifndef MAGNUM_TARGET_GLES
(this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data());
#else
(this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR_NV, color.data());
#endif
return this;
return *this;
}
/**
* @brief Set max anisotropy
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default value is `1.0f`, which means no anisotropy. Set to value
* greater than `1.0f` for anisotropic filtering. If
@ -213,9 +213,9 @@ class MAGNUM_EXPORT AbstractTexture {
* @requires_extension %Extension @extension{EXT,texture_filter_anisotropic}
* @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic}
*/
AbstractTexture* setMaxAnisotropy(Float anisotropy) {
AbstractTexture& setMaxAnisotropy(Float anisotropy) {
(this->*parameterfImplementation)(GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
return this;
return *this;
}
#endif
@ -234,7 +234,7 @@ class MAGNUM_EXPORT AbstractTexture {
/**
* @brief Generate mipmap
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Can not be used for rectangle textures. If
* @extension{EXT,direct_state_access} is not available, the texture
@ -244,7 +244,7 @@ class MAGNUM_EXPORT AbstractTexture {
* @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access}
* @requires_gl30 %Extension @extension{ARB,framebuffer_object}
*/
AbstractTexture* generateMipmap();
AbstractTexture& generateMipmap();
protected:
/**

67
src/Buffer.h

@ -490,7 +490,7 @@ class MAGNUM_EXPORT Buffer {
/**
* @brief Set target hint
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the buffer
* must be internally bound to some target before any operation. You
@ -503,9 +503,9 @@ class MAGNUM_EXPORT Buffer {
* http://www.opengl.org/wiki/Vertex_Specification#Index_buffers
* ... damned GL state
*/
Buffer* setTargetHint(Target hint) {
Buffer& setTargetHint(Target hint) {
_targetHint = hint;
return this;
return *this;
}
/**
@ -569,7 +569,7 @@ class MAGNUM_EXPORT Buffer {
* @param size Data size
* @param data Pointer to data
* @param usage %Buffer usage
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* buffer is not already bound somewhere, it is bound to hinted target
@ -577,25 +577,25 @@ class MAGNUM_EXPORT Buffer {
* @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferData} or
* @fn_gl_extension{NamedBufferData,EXT,direct_state_access}
*/
Buffer* setData(GLsizeiptr size, const GLvoid* data, Usage usage) {
Buffer& setData(GLsizeiptr size, const GLvoid* data, Usage usage) {
(this->*dataImplementation)(size, data, usage);
return this;
return *this;
}
/**
* @brief Set buffer data
* @param data Fixed-size array with data
* @param usage %Buffer usage
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setData(GLsizeiptr, const GLvoid*, Usage).
*/
#ifdef CORRADE_GCC46_COMPATIBILITY
#define size size_ /* With GCC 4.6 it conflicts with size(). WTF. */
#endif
template<std::size_t size, class T> 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);
return this;
return *this;
}
#ifdef CORRADE_GCC46_COMPATIBILITY
#undef size
@ -605,18 +605,19 @@ class MAGNUM_EXPORT Buffer {
* @brief Set buffer data
* @param data Vector with data
* @param usage %Buffer usage
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setData(GLsizeiptr, const GLvoid*, Usage)
*/
template<class T> 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);
return this;
return *this;
}
/** @overload */
template<std::size_t size, class T> void setData(const std::array<T, size>& data, Usage usage) {
template<std::size_t size, class T> Buffer& setData(const std::array<T, size>& data, Usage usage) {
setData(data.size()*sizeof(T), data.data(), usage);
return *this;
}
/**
@ -624,7 +625,7 @@ class MAGNUM_EXPORT Buffer {
* @param offset Offset in the buffer
* @param size Data size
* @param data Pointer to data
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* buffer is not already bound somewhere, it is bound to hinted target
@ -632,25 +633,25 @@ class MAGNUM_EXPORT Buffer {
* @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferSubData}
* or @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access}
*/
Buffer* setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
Buffer& setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
(this->*subDataImplementation)(offset, size, data);
return this;
return *this;
}
/**
* @brief Set buffer subdata
* @param offset Offset in the buffer
* @param data Fixed-size array with data
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setSubData(GLintptr, GLsizeiptr, const GLvoid*)
*/
#ifdef CORRADE_GCC46_COMPATIBILITY
#define size size_ /* With GCC 4.6 it conflicts with size(). WTF. */
#endif
template<std::size_t size, class T> 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);
return this;
return *this;
}
#ifdef CORRADE_GCC46_COMPATIBILITY
#undef size
@ -660,48 +661,48 @@ class MAGNUM_EXPORT Buffer {
* @brief Set buffer subdata
* @param offset Offset in the buffer
* @param data Vector with data
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setSubData(GLintptr, GLsizeiptr, const GLvoid*)
*/
template<class T> 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());
return this;
return *this;
}
/** @overload */
template<std::size_t size, class T> 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());
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Invalidate buffer data
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If running on OpenGL ES or extension @extension{ARB,invalidate_subdata}
* is not available, this function does nothing.
* @see @ref MapFlag "MapFlag::InvalidateBuffer", @fn_gl{InvalidateBufferData}
*/
Buffer* invalidateData() {
Buffer& invalidateData() {
(this->*invalidateImplementation)();
return this;
return *this;
}
/**
* @brief Invalidate buffer subdata
* @param offset Offset into the buffer
* @param length Length of the invalidated range
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If running on OpenGL ES or extension @extension{ARB,invalidate_subdata}
* is not available, this function does nothing.
* @see @ref MapFlag "MapFlag::InvalidateRange", @fn_gl{InvalidateBufferData}
*/
Buffer* invalidateSubData(GLintptr offset, GLsizeiptr length) {
Buffer& invalidateSubData(GLintptr offset, GLsizeiptr length) {
(this->*invalidateSubImplementation)(offset, length);
return this;
return *this;
}
#endif
@ -772,7 +773,7 @@ class MAGNUM_EXPORT Buffer {
* @brief Flush mapped range
* @param offset Offset relative to start of mapped range
* @param length Length of the flushed memory
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Flushes specified subsection of mapped range. Use only if you called
* map() with @ref MapFlag "MapFlag::FlushExplicit" flag. See
@ -786,9 +787,9 @@ class MAGNUM_EXPORT Buffer {
* @requires_gl30 %Extension @extension{ARB,map_buffer_range}
* @requires_gles30 %Extension @es_extension{EXT,map_buffer_range}
*/
Buffer* flushMappedRange(GLintptr offset, GLsizeiptr length) {
Buffer& flushMappedRange(GLintptr offset, GLsizeiptr length) {
(this->*flushMappedRangeImplementation)(offset, length);
return this;
return *this;
}
/**

54
src/CubeMapTexture.h

@ -60,9 +60,9 @@ Image2D positiveX({256, 256}, ImageFormat::RGBA, ImageType::UnsignedByte, dataPo
CubeMapTexture texture;
texture.setMagnificationFilter(Sampler::Filter::Linear)
// ...
->setStorage(Math::log2(256)+1, TextureFormat::RGBA8, {256, 256})
->setSubImage(CubeMapTexture::Coordinate::PositiveX, 0, {}, &positiveX)
->setSubImage(CubeMapTexture::Coordinate::NegativeX, 0, {}, &negativeX)
.setStorage(Math::log2(256)+1, TextureFormat::RGBA8, {256, 256})
.setSubImage(CubeMapTexture::Coordinate::PositiveX, 0, {}, &positiveX)
.setSubImage(CubeMapTexture::Coordinate::NegativeX, 0, {}, &negativeX)
// ...
@endcode
@ -101,9 +101,9 @@ class CubeMapTexture: public AbstractTexture {
*
* See Texture::setWrapping() for more information.
*/
CubeMapTexture* setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
CubeMapTexture& setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(this, wrapping);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES
@ -125,9 +125,9 @@ class CubeMapTexture: public AbstractTexture {
*
* See Texture::setStorage() for more information.
*/
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);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES
@ -166,20 +166,20 @@ class CubeMapTexture: public AbstractTexture {
* @param level Mip level
* @param internalFormat Internal format
* @param image %Image
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* See Texture::setImage() for more information.
*/
CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, const ImageReference2D& image) {
CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, const ImageReference2D& image) {
DataHelper<2>::setImage(this, static_cast<GLenum>(coordinate), level, internalFormat, image);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D& image) {
CubeMapTexture& setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, BufferImage2D& image) {
DataHelper<2>::setImage(this, static_cast<GLenum>(coordinate), level, internalFormat, image);
return this;
return *this;
}
#endif
@ -189,20 +189,20 @@ class CubeMapTexture: public AbstractTexture {
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image %Image
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* See Texture::setSubImage() for more information.
*/
CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image) {
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const ImageReference2D& image) {
DataHelper<2>::setSubImage(this, static_cast<GLenum>(coordinate), level, offset, image);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image) {
CubeMapTexture& setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, BufferImage2D& image) {
DataHelper<2>::setSubImage(this, static_cast<GLenum>(coordinate), level, offset, image);
return this;
return *this;
}
#endif
@ -224,27 +224,27 @@ class CubeMapTexture: public AbstractTexture {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
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);
return this;
return *this;
}
CubeMapTexture* setMagnificationFilter(Sampler::Filter filter) {
CubeMapTexture& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES3
CubeMapTexture* setBorderColor(const Color4& color) {
CubeMapTexture& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return this;
return *this;
}
CubeMapTexture* setMaxAnisotropy(Float anisotropy) {
CubeMapTexture& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return this;
return *this;
}
#endif
CubeMapTexture* generateMipmap() {
CubeMapTexture& generateMipmap() {
AbstractTexture::generateMipmap();
return this;
return *this;
}
#endif
};

50
src/CubeMapTextureArray.h

@ -53,7 +53,7 @@ Image3D dummy({64, 64, 16*6}, ImageFormat::RGBA, ImageType::UnsignedByte, nullpt
CubeMapTextureArray texture;
texture.setMagnificationFilter(Sampler::Filter::Linear)
// ...
->setStorage(Math::log2(64)+1, TextureFormat::RGBA8, {64, 64, 16});
.setStorage(Math::log2(64)+1, TextureFormat::RGBA8, {64, 64, 16});
for(std::size_t i = 0; i != 16; ++i) {
void* dataPositiveX = ...;
@ -105,9 +105,9 @@ class CubeMapTextureArray: public AbstractTexture {
*
* See Texture::setWrapping() for more information.
*/
CubeMapTextureArray* setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
CubeMapTextureArray& setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(this, wrapping);
return this;
return *this;
}
/**
@ -126,9 +126,9 @@ class CubeMapTextureArray: public AbstractTexture {
*
* See Texture::setStorage() for more information.
*/
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);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES
@ -167,7 +167,7 @@ class CubeMapTextureArray: public AbstractTexture {
* @param internalFormat Internal format
* @param image Image, ImageReference, BufferImage or
* Trade::ImageData of the same dimension count
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Sets texture image data from three-dimensional image for all cube
* faces for all layers. Each group of 6 2D images is one cube map
@ -175,15 +175,15 @@ class CubeMapTextureArray: public AbstractTexture {
*
* See Texture::setImage() for more information.
*/
CubeMapTextureArray* setImage(Int level, TextureFormat internalFormat, const ImageReference3D& image) {
CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, const ImageReference3D& image) {
DataHelper<3>::setImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image);
return this;
return *this;
}
/** @overload */
CubeMapTextureArray* setImage(Int level, TextureFormat internalFormat, BufferImage3D& image) {
CubeMapTextureArray& setImage(Int level, TextureFormat internalFormat, BufferImage3D& image) {
DataHelper<3>::setImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image);
return this;
return *this;
}
/**
@ -192,7 +192,7 @@ class CubeMapTextureArray: public AbstractTexture {
* @param offset Offset where to put data in the texture
* @param image Image3D, ImageReference3D, BufferImage3D or
* Trade::ImageData3D
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Sets texture image subdata for more than one level/face at once.
*
@ -205,15 +205,15 @@ class CubeMapTextureArray: public AbstractTexture {
*
* @see setSubImage(Int, Coordinate, Int, const Math::Vector<2, Int>&, const Image*)
*/
CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image) {
CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, const ImageReference3D& image) {
DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image);
return this;
return *this;
}
/** @overload */
CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, BufferImage3D& image) {
CubeMapTextureArray& setSubImage(Int level, const Vector3i& offset, BufferImage3D& image) {
DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image);
return this;
return *this;
}
/**
@ -234,27 +234,27 @@ class CubeMapTextureArray: public AbstractTexture {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
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);
return this;
return *this;
}
CubeMapTextureArray* setMagnificationFilter(Sampler::Filter filter) {
CubeMapTextureArray& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES3
CubeMapTextureArray* setBorderColor(const Color4& color) {
CubeMapTextureArray& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return this;
return *this;
}
CubeMapTextureArray* setMaxAnisotropy(Float anisotropy) {
CubeMapTextureArray& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return this;
return *this;
}
#endif
CubeMapTextureArray* generateMipmap() {
CubeMapTextureArray& generateMipmap() {
AbstractTexture::generateMipmap();
return this;
return *this;
}
#endif
};

12
src/DebugTools/ForceRenderer.cpp

@ -87,17 +87,17 @@ template<UnsignedInt dimensions> ForceRenderer<dimensions>::ForceRenderer(SceneG
Mesh* mesh = new Mesh;
mesh->setPrimitive(Mesh::Primitive::Lines)
->setIndexCount(indices.size())
->addVertexBuffer(vertexBuffer, 0,
.setIndexCount(indices.size())
.addVertexBuffer(vertexBuffer, 0,
typename Shaders::Flat<dimensions>::Position(Shaders::Flat<dimensions>::Position::Components::Two))
->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 0, positions.size());
ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
.setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 0, positions.size());
ResourceManager::instance()->set(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
}
template<UnsignedInt dimensions> void ForceRenderer<dimensions>::draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>* camera) {
shader->setTransformationProjectionMatrix(camera->projectionMatrix()*Implementation::forceRendererTransformation<dimensions>(transformationMatrix.transformPoint(forcePosition), *force)*DimensionTraits<dimensions, Float>::MatrixType::scaling(typename DimensionTraits<dimensions, Float>::VectorType(options->scale())))
->setColor(options->color())
->use();
.setColor(options->color())
.use();
mesh->draw();
}

18
src/DebugTools/ForceRenderer.h

@ -51,13 +51,13 @@ class ForceRendererOptions {
/**
* @brief Set color of rendered arrow
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is 100% opaque white.
*/
ForceRendererOptions* setColor(const Color4& color) {
ForceRendererOptions& setColor(const Color4& color) {
_color = color;
return this;
return *this;
}
/** @brief Scale of rendered arrow */
@ -65,13 +65,13 @@ class ForceRendererOptions {
/**
* @brief Set scale of rendered arrow
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is `1.0f`.
*/
ForceRendererOptions* setSize(Float size) {
ForceRendererOptions& setSize(Float size) {
_size = size;
return this;
return *this;
}
private:
@ -89,9 +89,9 @@ See @ref debug-tools-renderers for more information.
Example code:
@code
// Create some options
DebugTools::ResourceManager::instance()->set("my", (new DebugTools::ForceRendererOptions)
->setScale(5.0f)->setColor(Color3::fromHSV(120.0_degf, 1.0f, 0.7f)));
DebugTools::ResourceManager::instance()->set("my", DebugTools::ForceRendererOptions()
.setScale(5.0f)
.setColor(Color3::fromHSV(120.0_degf, 1.0f, 0.7f));
// Create debug renderer for given object, use "my" options for it
Object3D* object;

8
src/DebugTools/Implementation/AbstractShapeRenderer.cpp

@ -52,8 +52,8 @@ template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource,
/* Mesh configuration */
Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive())
->setVertexCount(data.positions(0).size())
->addVertexBuffer(buffer, 0, Shaders::Flat2D::Position());
.setVertexCount(data.positions(0).size())
.addVertexBuffer(buffer, 0, Shaders::Flat2D::Position());
ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
/* Index buffer, if needed, if not, resource key doesn't have to be set */
@ -74,8 +74,8 @@ template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource,
/* Mesh configuration */
Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive())
->setVertexCount(data.positions(0).size())
->addVertexBuffer(vertexBuffer, 0, Shaders::Flat3D::Position());
.setVertexCount(data.positions(0).size())
.addVertexBuffer(vertexBuffer, 0, Shaders::Flat3D::Position());
ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
/* Index buffer, if needed, if not, resource key doesn't have to be set */

4
src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp

@ -37,8 +37,8 @@ template<UnsignedInt dimensions> void AxisAlignedBoxRenderer<dimensions>::draw(R
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*
DimensionTraits<dimensions, Float>::MatrixType::translation((axisAlignedBox.min()+axisAlignedBox.max())/2)*
DimensionTraits<dimensions, Float>::MatrixType::scaling(axisAlignedBox.max()-axisAlignedBox.min()))
->setColor(options->color())
->use();
.setColor(options->color())
.use();
this->wireframeMesh->draw();
}

4
src/DebugTools/Implementation/BoxRenderer.cpp

@ -35,8 +35,8 @@ template<UnsignedInt dimensions> BoxRenderer<dimensions>::BoxRenderer(const Shap
template<UnsignedInt dimensions> void BoxRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) {
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*box.transformation())
->setColor(options->color())
->use();
.setColor(options->color())
.use();
this->wireframeMesh->draw();
}

4
src/DebugTools/Implementation/LineSegmentRenderer.cpp

@ -57,8 +57,8 @@ template<UnsignedInt dimensions> LineSegmentRenderer<dimensions>::LineSegmentRen
template<UnsignedInt dimensions> void LineSegmentRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions, Float>::MatrixType& projectionMatrix) {
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*
Implementation::lineSegmentRendererTransformation<dimensions>(line.a(), line.b()))
->setColor(options->color())
->use();
.setColor(options->color())
.use();
this->wireframeMesh->draw();
}

4
src/DebugTools/Implementation/PointRenderer.cpp

@ -57,8 +57,8 @@ template<UnsignedInt dimensions> void PointRenderer<dimensions>::draw(Resource<S
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*
DimensionTraits<dimensions, Float>::MatrixType::translation(point.position())*
DimensionTraits<dimensions, Float>::MatrixType::scaling(typename DimensionTraits<dimensions, Float>::VectorType(options->pointSize()/2)))
->setColor(options->color())
->use();
.setColor(options->color())
.use();
this->wireframeMesh->draw();
}

4
src/DebugTools/Implementation/SphereRenderer.cpp

@ -49,8 +49,8 @@ template<UnsignedInt dimensions> void SphereRenderer<dimensions>::draw(Resource<
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*
DimensionTraits<dimensions, Float>::MatrixType::translation(sphere.position())*
DimensionTraits<dimensions, Float>::MatrixType::scaling(typename DimensionTraits<dimensions, Float>::VectorType(sphere.radius())))
->setColor(options->color())
->use();
.setColor(options->color())
.use();
this->wireframeMesh->draw();
}

8
src/DebugTools/ObjectRenderer.cpp

@ -165,17 +165,17 @@ template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(Scen
ResourceManager::instance()->set(this->indexBuffer.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
mesh->setPrimitive(Mesh::Primitive::Lines)
->setIndexCount(Renderer<dimensions>::indices.size())
->addInterleavedVertexBuffer(vertexBuffer, 0,
.setIndexCount(Renderer<dimensions>::indices.size())
.addInterleavedVertexBuffer(vertexBuffer, 0,
typename Shaders::VertexColor<dimensions>::Position(),
typename Shaders::VertexColor<dimensions>::Color())
->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 0, Renderer<dimensions>::positions.size());
.setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 0, Renderer<dimensions>::positions.size());
ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
}
template<UnsignedInt dimensions> void ObjectRenderer<dimensions>::draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>* camera) {
shader->setTransformationProjectionMatrix(camera->projectionMatrix()*transformationMatrix*DimensionTraits<dimensions, Float>::MatrixType::scaling(typename DimensionTraits<dimensions, Float>::VectorType(options->size())))
->use();
.use();
mesh->draw();
}

9
src/DebugTools/ObjectRenderer.h

@ -50,13 +50,13 @@ class ObjectRendererOptions {
/**
* @brief Set size of the rendered axes
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is `1.0f`.
*/
ObjectRendererOptions* setSize(Float size) {
ObjectRendererOptions& setSize(Float size) {
_size = size;
return this;
return *this;
}
private:
@ -74,8 +74,7 @@ Visualizes object position, rotation and scale using colored axes. See
Example code:
@code
// Create some options
DebugTools::ResourceManager::instance()->set("my", (new DebugTools::ObjectRendererOptions)
->setSize(0.3f));
DebugTools::ResourceManager::instance()->set("my", DebugTools::ObjectRendererOptions().setSize(0.3f));
// Create debug renderer for given object, use "my" options for it
Object3D* object;

22
src/DebugTools/ShapeRenderer.h

@ -73,13 +73,13 @@ class ShapeRendererOptions {
/**
* @brief Set shape rendering mode
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is @ref RenderMode "RenderMode::Wireframe".
*/
ShapeRendererOptions* setRenderMode(RenderMode mode) {
ShapeRendererOptions& setRenderMode(RenderMode mode) {
_renderMode = mode;
return this;
return *this;
}
/** @brief Color of rendered shape */
@ -87,13 +87,13 @@ class ShapeRendererOptions {
/**
* @brief Set color of rendered shape
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is 100% opaque white.
*/
ShapeRendererOptions* setColor(const Color4& color) {
ShapeRendererOptions& setColor(const Color4& color) {
_color = color;
return this;
return *this;
}
/** @brief Point size */
@ -101,14 +101,14 @@ class ShapeRendererOptions {
/**
* @brief Set point size
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Size of rendered crosshairs, representing Shapes::Point shapes.
* Default is `0.25f`.
*/
ShapeRendererOptions* setPointSize(Float size) {
ShapeRendererOptions& setPointSize(Float size) {
_pointSize = size;
return this;
return *this;
}
private:
@ -128,8 +128,8 @@ Visualizes collision shapes using wireframe primitives. See
Example code:
@code
// Create some options
DebugTools::ResourceManager::instance()->set("red", (new DebugTools::ShapeRendererOptions)
->setColor({1.0f, 0.0f, 0.0f}));
DebugTools::ResourceManager::instance()->set("red",
DebugTools::ShapeRendererOptions().setColor({1.0f, 0.0f, 0.0f}));
// Create debug renderer for given shape, use "red" options for it
Shapes::AbstractShape2D* shape;

4
src/DefaultFramebuffer.cpp

@ -37,7 +37,7 @@ DefaultFramebuffer defaultFramebuffer;
DefaultFramebuffer::DefaultFramebuffer() { _id = 0; }
#ifndef MAGNUM_TARGET_GLES2
DefaultFramebuffer* DefaultFramebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
DefaultFramebuffer& DefaultFramebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;
for(const auto& attachment: attachments)
@ -52,7 +52,7 @@ DefaultFramebuffer* DefaultFramebuffer::mapForDraw(std::initializer_list<std::pa
(this->*drawBuffersImplementation)(max+1, _attachments);
delete[] _attachments;
return this;
return *this;
}
#endif

20
src/DefaultFramebuffer.h

@ -309,7 +309,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Map shader outputs to buffer attachment
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @p attachments is list of shader outputs mapped to buffer
* attachments. %Shader outputs which are not listed are not used, you
@ -328,12 +328,12 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
DefaultFramebuffer* mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
DefaultFramebuffer& mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
/**
* @brief Map shader output to buffer attachment
* @param attachment %Buffer attachment
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
@ -347,16 +347,16 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
DefaultFramebuffer* mapForDraw(DrawAttachment attachment) {
DefaultFramebuffer& mapForDraw(DrawAttachment attachment) {
(this->*drawBufferImplementation)(static_cast<GLenum>(attachment));
return this;
return *this;
}
#endif
/**
* @brief Map given attachment for reading
* @param attachment %Buffer attachment
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebuffer is not currently bound, it is bound before the
@ -365,9 +365,9 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/
DefaultFramebuffer* mapForRead(ReadAttachment attachment) {
DefaultFramebuffer& mapForRead(ReadAttachment attachment) {
(this->*readBufferImplementation)(static_cast<GLenum>(attachment));
return this;
return *this;
}
/**
@ -403,9 +403,9 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
DefaultFramebuffer* setViewport(const Rectanglei& rectangle) {
DefaultFramebuffer& setViewport(const Rectanglei& rectangle) {
AbstractFramebuffer::setViewport(rectangle);
return this;
return *this;
}
#endif

8
src/Framebuffer.cpp

@ -67,7 +67,7 @@ Framebuffer::~Framebuffer() {
glDeleteFramebuffers(1, &_id);
}
Framebuffer* Framebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
Framebuffer& Framebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;
for(const auto& attachment: attachments)
@ -82,7 +82,7 @@ Framebuffer* Framebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt
(this->*drawBuffersImplementation)(max+1, _attachments);
delete[] _attachments;
return this;
return *this;
}
void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments) {
@ -107,10 +107,10 @@ void Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attac
delete[] _attachments;
}
Framebuffer* Framebuffer::attachTexture2D(BufferAttachment attachment, Texture2D* texture, Int mipLevel) {
Framebuffer& Framebuffer::attachTexture2D(BufferAttachment attachment, Texture2D* texture, Int mipLevel) {
/** @todo Check for texture target compatibility */
(this->*texture2DImplementation)(attachment, GLenum(texture->target()), texture->id(), mipLevel);
return this;
return *this;
}
void Framebuffer::initializeContextBasedFunctionality(Context* context) {

48
src/Framebuffer.h

@ -304,7 +304,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
/**
* @brief Map shader output to attachments
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @p attachments is list of shader outputs mapped to framebuffer
* color attachment IDs. %Shader outputs which are not listed are not
@ -322,12 +322,12 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
*/
Framebuffer* mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
Framebuffer& mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
/**
* @brief Map shader output to attachment
* @param attachment Draw attachment
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
@ -340,9 +340,9 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl{DrawBuffers} in OpenGL ES 3.0
* @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
*/
Framebuffer* mapForDraw(DrawAttachment attachment) {
Framebuffer& mapForDraw(DrawAttachment attachment) {
(this->*drawBufferImplementation)(GLenum(attachment));
return this;
return *this;
}
/**
@ -379,7 +379,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
/**
* @brief Map given color attachment for reading
* @param attachment Color attachment
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
@ -388,16 +388,16 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/
Framebuffer* mapForRead(ColorAttachment attachment) {
Framebuffer& mapForRead(ColorAttachment attachment) {
(this->*readBufferImplementation)(GLenum(attachment));
return this;
return *this;
}
/**
* @brief Attach renderbuffer to given buffer
* @param attachment %Buffer attachment
* @param renderbuffer %Renderbuffer
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
@ -405,9 +405,9 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} or
* @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access}
*/
Framebuffer* attachRenderbuffer(BufferAttachment attachment, Renderbuffer* renderbuffer) {
Framebuffer& attachRenderbuffer(BufferAttachment attachment, Renderbuffer* renderbuffer) {
(this->*renderbufferImplementation)(attachment, renderbuffer);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES
@ -416,7 +416,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param attachment %Buffer attachment
* @param texture 1D texture
* @param level Mip level
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
@ -425,9 +425,9 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}
* @requires_gl Only 2D and 3D textures are available in OpenGL ES.
*/
Framebuffer* attachTexture1D(BufferAttachment attachment, Texture1D* texture, Int level) {
Framebuffer& attachTexture1D(BufferAttachment attachment, Texture1D* texture, Int level) {
(this->*texture1DImplementation)(attachment, texture, level);
return this;
return *this;
}
#endif
@ -436,7 +436,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param attachment %Buffer attachment
* @param texture 2D texture
* @param level Mip level
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
@ -444,7 +444,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see attachCubeMapTexture(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
*/
Framebuffer* attachTexture2D(BufferAttachment attachment, Texture2D* texture, Int level);
Framebuffer& attachTexture2D(BufferAttachment attachment, Texture2D* texture, Int level);
/**
* @brief Attach cube map texture to given buffer
@ -452,7 +452,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param texture Cube map texture
* @param coordinate Cube map coordinate
* @param level Mip level
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
@ -460,9 +460,9 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see attachTexture2D(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
*/
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);
return this;
return *this;
}
/**
@ -471,7 +471,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @param texture 3D texture
* @param level Mip level
* @param layer Layer of 2D image within a 3D texture
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
@ -480,17 +480,17 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{NamedFramebufferTexture3D,EXT,direct_state_access}
* @requires_es_extension %Extension @es_extension{OES,texture_3D}
*/
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 */
(this->*texture3DImplementation)(attachment, texture, level, layer);
return this;
return *this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
Framebuffer* setViewport(const Rectanglei& rectangle) {
Framebuffer& setViewport(const Rectanglei& rectangle) {
AbstractFramebuffer::setViewport(rectangle);
return this;
return *this;
}
#endif

4
src/Mesh.cpp

@ -117,7 +117,7 @@ Mesh& Mesh::operator=(Mesh&& other) {
return *this;
}
Mesh* Mesh::setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end) {
Mesh& Mesh::setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end) {
#ifdef CORRADE_TARGET_NACL
CORRADE_ASSERT(buffer->targetHint() == Buffer::Target::ElementArray,
"Mesh::setIndexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::ElementArray << "but got" << buffer->targetHint(), this);
@ -133,7 +133,7 @@ Mesh* Mesh::setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type, Unsi
static_cast<void>(end);
#endif
(this->*bindIndexBufferImplementation)(buffer);
return this;
return *this;
}
void Mesh::draw() {

114
src/Mesh.h

@ -77,19 +77,19 @@ class MyShader: public AbstractShaderProgram {
// ...
};
Mesh* mesh;
Buffer* vertexBuffer;
Mesh mesh;
Buffer vertexBuffer;
// Fill vertex buffer with position data
static constexpr Vector3 positions[30] = {
// ...
};
vertexBuffer->setData(positions, Buffer::Usage::StaticDraw);
vertexBuffer.setData(positions, Buffer::Usage::StaticDraw);
// Set primitive and vertex count, add the buffer and specify its layout
mesh->setPrimitive(Mesh::Primitive::Triangles)
->setVertexCount(30)
->addVertexBuffer(vertexBuffer, 0, MyShader::Position());
mesh.setPrimitive(Mesh::Primitive::Triangles)
.setVertexCount(30)
.addVertexBuffer(vertexBuffer, 0, MyShader::Position());
@endcode
@subsubsection Mesh-configuration-examples-nonindexed-phong Interleaved vertex data
@ -97,8 +97,8 @@ mesh->setPrimitive(Mesh::Primitive::Triangles)
@code
// Non-indexed primitive with positions and normals
Trade::MeshData3D plane = Primitives::Plane::solid();
Mesh* mesh;
Buffer* vertexBuffer;
Mesh mesh;
Buffer vertexBuffer;
// Fill vertex buffer with interleaved position and normal data
MeshTools::interleave(mesh, buffer, Buffer::Usage::StaticDraw,
@ -106,8 +106,8 @@ MeshTools::interleave(mesh, buffer, Buffer::Usage::StaticDraw,
// Set primitive and specify layout of interleaved vertex buffer, vertex count
// has been already set by MeshTools::interleave()
mesh->setPrimitive(plane.primitive())
->addInterleavedVertexBuffer(buffer, 0,
mesh.setPrimitive(plane.primitive())
.addInterleavedVertexBuffer(buffer, 0,
Shaders::PhongShader::Position(),
Shaders::PhongShader::Normal());
@endcode
@ -122,33 +122,33 @@ class MyShader: public AbstractShaderProgram {
// ...
};
Buffer *vertexBuffer, *indexBuffer;
Mesh* mesh;
Buffer vertexBuffer, indexBuffer;
Mesh mesh;
// Fill vertex buffer with position data
static constexpr Vector3 positions[300] = {
// ...
};
vertexBuffer->setData(positions, Buffer::Usage::StaticDraw);
vertexBuffer.setData(positions, Buffer::Usage::StaticDraw);
// Fill index buffer with index data
static constexpr GLubyte indices[75] = {
// ...
};
indexBuffer->setData(indices, Buffer::Usage::StaticDraw);
indexBuffer.setData(indices, Buffer::Usage::StaticDraw);
// Set primitive, index count, specify the buffers
mesh->setPrimitive(Mesh::Primitive::Triangles)
->setIndexCount(75)
->addVertexBuffer(vertexBuffer, 0, MyShader::Position())
->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 176, 229);
mesh.setPrimitive(Mesh::Primitive::Triangles)
.setIndexCount(75)
.addVertexBuffer(vertexBuffer, 0, MyShader::Position())
.setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 176, 229);
@endcode
@code
// Indexed primitive
Trade::MeshData3D cube = Primitives::Cube::solid();
Buffer *vertexBuffer, *indexBuffer;
Mesh* mesh;
Buffer vertexBuffer, indexBuffer;
Mesh mesh;
// Fill vertex buffer with interleaved position and normal data
MeshTools::interleave(mesh, vertexBuffer, Buffer::Usage::StaticDraw,
@ -160,8 +160,8 @@ MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw,
// Set primitive and specify layout of interleaved vertex buffer. Index count
// and index buffer has been already specified by MeshTools::compressIndices().
mesh->setPrimitive(plane.primitive())
->addInterleavedVertexBuffer(vertexBuffer, 0,
mesh.setPrimitive(plane.primitive())
.addInterleavedVertexBuffer(vertexBuffer, 0,
Shaders::PhongShader::Position(),
Shaders::PhongShader::Normal());
@endcode
@ -366,15 +366,15 @@ class MAGNUM_EXPORT Mesh {
/**
* @brief Set primitive type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is @ref Primitive "Primitive::Triangles".
* @see setVertexCount(), addVertexBuffer(),
* addInterleavedVertexBuffer(), addVertexBufferStride()
*/
Mesh* setPrimitive(Primitive primitive) {
Mesh& setPrimitive(Primitive primitive) {
_primitive = primitive;
return this;
return *this;
}
/** @brief Vertex count */
@ -382,15 +382,15 @@ class MAGNUM_EXPORT Mesh {
/**
* @brief Set vertex count
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is zero.
* @see setPrimitive(), addVertexBuffer(), addInterleavedVertexBuffer(),
* addVertexBufferStride(), MeshTools::interleave()
*/
Mesh* setVertexCount(Int vertexCount) {
Mesh& setVertexCount(Int vertexCount) {
_vertexCount = vertexCount;
return this;
return *this;
}
/** @brief Index count */
@ -398,19 +398,19 @@ class MAGNUM_EXPORT Mesh {
/**
* @brief Set index count
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is zero.
* @see setIndexBuffer(), MeshTools::compressIndices()
*/
Mesh* setIndexCount(Int count) {
Mesh& setIndexCount(Int count) {
_indexCount = count;
return this;
return *this;
}
/**
* @brief Add buffer with non-interleaved vertex attributes for use with given shader
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Attribute list is combination of
* @ref AbstractShaderProgram::Attribute "attribute definitions"
@ -425,20 +425,20 @@ class MAGNUM_EXPORT Mesh {
* but it accepts only position and normal, so you have to skip the
* texture coordinate array:
* @code
* Mesh* mesh;
* Buffer* buffer;
* mesh->addVertexBuffer(buffer,
* Mesh mesh;
* Buffer buffer;
* mesh.addVertexBuffer(buffer,
* 35, // offset of the data
* Shaders::PhongShader::Position(), // position array
* sizeof(Vector2)*mesh->vertexCount(), // skip texture coordinate array
* sizeof(Vector2)*mesh.vertexCount(), // skip texture coordinate array
* Shaders::PhongShader::Normal()); // normal array
* @endcode
*
* Vou can also achieve the same effect by calling this function more
* times with absolute offsets:
* @code
* mesh->addVertexBuffer(buffer, 35, Shaders::PhongShader::Position());
* ->addVertexBuffer(buffer, 35 + (sizeof(Shaders::PhongShader::Position::Type) + sizeof(Vector2))*
* mesh.addVertexBuffer(buffer, 35, Shaders::PhongShader::Position());
* .addVertexBuffer(buffer, 35 + (sizeof(Shaders::PhongShader::Position::Type) + sizeof(Vector2))*
* mesh->vertexCount(), Shaders::PhongShader::Normal());
* @endcode
*
@ -457,11 +457,11 @@ class MAGNUM_EXPORT Mesh {
* @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access}
* if @extension{APPLE,vertex_array_object} is available
*/
template<class ...T> Mesh* addVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes);
template<class ...T> Mesh& addVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes);
/**
* @brief Add buffer with interleaved vertex attributes for use with given shader
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Parameter @p offset is offset of the interleaved array from the
* beginning, attribute list is combination of
@ -478,9 +478,9 @@ class MAGNUM_EXPORT Mesh {
* position and normal, so you have to skip weight and texture
* coordinate in each vertex:
* @code
* Mesh* mesh;
* Buffer* buffer;
* mesh->addInterleavedVertexBuffer(buffer,
* Mesh mesh;
* Buffer buffer;
* mesh.addInterleavedVertexBuffer(buffer,
* 35, // skip other data
* sizeof(Float), // skip vertex weight
* Shaders::PhongShader::Position(), // vertex position
@ -498,9 +498,9 @@ class MAGNUM_EXPORT Mesh {
* sizeof(Vector2) +
* sizeof(Shaders::PhongShader::Normal::Type);
*
* mesh->addVertexBufferStride(buffer, 35 + sizeof(Float),
* mesh.addVertexBufferStride(buffer, 35 + sizeof(Float),
* stride, Shaders::PhongShader::Position());
* ->addVertexBufferStride(buffer, 35 + sizeof(Float) +
* .addVertexBufferStride(buffer, 35 + sizeof(Float) +
* sizeof(Shaders::PhongShader::Position::Type) + sizeof(Vector2),
* stride, Shaders::PhongShader::Normal());
* @endcode
@ -517,20 +517,20 @@ class MAGNUM_EXPORT Mesh {
* @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access}
* if @extension{APPLE,vertex_array_object} is available
*/
template<class ...T> inline Mesh* addInterleavedVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes) {
template<class ...T> inline Mesh& addInterleavedVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes) {
addInterleavedVertexBufferInternal(buffer, offset, strideOfInterleaved(attributes...), attributes...);
return this;
return *this;
}
/**
* @brief Add buffer with interleaved vertex attributes for use with given shader
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* See addInterleavedVertexBuffer() for more information.
*/
template<UnsignedInt location, class T> inline Mesh* addVertexBufferStride(Buffer* buffer, GLintptr offset, GLsizei stride, const AbstractShaderProgram::Attribute<location, T>& attribute) {
template<UnsignedInt location, class T> inline Mesh& addVertexBufferStride(Buffer* buffer, GLintptr offset, GLsizei stride, const AbstractShaderProgram::Attribute<location, T>& attribute) {
addInterleavedVertexBufferInternal(buffer, offset, stride, attribute);
return this;
return *this;
}
/**
@ -540,7 +540,7 @@ class MAGNUM_EXPORT Mesh {
* @param type Index data type
* @param start Minimum array index contained in the buffer
* @param end Maximum array index contained in the buffer
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* The smaller range is specified with @p start and @p end the less
* memory operations are needed (and possibly some optimizations),
@ -553,14 +553,14 @@ class MAGNUM_EXPORT Mesh {
* @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if
* @extension{APPLE,vertex_array_object} is available)
*/
Mesh* setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end);
Mesh& setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end);
/**
* @brief Set index buffer
* @param buffer Index buffer
* @param offset Offset into the buffer
* @param type Index data type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Prefer to use setIndexBuffer(Buffer*, GLintptr, IndexType, UnsignedInt, UnsignedInt)
* for better performance.
@ -568,7 +568,7 @@ class MAGNUM_EXPORT Mesh {
* @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if
* @extension{APPLE,vertex_array_object} is available)
*/
Mesh* setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type) {
Mesh& setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type) {
return setIndexBuffer(buffer, offset, type, 0, 0);
}
@ -783,12 +783,12 @@ Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::Primitive value);
/** @debugoperator{Magnum::Mesh} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::IndexType value);
template<class ...T> inline Mesh* Mesh::addVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes) {
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);
"Mesh::addVertexBuffer(): vertex count must be set before binding attributes", *this);
addVertexBufferInternal(buffer, offset, attributes...);
return this;
return *this;
}

2
src/MeshTools/CompressIndices.cpp

@ -80,7 +80,7 @@ void compressIndices(Mesh* mesh, Buffer* buffer, Buffer::Usage usage, const std:
std::tie(indexCount, indexType, data) = compressIndicesInternal(indices, *minmax.second);
mesh->setIndexCount(indices.size())
->setIndexBuffer(buffer, 0, indexType, *minmax.first, *minmax.second);
.setIndexBuffer(buffer, 0, indexType, *minmax.first, *minmax.second);
buffer->setData(indexCount*Mesh::indexSize(indexType), data, usage);
delete[] data;

4
src/Platform/AbstractXApplication.h

@ -204,7 +204,7 @@ class AbstractXApplication::Configuration {
/**
* @brief Set window title
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is `"Magnum X Application"`.
*/
@ -218,7 +218,7 @@ class AbstractXApplication::Configuration {
/**
* @brief Set window size
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is `{800, 600}`.
*/

46
src/ResourceManager.h

@ -287,7 +287,7 @@ template<class... Types> class ResourceManager: private Implementation::Resource
/**
* @brief Set resource data
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @p policy is set to `ResourcePolicy::ReferenceCounted`, there
* must be already at least one reference to given resource, otherwise
@ -304,19 +304,19 @@ template<class... Types> class ResourceManager: private Implementation::Resource
* subsequent updates are not possible.
* @see referenceCount(), state()
*/
template<class T> 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);
return this;
return *this;
}
/**
* @brief Set resource data
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as above function with state set to @ref ResourceDataState "ResourceDataState::Final"
* and policy to @ref ResourcePolicy "ResourcePolicy::Resident".
*/
template<class T> ResourceManager<Types...>* set(ResourceKey key, T* data) {
template<class T> ResourceManager<Types...>& set(ResourceKey key, T* data) {
return set(key, data, ResourceDataState::Final, ResourcePolicy::Resident);
}
@ -332,51 +332,51 @@ template<class... Types> class ResourceManager: private Implementation::Resource
/**
* @brief Set fallback for not found resources
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
template<class T> ResourceManager<Types...>* setFallback(T* data) {
template<class T> ResourceManager<Types...>& setFallback(T* data) {
this->Implementation::ResourceManagerData<T>::setFallback(data);
return this;
return *this;
}
/**
* @brief Free all resources of given type which are not referenced
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
template<class T> ResourceManager<Types...>* free() {
template<class T> ResourceManager<Types...>& free() {
this->Implementation::ResourceManagerData<T>::free();
return this;
return *this;
}
/**
* @brief Free all resources which are not referenced
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
ResourceManager<Types...>* free() {
ResourceManager<Types...>& free() {
freeInternal<Types...>();
return this;
return *this;
}
/**
* @brief Clear all resources of given type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Unlike free() this function assumes that no resource is referenced.
*/
template<class T> ResourceManager<Types...>* clear() {
template<class T> ResourceManager<Types...>& clear() {
this->Implementation::ResourceManagerData<T>::clear();
return this;
return *this;
}
/**
* @brief Clear all resources
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Unlike free() this function assumes that no resource is referenced.
*/
ResourceManager<Types...>* clear() {
ResourceManager<Types...>& clear() {
clearInternal<Types...>();
return this;
return *this;
}
/** @brief Loader for given type of resources */
@ -391,15 +391,15 @@ template<class... Types> class ResourceManager: private Implementation::Resource
/**
* @brief Set loader for given type of resources
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* See AbstractResourceLoader documentation for more information.
* @attention The loader is deleted on destruction before unloading
* all resources.
*/
template<class T> ResourceManager<Types...>* setLoader(AbstractResourceLoader<T>* loader) {
template<class T> ResourceManager<Types...>& setLoader(AbstractResourceLoader<T>* loader) {
this->Implementation::ResourceManagerData<T>::setLoader(loader);
return this;
return *this;
}
private:

4
src/SceneGraph/AbstractCamera.h

@ -81,9 +81,9 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
/**
* @brief Set aspect ratio policy
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
AbstractCamera<dimensions, T>* setAspectRatioPolicy(AspectRatioPolicy policy);
AbstractCamera<dimensions, T>& setAspectRatioPolicy(AspectRatioPolicy policy);
/**
* @brief Camera matrix

4
src/SceneGraph/AbstractCamera.hpp

@ -74,10 +74,10 @@ template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>::Abstrac
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>::~AbstractCamera() = default;
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>* AbstractCamera<dimensions, T>::setAspectRatioPolicy(AspectRatioPolicy policy) {
template<UnsignedInt dimensions, class T> AbstractCamera<dimensions, T>& AbstractCamera<dimensions, T>::setAspectRatioPolicy(AspectRatioPolicy policy) {
_aspectRatioPolicy = policy;
fixAspectRatio();
return this;
return *this;
}
template<UnsignedInt dimensions, class T> void AbstractCamera<dimensions, T>::setViewport(const Vector2i& size) {

6
src/SceneGraph/AbstractTransformation.h

@ -136,11 +136,11 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Abstrac
/**
* @brief Reset object transformation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
AbstractTransformation<dimensions, T>* resetTransformation() {
AbstractTransformation<dimensions, T>& resetTransformation() {
doResetTransformation();
return this;
return *this;
}
protected:

16
src/SceneGraph/AbstractTranslationRotation2D.h

@ -46,31 +46,31 @@ template<class T> class AbstractBasicTranslationRotation2D: public AbstractTrans
* @brief Translate object
* @param vector Translation vector
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see Vector2::xAxis(), Vector2::yAxis()
*/
AbstractBasicTranslationRotation2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation2D<T>& translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
doTranslate(vector, type);
return this;
return *this;
}
/**
* @brief Rotate object
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
AbstractBasicTranslationRotation2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation2D<T>& rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotate(angle, type);
return this;
return *this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractBasicTranslationRotation2D<T>* resetTransformation() {
AbstractBasicTranslationRotation2D<T>& resetTransformation() {
AbstractTransformation<2, T>::resetTransformation();
return this;
return *this;
}
#endif

34
src/SceneGraph/AbstractTranslationRotation3D.h

@ -47,13 +47,13 @@ template<class T> class AbstractBasicTranslationRotation3D: public AbstractTrans
* @brief Translate object
* @param vector Translation vector
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis()
*/
AbstractBasicTranslationRotation3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>& translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
doTranslate(vector, type);
return this;
return *this;
}
/**
@ -61,63 +61,63 @@ template<class T> class AbstractBasicTranslationRotation3D: public AbstractTrans
* @param angle Angle (counterclockwise)
* @param normalizedAxis Normalized rotation axis
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis()
*/
AbstractBasicTranslationRotation3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
doRotate(angle, normalizedAxis, type);
return this;
return *this;
}
/**
* @brief Rotate object around X axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* In some implementations faster than calling
* `rotate(angle, Vector3::xAxis())`.
*/
AbstractBasicTranslationRotation3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>& rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateX(angle, type);
return this;
return *this;
}
/**
* @brief Rotate object around Y axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* In some implementations faster than calling
* `rotate(angle, Vector3::yAxis())`.
*/
AbstractBasicTranslationRotation3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>& rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateX(angle, type);
return this;
return *this;
}
/**
* @brief Rotate object around Z axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* In some implementations faster than calling
* `rotate(angle, Vector3::zAxis())`.
*/
AbstractBasicTranslationRotation3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>& rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
doRotateZ(angle, type);
return this;
return *this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractBasicTranslationRotation3D<T>* resetTransformation() {
AbstractBasicTranslationRotation3D<T>& resetTransformation() {
AbstractTransformation<3, T>::resetTransformation();
return this;
return *this;
}
#endif

18
src/SceneGraph/AbstractTranslationRotationScaling2D.h

@ -45,28 +45,28 @@ template<class T> class AbstractBasicTranslationRotationScaling2D: public Abstra
* @brief Scale object
* @param vector Scaling vector
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see Vector2::xScale(), Vector2::yScale()
*/
AbstractBasicTranslationRotationScaling2D<T>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling2D<T>& scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
doScale(vector, type);
return this;
return *this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractBasicTranslationRotationScaling2D<T>* resetTransformation() {
AbstractBasicTranslationRotationScaling2D<T>& resetTransformation() {
AbstractBasicTranslationRotation2D<T>::resetTransformation();
return this;
return *this;
}
AbstractBasicTranslationRotationScaling2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling2D<T>& translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation2D<T>::translate(vector, type);
return this;
return *this;
}
AbstractBasicTranslationRotationScaling2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling2D<T>& rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation2D<T>::rotate(angle, type);
return this;
return *this;
}
#endif

30
src/SceneGraph/AbstractTranslationRotationScaling3D.h

@ -45,40 +45,40 @@ template<class T> class AbstractBasicTranslationRotationScaling3D: public Abstra
* @brief Scale object
* @param vector Scaling vector
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see Vector3::xScale(), Vector3::yScale(), Vector3::zScale()
*/
AbstractBasicTranslationRotationScaling3D<T>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling3D<T>& scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
doScale(vector, type);
return this;
return *this;
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractBasicTranslationRotationScaling3D<T>* resetTransformation() {
AbstractBasicTranslationRotationScaling3D<T>& resetTransformation() {
AbstractBasicTranslationRotation3D<T>::resetTransformation();
return this;
return *this;
}
AbstractBasicTranslationRotationScaling3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling3D<T>& translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>::translate(vector, type);
return this;
return *this;
}
AbstractBasicTranslationRotationScaling3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling3D<T>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>::rotate(angle, normalizedAxis, type);
return this;
return *this;
}
AbstractBasicTranslationRotationScaling3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling3D<T>& rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>::rotateX(angle, type);
return this;
return *this;
}
AbstractBasicTranslationRotationScaling3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling3D<T>& rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>::rotateY(angle, type);
return this;
return *this;
}
AbstractBasicTranslationRotationScaling3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotationScaling3D<T>& rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
AbstractBasicTranslationRotation3D<T>::rotateZ(angle, type);
return this;
return *this;
}
#endif

22
src/SceneGraph/Animable.h

@ -165,7 +165,7 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Animabl
/**
* @brief Set animation state
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Note that changing state from @ref AnimationState "AnimationState::Stopped"
* to @ref AnimationState "AnimationState::Paused" is ignored and
@ -174,7 +174,7 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Animabl
* @see animationStarted(), animationPaused(), animationResumed(),
* animationStopped()
*/
Animable<dimensions, T>* setState(AnimationState state);
Animable<dimensions, T>& setState(AnimationState state);
/**
* @brief Whether the animation is repeated
@ -185,14 +185,14 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Animabl
/**
* @brief Enable/disable repeated animation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is `false`.
* @see setRepeatCount()
*/
Animable<dimensions, T>* setRepeated(bool repeated) {
Animable<dimensions, T>& setRepeated(bool repeated) {
_repeated = repeated;
return this;
return *this;
}
/**
@ -204,15 +204,15 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Animabl
/**
* @brief Set repeat count
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Has effect only if repeated animation is enabled. `0` means
* infinitely repeated animation. Default is `0`.
* @see setRepeated()
*/
Animable<dimensions, T>* setRepeatCount(UnsignedShort count) {
Animable<dimensions, T>& setRepeatCount(UnsignedShort count) {
_repeatCount = count;
return this;
return *this;
}
/**
@ -226,15 +226,15 @@ template<UnsignedInt dimensions, class T> class MAGNUM_SCENEGRAPH_EXPORT Animabl
protected:
/**
* @brief Set animation duration
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Sets duration of the animation cycle in seconds. Set to `0.0f` for
* infinite non-repeating animation. Default is `0.0f`.
*/
/* Protected so only animation implementer can change it */
Animable<dimensions, T>* setDuration(Float duration) {
Animable<dimensions, T>& setDuration(Float duration) {
_duration = duration;
return this;
return *this;
}
/**

8
src/SceneGraph/Animable.hpp

@ -39,17 +39,17 @@ template<UnsignedInt dimensions, class T> Animable<dimensions, T>::Animable(Abst
template<UnsignedInt dimensions, class T> Animable<dimensions, T>::~Animable() {}
template<UnsignedInt dimensions, class T> Animable<dimensions, T>* Animable<dimensions, T>::setState(AnimationState state) {
if(currentState == state) return this;
template<UnsignedInt dimensions, class T> Animable<dimensions, T>& Animable<dimensions, T>::setState(AnimationState state) {
if(currentState == state) return *this;
/* Not allowed (for sanity) */
if(previousState == AnimationState::Stopped && state == AnimationState::Paused)
return this;
return *this;
/* Wake up the group in case no animations are running */
group()->wakeUp = true;
currentState = state;
return this;
return *this;
}
template<UnsignedInt dimensions, class T> AnimableGroup<dimensions, T>* Animable<dimensions, T>::group() {

14
src/SceneGraph/Camera2D.h

@ -39,9 +39,9 @@ See Drawable documentation for introduction. The camera by default displays
OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` and doesn't do any aspect ratio
correction. Common setup example:
@code
SceneGraph::Camera2D* camera = new SceneGraph::Camera2D(&cameraObject);
camera->setProjection({4.0f/3.0f, 1.0f})
->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
SceneGraph::Camera2D camera(&cameraObject);
camera.setProjection({4.0f/3.0f, 1.0f})
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode
@section Camera2D-explicit-specializations Explicit template specializations
@ -70,17 +70,17 @@ template<class T> class MAGNUM_SCENEGRAPH_EXPORT BasicCamera2D: public AbstractC
/**
* @brief Set projection
* @param size Size of the view
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see Matrix3::projection()
*/
BasicCamera2D<T>* setProjection(const Math::Vector2<T>& size);
BasicCamera2D<T>& setProjection(const Math::Vector2<T>& size);
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
BasicCamera2D<T>* setAspectRatioPolicy(AspectRatioPolicy policy) {
BasicCamera2D<T>& setAspectRatioPolicy(AspectRatioPolicy policy) {
AbstractCamera<2, T>::setAspectRatioPolicy(policy);
return this;
return *this;
}
#endif
};

4
src/SceneGraph/Camera2D.hpp

@ -37,11 +37,11 @@ namespace Magnum { namespace SceneGraph {
template<class T> BasicCamera2D<T>::BasicCamera2D(AbstractObject<2, T>* object): AbstractCamera<2, T>(object) {}
template<class T> BasicCamera2D<T>* BasicCamera2D<T>::setProjection(const Math::Vector2<T>& size) {
template<class T> BasicCamera2D<T>& BasicCamera2D<T>::setProjection(const Math::Vector2<T>& size) {
AbstractCamera<2, T>::rawProjectionMatrix = Math::Matrix3<T>::projection(size);
AbstractCamera<2, T>::fixAspectRatio();
return this;
return *this;
}
}}

22
src/SceneGraph/Camera3D.h

@ -44,9 +44,9 @@ See Drawable documentation for introduction. The camera by default displays
OpenGL unit cube `[(-1, -1, -1); (1, 1, 1)]` with orthographic projection and
doesn't do any aspect ratio correction. Common setup example:
@code
SceneGraph::Camera3D* camera = new SceneGraph::Camera3D(&cameraObject);
camera->setPerspective({}, 0.001f, 100.0f)
->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
SceneGraph::Camera3D camera(&cameraObject);
camera.setPerspective({}, 0.001f, 100.0f)
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend);
@endcode
@section Camera3D-explicit-specializations Explicit template specializations
@ -74,22 +74,22 @@ template<class T> class MAGNUM_SCENEGRAPH_EXPORT BasicCamera3D: public AbstractC
* @param size Size of the view
* @param near Near clipping plane
* @param far Far clipping plane
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setPerspective(), Matrix4::orthographicProjection()
*/
BasicCamera3D<T>* setOrthographic(const Math::Vector2<T>& size, T near, T far);
BasicCamera3D<T>& setOrthographic(const Math::Vector2<T>& size, T near, T far);
/**
* @brief Set perspective projection
* @param size Size of near clipping plane
* @param near Near clipping plane
* @param far Far clipping plane
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setOrthographic(), Matrix4::perspectiveProjection()
*/
BasicCamera3D<T>* setPerspective(const Math::Vector2<T>& size, T near, T far);
BasicCamera3D<T>& setPerspective(const Math::Vector2<T>& size, T near, T far);
/**
* @brief Set perspective projection
@ -97,11 +97,11 @@ template<class T> class MAGNUM_SCENEGRAPH_EXPORT BasicCamera3D: public AbstractC
* @param aspectRatio Aspect ratio
* @param near Near clipping plane
* @param far Far clipping plane
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setOrthographic(), Matrix4::perspectiveProjection()
*/
BasicCamera3D<T>* setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far);
BasicCamera3D<T>& setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far);
/** @brief Near clipping plane */
T near() const { return _near; }
@ -111,9 +111,9 @@ template<class T> class MAGNUM_SCENEGRAPH_EXPORT BasicCamera3D: public AbstractC
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
BasicCamera3D<T>* setAspectRatioPolicy(AspectRatioPolicy policy) {
BasicCamera3D<T>& setAspectRatioPolicy(AspectRatioPolicy policy) {
AbstractCamera<3, T>::setAspectRatioPolicy(policy);
return this;
return *this;
}
#endif

12
src/SceneGraph/Camera3D.hpp

@ -37,34 +37,34 @@ namespace Magnum { namespace SceneGraph {
template<class T> BasicCamera3D<T>::BasicCamera3D(AbstractObject<3, T>* object): AbstractCamera<3, T>(object), _near(T(0)), _far(T(0)) {}
template<class T> BasicCamera3D<T>* BasicCamera3D<T>::setOrthographic(const Math::Vector2<T>& size, T near, T far) {
template<class T> BasicCamera3D<T>& BasicCamera3D<T>::setOrthographic(const Math::Vector2<T>& size, T near, T far) {
/** @todo Get near/far from the matrix */
_near = near;
_far = far;
AbstractCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::orthographicProjection(size, near, far);
AbstractCamera<3, T>::fixAspectRatio();
return this;
return *this;
}
template<class T> BasicCamera3D<T>* BasicCamera3D<T>::setPerspective(const Math::Vector2<T>& size, T near, T far) {
template<class T> BasicCamera3D<T>& BasicCamera3D<T>::setPerspective(const Math::Vector2<T>& size, T near, T far) {
/** @todo Get near/far from the matrix */
_near = near;
_far = far;
AbstractCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::perspectiveProjection(size, near, far);
AbstractCamera<3, T>::fixAspectRatio();
return this;
return *this;
}
template<class T> BasicCamera3D<T>* BasicCamera3D<T>::setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far) {
template<class T> BasicCamera3D<T>& BasicCamera3D<T>::setPerspective(Math::Rad<T> fov, T aspectRatio, T near, T far) {
/** @todo Get near/far from the matrix */
_near = near;
_far = far;
AbstractCamera<3, T>::rawProjectionMatrix = Math::Matrix4<T>::perspectiveProjection(fov, aspectRatio, near, far);
AbstractCamera<3, T>::fixAspectRatio();
return this;
return *this;
}
}}

12
src/SceneGraph/Drawable.h

@ -68,7 +68,7 @@ SceneGraph::DrawableGroup3D drawables;
(new DrawableObject(&scene, &drawables))
->translate(Vector3::yAxis(-0.3f))
->rotateX(30.0_degf);
.rotateX(30.0_degf);
(new AnotherDrawableObject(&scene, &drawables))
->translate(Vector3::zAxis(0.5f));
// ...
@ -96,14 +96,14 @@ setup etc into one group, then put all transparent into another and set common
parameters once for whole group instead of setting them again in each draw()
implementation. Example:
@code
Shaders::PhongShader* shader;
Shaders::PhongShader shader;
SceneGraph::DrawableGroup3D phongObjects, transparentObjects;
void MyApplication::drawEvent() {
shader->setProjectionMatrix(camera->projectionMatrix())
->setLightPosition(lightPosition)
->setLightColor(lightColor)
->setAmbientColor(ambientColor);
shader.setProjectionMatrix(camera->projectionMatrix())
.setLightPosition(lightPosition)
.setLightColor(lightColor)
.setAmbientColor(ambientColor);
camera.draw(phongObjects);
Renderer::setFeature(Renderer::Feature::Blending, true);

42
src/SceneGraph/DualComplexTransformation.h

@ -70,87 +70,87 @@ template<class T> class BasicDualComplexTransformation: public AbstractBasicTran
/**
* @brief Normalize rotation part
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Normalizes the rotation part to prevent rounding errors when rotating
* the object subsequently.
* @see DualComplex::normalized()
*/
Object<BasicDualComplexTransformation<T>>* normalizeRotation() {
Object<BasicDualComplexTransformation<T>>& normalizeRotation() {
setTransformationInternal(_transformation.normalized());
return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
return static_cast<Object<BasicDualComplexTransformation<T>>&>(*this);
}
/**
* @brief Set transformation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Expects that the dual complex number is normalized.
* @see DualComplex::isNormalized()
*/
Object<BasicDualComplexTransformation<T>>* setTransformation(const Math::DualComplex<T>& transformation) {
Object<BasicDualComplexTransformation<T>>& setTransformation(const Math::DualComplex<T>& transformation) {
CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualComplexTransformation::setTransformation(): the dual complex number is not normalized",
static_cast<Object<BasicDualComplexTransformation<T>>*>(this));
static_cast<Object<BasicDualComplexTransformation<T>>&>(*this));
setTransformationInternal(transformation);
return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
return static_cast<Object<BasicDualComplexTransformation<T>>&>(*this);
}
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<BasicDualComplexTransformation<T>>* resetTransformation() {
Object<BasicDualComplexTransformation<T>>& resetTransformation() {
setTransformationInternal({});
return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
return static_cast<Object<BasicDualComplexTransformation<T>>&>(*this);
}
/**
* @brief Transform object
* @param transformation Transformation
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Expects that the dual complex number is normalized.
* @see DualComplex::isNormalized()
*/
Object<BasicDualComplexTransformation<T>>* transform(const Math::DualComplex<T>& transformation, TransformationType type = TransformationType::Global) {
Object<BasicDualComplexTransformation<T>>& transform(const Math::DualComplex<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualComplexTransformation::transform(): the dual complex number is not normalized",
static_cast<Object<BasicDualComplexTransformation<T>>*>(this));
static_cast<Object<BasicDualComplexTransformation<T>>&>(*this));
transformInternal(transformation, type);
return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
return static_cast<Object<BasicDualComplexTransformation<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with DualComplex::translation().
*/
Object<BasicDualComplexTransformation<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
Object<BasicDualComplexTransformation<T>>& translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualComplex<T>::translation(vector), type);
return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
return static_cast<Object<BasicDualComplexTransformation<T>>&>(*this);
}
/**
* @brief Rotate object
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with DualComplex::rotation().
* @see normalizeRotation()
*/
Object<BasicDualComplexTransformation<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicDualComplexTransformation<T>>& rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualComplex<T>::rotation(angle), type);
return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
return static_cast<Object<BasicDualComplexTransformation<T>>&>(*this);
}
/**
* @brief Move object in stacking order
* @param under Sibling object under which to move or `nullptr`,
* if you want to move it above all.
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Object<BasicDualComplexTransformation<T>>* move(Object<BasicDualComplexTransformation<T>>* under) {
Object<BasicDualComplexTransformation<T>>& move(Object<BasicDualComplexTransformation<T>>* under) {
static_cast<Object<BasicDualComplexTransformation>*>(this)->Containers::template LinkedList<Object<BasicDualComplexTransformation<T>>>::move(this, under);
return static_cast<Object<BasicDualComplexTransformation<T>>*>(this);
return static_cast<Object<BasicDualComplexTransformation<T>>&>(*this);
}
protected:

42
src/SceneGraph/DualQuaternionTransformation.h

@ -72,62 +72,62 @@ template<class T> class BasicDualQuaternionTransformation: public AbstractBasicT
/**
* @brief Normalize rotation part
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Normalizes the rotation part to prevent rounding errors when rotating
* the object subsequently.
* @see DualQuaternion::normalized()
*/
Object<BasicDualQuaternionTransformation<T>>* normalizeRotation() {
Object<BasicDualQuaternionTransformation<T>>& normalizeRotation() {
setTransformation(_transformation.normalized());
return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
return static_cast<Object<BasicDualQuaternionTransformation<T>>&>(*this);
}
/**
* @brief Set transformation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Expects that the dual quaternion is normalized.
* @see DualQuaternion::isNormalized()
*/
Object<BasicDualQuaternionTransformation<T>>* setTransformation(const Math::DualQuaternion<T>& transformation) {
Object<BasicDualQuaternionTransformation<T>>& setTransformation(const Math::DualQuaternion<T>& transformation) {
CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualQuaternionTransformation::setTransformation(): the dual quaternion is not normalized",
static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this));
static_cast<Object<BasicDualQuaternionTransformation<T>>&>(*this));
setTransformationInternal(transformation);
return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
return static_cast<Object<BasicDualQuaternionTransformation<T>>&>(*this);
}
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<BasicDualQuaternionTransformation<T>>* resetTransformation() {
Object<BasicDualQuaternionTransformation<T>>& resetTransformation() {
setTransformation({});
return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
return static_cast<Object<BasicDualQuaternionTransformation<T>>&>(*this);
}
/**
* @brief Multiply transformation
* @param transformation Transformation
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Expects that the dual quaternion is normalized.
* @see DualQuaternion::isNormalized()
*/
Object<BasicDualQuaternionTransformation<T>>* transform(const Math::DualQuaternion<T>& transformation, TransformationType type = TransformationType::Global) {
Object<BasicDualQuaternionTransformation<T>>& transform(const Math::DualQuaternion<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isNormalized(),
"SceneGraph::DualQuaternionTransformation::transform(): the dual quaternion is not normalized",
static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this));
static_cast<Object<BasicDualQuaternionTransformation<T>>&>(*this));
transformInternal(transformation, type);
return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
return static_cast<Object<BasicDualQuaternionTransformation<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with DualQuaternion::translation().
*/
Object<BasicDualQuaternionTransformation<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
Object<BasicDualQuaternionTransformation<T>>& translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualQuaternion<T>::translation(vector), type);
return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
return static_cast<Object<BasicDualQuaternionTransformation<T>>&>(*this);
}
/**
@ -135,26 +135,26 @@ template<class T> class BasicDualQuaternionTransformation: public AbstractBasicT
* @param angle Angle (counterclockwise)
* @param normalizedAxis Normalized rotation axis
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with DualQuaternion::rotation().
* @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(),
* normalizeRotation()
*/
Object<BasicDualQuaternionTransformation<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
Object<BasicDualQuaternionTransformation<T>>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transformInternal(Math::DualQuaternion<T>::rotation(angle, normalizedAxis), type);
return static_cast<Object<BasicDualQuaternionTransformation<T>>*>(this);
return static_cast<Object<BasicDualQuaternionTransformation<T>>&>(*this);
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
Object<BasicDualQuaternionTransformation<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicDualQuaternionTransformation<T>>& rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::xAxis(), type);
}
Object<BasicDualQuaternionTransformation<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicDualQuaternionTransformation<T>>& rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::yAxis(), type);
}
Object<BasicDualQuaternionTransformation<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicDualQuaternionTransformation<T>>& rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
return rotate(angle, Math::Vector3<T>::zAxis(), type);
}
#endif

18
src/SceneGraph/FeatureGroup.h

@ -91,21 +91,21 @@ template<UnsignedInt dimensions, class Feature, class T> class FeatureGroup: pub
/**
* @brief Add feature to the group
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If the features is part of another group, it is removed from it.
* @see remove(), AbstractGroupedFeature::AbstractGroupedFeature()
*/
FeatureGroup<dimensions, Feature, T>* add(Feature* feature);
FeatureGroup<dimensions, Feature, T>& add(Feature* feature);
/**
* @brief Remove feature from the group
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* The feature must be part of the group.
* @see add()
*/
FeatureGroup<dimensions, Feature, T>* remove(Feature* feature);
FeatureGroup<dimensions, Feature, T>& remove(Feature* feature);
};
#ifndef CORRADE_GCC46_COMPATIBILITY
@ -158,7 +158,7 @@ template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions
for(auto i: this->features) static_cast<Feature*>(i)->_group = nullptr;
}
template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions, Feature, T>* FeatureGroup<dimensions, Feature, T>::add(Feature* feature) {
template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions, Feature, T>& FeatureGroup<dimensions, Feature, T>::add(Feature* feature) {
/* Remove from previous group */
if(feature->_group)
feature->_group->remove(feature);
@ -166,16 +166,16 @@ template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions
/* Crossreference the feature and group together */
AbstractFeatureGroup<dimensions, T>::add(feature);
feature->_group = this;
return this;
return *this;
}
template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions, Feature, T>* FeatureGroup<dimensions, Feature, T>::remove(Feature* feature) {
template<UnsignedInt dimensions, class Feature, class T> FeatureGroup<dimensions, Feature, T>& FeatureGroup<dimensions, Feature, T>::remove(Feature* feature) {
CORRADE_ASSERT(feature->_group == this,
"SceneGraph::AbstractFeatureGroup::remove(): feature is not part of this group", this);
"SceneGraph::AbstractFeatureGroup::remove(): feature is not part of this group", *this);
AbstractFeatureGroup<dimensions, T>::remove(feature);
feature->_group = nullptr;
return this;
return *this;
}
}}

40
src/SceneGraph/MatrixTransformation2D.h

@ -69,9 +69,9 @@ template<class T> class BasicMatrixTransformation2D: public AbstractBasicTransla
/**
* @brief Set transformation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Object<BasicMatrixTransformation2D<T>>* setTransformation(const Math::Matrix3<T>& transformation) {
Object<BasicMatrixTransformation2D<T>>& setTransformation(const Math::Matrix3<T>& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */
@ -80,52 +80,52 @@ template<class T> class BasicMatrixTransformation2D: public AbstractBasicTransla
static_cast<Object<BasicMatrixTransformation2D<T>>*>(this)->setDirty();
}
return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation2D<T>>&>(*this);
}
/**
* @brief Transform object
* @param transformation Transformation
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Object<BasicMatrixTransformation2D<T>>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation2D<T>>& transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
setTransformation(type == TransformationType::Global ?
transformation*_transformation : _transformation*transformation);
return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation2D<T>>&>(*this);
}
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<BasicMatrixTransformation2D<T>>* resetTransformation() {
Object<BasicMatrixTransformation2D<T>>& resetTransformation() {
setTransformation({});
return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation2D<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with Matrix3::translation().
*/
Object<BasicMatrixTransformation2D<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation2D<T>>& translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::translation(vector), type);
return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation2D<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::rotate()
* Same as calling transform() with Matrix3::rotation().
*/
Object<BasicMatrixTransformation2D<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation2D<T>>& rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::rotation(angle), type);
return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation2D<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::scale()
* Same as calling transform() with Matrix3::scaling().
*/
Object<BasicMatrixTransformation2D<T>>* scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation2D<T>>& scale(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::scaling(vector), type);
return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation2D<T>>&>(*this);
}
/**
@ -133,24 +133,24 @@ template<class T> class BasicMatrixTransformation2D: public AbstractBasicTransla
* @param normal Normal of the line through which to reflect
* (normalized)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix3::reflection().
*/
Object<BasicMatrixTransformation2D<T>>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation2D<T>>& reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::reflection(normal), type);
return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation2D<T>>&>(*this);
}
/**
* @brief Move object in stacking order
* @param under Sibling object under which to move or `nullptr`,
* if you want to move it above all.
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Object<BasicMatrixTransformation2D<T>>* move(Object<BasicMatrixTransformation2D<T>>* under) {
Object<BasicMatrixTransformation2D<T>>& move(Object<BasicMatrixTransformation2D<T>>* under) {
static_cast<Object<BasicMatrixTransformation2D>*>(this)->Containers::template LinkedList<Object<BasicMatrixTransformation2D<T>>>::move(this, under);
return static_cast<Object<BasicMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation2D<T>>&>(*this);
}
protected:

52
src/SceneGraph/MatrixTransformation3D.h

@ -69,9 +69,9 @@ template<class T> class BasicMatrixTransformation3D: public AbstractBasicTransla
/**
* @brief Set transformation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Object<BasicMatrixTransformation3D<T>>* setTransformation(const Math::Matrix4<T>& transformation) {
Object<BasicMatrixTransformation3D<T>>& setTransformation(const Math::Matrix4<T>& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */
@ -80,91 +80,91 @@ template<class T> class BasicMatrixTransformation3D: public AbstractBasicTransla
static_cast<Object<BasicMatrixTransformation3D<T>>*>(this)->setDirty();
}
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<BasicMatrixTransformation3D<T>>* resetTransformation() {
Object<BasicMatrixTransformation3D<T>>& resetTransformation() {
setTransformation({});
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Multiply transformation
* @param transformation Transformation
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Object<BasicMatrixTransformation3D<T>>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation3D<T>>& transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
setTransformation(type == TransformationType::Global ?
transformation*_transformation : _transformation*transformation);
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with Matrix4::translation().
*/
Object<BasicMatrixTransformation3D<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation3D<T>>& translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::translation(vector), type);
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::rotate()
* Same as calling transform() with Matrix4::rotation().
*/
Object<BasicMatrixTransformation3D<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation3D<T>>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotation(angle, normalizedAxis), type);
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Rotate object around X axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::rotationX().
*/
Object<BasicMatrixTransformation3D<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation3D<T>>& rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationX(angle), type);
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Rotate object around Y axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::rotationY().
*/
Object<BasicMatrixTransformation3D<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation3D<T>>& rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationY(angle), type);
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Rotate object around Z axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::rotationZ().
*/
Object<BasicMatrixTransformation3D<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation3D<T>>& rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::rotationZ(angle), type);
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::scale()
* Same as calling transform() with Matrix4::scaling().
*/
Object<BasicMatrixTransformation3D<T>>* scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation3D<T>>& scale(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::scaling(vector), type);
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
/**
@ -172,13 +172,13 @@ template<class T> class BasicMatrixTransformation3D: public AbstractBasicTransla
* @param normal Normal of the plane through which to reflect
* (normalized)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::reflection().
*/
Object<BasicMatrixTransformation3D<T>>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
Object<BasicMatrixTransformation3D<T>>& reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::reflection(normal), type);
return static_cast<Object<BasicMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicMatrixTransformation3D<T>>&>(*this);
}
protected:

8
src/SceneGraph/Object.h

@ -190,20 +190,20 @@ template<class Transformation> class MAGNUM_SCENEGRAPH_EXPORT Object: public Abs
/**
* @brief Set parent object
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setParentKeepTransformation()
*/
Object<Transformation>* setParent(Object<Transformation>* parent);
Object<Transformation>& setParent(Object<Transformation>* parent);
/**
* @brief Set parent object and keep absolute transformation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* While setParent() preserves only relative transformation of the
* object, this funcition preserves absolute transformation.
*/
Object<Transformation>* setParentKeepTransformation(Object<Transformation>* parent);
Object<Transformation>& setParentKeepTransformation(Object<Transformation>* parent);
/*@}*/

14
src/SceneGraph/Object.hpp

@ -65,16 +65,16 @@ template<class Transformation> const Object<Transformation>* Object<Transformati
return scene();
}
template<class Transformation> Object<Transformation>* Object<Transformation>::setParent(Object<Transformation>* parent) {
template<class Transformation> Object<Transformation>& Object<Transformation>::setParent(Object<Transformation>* parent) {
/* Skip if parent is already parent or this is scene (which cannot have parent) */
/** @todo Assert for setting parent to scene */
if(this->parent() == parent || isScene()) return this;
if(this->parent() == parent || isScene()) return *this;
/* Object cannot be parented to its child */
Object<Transformation>* p = parent;
while(p) {
/** @todo Assert for this */
if(p == this) return this;
if(p == this) return *this;
p = p->parent();
}
@ -85,18 +85,18 @@ template<class Transformation> Object<Transformation>* Object<Transformation>::s
if(parent) parent->Containers::LinkedList<Object<Transformation>>::insert(this);
setDirty();
return this;
return *this;
}
template<class Transformation> Object<Transformation>* Object<Transformation>::setParentKeepTransformation(Object<Transformation>* parent) {
CORRADE_ASSERT(scene() == parent->scene(), "SceneGraph::Object::setParentKeepTransformation(): both parents must be in the same scene", this);
template<class Transformation> Object<Transformation>& Object<Transformation>::setParentKeepTransformation(Object<Transformation>* parent) {
CORRADE_ASSERT(scene() == parent->scene(), "SceneGraph::Object::setParentKeepTransformation(): both parents must be in the same scene", *this);
const auto transformation = Transformation::compose(
Transformation::inverted(parent->absoluteTransformation()), absoluteTransformation());
setParent(parent);
this->setTransformation(transformation);
return this;
return *this;
}
template<class Transformation> typename Transformation::DataType Object<Transformation>::absoluteTransformation() const {

48
src/SceneGraph/RigidMatrixTransformation2D.h

@ -75,77 +75,77 @@ template<class T> class BasicRigidMatrixTransformation2D: public AbstractBasicTr
/**
* @brief Normalize rotation part
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Normalizes the rotation part using Math::Algorithms::gramSchmidt()
* to prevent rounding errors when rotating the object subsequently.
*/
Object<BasicRigidMatrixTransformation2D<T>>* normalizeRotation() {
Object<BasicRigidMatrixTransformation2D<T>>& normalizeRotation() {
setTransformationInternal(Math::Matrix3<T>::from(
Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()),
_transformation.translation()));
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this);
}
/**
* @brief Set transformation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Expects that the matrix represents rigid transformation.
* @see Matrix3::isRigidTransformation()
*/
Object<BasicRigidMatrixTransformation2D<T>>* setTransformation(const Math::Matrix3<T>& transformation) {
Object<BasicRigidMatrixTransformation2D<T>>& setTransformation(const Math::Matrix3<T>& transformation) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation2D::setTransformation(): the matrix doesn't represent rigid transformation",
static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this));
static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this));
setTransformationInternal(transformation);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this);
}
/** @copydoc AbstractTranslationRotationScaling2D::resetTransformation() */
Object<BasicRigidMatrixTransformation2D<T>>* resetTransformation() {
Object<BasicRigidMatrixTransformation2D<T>>& resetTransformation() {
setTransformationInternal({});
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this);
}
/**
* @brief Transform object
* @param transformation Transformation
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Expects that the matrix represents rigid transformation.
* @see Matrix3::isRigidTransformation()
*/
Object<BasicRigidMatrixTransformation2D<T>>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation2D<T>>& transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation",
static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this));
static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this));
transformInternal(transformation, type);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with Matrix3::translation().
*/
Object<BasicRigidMatrixTransformation2D<T>>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation2D<T>>& translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::translation(vector), type);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this);
}
/**
* @brief Rotate object
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix3::rotation().
* @see normalizeRotation()
*/
Object<BasicRigidMatrixTransformation2D<T>>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation2D<T>>& rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::rotation(angle), type);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this);
}
/**
@ -153,24 +153,24 @@ template<class T> class BasicRigidMatrixTransformation2D: public AbstractBasicTr
* @param normal Normal of the line through which to reflect
* (normalized)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix3::reflection().
*/
Object<BasicRigidMatrixTransformation2D<T>>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation2D<T>>& reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix3<T>::reflection(normal), type);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this);
}
/**
* @brief Move object in stacking order
* @param under Sibling object under which to move or `nullptr`,
* if you want to move it above all.
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Object<BasicRigidMatrixTransformation2D<T>>* move(Object<BasicRigidMatrixTransformation2D<T>>* under) {
Object<BasicRigidMatrixTransformation2D<T>>& move(Object<BasicRigidMatrixTransformation2D<T>>* under) {
static_cast<Object<BasicRigidMatrixTransformation2D>*>(this)->Containers::template LinkedList<Object<BasicRigidMatrixTransformation2D<T>>>::move(this, under);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation2D<T>>&>(*this);
}
protected:

60
src/SceneGraph/RigidMatrixTransformation3D.h

@ -75,63 +75,63 @@ template<class T> class BasicRigidMatrixTransformation3D: public AbstractBasicTr
/**
* @brief Normalize rotation part
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Normalizes the rotation part using Math::Algorithms::gramSchmidt()
* to prevent rounding errors when rotating the object subsequently.
*/
Object<BasicRigidMatrixTransformation3D<T>>* normalizeRotation() {
Object<BasicRigidMatrixTransformation3D<T>>& normalizeRotation() {
setTransformation(Math::Matrix4<T>::from(
Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()),
_transformation.translation()));
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Set transformation
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Expects that the matrix represents rigid transformation.
* @see Matrix4::isRigidTransformation()
*/
Object<BasicRigidMatrixTransformation3D<T>>* setTransformation(const Math::Matrix4<T>& transformation) {
Object<BasicRigidMatrixTransformation3D<T>>& setTransformation(const Math::Matrix4<T>& transformation) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation3D::setTransformation(): the matrix doesn't represent rigid transformation",
static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this));
static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this));
setTransformationInternal(transformation);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/** @copydoc AbstractTranslationRotationScaling3D::resetTransformation() */
Object<BasicRigidMatrixTransformation3D<T>>* resetTransformation() {
Object<BasicRigidMatrixTransformation3D<T>>& resetTransformation() {
setTransformation({});
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Multiply transformation
* @param transformation Transformation
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Expects that the matrix represents rigid transformation.
* @see Matrix4::isRigidTransformation()
*/
Object<BasicRigidMatrixTransformation3D<T>>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation3D<T>>& transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation",
static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this));
static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this));
transformInternal(transformation, type);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/**
* @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with Matrix4::translation().
*/
Object<BasicRigidMatrixTransformation3D<T>>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation3D<T>>& translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::translation(vector), type);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/**
@ -139,57 +139,57 @@ template<class T> class BasicRigidMatrixTransformation3D: public AbstractBasicTr
* @param angle Angle (counterclockwise)
* @param normalizedAxis Normalized rotation axis
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::rotation().
* @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis(), normalizeRotation()
*/
Object<BasicRigidMatrixTransformation3D<T>>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation3D<T>>& rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotation(angle, normalizedAxis), type);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Rotate object around X axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::rotationX().
* @see normalizeRotation()
*/
Object<BasicRigidMatrixTransformation3D<T>>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation3D<T>>& rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationX(angle), type);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Rotate object around Y axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::rotationY().
* @see normalizeRotation()
*/
Object<BasicRigidMatrixTransformation3D<T>>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation3D<T>>& rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationY(angle), type);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/**
* @brief Rotate object around Z axis
* @param angle Angle (counterclockwise)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::rotationZ().
* @see normalizeRotation()
*/
Object<BasicRigidMatrixTransformation3D<T>>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation3D<T>>& rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::rotationZ(angle), type);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
/**
@ -197,13 +197,13 @@ template<class T> class BasicRigidMatrixTransformation3D: public AbstractBasicTr
* @param normal Normal of the plane through which to reflect
* (normalized)
* @param type Transformation type
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Same as calling transform() with Matrix4::reflection().
*/
Object<BasicRigidMatrixTransformation3D<T>>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
Object<BasicRigidMatrixTransformation3D<T>>& reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
transformInternal(Math::Matrix4<T>::reflection(normal), type);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>*>(this);
return static_cast<Object<BasicRigidMatrixTransformation3D<T>>&>(*this);
}
protected:

7
src/SceneGraph/Test/AnimableTest.cpp

@ -143,8 +143,11 @@ void AnimableTest::state() {
CORRADE_COMPARE(group.runningCount(), 0);
/* Verify running count can go past 0/1 */
group.add((new StateTrackingAnimable(&object, &group))->setState(AnimationState::Running));
group.add((new StateTrackingAnimable(&object, &group))->setState(AnimationState::Running));
auto a = new StateTrackingAnimable(&object, &group);
auto b = new StateTrackingAnimable(&object, &group);
a->setState(AnimationState::Running);
b->setState(AnimationState::Running);
group.add(a).add(b);
group.step(1.0f, 1.0f);
CORRADE_COMPARE(group.runningCount(), 2);
}

12
src/SceneGraph/Test/DualQuaternionTransformationTest.cpp

@ -160,9 +160,9 @@ void DualQuaternionTransformationTest::rotate() {
Object3D o;
o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(Deg(17.0f))
->rotateY(Deg(25.0f))
->rotateZ(Deg(-23.0f))
->rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()));
.rotateY(Deg(25.0f))
.rotateZ(Deg(-23.0f))
.rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()))*
Matrix4::rotationZ(Deg(-23.0f))*
@ -173,9 +173,9 @@ void DualQuaternionTransformationTest::rotate() {
Object3D o;
o.transform(DualQuaternion::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(Deg(17.0f), TransformationType::Local)
->rotateY(Deg(25.0f), TransformationType::Local)
->rotateZ(Deg(-23.0f), TransformationType::Local)
->rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local);
.rotateY(Deg(25.0f), TransformationType::Local)
.rotateZ(Deg(-23.0f), TransformationType::Local)
.rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::rotationX(Deg(17.0f))*

12
src/SceneGraph/Test/MatrixTransformation3DTest.cpp

@ -145,9 +145,9 @@ void MatrixTransformation3DTest::rotate() {
Object3D o;
o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(Deg(17.0f))
->rotateY(Deg(25.0f))
->rotateZ(Deg(-23.0f))
->rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()));
.rotateY(Deg(25.0f))
.rotateZ(Deg(-23.0f))
.rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()))*
Matrix4::rotationZ(Deg(-23.0f))*
@ -158,9 +158,9 @@ void MatrixTransformation3DTest::rotate() {
Object3D o;
o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(Deg(17.0f), TransformationType::Local)
->rotateY(Deg(25.0f), TransformationType::Local)
->rotateZ(Deg(-23.0f), TransformationType::Local)
->rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local);
.rotateY(Deg(25.0f), TransformationType::Local)
.rotateZ(Deg(-23.0f), TransformationType::Local)
.rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::rotationX(Deg(17.0f))*

12
src/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp

@ -165,9 +165,9 @@ void RigidMatrixTransformation3DTest::rotate() {
Object3D o;
o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(Deg(17.0f))
->rotateY(Deg(25.0f))
->rotateZ(Deg(-23.0f))
->rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()));
.rotateY(Deg(25.0f))
.rotateZ(Deg(-23.0f))
.rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::rotation(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()))*
Matrix4::rotationZ(Deg(-23.0f))*
@ -178,9 +178,9 @@ void RigidMatrixTransformation3DTest::rotate() {
Object3D o;
o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(Deg(17.0f), TransformationType::Local)
->rotateY(Deg(25.0f), TransformationType::Local)
->rotateZ(Deg(-23.0f), TransformationType::Local)
->rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local);
.rotateY(Deg(25.0f), TransformationType::Local)
.rotateZ(Deg(-23.0f), TransformationType::Local)
.rotate(Deg(96.0f), Vector3(1.0f/Constants::sqrt3()), TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(),
Matrix4::translation({1.0f, -0.3f, 2.3f})*
Matrix4::rotationX(Deg(17.0f))*

33
src/Shaders/DistanceFieldVector.h

@ -51,37 +51,40 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
public:
DistanceFieldVector();
/** @brief Set transformation and projection matrix */
DistanceFieldVector* setTransformationProjectionMatrix(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) {
/**
* @brief Set transformation and projection matrix
* @return Reference to self (for method chaining)
*/
DistanceFieldVector& setTransformationProjectionMatrix(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) {
AbstractShaderProgram::setUniform(transformationProjectionMatrixUniform, matrix);
return this;
return *this;
}
/**
* @brief Set fill color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setOutlineColor()
*/
DistanceFieldVector* setColor(const Color4& color) {
DistanceFieldVector& setColor(const Color4& color) {
AbstractShaderProgram::setUniform(colorUniform, color);
return this;
return *this;
}
/**
* @brief Set outline color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* @see setOutlineRange(), setColor()
*/
DistanceFieldVector* setOutlineColor(const Color4& color) {
DistanceFieldVector& setOutlineColor(const Color4& color) {
AbstractShaderProgram::setUniform(outlineColorUniform, color);
return this;
return *this;
}
/**
* @brief Set outline range
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Parameter @p start describes where fill ends and possible outline
* starts. Initial value is `0.5f`, larger values will make the vector
@ -93,22 +96,22 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
*
* @see setOutlineColor()
*/
DistanceFieldVector* setOutlineRange(Float start, Float end) {
DistanceFieldVector& setOutlineRange(Float start, Float end) {
AbstractShaderProgram::setUniform(outlineRangeUniform, Vector2(start, end));
return this;
return *this;
}
/**
* @brief Set smoothness radius
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Larger values will make edges look less aliased (but blurry), smaller
* values will make them look more crisp (but possibly aliased). Initial
* value is `0.04f`.
*/
DistanceFieldVector* setSmoothness(Float value) {
DistanceFieldVector& setSmoothness(Float value) {
AbstractShaderProgram::setUniform(smoothnessUniform, value);
return this;
return *this;
}
private:

12
src/Shaders/Flat.h

@ -53,20 +53,20 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public Abstra
/**
* @brief Set transformation and projection matrix
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Flat<dimensions>* setTransformationProjectionMatrix(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) {
Flat<dimensions>& setTransformationProjectionMatrix(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) {
setUniform(transformationProjectionMatrixUniform, matrix);
return this;
return *this;
}
/**
* @brief Set color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Flat<dimensions>* setColor(const Color4& color) {
Flat<dimensions>& setColor(const Color4& color) {
setUniform(colorUniform, color);
return this;
return *this;
}
private:

38
src/Shaders/MeshVisualizer.h

@ -114,67 +114,67 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer: public AbstractShaderProgram {
/**
* @brief Set transformation and projection matrix
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
MeshVisualizer* setTransformationProjectionMatrix(const Matrix4& matrix) {
MeshVisualizer& setTransformationProjectionMatrix(const Matrix4& matrix) {
setUniform(transformationProjectionMatrixUniform, matrix);
return this;
return *this;
}
/**
* @brief Set viewport size
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Has effect only if @ref Flag "Flag::Wireframe" is enabled.
*/
MeshVisualizer* setViewportSize(const Vector2& size) {
MeshVisualizer& setViewportSize(const Vector2& size) {
setUniform(viewportSizeUniform, size);
return this;
return *this;
}
/**
* @brief Set base object color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Initial value is fully opaque white.
*/
MeshVisualizer* setColor(const Color4& color) {
MeshVisualizer& setColor(const Color4& color) {
setUniform(colorUniform, color);
return this;
return *this;
}
/**
* @brief Set wireframe color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Initial value is fully opaque black. Has effect only if
* @ref Flag "Flag::Wireframe" is enabled.
*/
MeshVisualizer* setWireframeColor(const Color4& color) {
MeshVisualizer& setWireframeColor(const Color4& color) {
if(flags & Flag::Wireframe) setUniform(wireframeColorUniform, color);
return this;
return *this;
}
/**
* @brief Set wireframe width
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Initial value is `1.0f`. Has effect only if
* @ref Flag "Flag::Wireframe" is enabled.
*/
MeshVisualizer* setWireframeWidth(Float width) {
MeshVisualizer& setWireframeWidth(Float width) {
if(flags & Flag::Wireframe) setUniform(wireframeWidthUniform, width);
return this;
return *this;
}
/**
* @brief Set line smoothness
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Initial value is `2.0f`. Has effect only if
* @ref Flag "Flag::Wireframe" is enabled.
*/
MeshVisualizer* setSmoothness(Float smoothness);
MeshVisualizer& setSmoothness(Float smoothness);
private:
Flags flags;
@ -188,10 +188,10 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizer: public AbstractShaderProgram {
CORRADE_ENUMSET_OPERATORS(MeshVisualizer::Flags)
inline MeshVisualizer* MeshVisualizer::setSmoothness(Float smoothness) {
inline MeshVisualizer& MeshVisualizer::setSmoothness(Float smoothness) {
if(flags & Flag::Wireframe)
setUniform(smoothnessUniform, smoothness);
return this;
return *this;
}
}}

60
src/Shaders/Phong.h

@ -119,87 +119,87 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
/**
* @brief Set ambient color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If not set, default value is `(0.0f, 0.0f, 0.0f)`. Has no effect if
* @ref Flag "Flag::AmbientTexture" is set.
*/
Phong* setAmbientColor(const Color3& color);
Phong& setAmbientColor(const Color3& color);
/**
* @brief Set diffuse color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Has no effect if @ref Flag "Flag::AmbientTexture" is used.
*/
Phong* setDiffuseColor(const Color3& color);
Phong& setDiffuseColor(const Color3& color);
/**
* @brief Set specular color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If not set, default value is `(1.0f, 1.0f, 1.0f)`. Has no effect if
* @ref Flag "Flag::SpecularTexture" is set.
*/
Phong* setSpecularColor(const Color3& color);
Phong& setSpecularColor(const Color3& color);
/**
* @brief Set shininess
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* The larger value, the harder surface (smaller specular highlight).
* If not set, default value is `80.0f`.
*/
Phong* setShininess(Float shininess) {
Phong& setShininess(Float shininess) {
setUniform(shininessUniform, shininess);
return this;
return *this;
}
/**
* @brief Set transformation matrix
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Phong* setTransformationMatrix(const Matrix4& matrix) {
Phong& setTransformationMatrix(const Matrix4& matrix) {
setUniform(transformationMatrixUniform, matrix);
return this;
return *this;
}
/**
* @brief Set normal matrix
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Phong* setNormalMatrix(const Math::Matrix<3, Float>& matrix) {
Phong& setNormalMatrix(const Math::Matrix<3, Float>& matrix) {
setUniform(normalMatrixUniform, matrix);
return this;
return *this;
}
/**
* @brief Set projection matrix
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Phong* setProjectionMatrix(const Matrix4& matrix) {
Phong& setProjectionMatrix(const Matrix4& matrix) {
setUniform(projectionMatrixUniform, matrix);
return this;
return *this;
}
/**
* @brief Set light position
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Phong* setLightPosition(const Vector3& light) {
Phong& setLightPosition(const Vector3& light) {
setUniform(lightUniform, light);
return this;
return *this;
}
/**
* @brief Set light color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If not set, default value is `(1.0f, 1.0f, 1.0f)`.
*/
Phong* setLightColor(const Color3& color) {
Phong& setLightColor(const Color3& color) {
setUniform(lightColorUniform, color);
return this;
return *this;
}
private:
@ -218,19 +218,19 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
CORRADE_ENUMSET_OPERATORS(Phong::Flags)
inline Phong* Phong::setAmbientColor(const Color3& color) {
inline Phong& Phong::setAmbientColor(const Color3& color) {
if(!(_flags & Flag::AmbientTexture)) setUniform(ambientColorUniform, color);
return this;
return *this;
}
inline Phong* Phong::setDiffuseColor(const Color3& color) {
inline Phong& Phong::setDiffuseColor(const Color3& color) {
if(!(_flags & Flag::DiffuseTexture)) setUniform(diffuseColorUniform, color);
return this;
return *this;
}
inline Phong* Phong::setSpecularColor(const Color3& color) {
inline Phong& Phong::setSpecularColor(const Color3& color) {
if(!(_flags & Flag::SpecularTexture)) setUniform(specularColorUniform, color);
return this;
return *this;
}
}}

12
src/Shaders/Vector.h

@ -49,20 +49,20 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Vector: public Abst
/**
* @brief Set transformation and projection matrix
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Vector* setTransformationProjectionMatrix(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) {
Vector& setTransformationProjectionMatrix(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) {
AbstractShaderProgram::setUniform(transformationProjectionMatrixUniform, matrix);
return this;
return *this;
}
/**
* @brief Set fill color
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*/
Vector* setColor(const Color4& color) {
Vector& setColor(const Color4& color) {
AbstractShaderProgram::setUniform(colorUniform, color);
return this;
return *this;
}
private:

6
src/Shaders/VertexColor.h

@ -56,13 +56,13 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColor: public
/**
* @brief Set transformation and projection matrix
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default is identity matrix.
*/
VertexColor<dimensions>* setTransformationProjectionMatrix(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) {
VertexColor<dimensions>& setTransformationProjectionMatrix(const typename DimensionTraits<dimensions, Float>::MatrixType& matrix) {
setUniform(transformationProjectionMatrixUniform, matrix);
return this;
return *this;
}
private:

8
src/Shapes/Shape.h

@ -92,11 +92,11 @@ template<class T> class Shape: public AbstractShape<T::Dimensions> {
/**
* @brief Set shape
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Marks the feature as dirty.
*/
Shape<T>* setShape(const T& shape);
Shape<T>& setShape(const T& shape);
/**
* @brief Transformed shape
@ -117,10 +117,10 @@ template<class T> class Shape: public AbstractShape<T::Dimensions> {
Implementation::Shape<T> _shape, _transformedShape;
};
template<class T> inline Shape<T>* Shape<T>::setShape(const T& shape) {
template<class T> inline Shape<T>& Shape<T>::setShape(const T& shape) {
Implementation::ShapeHelper<T>::set(*this, shape);
this->object()->setDirty();
return this;
return *this;
}
template<class T> inline const T& Shape<T>::transformedShape() {

6
src/Text/DistanceFieldGlyphCache.cpp

@ -75,9 +75,9 @@ void DistanceFieldGlyphCache::setImage(const Vector2i& offset, const ImageRefere
Texture2D input;
input.setWrapping(Sampler::Wrapping::ClampToEdge)
->setMinificationFilter(Sampler::Filter::Linear)
->setMagnificationFilter(Sampler::Filter::Linear)
->setImage(0, internalFormat, image);
.setMinificationFilter(Sampler::Filter::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
.setImage(0, internalFormat, image);
/* Create distance field from input texture */
TextureTools::distanceField(&input, texture(), Rectanglei::fromSize(offset*scale, image.size()*scale), radius, image.size());

6
src/Text/GlyphCache.cpp

@ -70,9 +70,9 @@ void GlyphCache::initialize(const Vector2i& size) {
void GlyphCache::initialize(const TextureFormat internalFormat, const Vector2i& size) {
/* Initialize texture */
_texture.setWrapping(Sampler::Wrapping::ClampToEdge)
->setMinificationFilter(Sampler::Filter::Linear)
->setMagnificationFilter(Sampler::Filter::Linear)
->setStorage(1, internalFormat, size);
.setMinificationFilter(Sampler::Filter::Linear)
.setMagnificationFilter(Sampler::Filter::Linear)
.setStorage(1, internalFormat, size);
/* Default "Not Found" glyph */
glyphs.insert({0, {}});

6
src/Text/TextRenderer.cpp

@ -187,8 +187,8 @@ std::tuple<Mesh, Rectangle> AbstractTextRenderer::render(AbstractFont* const fon
in subclass) */
Mesh mesh;
mesh.setPrimitive(Mesh::Primitive::Triangles)
->setIndexCount(indexCount)
->setIndexBuffer(indexBuffer, 0, indexType, 0, vertexCount);
.setIndexCount(indexCount)
.setIndexBuffer(indexBuffer, 0, indexType, 0, vertexCount);
delete layouter;
return std::make_tuple(std::move(mesh), rectangle);
@ -296,7 +296,7 @@ void AbstractTextRenderer::reserve(const uint32_t glyphCount, const Buffer::Usag
}
_indexBuffer.setData(indicesSize, nullptr, indexBufferUsage);
_mesh.setIndexCount(0)
->setIndexBuffer(&_indexBuffer, 0, indexType, 0, vertexCount);
.setIndexBuffer(&_indexBuffer, 0, indexType, 0, vertexCount);
/* Map buffer for filling */
void* const indices = bufferMapImplementation(_indexBuffer, indicesSize);

22
src/Text/TextRenderer.h

@ -170,10 +170,10 @@ The text can be then drawn by configuring text shader, binding font texture
and drawing the mesh:
@code
Text::AbstractFont* font;
Text::GlyphCache* cache;
Text::GlyphCache cache;
Shaders::VectorShader2D* shader;
Buffer *vertexBuffer, *indexBuffer;
Shaders::VectorShader2D shader;
Buffer vertexBuffer, indexBuffer;
Mesh mesh;
// Render the text
@ -182,9 +182,9 @@ std::tie(mesh, rectangle) = Text::TextRenderer2D::render(font, cache, 0.15f,
"Hello World!", vertexBuffer, indexBuffer, Buffer::Usage::StaticDraw);
// Draw white text centered on the screen
shader->setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f))
->setColor(Color3(1.0f));
->use();
shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f))
.setColor(Color3(1.0f));
.use();
glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer);
mesh.draw();
@endcode
@ -197,8 +197,8 @@ mutable texts (e.g. FPS counters, chat messages) there is another approach
that doesn't recreate everything on each text change:
@code
Text::AbstractFont* font;
Text::GlyphCache* cache;
Shaders::VectorShader2D* shader;
Text::GlyphCache cache;
Shaders::VectorShader2D shader;
// Initialize renderer and reserve memory for enough glyphs
Text::TextRenderer2D renderer(font, cache, 0.15f);
@ -208,9 +208,9 @@ renderer.reserve(32, Buffer::Usage::DynamicDraw, Buffer::Usage::StaticDraw);
renderer.render("Hello World Countdown: 10");
// Draw the text centered on the screen
shader->setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f))
->setColor(Color3(1.0f));
->use();
shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f))
.setColor(Color3(1.0f));
.use();
glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer);
renderer.mesh().draw();
@endcode

66
src/Texture.h

@ -50,12 +50,12 @@ Image2D image({4096, 4096}, ImageFormat::RGBA, ImageType::UnsignedByte, data);
Texture2D texture;
texture.setMagnificationFilter(Sampler::Filter::Linear)
->setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
->setWrapping(Sampler::Wrapping::ClampToEdge)
->setMaxAnisotropy(Sampler::maxSupportedAnisotropy())
->setStorage(Math::log2(4096)+1, TextureFormat::RGBA8, {4096, 4096})
->setSubImage(0, {}, &image)
->generateMipmap();
.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setWrapping(Sampler::Wrapping::ClampToEdge)
.setMaxAnisotropy(Sampler::maxSupportedAnisotropy())
.setStorage(Math::log2(4096)+1, TextureFormat::RGBA8, {4096, 4096})
.setSubImage(0, {}, &image)
.generateMipmap();
@endcode
@attention Don't forget to fully configure the texture before use. Note that
@ -84,7 +84,7 @@ array with 16 layers of 64x64 images:
Texture3D texture(Texture3D::Target::Texture2DArray);
texture.setMagnificationFilter(Sampler::Filter::Linear)
// ...
->setStorage(levels, TextureFormat::RGBA8, {64, 64,16});
.setStorage(levels, TextureFormat::RGBA8, {64, 64,16});
for(std::size_t i = 0; i != 16; ++i) {
void* data = ...;
@ -249,7 +249,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
/**
* @brief Set wrapping
* @param wrapping Wrapping type for all texture dimensions
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Sets wrapping type for coordinates out of range (0, 1) for normal
* textures and (0, textureSizeInGivenDirection-1) for rectangle
@ -264,9 +264,9 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* with @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T},
* @def_gl{TEXTURE_WRAP_R}
*/
Texture<Dimensions>* setWrapping(const Array<Dimensions, Sampler::Wrapping>& wrapping) {
Texture<Dimensions>& setWrapping(const Array<Dimensions, Sampler::Wrapping>& wrapping) {
DataHelper<Dimensions>::setWrapping(this, wrapping);
return this;
return *this;
}
/**
@ -274,7 +274,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @param levels Mip level count
* @param internalFormat Internal format
* @param size Size of largest mip level
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Specifies entire structure of a texture at once, removing the need
* for additional consistency checks and memory reallocations when
@ -296,9 +296,9 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}.
*/
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);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES
@ -347,7 +347,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @param level Mip level
* @param internalFormat Internal format
* @param image %Image
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* For better performance when generating mipmaps using
* generateMipmap() or calling setImage() more than once use
@ -361,16 +361,16 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureImage3D,EXT,direct_state_access}
*/
Texture<Dimensions>* setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions>& image) {
Texture<Dimensions>& setImage(Int level, TextureFormat internalFormat, const ImageReference<dimensions>& image) {
DataHelper<Dimensions>::setImage(this, _target, level, internalFormat, image);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
Texture<Dimensions>* setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>& image) {
Texture<Dimensions>& setImage(Int level, TextureFormat internalFormat, BufferImage<dimensions>& image) {
DataHelper<Dimensions>::setImage(this, _target, level, internalFormat, image);
return this;
return *this;
}
#endif
@ -379,7 +379,7 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image %Image
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the
* texture is bound to some layer before the operation.
@ -389,16 +389,16 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
* @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/
* @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access}
*/
Texture<Dimensions>* setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, const ImageReference<dimensions>& image) {
Texture<Dimensions>& setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, const ImageReference<dimensions>& image) {
DataHelper<Dimensions>::setSubImage(this, _target, level, offset, image);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES2
/** @overload */
Texture<Dimensions>* setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, BufferImage<dimensions>& image) {
Texture<Dimensions>& setSubImage(Int level, const typename DimensionTraits<Dimensions, Int>::VectorType& offset, BufferImage<dimensions>& image) {
DataHelper<Dimensions>::setSubImage(this, _target, level, offset, image);
return this;
return *this;
}
#endif
@ -418,27 +418,27 @@ template<UnsignedInt dimensions> class Texture: public AbstractTexture {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
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);
return this;
return *this;
}
Texture<Dimensions>* setMagnificationFilter(Sampler::Filter filter) {
Texture<Dimensions>& setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return this;
return *this;
}
#ifndef MAGNUM_TARGET_GLES3
Texture<Dimensions>* setBorderColor(const Color4& color) {
Texture<Dimensions>& setBorderColor(const Color4& color) {
AbstractTexture::setBorderColor(color);
return this;
return *this;
}
Texture<Dimensions>* setMaxAnisotropy(Float anisotropy) {
Texture<Dimensions>& setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return this;
return *this;
}
#endif
Texture<Dimensions>* generateMipmap() {
Texture<Dimensions>& generateMipmap() {
AbstractTexture::generateMipmap();
return this;
return *this;
}
#endif
};

18
src/TextureTools/DistanceField.cpp

@ -47,19 +47,19 @@ class DistanceFieldShader: public AbstractShaderProgram {
explicit DistanceFieldShader();
DistanceFieldShader* setRadius(Int radius) {
DistanceFieldShader& setRadius(Int radius) {
setUniform(radiusUniform, radius);
return this;
return *this;
}
DistanceFieldShader* setScaling(const Vector2& scaling) {
DistanceFieldShader& setScaling(const Vector2& scaling) {
setUniform(scalingUniform, scaling);
return this;
return *this;
}
DistanceFieldShader* setImageSizeInverted(const Vector2& size) {
DistanceFieldShader& setImageSizeInverted(const Vector2& size) {
setUniform(imageSizeInvertedUniform, size);
return this;
return *this;
}
private:
@ -158,8 +158,8 @@ void distanceField(Texture2D* input, Texture2D* output, const Rectanglei& rectan
DistanceFieldShader shader;
shader.setRadius(radius)
->setScaling(Vector2(imageSize)/rectangle.size())
->use();
.setScaling(Vector2(imageSize)/rectangle.size())
.use();
input->bind(DistanceFieldShader::TextureLayer);
@ -174,7 +174,7 @@ void distanceField(Texture2D* input, Texture2D* output, const Rectanglei& rectan
Mesh mesh;
mesh.setPrimitive(Mesh::Primitive::Triangles)
->setVertexCount(3);
.setVertexCount(3);
/* Older GLSL doesn't have gl_VertexID, vertices must be supplied explicitly */
Buffer buffer;

8
src/Timeline.h

@ -63,7 +63,7 @@ MyApplication::MyApplication(const Parameters& parameters): Platform::Applicatio
// Initialization ...
timeline.setMinimalFrameTime(1/120.0f) // 120 FPS at max
->start();
.start();
}
void MyApplication::drawEvent() {
@ -96,14 +96,14 @@ class MAGNUM_EXPORT Timeline {
/**
* @brief Set minimal frame time
* @return Pointer to self (for method chaining)
* @return Reference to self (for method chaining)
*
* Default value is 0.
* @see nextFrame()
*/
Timeline* setMinimalFrameTime(Float seconds) {
Timeline& setMinimalFrameTime(Float seconds) {
_minimalFrameTime = seconds;
return this;
return *this;
}
/**

Loading…
Cancel
Save