mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
2.9 KiB
67 lines
2.9 KiB
|
13 years ago
|
namespace Magnum {
|
||
|
|
/** @page method-chaining Method chaining
|
||
|
|
|
||
|
|
@brief Little feature helping to reduce typing and encourage best practices.
|
||
|
|
|
||
|
|
Method chaining ([Wikipedia](http://en.wikipedia.org/wiki/Method_chaining)) is a
|
||
|
|
feature which allows you to chain method calls one after another without
|
||
|
|
repeatedly specifying variable the method is called on. Its primary goal is to
|
||
|
|
reduce unnecessary repeated names, improving code readability.
|
||
|
|
|
||
|
|
%Magnum uses this feature for configuring OpenGL objects (such as various mesh
|
||
|
|
and framebuffer options, shader uniforms etc.). Because OpenGL was designed with
|
||
|
|
"bind-to-modify" approach, most configuration calls need to bind the object
|
||
|
|
first and only after that change the parameters (unless @extension{EXT,direct_state_access}
|
||
|
|
extension is available to avoid this). To reduce unneeded bind calls, %Magnum
|
||
|
|
binds the object only if it is not already 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;
|
||
|
|
|
||
|
|
carDiffuseTexture->setStorage(5, Texture2D::InternalFormat::SRGB8);
|
||
|
|
carSpecularTexture->setStorage(3, Texture2D::InternalFormat::R8);
|
||
|
|
carBumpTexture->setStorage(5, Texture2D::InternalFormat::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,
|
||
|
|
which might be good when somebody needs to change something for all three
|
||
|
|
textures at once, but on the other hand the code is cluttered with repeated
|
||
|
|
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, Texture2D::InternalFormat::SRGB8)
|
||
|
|
->setSubImage(0, {}, diffuse)
|
||
|
|
->generateMipmap();
|
||
|
|
carSpecularTexture->setStorage(3, Texture2D::InternalFormat::R8)
|
||
|
|
->setSubImage(0, {}, diffuse)
|
||
|
|
->generateMipmap();
|
||
|
|
carBumpTexture->setStorage(5, Texture2D::InternalFormat::RGB8)
|
||
|
|
->setSubImage(0, {}, bump)
|
||
|
|
->generateMipmap();
|
||
|
|
@endcode
|
||
|
|
|
||
|
|
Method chaining is not used on non-configuring functions, such as Framebuffer::clear()
|
||
|
|
or Mesh::draw(), as these won't be commonly used in conjunction with other
|
||
|
|
functions anyway.
|
||
|
|
|
||
|
|
Method chaining is also used in SceneGraph and other libraries and in some cases
|
||
|
|
it allows you to just "configure and forget" without even saving the created
|
||
|
|
object to some variable, for example when adding static object to an scene:
|
||
|
|
@code
|
||
|
|
Scene3D scene;
|
||
|
|
|
||
|
|
(new MyObject(&scene))
|
||
|
|
->rotateX(90.0_degf)
|
||
|
|
->translate({-1.5f, 0.5f, 7.0f});
|
||
|
|
@endcode
|
||
|
|
*/
|
||
|
|
}
|