From 22d405809f33011b846b8b8dd8713806f4588cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 5 Jan 2013 19:52:53 +0100 Subject: [PATCH] DebugTools: ShapeRenderer cleanup. * Added missing forward declarations. * Added getters and setters to ShapeRendererOptions class. * Cube primitive is indexed, modified the mesh creation accordingly. It now uses MeshTools, link the library to DebugTools. * Simplified resource handling so it's now handled in one place. It still needs to be thought out better. --- src/DebugTools/CMakeLists.txt | 2 +- src/DebugTools/DebugTools.h | 5 +- .../Implementation/AbstractBoxRenderer.cpp | 94 +++++++++++-------- .../Implementation/AbstractBoxRenderer.h | 21 ++++- .../Implementation/AbstractShapeRenderer.cpp | 2 - .../Implementation/AbstractShapeRenderer.h | 8 -- .../Implementation/AxisAlignedBoxRenderer.cpp | 2 +- src/DebugTools/Implementation/BoxRenderer.cpp | 2 +- src/DebugTools/ResourceManager.cpp | 4 +- src/DebugTools/ShapeRenderer.h | 43 ++++++--- 10 files changed, 112 insertions(+), 71 deletions(-) diff --git a/src/DebugTools/CMakeLists.txt b/src/DebugTools/CMakeLists.txt index 3b6f17daf..25bd0dfeb 100644 --- a/src/DebugTools/CMakeLists.txt +++ b/src/DebugTools/CMakeLists.txt @@ -18,7 +18,7 @@ set(MagnumDebugTools_HEADERS add_library(MagnumDebugTools SHARED ${MagnumDebugTools_SRCS}) -target_link_libraries(MagnumDebugTools Magnum MagnumPhysics MagnumPrimitives MagnumSceneGraph MagnumShaders) +target_link_libraries(MagnumDebugTools Magnum MagnumMeshTools MagnumPhysics MagnumPrimitives MagnumSceneGraph MagnumShaders) install(TARGETS MagnumDebugTools DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${MagnumDebugTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/DebugTools) diff --git a/src/DebugTools/DebugTools.h b/src/DebugTools/DebugTools.h index 82ab4d2b3..529a3194a 100644 --- a/src/DebugTools/DebugTools.h +++ b/src/DebugTools/DebugTools.h @@ -25,8 +25,11 @@ namespace Magnum { namespace DebugTools { class Profiler; class ResourceManager; + template class ShapeRenderer; -struct ShapeRendererOptions; +typedef ShapeRenderer<2> ShapeRenderer2D; +typedef ShapeRenderer<3> ShapeRenderer3D; +class ShapeRendererOptions; }} diff --git a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp index d22610977..e3283626b 100644 --- a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp @@ -16,55 +16,71 @@ #include "AbstractBoxRenderer.h" #include "Buffer.h" +#include "IndexedMesh.h" #include "DebugTools/ResourceManager.h" +#include "MeshTools/CompressIndices.h" #include "Primitives/Cube.h" #include "Primitives/Square.h" #include "Shaders/FlatShader.h" namespace Magnum { namespace DebugTools { 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()); - } - }; -} +AbstractBoxRenderer<2>::AbstractBoxRenderer() { + /* Shader */ + shader = ResourceManager::instance()->get("FlatShader2D"); + if(!shader) ResourceManager::instance()->set(shader.key(), + new Shaders::FlatShader2D, ResourceDataState::Final, ResourcePolicy::Resident); + + /* Mesh and vertex buffer */ + mesh = ResourceManager::instance()->get("box2d"); + buffer = ResourceManager::instance()->get("box2d"); + if(mesh) return; + + /* Create the mesh */ + Primitives::Square square; + Buffer* buffer = new Buffer(Buffer::Target::Array); + Mesh* mesh = new Mesh; -template AbstractBoxRenderer::AbstractBoxRenderer(): AbstractShapeRenderer(BoxMesh::shader(), BoxMesh::key()), buffer(ResourceManager::instance()->get(BoxMesh::key())) { - if(!this->mesh) { - ResourceManager::instance()->set(this->buffer.key(), new Buffer, ResourceDataState::Final, ResourcePolicy::Manual); - ResourceManager::instance()->set(this->mesh.key(), BoxMesh::mesh(buffer), ResourceDataState::Final, ResourcePolicy::Manual); - } + buffer->setData(*square.positions(0), Buffer::Usage::StaticDraw); + ResourceManager::instance()->set(this->buffer.key(), buffer, ResourceDataState::Final, ResourcePolicy::Manual); + + mesh->setPrimitive(square.primitive()) + ->setVertexCount(square.positions(0)->size()) + ->addVertexBuffer(buffer, Shaders::FlatShader2D::Position()); + ResourceManager::instance()->set(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); } -template AbstractBoxRenderer::~AbstractBoxRenderer() {} +AbstractBoxRenderer<3>::AbstractBoxRenderer() { + /* Shader */ + shader = ResourceManager::instance()->get("FlatShader3D"); + if(!shader) ResourceManager::instance()->set(shader.key(), + new Shaders::FlatShader3D, ResourceDataState::Final, ResourcePolicy::Resident); + + /* Mesh and vertex buffer */ + mesh = ResourceManager::instance()->get("box3d"); + vertexBuffer = ResourceManager::instance()->get("box3d-vertices"); + indexBuffer = ResourceManager::instance()->get("box3d-indices"); + if(mesh) return; + + /* Create the mesh */ + Primitives::Cube cube; + Buffer* vertexBuffer = new Buffer(Buffer::Target::Array); + Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray); + IndexedMesh* mesh = new IndexedMesh; + + vertexBuffer->setData(*cube.positions(0), Buffer::Usage::StaticDraw); + ResourceManager::instance()->set(this->vertexBuffer.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); + + MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *cube.indices()); + ResourceManager::instance()->set(this->indexBuffer.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); + + mesh->setPrimitive(cube.primitive()) + ->setVertexCount(cube.positions(0)->size()) + ->addVertexBuffer(vertexBuffer, Shaders::FlatShader3D::Position()); + ResourceManager::instance()->set(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); +} -template class AbstractBoxRenderer<2>; -template class AbstractBoxRenderer<3>; +AbstractBoxRenderer<2>::~AbstractBoxRenderer() {} +AbstractBoxRenderer<3>::~AbstractBoxRenderer() {} }}} diff --git a/src/DebugTools/Implementation/AbstractBoxRenderer.h b/src/DebugTools/Implementation/AbstractBoxRenderer.h index ef3023527..5f2ecfe8c 100644 --- a/src/DebugTools/Implementation/AbstractBoxRenderer.h +++ b/src/DebugTools/Implementation/AbstractBoxRenderer.h @@ -17,20 +17,39 @@ #include "AbstractShapeRenderer.h" +#include "Resource.h" +#include "Shaders/Shaders.h" + #include "corradeCompatibility.h" namespace Magnum { namespace DebugTools { namespace Implementation { -template class AbstractBoxRenderer: public AbstractShapeRenderer { +template class AbstractBoxRenderer {}; + +template<> class AbstractBoxRenderer<2>: public AbstractShapeRenderer<2> { public: AbstractBoxRenderer(); ~AbstractBoxRenderer(); protected: + Resource mesh; + Resource shader; Resource buffer; }; +template<> class AbstractBoxRenderer<3>: public AbstractShapeRenderer<3> { + public: + AbstractBoxRenderer(); + + ~AbstractBoxRenderer(); + + protected: + Resource mesh; + Resource shader; + Resource vertexBuffer, indexBuffer; +}; + }}} #endif diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp index 0ddb6964c..a1cf63dbb 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp @@ -22,8 +22,6 @@ namespace Magnum { namespace DebugTools { namespace Implementation { -template AbstractShapeRenderer::AbstractShapeRenderer(ResourceKey shader, ResourceKey mesh): shader(ResourceManager::instance()->get>(shader)), mesh(ResourceManager::instance()->get(mesh)) {} - template AbstractShapeRenderer::~AbstractShapeRenderer() {} template class AbstractShapeRenderer<2>; diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.h b/src/DebugTools/Implementation/AbstractShapeRenderer.h index adec6e7fe..ee2c15a23 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.h +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.h @@ -16,24 +16,16 @@ */ #include "DimensionTraits.h" -#include "ResourceManager.h" #include "SceneGraph/SceneGraph.h" -#include "Shaders/Shaders.h" #include "DebugTools/DebugTools.h" namespace Magnum { namespace DebugTools { namespace Implementation { 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; }; }}} diff --git a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp index 507682d9a..345f69642 100644 --- a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp @@ -28,7 +28,7 @@ template void AxisAlignedBoxRenderer::draw( DimensionTraits::MatrixType::translation(axisAlignedBox.transformedPosition())* DimensionTraits::MatrixType::scaling(axisAlignedBox.transformedSize()); this->shader->setTransformationProjectionMatrix(camera->projectionMatrix()*camera->cameraMatrix()*transformation) - ->setColor(options->color) + ->setColor(options->color()) ->use(); this->mesh->draw(); } diff --git a/src/DebugTools/Implementation/BoxRenderer.cpp b/src/DebugTools/Implementation/BoxRenderer.cpp index a11ade2e7..4a0b98675 100644 --- a/src/DebugTools/Implementation/BoxRenderer.cpp +++ b/src/DebugTools/Implementation/BoxRenderer.cpp @@ -25,7 +25,7 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template void BoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractCamera* camera) { this->shader->setTransformationProjectionMatrix(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation()) - ->setColor(options->color) + ->setColor(options->color()) ->use(); this->mesh->draw(); } diff --git a/src/DebugTools/ResourceManager.cpp b/src/DebugTools/ResourceManager.cpp index 5e85d0f48..3c75732e9 100644 --- a/src/DebugTools/ResourceManager.cpp +++ b/src/DebugTools/ResourceManager.cpp @@ -19,8 +19,7 @@ #include "Buffer.h" #include "Mesh.h" -#include "Shaders/FlatShader.h" -#include "ShapeRenderer.h" +#include "DebugTools/ShapeRenderer.h" namespace Magnum { @@ -30,7 +29,6 @@ namespace DebugTools { ResourceManager::ResourceManager() { setFallback(new ShapeRendererOptions); - set("shader2d", new Shaders::FlatShader<2>, ResourceDataState::Final, ResourcePolicy::Resident); } ResourceManager::~ResourceManager() {} diff --git a/src/DebugTools/ShapeRenderer.h b/src/DebugTools/ShapeRenderer.h index 0a600dff4..21adf2c59 100644 --- a/src/DebugTools/ShapeRenderer.h +++ b/src/DebugTools/ShapeRenderer.h @@ -39,22 +39,38 @@ namespace Implementation { See ShapeRenderer documentation for more information. */ -struct ShapeRendererOptions { - Color3<> color; /**< @brief Color */ +class ShapeRendererOptions { + public: + /** @brief Color of rendered shape */ + inline constexpr Color3<> color() const { return _color; } + + /** + * @brief Set color of rendered shape + * @return Pointer to self (for method chaining) + * + * Default is black. + */ + inline ShapeRendererOptions* setColor(const Color3<>& color) { + _color = color; + return this; + } + + private: + Color3<> _color; }; /** @brief Shape renderer -Creates renderers for object collision shape. +Visualizes collision shape. @section ShapeRenderer-usage Basic usage ResourceManager must be instanced for the whole lifetime of debug -renderers. You can specify options via Options struct - add it to the manager -and then create debug renderer with the same options key. This way you can -easily share the same options with more renderers. If no options for given key -exist, default is used. +renderers. You can specify options via ShapeRendererOptions struct - add it to +the manager and then create debug renderer with the same options key. This way +you can easily share the same options with more renderers. If no options for +given key exist, default is used. Example code: @code @@ -66,14 +82,13 @@ DebugTools::ResourceManager manager; SceneGraph::DrawableGroup2D debugDrawables; // Create some options -auto o = new DebugTools::ShapeRendererOptions { - {1.0f, 0.0f, 0.0f} // Red color -}; -manager->set("red", o, ResourceDataState::Final, ResourcePolicy::Persistent); +DebugTools::ResourceManager::instance()->set("red", + (new DebugTools::ShapeRendererOptions())->setColor({1.0f, 0.0f, 0.0f}), + ResourceDataState::Final, ResourcePolicy::Persistent); // Create debug renderer for given shape, use "red" options for it Physics::ObjectShape2D* shape; -debugDrawables.add(new DebugTools::ShapeRenderer2D(shape, "red", debugDrawables)); +new DebugTools::ShapeRenderer2D(shape, "red", debugDrawables); @endcode @see ShapeRenderer2D, ShapeRenderer3D @@ -92,8 +107,8 @@ template class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: * information. * @param drawables Drawable group * - * @attention @p shape must be available for the whole lifetime of - * this class + * The renderer is automatically added to shape's object features, + * @p shape must be available for the whole lifetime of the renderer. */ explicit ShapeRenderer(Physics::ObjectShape* shape, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup* drawables = nullptr);