template<UnsignedInt dimensions, class T>
Drawable class
Drawable.
Contents
Adds drawing functionality to the object. Each Drawable is part of some DrawableGroup and the whole group can be drawn with particular camera using Camera::
Usage
First thing is to add Drawable feature to some object and implement draw() function. You can do it conveniently using multiple inheritance (see Object features for introduction). Example drawable object that draws blue sphere:
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D; typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D; class RedCube: public Object3D, public SceneGraph::Drawable3D { public: explicit RedCube(Object3D* parent, SceneGraph::DrawableGroup3D* group): Object3D{parent}, SceneGraph::Drawable3D{*this, group} { std::tie(_mesh, _vertices, _indices) = MeshTools::compile(Primitives::UVSphere::solid(16, 32), BufferUsage::StaticDraw); } private: void draw(const Matrix4& transformationMatrix, Camera3D& camera) override { _shader.setDiffuseColor(Color3::fromHSV(216.0_degf, 0.85f, 1.0f)) .setLightPosition(camera.cameraMatrix().transformPoint({5.0f, 5.0f, 7.0f})) .setTransformationMatrix(transformationMatrix) .setNormalMatrix(transformationMatrix.rotation()) .setProjectionMatrix(camera.projectionMatrix()); _mesh.draw(_shader); } Mesh _mesh; std::unique_ptr<Buffer> _vertices, _indices; Shaders::Phong _shader; }
The transformationMatrix
parameter in draw() function contains transformation of the object (to which the drawable is attached) relative to camera
. The camera contains projection matrix. Some shaders (like the Shaders::
Shaders::Flat3D shader; shader.setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix);
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 DrawableGroup::
Scene3D scene; SceneGraph::DrawableGroup3D drawables; (new RedCube(&scene, &drawables)) ->translate(Vector3::yAxis(-0.3f)) .rotateX(30.0_degf); // ...
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 drawEvent() implementation. See Camera2D and Camera3D documentation for more information.
auto cameraObject = new Object3D(&scene); cameraObject->translate(Vector3::zAxis(5.0f)); auto camera = new SceneGraph::Camera3D(&cameraObject); camera->setProjectionMatrix(Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f)); // ... void MyApplication::drawEvent() { camera->draw(drawables); // ... swapBuffers(); }
Using multiple drawable groups to improve performance
You can organize your drawables to multiple groups to minimize OpenGL state changes — for example put all objects using the same shader, the same light 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:
Shaders::PhongShader shader; SceneGraph::DrawableGroup3D phongObjects, transparentObjects; void MyApplication::drawEvent() { shader.setProjectionMatrix(camera->projectionMatrix()) .setLightPosition(lightPositionRelativeToCamera) .setLightColor(lightColor) .setAmbientColor(ambientColor); // Each drawable sets only unique properties such as transformation matrix // and diffuse color camera.draw(phongObjects); Renderer::enable(Renderer::Feature::Blending); // Also here camera.draw(transparentObjects); Renderer::disable(Renderer::Feature::Blending); // ... }
Explicit template specializations
The following specializations are explicitly compiled into SceneGraph library. For other specializations (e.g. using Double type) you have to use Drawable.hpp implementation file to avoid linker errors. See also Template headers and implementation files for more information.
Base classes
-
template<UnsignedInt dimensions, class Derived, class T>class AbstractGroupedFeature
- Base for grouped features.
Constructors, destructors, conversion operators
- Drawable(AbstractObject<dimensions, T>& object, DrawableGroup<dimensions, T>* drawables = nullptr) explicit
- Constructor.
Public functions
- auto drawables() -> DrawableGroup<dimensions, T>*
- Group containing this drawable.
- auto drawables() const -> const DrawableGroup<dimensions, T>*
- void draw(const MatrixTypeFor<dimensions, T>& transformationMatrix, Camera<dimensions, T>& camera) pure virtual
- Draw the object using given camera.
Function documentation
template<UnsignedInt dimensions, class T>
Magnum:: SceneGraph:: Drawable<dimensions, T>:: Drawable(AbstractObject<dimensions, T>& object,
DrawableGroup<dimensions, T>* drawables = nullptr) explicit
Constructor.
Parameters | |
---|---|
object | Object this drawable belongs to |
drawables | Group this drawable belongs to |
Adds the feature to the object and also to the group, if specified. Otherwise you can use DrawableGroup::
template<UnsignedInt dimensions, class T>
DrawableGroup<dimensions, T>* Magnum:: SceneGraph:: Drawable<dimensions, T>:: drawables()
Group containing this drawable.
If the drawable doesn't belong to any group, returns nullptr
.
template<UnsignedInt dimensions, class T>
const DrawableGroup<dimensions, T>* Magnum:: SceneGraph:: Drawable<dimensions, T>:: drawables() const
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
template<UnsignedInt dimensions, class T>
void Magnum:: SceneGraph:: Drawable<dimensions, T>:: draw(const MatrixTypeFor<dimensions, T>& transformationMatrix,
Camera<dimensions, T>& camera) pure virtual
Draw the object using given camera.
Parameters | |
---|---|
transformationMatrix | Object transformation relative to camera |
camera | Camera |
Projection matrix can be retrieved from Camera::