Browse Source

SceneGraph: show both single and multiple inheritance in Drawable docs.

pull/272/head
Vladimír Vondruš 8 years ago
parent
commit
b255f31ca4
  1. 48
      doc/snippets/MagnumSceneGraph-gl.cpp
  2. 55
      src/Magnum/SceneGraph/Drawable.h

48
doc/snippets/MagnumSceneGraph-gl.cpp

@ -90,18 +90,23 @@ static_cast<void>(absolutePosition);
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
class RedCube: public Object3D, public SceneGraph::Drawable3D {
class RedCubeDrawable: public SceneGraph::Drawable3D {
public:
explicit RedCube(Object3D* parent, SceneGraph::DrawableGroup3D* group): Object3D{parent}, SceneGraph::Drawable3D{*this, group} {
explicit RedCubeDrawable(Object3D& object, SceneGraph::DrawableGroup3D* group):
SceneGraph::Drawable3D{object, group}
{
_mesh = MeshTools::compile(Primitives::cubeSolid());
}
private:
void draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) override {
_shader.setDiffuseColor(Color3::fromHsv(216.0_degf, 0.85f, 1.0f))
.setLightPosition(camera.cameraMatrix().transformPoint({5.0f, 5.0f, 7.0f}))
using namespace Math::Literals;
_shader.setDiffuseColor(0xa5c9ea_rgbf)
.setLightPosition(camera.cameraMatrix().transformPoint(
{5.0f, 5.0f, 7.0f}))
.setTransformationMatrix(transformationMatrix)
.setNormalMatrix(transformationMatrix.rotation())
.setNormalMatrix(transformationMatrix.rotationScaling())
.setProjectionMatrix(camera.projectionMatrix());
_mesh.draw(_shader);
}
@ -111,11 +116,29 @@ class RedCube: public Object3D, public SceneGraph::Drawable3D {
};
/* [Drawable-usage] */
/* [Drawable-usage-multiple-inheritance] */
class RedCube: public Object3D, public SceneGraph::Drawable3D {
public:
explicit RedCube(Object3D* parent, SceneGraph::DrawableGroup3D* group):
Object3D{parent}, SceneGraph::Drawable3D{*this, group}
{
_mesh = MeshTools::compile(Primitives::cubeSolid());
}
private:
void draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) override;
GL::Mesh _mesh;
Shaders::Phong _shader;
};
/* [Drawable-usage-multiple-inheritance] */
void draw(const Matrix4&, SceneGraph::Camera3D&);
void draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) {
/* [Drawable-usage-shader] */
Shaders::Flat3D shader;
shader.setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix);
shader.setTransformationProjectionMatrix(
camera.projectionMatrix()*transformationMatrix);
/* [Drawable-usage-shader] */
}
@ -198,11 +221,20 @@ int main() {
Scene3D scene;
SceneGraph::DrawableGroup3D drawables;
(new RedCube(&scene, &drawables))
->translate(Vector3::yAxis(-0.3f))
Object3D* redCube = new Object3D{&scene};
(*redCube)
.translate(Vector3::yAxis(-0.3f))
.rotateX(30.0_degf);
new RedCubeDrawable{*redCube, &drawables};
// ...
/* [Drawable-usage-instance] */
/* [Drawable-usage-instance-multiple-inheritance] */
(new RedCube(&scene, &drawables))
->translate(Vector3::yAxis(-0.3f))
.rotateX(30.0_degf);
/* [Drawable-usage-instance-multiple-inheritance] */
return 0; /* on iOS SDL redefines main to SDL_main and then return is needed */
}

55
src/Magnum/SceneGraph/Drawable.h

@ -40,42 +40,67 @@ Adds drawing functionality to the object. Each Drawable is part of some
@ref DrawableGroup and the whole group can be drawn with particular camera
using @ref Camera::draw().
@section SceneGraph-Drawable-usage Usage
@section SceneGraph-Drawable-subclassing Subclassing
First thing is to add @ref Drawable feature to some object and implement
@ref draw() function. You can do it conveniently using multiple inheritance
(see @ref scenegraph-features for introduction). Example drawable object that
draws blue sphere:
The class is used via subclassing and implementing the @ref draw() function.
The simplest option is to do it via single inheritance. Example drawable object
that draws a blue sphere:
@snippet MagnumSceneGraph-gl.cpp Drawable-usage
The @p transformationMatrix parameter in @ref draw() function contains
For brevity the class has its own shader and mesh instance and a hardcoded
light position, usually you'll have them stored in a central location, shared
by multiple objects, and pass only references around.
The @p transformationMatrix parameter in the @ref draw() function contains
transformation of the object (to which the drawable is attached) relative to
@p camera. The camera contains projection matrix. Some shaders (like the
@ref Shaders::Phong used in the example) have separate functions for setting
@p camera. The camera contains the projection matrix. Some shaders (like the
@ref Shaders::Phong used in the snippet) have separate functions for setting
transformation and projection matrix, but some (such as @ref Shaders::Flat)
have single function to set composite transformation and projection matrix. In
that case you need to combine the two matrices manually like in the following
code. Some shaders have additional requirements for various transformation
matrices, see their respective documentation for details.
have a single function to set composite transformation and projection matrix.
In that case you need to combine the two matrices manually like in the
following code. Some shaders might have additional requirements, see their
respective documentation for details.
@snippet MagnumSceneGraph-gl.cpp Drawable-usage-shader
@subsection SceneGraph-Drawable-usage Drawing the scene
There is no way to just draw all the drawables in the scene, you need to create
some drawable group and add the drawable objects to both the scene and the
group. You can also use @ref DrawableGroup::add() and
@ref DrawableGroup::remove() instead of passing the group in the constructor.
If you don't need to change any properties of the drawable later, you can just
"create and forget", the scene graph will take care of all memory manager from
there.
@snippet MagnumSceneGraph-gl.cpp Drawable-usage-instance
The last thing you need is camera attached to some object (thus using its
transformation). Using the camera and the drawable group you can perform
drawing in your @ref Platform::Sdl2Application::drawEvent() "drawEvent()"
The last thing you need is a camera attached to some object (thus using its
transformation). With the camera and the drawable group you can perform drawing
in your @ref Platform::Sdl2Application::drawEvent() "drawEvent()"
implementation. See @ref Camera2D and @ref Camera3D documentation for more
information.
@snippet MagnumSceneGraph-gl.cpp Drawable-usage-camera
@section SceneGraph-Drawable-multiple-inheritance Using multiple inheritance
Besides single inheritance, it's also possible to derive your class from both
@ref Object and @ref Drawable. This for example allows you to directly access
object transformation and parent/child relationship from within the drawable
object.
@snippet MagnumSceneGraph-gl.cpp Drawable-usage-multiple-inheritance
The @ref draw() implementation is the same as in the above snippet. Note that,
in contrast to the single inheritance case, where the @ref Drawable constructor
got the holder @cpp object @ce, here we pass it @cpp *this @ce, because this
class is both the holder object and the drawable. Instantiating the drawable
object is then done in a single step:
@snippet MagnumSceneGraph-gl.cpp Drawable-usage-instance-multiple-inheritance
@section SceneGraph-Drawable-multiple-groups Using multiple drawable groups to improve performance
You can organize your drawables to multiple groups to minimize OpenGL state

Loading…
Cancel
Save