mirror of https://github.com/mosra/magnum.git
11 changed files with 602 additions and 300 deletions
@ -0,0 +1,209 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 |
||||
Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Magnum/Timeline.h" |
||||
#include "Magnum/GL/Buffer.h" |
||||
#include "Magnum/GL/Mesh.h" |
||||
#include "Magnum/GL/DefaultFramebuffer.h" |
||||
#include "Magnum/GL/Renderer.h" |
||||
#include "Magnum/Math/Color.h" |
||||
#include "Magnum/MeshTools/Compile.h" |
||||
#include "Magnum/Primitives/Cube.h" |
||||
#include "Magnum/Platform/Sdl2Application.h" |
||||
#include "Magnum/SceneGraph/AnimableGroup.h" |
||||
#include "Magnum/SceneGraph/Camera.h" |
||||
#include "Magnum/SceneGraph/Drawable.h" |
||||
#include "Magnum/SceneGraph/MatrixTransformation2D.h" |
||||
#include "Magnum/SceneGraph/MatrixTransformation3D.h" |
||||
#include "Magnum/SceneGraph/Object.h" |
||||
#include "Magnum/SceneGraph/Scene.h" |
||||
#include "Magnum/Shaders/Flat.h" |
||||
#include "Magnum/Shaders/Phong.h" |
||||
#include "Magnum/Trade/MeshData3D.h" |
||||
|
||||
using namespace Magnum; |
||||
using namespace Magnum::Math::Literals; |
||||
|
||||
struct MyApplication: Platform::Application { |
||||
explicit MyApplication(const Arguments& arguments); |
||||
|
||||
void drawEvent() override; |
||||
void mousePressEvent(MouseEvent& event) override; |
||||
|
||||
SceneGraph::AnimableGroup3D animables; |
||||
Timeline timeline; |
||||
SceneGraph::Object<SceneGraph::MatrixTransformation2D>* cameraObject{}; |
||||
SceneGraph::Camera2D camera{*cameraObject}; |
||||
}; |
||||
|
||||
/* [Animable-usage-timeline] */ |
||||
MyApplication::MyApplication(const Arguments& arguments): Platform::Application{arguments} { |
||||
// ...
|
||||
|
||||
timeline.start(); |
||||
} |
||||
|
||||
void MyApplication::drawEvent() { |
||||
animables.step(timeline.previousFrameTime(), timeline.previousFrameDuration()); |
||||
|
||||
// ...
|
||||
|
||||
timeline.nextFrame(); |
||||
} |
||||
/* [Animable-usage-timeline] */ |
||||
|
||||
void MyApplication::mousePressEvent(MouseEvent& event) { |
||||
/* [Camera-projectionSize] */ |
||||
Vector2 position = (Vector2{event.position()}/Vector2{GL::defaultFramebuffer.viewport().size()} |
||||
- Vector2{0.5f})*Vector2::yScale(-1.0f)*camera.projectionSize(); |
||||
/* [Camera-projectionSize] */ |
||||
|
||||
/* [Camera-projectionSize-absolute] */ |
||||
Vector2 absolutePosition = cameraObject->absoluteTransformation().transformPoint(position); |
||||
/* [Camera-projectionSize-absolute] */ |
||||
static_cast<void>(absolutePosition); |
||||
} |
||||
|
||||
/* [Drawable-usage] */ |
||||
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::cubeSolid(), GL::BufferUsage::StaticDraw); |
||||
} |
||||
|
||||
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})) |
||||
.setTransformationMatrix(transformationMatrix) |
||||
.setNormalMatrix(transformationMatrix.rotation()) |
||||
.setProjectionMatrix(camera.projectionMatrix()); |
||||
_mesh.draw(_shader); |
||||
} |
||||
|
||||
GL::Mesh _mesh; |
||||
std::unique_ptr<GL::Buffer> _vertices, _indices; |
||||
Shaders::Phong _shader; |
||||
}; |
||||
/* [Drawable-usage] */ |
||||
|
||||
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); |
||||
/* [Drawable-usage-shader] */ |
||||
} |
||||
|
||||
namespace A { |
||||
|
||||
struct MyApplication: Platform::Application { |
||||
explicit MyApplication(const Arguments& arguments); |
||||
|
||||
void drawEvent() override; |
||||
|
||||
Scene3D _scene; |
||||
SceneGraph::Object<SceneGraph::MatrixTransformation3D>* _cameraObject; |
||||
SceneGraph::Camera3D* _camera; |
||||
SceneGraph::DrawableGroup3D _drawables; |
||||
}; |
||||
|
||||
/* [Drawable-usage-camera] */ |
||||
MyApplication::MyApplication(const Arguments& arguments): Platform::Application{arguments} { |
||||
// ...
|
||||
|
||||
_cameraObject = new Object3D{&_scene}; |
||||
_cameraObject->translate(Vector3::zAxis(5.0f)); |
||||
_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(); |
||||
} |
||||
/* [Drawable-usage-camera] */ |
||||
|
||||
} |
||||
|
||||
namespace B { |
||||
|
||||
struct MyApplication: Platform::Application { |
||||
explicit MyApplication(const Arguments& arguments); |
||||
|
||||
void drawEvent() override; |
||||
|
||||
SceneGraph::Object<SceneGraph::MatrixTransformation2D>* _cameraObject; |
||||
SceneGraph::Camera3D* _camera; |
||||
Vector3 _lightPositionRelativeToCamera, _lightColor, _ambientColor; |
||||
/* [Drawable-multiple-groups] */ |
||||
// ...
|
||||
|
||||
Shaders::Phong _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); |
||||
|
||||
GL::Renderer::enable(GL::Renderer::Feature::Blending); |
||||
|
||||
/* Also here */ |
||||
_camera->draw(_transparentObjects); |
||||
|
||||
GL::Renderer::disable(GL::Renderer::Feature::Blending); |
||||
|
||||
// ...
|
||||
} |
||||
/* [Drawable-multiple-groups] */ |
||||
|
||||
} |
||||
|
||||
int main() { |
||||
/* [Drawable-usage-instance] */ |
||||
Scene3D scene; |
||||
SceneGraph::DrawableGroup3D drawables; |
||||
|
||||
(new RedCube(&scene, &drawables)) |
||||
->translate(Vector3::yAxis(-0.3f)) |
||||
.rotateX(30.0_degf); |
||||
|
||||
// ...
|
||||
/* [Drawable-usage-instance] */ |
||||
return 0; /* on iOS SDL redefines main to SDL_main and then return is needed */ |
||||
} |
||||
@ -0,0 +1,332 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 |
||||
Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Magnum/Math/Matrix4.h" |
||||
#include "Magnum/SceneGraph/Animable.h" |
||||
#include "Magnum/SceneGraph/AnimableGroup.h" |
||||
#include "Magnum/SceneGraph/AbstractGroupedFeature.h" |
||||
#include "Magnum/SceneGraph/AbstractTranslationRotation3D.h" |
||||
#include "Magnum/SceneGraph/MatrixTransformation2D.h" |
||||
#include "Magnum/SceneGraph/MatrixTransformation3D.h" |
||||
#include "Magnum/SceneGraph/Camera.h" |
||||
#include "Magnum/SceneGraph/Drawable.h" |
||||
#include "Magnum/SceneGraph/Object.h" |
||||
#include "Magnum/SceneGraph/Scene.h" |
||||
|
||||
using namespace Magnum; |
||||
using namespace Magnum::Math::Literals; |
||||
|
||||
/* [AbstractFeature-caching] */ |
||||
class CachingFeature: public SceneGraph::AbstractFeature3D { |
||||
public: |
||||
explicit CachingFeature(SceneGraph::AbstractObject3D& object): SceneGraph::AbstractFeature3D{object} { |
||||
setCachedTransformations(SceneGraph::CachedTransformation::Absolute); |
||||
} |
||||
|
||||
private: |
||||
void clean(const Matrix4& absoluteTransformationMatrix) override { |
||||
_absolutePosition = absoluteTransformationMatrix.translation(); |
||||
} |
||||
|
||||
Vector3 _absolutePosition; |
||||
}; |
||||
/* [AbstractFeature-caching] */ |
||||
|
||||
/* [AbstractFeature-object-transformation] */ |
||||
class TransformingFeature: public SceneGraph::AbstractFeature3D { |
||||
public: |
||||
template<class T> explicit TransformingFeature(SceneGraph::Object<T>& object): |
||||
SceneGraph::AbstractFeature3D{object}, _transformation{object} {} |
||||
|
||||
private: |
||||
SceneGraph::AbstractTranslationRotation3D& _transformation; |
||||
}; |
||||
/* [AbstractFeature-object-transformation] */ |
||||
|
||||
/* [AbstractGroupedFeature-subclassing] */ |
||||
class Drawable: public SceneGraph::AbstractGroupedFeature3D<Drawable> { |
||||
// ...
|
||||
}; |
||||
|
||||
typedef SceneGraph::FeatureGroup3D<Drawable> DrawableGroup; |
||||
/* [AbstractGroupedFeature-subclassing] */ |
||||
|
||||
/* [Animable-usage-definition] */ |
||||
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D; |
||||
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D; |
||||
|
||||
class AnimableObject: public Object3D, public SceneGraph::Animable3D { |
||||
public: |
||||
AnimableObject(Object3D* parent = nullptr, SceneGraph::AnimableGroup3D* group = nullptr): Object3D{parent}, SceneGraph::Animable3D{*this, group} { |
||||
setDuration(10.0f); |
||||
// ...
|
||||
} |
||||
|
||||
private: |
||||
void animationStep(Float, Float delta) override { |
||||
rotateX(15.0_degf*delta); // rotate at 15 degrees per second
|
||||
} |
||||
}; |
||||
/* [Animable-usage-definition] */ |
||||
|
||||
/* [typedef] */ |
||||
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D; |
||||
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D; |
||||
/* [typedef] */ |
||||
|
||||
/* [Object-typedef] */ |
||||
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D; |
||||
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D; |
||||
/* [Object-typedef] */ |
||||
|
||||
/* [feature-inherit] */ |
||||
class BouncingBall: public Object3D, SceneGraph::Drawable3D, SceneGraph::Animable3D { |
||||
public: |
||||
explicit BouncingBall(Object3D* parent): |
||||
Object3D{parent}, SceneGraph::Drawable3D{*this}, SceneGraph::Animable3D{*this} {} |
||||
|
||||
private: |
||||
// drawing implementation for Drawable feature
|
||||
void draw(const Matrix4&, SceneGraph::Camera3D&) override; |
||||
|
||||
// animation step for Animable feature
|
||||
void animationStep(Float, Float) override; |
||||
}; |
||||
/* [feature-inherit] */ |
||||
|
||||
/* [caching] */ |
||||
class CachingObject: public Object3D, SceneGraph::AbstractFeature3D { |
||||
public: |
||||
explicit CachingObject(Object3D* parent): Object3D{parent}, SceneGraph::AbstractFeature3D{*this} { |
||||
setCachedTransformations(SceneGraph::CachedTransformation::Absolute); |
||||
} |
||||
|
||||
protected: |
||||
void clean(const Matrix4& absoluteTransformation) override { |
||||
_absolutePosition = absoluteTransformation.translation(); |
||||
} |
||||
|
||||
private: |
||||
Vector3 _absolutePosition; |
||||
}; |
||||
/* [caching] */ |
||||
|
||||
namespace { |
||||
|
||||
/* [transformation] */ |
||||
class TransformingFeature: public SceneGraph::AbstractFeature3D { |
||||
public: |
||||
template<class T> explicit TransformingFeature(SceneGraph::Object<T>& object): |
||||
SceneGraph::AbstractFeature3D(object), _transformation(object) {} |
||||
|
||||
private: |
||||
SceneGraph::AbstractTranslationRotation3D& _transformation; |
||||
}; |
||||
/* [transformation] */ |
||||
|
||||
} |
||||
|
||||
int main() { |
||||
{ |
||||
/* [method-chaining] */ |
||||
Scene3D scene; |
||||
|
||||
Object3D object; |
||||
object.setParent(&scene) |
||||
.rotateY(15.0_degf) |
||||
.translate(Vector3::xAxis(5.0f)); |
||||
/* [method-chaining] */ |
||||
} |
||||
|
||||
{ |
||||
/* [hierarchy] */ |
||||
Scene3D scene; |
||||
|
||||
Object3D* first = new Object3D{&scene}; |
||||
Object3D* second = new Object3D{first}; |
||||
/* [hierarchy] */ |
||||
static_cast<void>(second); |
||||
} |
||||
|
||||
{ |
||||
/* [hierarchy-addChild] */ |
||||
Scene3D scene; |
||||
|
||||
Object3D& first = scene.addChild<Object3D>(); |
||||
Object3D& second = first.addChild<Object3D>(); |
||||
/* [hierarchy-addChild] */ |
||||
static_cast<void>(second); |
||||
} |
||||
|
||||
{ |
||||
struct MyFeature { |
||||
explicit MyFeature(SceneGraph::AbstractObject3D&, int, int) {} |
||||
}; |
||||
int some{}, params{}; |
||||
{ |
||||
/* [feature] */ |
||||
Object3D o; |
||||
new MyFeature{o, some, params}; |
||||
/* [feature] */ |
||||
} |
||||
|
||||
{ |
||||
/* [feature-addFeature] */ |
||||
Object3D o; |
||||
o.addFeature<MyFeature>(some, params); |
||||
/* [feature-addFeature] */ |
||||
} |
||||
} |
||||
|
||||
{ |
||||
/* [construction-order] */ |
||||
{ |
||||
Scene3D scene; |
||||
Object3D object(&scene); |
||||
} |
||||
/* [construction-order] */ |
||||
} |
||||
|
||||
{ |
||||
/* [construction-order-crash] */ |
||||
{ |
||||
Object3D object; |
||||
Scene3D scene; |
||||
|
||||
object.setParent(&scene); |
||||
} // crash!
|
||||
/* [construction-order-crash] */ |
||||
} |
||||
|
||||
{ |
||||
struct MyFeature { |
||||
explicit MyFeature(...) {} |
||||
}; |
||||
{ |
||||
/* [feature-construction-order] */ |
||||
class MyObject: public Object3D, MyFeature { |
||||
public: |
||||
MyObject(Object3D* parent): Object3D(parent), MyFeature{*this} {} |
||||
}; |
||||
/* [feature-construction-order] */ |
||||
} |
||||
{ |
||||
/* [feature-construction-order-crash] */ |
||||
class MyObject: MyFeature, public Object3D { |
||||
public: |
||||
MyObject(Object3D* parent): MyFeature{*this}, Object3D(parent) {} // crash!
|
||||
}; |
||||
/* [feature-construction-order-crash] */ |
||||
} |
||||
{ |
||||
#ifdef __GNUC__ |
||||
#pragma GCC diagnostic push |
||||
#pragma GCC diagnostic ignored "-Wreorder" |
||||
#endif |
||||
/* [feature-construction-order-crash-destruction] */ |
||||
class MyObject: MyFeature, public Object3D { |
||||
public: |
||||
MyObject(Object3D* parent): Object3D(parent), MyFeature(*this) {} |
||||
|
||||
// crash on destruction!
|
||||
}; |
||||
/* [feature-construction-order-crash-destruction] */ |
||||
} |
||||
#ifdef __GNUC__ |
||||
#pragma GCC diagnostic pop |
||||
#endif |
||||
} |
||||
|
||||
{ |
||||
SceneGraph::Object<SceneGraph::MatrixTransformation3D> object; |
||||
#ifdef __GNUC__ |
||||
#pragma GCC diagnostic push |
||||
#pragma GCC diagnostic ignored "-Wunused-variable" |
||||
#endif |
||||
/* [AbstractObject-features-range] */ |
||||
for(SceneGraph::AbstractFeature3D& feature: object.features()) { |
||||
// ...
|
||||
} |
||||
/* [AbstractObject-features-range] */ |
||||
|
||||
{ |
||||
/* [Object-children-range] */ |
||||
Object3D o; |
||||
for(Object3D& child: o.children()) { |
||||
// ...
|
||||
} |
||||
/* [Object-children-range] */ |
||||
} |
||||
#ifdef __GNUC__ |
||||
#pragma GCC diagnostic pop |
||||
#endif |
||||
|
||||
/* [AbstractObject-features] */ |
||||
for(SceneGraph::AbstractFeature3D* feature = object.features().first(); feature; feature = feature->nextFeature()) { |
||||
// ...
|
||||
} |
||||
/* [AbstractObject-features] */ |
||||
|
||||
{ |
||||
Object3D o; |
||||
/* [Object-children] */ |
||||
for(Object3D* child = o.children().first(); child; child = child->nextSibling()) { |
||||
// ...
|
||||
} |
||||
/* [Object-children] */ |
||||
} |
||||
|
||||
{ |
||||
/* [Animable-usage] */ |
||||
Scene3D scene; |
||||
SceneGraph::AnimableGroup3D animables; |
||||
|
||||
(new AnimableObject(&scene, &animables)) |
||||
->setState(SceneGraph::AnimationState::Running); |
||||
// ...
|
||||
/* [Animable-usage] */ |
||||
} |
||||
|
||||
{ |
||||
SceneGraph::Object<SceneGraph::MatrixTransformation2D> cameraObject; |
||||
/* [Camera-2D] */ |
||||
SceneGraph::Camera2D camera{cameraObject}; |
||||
camera.setProjectionMatrix(Matrix3::projection({4.0f/3.0f, 1.0f})) |
||||
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend); |
||||
/* [Camera-2D] */ |
||||
} |
||||
|
||||
{ |
||||
SceneGraph::Object<SceneGraph::MatrixTransformation3D> cameraObject; |
||||
/* [Camera-3D] */ |
||||
SceneGraph::Camera3D camera{cameraObject}; |
||||
camera.setProjectionMatrix(Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f)) |
||||
.setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend); |
||||
/* [Camera-3D] */ |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue