diff --git a/src/Extensions.h b/src/Extensions.h index a99f9d569..472b45a91 100644 --- a/src/Extensions.h +++ b/src/Extensions.h @@ -51,6 +51,7 @@ namespace Extensions { namespace GL { #line 1 namespace AMD { + _extension(GL,AMD,vertex_shader_layer, GL210, None) // #417 _extension(GL,AMD,shader_trinary_minmax, GL210, None) // #428 } namespace APPLE { _extension(GL,APPLE,flush_buffer_range, GL210, GL300) // #321 diff --git a/src/Physics/CMakeLists.txt b/src/Physics/CMakeLists.txt index e3eec9146..f577e1594 100644 --- a/src/Physics/CMakeLists.txt +++ b/src/Physics/CMakeLists.txt @@ -12,7 +12,9 @@ set(MagnumPhysics_SRCS ShapeGroup.cpp Sphere.cpp + Implementation/AbstractBoxRenderer.cpp Implementation/AbstractDebugRenderer.cpp + Implementation/AxisAlignedBoxRenderer.cpp Implementation/BoxRenderer.cpp) set(MagnumPhysics_HEADERS diff --git a/src/Physics/DebugDrawResourceManager.cpp b/src/Physics/DebugDrawResourceManager.cpp index c2f35c2f3..8e958bc57 100644 --- a/src/Physics/DebugDrawResourceManager.cpp +++ b/src/Physics/DebugDrawResourceManager.cpp @@ -13,6 +13,8 @@ GNU Lesser General Public License version 3 for more details. */ +#define MAGNUM_RESOURCEMANAGER_DEFINE_INTERNALINSTANCE + #include "DebugDrawResourceManager.h" #include "AbstractShaderProgram.h" @@ -21,9 +23,11 @@ #include "ResourceManager.h" #include "Shaders/FlatShader.h" #include "AbstractShape.h" +#include "AxisAlignedBox.h" #include "Box.h" #include "ObjectShape.h" #include "ShapeGroup.h" +#include "Implementation/AxisAlignedBoxRenderer.h" #include "Implementation/BoxRenderer.h" #include "Implementation/DebugRenderer.h" @@ -39,11 +43,13 @@ template SceneGraph::Drawable* DebugDrawRes return renderer; } -template SceneGraph::Drawable<2>* DebugDrawResourceManager::createDebugRenderer(ObjectShape<2>* shape, ResourceKey options); -template SceneGraph::Drawable<3>* DebugDrawResourceManager::createDebugRenderer(ObjectShape<3>* shape, ResourceKey options); +template SceneGraph::Drawable<2> PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<2>* shape, ResourceKey options); +template SceneGraph::Drawable<3> PHYSICS_EXPORT * DebugDrawResourceManager::createDebugRenderer(ObjectShape<3>* shape, ResourceKey options); void DebugDrawResourceManager::createDebugMesh(Implementation::DebugRenderer<2>* renderer, AbstractShape2D* shape) { switch(shape->type()) { + case AbstractShape2D::Type::AxisAlignedBox: + renderer->addRenderer(new Implementation::AxisAlignedBoxRenderer<2>(*static_cast(shape))); case AbstractShape2D::Type::Box: renderer->addRenderer(new Implementation::BoxRenderer<2>(*static_cast(shape))); break; diff --git a/src/Physics/DebugDrawResourceManager.h b/src/Physics/DebugDrawResourceManager.h index 618b594eb..c8253dfbf 100644 --- a/src/Physics/DebugDrawResourceManager.h +++ b/src/Physics/DebugDrawResourceManager.h @@ -21,7 +21,12 @@ #include "Magnum.h" #include "Color.h" + +#ifndef MAGNUM_RESOURCEMANAGER_DEFINE_INTERNALINSTANCE +#define MAGNUM_RESOURCEMANAGER_DONT_DEFINE_INTERNALINSTANCE +#endif #include "ResourceManager.h" + #include "SceneGraph/SceneGraph.h" #include "magnumPhysicsVisibility.h" @@ -41,6 +46,8 @@ namespace Physics { namespace Implementation { }} #endif +extern template ResourceManager PHYSICS_EXPORT *& ResourceManager::internalInstance(); + namespace Physics { template class AbstractShape; diff --git a/src/Physics/Implementation/AbstractBoxRenderer.cpp b/src/Physics/Implementation/AbstractBoxRenderer.cpp new file mode 100644 index 000000000..95e7cdaeb --- /dev/null +++ b/src/Physics/Implementation/AbstractBoxRenderer.cpp @@ -0,0 +1,70 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "AbstractBoxRenderer.h" + +#include "Buffer.h" +#include "Physics/DebugDrawResourceManager.h" +#include "Primitives/Cube.h" +#include "Primitives/Square.h" +#include "Shaders/FlatShader.h" + +namespace Magnum { namespace Physics { namespace Implementation { + +namespace { + template struct BoxMesh {}; + + template<> struct BoxMesh<2> { + static ResourceKey shader() { return {"shader2d"}; } + static ResourceKey key() { return {"box2d"}; } + + static Mesh* mesh(Buffer* buffer) { + Primitives::Square square; + Mesh* mesh = new Mesh; + buffer->setData(*square.positions(0), Buffer::Usage::StaticDraw); + return mesh->setPrimitive(square.primitive()) + ->setVertexCount(square.positions(0)->size()) + ->addVertexBuffer(buffer, Shaders::FlatShader<2>::Position()); + } + }; + + template<> struct BoxMesh<3> { + static ResourceKey shader() { return {"shader3d"}; } + static ResourceKey key() { return {"box3d"}; } + + static Mesh* mesh(Buffer* buffer) { + Primitives::Cube cube; + Mesh* mesh = new Mesh; + buffer->setData(*cube.positions(0), Buffer::Usage::StaticDraw); + return mesh->setPrimitive(cube.primitive()) + ->setVertexCount(cube.positions(0)->size()) + ->addVertexBuffer(buffer, Shaders::FlatShader<2>::Position()); + } + }; +} + +template AbstractBoxRenderer::AbstractBoxRenderer(): AbstractDebugRenderer(BoxMesh::shader(), BoxMesh::key()), buffer(DebugDrawResourceManager::instance()->get(BoxMesh::key())) { + if(!this->mesh) { + DebugDrawResourceManager::instance()->set(this->buffer.key(), new Buffer, ResourceDataState::Final, ResourcePolicy::Manual); + DebugDrawResourceManager::instance()->set(this->mesh.key(), BoxMesh::mesh(buffer), ResourceDataState::Final, ResourcePolicy::Manual); + } +} + +template AbstractBoxRenderer::~AbstractBoxRenderer() {} + +template class AbstractBoxRenderer<2>; +template class AbstractBoxRenderer<3>; + +}}} diff --git a/src/Physics/Implementation/AbstractBoxRenderer.h b/src/Physics/Implementation/AbstractBoxRenderer.h new file mode 100644 index 000000000..87c57687e --- /dev/null +++ b/src/Physics/Implementation/AbstractBoxRenderer.h @@ -0,0 +1,40 @@ +#ifndef Magnum_Physics_Implementation_AbstractBoxRenderer_h +#define Magnum_Physics_Implementation_AbstractBoxRenderer_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "AbstractDebugRenderer.h" + +#include "magnumCompatibility.h" + +namespace Magnum { + +class Buffer; + +namespace Physics { namespace Implementation { + +template class AbstractBoxRenderer: public AbstractDebugRenderer { + public: + AbstractBoxRenderer(); + + ~AbstractBoxRenderer(); + + protected: + Resource buffer; +}; + +}}} + +#endif diff --git a/src/Physics/Implementation/AbstractShapeRenderer.cpp b/src/Physics/Implementation/AbstractShapeRenderer.cpp new file mode 100644 index 000000000..ee4d3596e --- /dev/null +++ b/src/Physics/Implementation/AbstractShapeRenderer.cpp @@ -0,0 +1,32 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "AbstractShapeRenderer.h" + +#include "AbstractShaderProgram.h" +#include "Mesh.h" +#include "Physics/DebugDrawResourceManager.h" +#include "Shaders/FlatShader.h" + +namespace Magnum { namespace Physics { namespace Implementation { + +template AbstractShapeRenderer::AbstractShapeRenderer(ResourceKey shader, ResourceKey mesh): shader(DebugDrawResourceManager::instance()->get>(shader)), mesh(DebugDrawResourceManager::instance()->get(mesh)) {} + +template AbstractShapeRenderer::~AbstractShapeRenderer() {} + +template class AbstractShapeRenderer<2>; +template class AbstractShapeRenderer<3>; + +}}} diff --git a/src/Physics/Implementation/AbstractShapeRenderer.h b/src/Physics/Implementation/AbstractShapeRenderer.h new file mode 100644 index 000000000..276d53ba2 --- /dev/null +++ b/src/Physics/Implementation/AbstractShapeRenderer.h @@ -0,0 +1,50 @@ +#ifndef Magnum_Physics_Implementation_AbstractShapeRenderer_h +#define Magnum_Physics_Implementation_AbstractShapeRenderer_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "DimensionTraits.h" +#include "ResourceManager.h" +#include "SceneGraph/SceneGraph.h" + +namespace Magnum { + +class AbstractShaderProgram; +class Mesh; + +namespace Shaders { + template class FlatShader; +} + +namespace Physics { namespace Implementation { + +struct Options; + +template class AbstractShapeRenderer { + public: + AbstractShapeRenderer(ResourceKey shader, ResourceKey mesh); + + virtual ~AbstractShapeRenderer(); + + virtual void draw(Resource& options, const typename DimensionTraits::MatrixType& transformationMatrix, SceneGraph::AbstractCamera* camera) = 0; + + protected: + Resource> shader; + Resource mesh; +}; + +}}} + +#endif diff --git a/src/Physics/Implementation/AxisAlignedBoxRenderer.cpp b/src/Physics/Implementation/AxisAlignedBoxRenderer.cpp new file mode 100644 index 000000000..57e701116 --- /dev/null +++ b/src/Physics/Implementation/AxisAlignedBoxRenderer.cpp @@ -0,0 +1,38 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "AxisAlignedBoxRenderer.h" + +#include "Mesh.h" +#include "Physics/DebugDrawResourceManager.h" +#include "SceneGraph/AbstractCamera.h" +#include "Shaders/FlatShader.h" + +namespace Magnum { namespace Physics { namespace Implementation { + +template void AxisAlignedBoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractCamera* camera) { + typename DimensionTraits::MatrixType transformation = + DimensionTraits::MatrixType::translation(axisAlignedBox.transformedPosition())* + DimensionTraits::MatrixType::scaling(axisAlignedBox.transformedSize()); + this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*transformation) + ->setColor(options->color) + ->use(); + this->mesh->draw(); +} + +template class AxisAlignedBoxRenderer<2>; +template class AxisAlignedBoxRenderer<3>; + +}}} diff --git a/src/Physics/Implementation/AxisAlignedBoxRenderer.h b/src/Physics/Implementation/AxisAlignedBoxRenderer.h new file mode 100644 index 000000000..5ee7062ec --- /dev/null +++ b/src/Physics/Implementation/AxisAlignedBoxRenderer.h @@ -0,0 +1,38 @@ +#ifndef Magnum_Physics_Implementation_AxisAlignedBoxRenderer_h +#define Magnum_Physics_Implementation_AxisAlignedBoxRenderer_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "AbstractBoxRenderer.h" + +#include "Physics/AxisAlignedBox.h" + +#include "magnumCompatibility.h" + +namespace Magnum { namespace Physics { namespace Implementation { + +template class AxisAlignedBoxRenderer: public AbstractBoxRenderer { + public: + inline AxisAlignedBoxRenderer(AxisAlignedBox& axisAlignedBox): axisAlignedBox(axisAlignedBox) {} + + void draw(Resource& options, const typename DimensionTraits::MatrixType& transformation, typename SceneGraph::AbstractCamera* camera) override; + + private: + AxisAlignedBox& axisAlignedBox; +}; + +}}} + +#endif diff --git a/src/Physics/Implementation/BoxRenderer.cpp b/src/Physics/Implementation/BoxRenderer.cpp index a6cc9d4ca..1624e7aa3 100644 --- a/src/Physics/Implementation/BoxRenderer.cpp +++ b/src/Physics/Implementation/BoxRenderer.cpp @@ -15,55 +15,13 @@ #include "BoxRenderer.h" -#include "Buffer.h" -#include "Physics/Box.h" +#include "Mesh.h" #include "Physics/DebugDrawResourceManager.h" -#include "Primitives/Cube.h" -#include "Primitives/Square.h" #include "SceneGraph/AbstractCamera.h" #include "Shaders/FlatShader.h" namespace Magnum { namespace Physics { namespace Implementation { -namespace { - template struct BoxMesh {}; - - template<> struct BoxMesh<2> { - static ResourceKey shader() { return {"shader2d"}; } - static ResourceKey key() { return {"box2d"}; } - - static Mesh* mesh(Buffer* buffer) { - Primitives::Square square; - Mesh* mesh = new Mesh; - buffer->setData(*square.positions(0), Buffer::Usage::StaticDraw); - return mesh->setPrimitive(square.primitive()) - ->setVertexCount(square.positions(0)->size()) - ->addVertexBuffer(buffer, Shaders::FlatShader<2>::Position()); - } - }; - - template<> struct BoxMesh<3> { - static ResourceKey shader() { return {"shader3d"}; } - static ResourceKey key() { return {"box3d"}; } - - static Mesh* mesh(Buffer* buffer) { - Primitives::Cube cube; - Mesh* mesh = new Mesh; - buffer->setData(*cube.positions(0), Buffer::Usage::StaticDraw); - return mesh->setPrimitive(cube.primitive()) - ->setVertexCount(cube.positions(0)->size()) - ->addVertexBuffer(buffer, Shaders::FlatShader<2>::Position()); - } - }; -} - -template BoxRenderer::BoxRenderer(Box& box): AbstractDebugRenderer(BoxMesh::shader(), BoxMesh::key()), buffer(DebugDrawResourceManager::instance()->get(BoxMesh::key())), box(box) { - if(!this->mesh) { - DebugDrawResourceManager::instance()->set(this->buffer.key(), new Buffer, ResourceDataState::Final, ResourcePolicy::Manual); - DebugDrawResourceManager::instance()->set(this->mesh.key(), BoxMesh::mesh(buffer), ResourceDataState::Final, ResourcePolicy::Manual); - } -} - template void BoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractCamera* camera) { this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation()) ->setColor(options->color) diff --git a/src/Physics/Implementation/BoxRenderer.h b/src/Physics/Implementation/BoxRenderer.h index d563c7c63..c1e248478 100644 --- a/src/Physics/Implementation/BoxRenderer.h +++ b/src/Physics/Implementation/BoxRenderer.h @@ -15,28 +15,21 @@ GNU Lesser General Public License version 3 for more details. */ -#include "AbstractDebugRenderer.h" +#include "AbstractBoxRenderer.h" -#include "magnumCompatibility.h" - -namespace Magnum { - -class Buffer; +#include "Physics/Box.h" -namespace Physics { - -template class Box; +#include "magnumCompatibility.h" -namespace Implementation { +namespace Magnum { namespace Physics { namespace Implementation { -template class BoxRenderer: public AbstractDebugRenderer { +template class BoxRenderer: public AbstractBoxRenderer { public: - BoxRenderer(Box& box); + inline BoxRenderer(Box& box): box(box) {} void draw(Resource& options, const typename DimensionTraits::MatrixType& transformation, typename SceneGraph::AbstractCamera* camera) override; private: - Resource buffer; Box& box; }; diff --git a/src/ResourceManager.h b/src/ResourceManager.h index 0d0a3538d..bd164e741 100644 --- a/src/ResourceManager.h +++ b/src/ResourceManager.h @@ -461,7 +461,10 @@ cube->draw(); template class ResourceManager: protected Implementation::ResourceManagerData... { public: /** @brief Global instance */ - inline static ResourceManager* instance() { return _instance; } + inline static ResourceManager* instance() { + CORRADE_ASSERT(internalInstance(), "ResourceManager::instance(): no instance exists", nullptr); + return internalInstance(); + } /** * @brief Constructor @@ -472,8 +475,8 @@ template class ResourceManager: protected Implementation::Resour * @see instance() */ inline ResourceManager() { - CORRADE_ASSERT(!_instance, "ResourceManager: another instance is already created!", ); - _instance = this; + CORRADE_ASSERT(!internalInstance(), "ResourceManager::ResourceManager(): another instance is already created", ); + internalInstance() = this; } /** @@ -482,7 +485,10 @@ template class ResourceManager: protected Implementation::Resour * Sets global instance pointer to `nullptr`. * @see instance() */ - inline ~ResourceManager() { _instance = nullptr; } + inline ~ResourceManager() { + CORRADE_INTERNAL_ASSERT(internalInstance() == this); + internalInstance() = nullptr; + } /** @brief Count of resources of given type */ template inline std::size_t count() { @@ -567,16 +573,21 @@ template class ResourceManager: protected Implementation::Resour } inline void freeInternal() const {} - static ResourceManager* _instance; + static ResourceManager*& internalInstance(); }; +#ifndef MAGNUM_RESOURCEMANAGER_DONT_DEFINE_INTERNALINSTANCE +template ResourceManager*& ResourceManager::internalInstance() { + static ResourceManager* _instance(nullptr); + return _instance; +} +#endif + /** @debugoperator{Magnum::ResourceKey} */ template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const ResourceKey& value) { return debug << static_cast&>(value); } -template ResourceManager* ResourceManager::_instance(nullptr); - } #endif