From 99efc0cb62d820ca54d9c07667298b94cf8e3033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 25 Jan 2013 01:20:36 +0100 Subject: [PATCH] DebugTools: common mesh building implementation for all shape renderers. --- .../Implementation/AbstractBoxRenderer.cpp | 63 ++--------------- .../Implementation/AbstractBoxRenderer.h | 16 +---- .../Implementation/AbstractShapeRenderer.cpp | 70 +++++++++++++++++++ .../Implementation/AbstractShapeRenderer.h | 21 +++++- .../Implementation/AxisAlignedBoxRenderer.cpp | 2 + .../Implementation/AxisAlignedBoxRenderer.h | 2 +- src/DebugTools/Implementation/BoxRenderer.cpp | 2 + src/DebugTools/Implementation/BoxRenderer.h | 2 +- 8 files changed, 103 insertions(+), 75 deletions(-) diff --git a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp index e62bbc87a..e04c76c54 100644 --- a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp @@ -15,73 +15,22 @@ #include "AbstractBoxRenderer.h" -#include "Buffer.h" -#include "DebugTools/ResourceManager.h" -#include "MeshTools/CompressIndices.h" #include "Primitives/Cube.h" #include "Primitives/Square.h" -#include "Shaders/FlatShader.h" #include "Trade/MeshData2D.h" #include "Trade/MeshData3D.h" namespace Magnum { namespace DebugTools { namespace Implementation { -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 */ - Trade::MeshData2D square = Primitives::Square::wireframe(); - Buffer* buffer = new Buffer(Buffer::Target::Array); - Mesh* mesh = new Mesh; - - 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, 0, Shaders::FlatShader2D::Position()); - ResourceManager::instance()->set(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); +AbstractBoxRenderer<2>::AbstractBoxRenderer(): AbstractShapeRenderer<2>("box2d", "box2d-vertices", "box2d-indices") { + if(!mesh) this->createResources(Primitives::Square::wireframe()); } -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 */ - Trade::MeshData3D cube = Primitives::Cube::wireframe(); - Buffer* vertexBuffer = new Buffer(Buffer::Target::Array); - Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray); - Mesh* mesh = new Mesh; - - 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, 0, Shaders::FlatShader3D::Position()); - ResourceManager::instance()->set(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); +AbstractBoxRenderer<3>::AbstractBoxRenderer(): AbstractShapeRenderer<3>("box3d", "box3d-vertices", "box3d-indices") { + if(!mesh) this->createResources(Primitives::Cube::wireframe()); } -AbstractBoxRenderer<2>::~AbstractBoxRenderer() {} -AbstractBoxRenderer<3>::~AbstractBoxRenderer() {} +template class AbstractBoxRenderer<2>; +template class AbstractBoxRenderer<3>; }}} diff --git a/src/DebugTools/Implementation/AbstractBoxRenderer.h b/src/DebugTools/Implementation/AbstractBoxRenderer.h index 5f2ecfe8c..cc6f2a9a4 100644 --- a/src/DebugTools/Implementation/AbstractBoxRenderer.h +++ b/src/DebugTools/Implementation/AbstractBoxRenderer.h @@ -24,30 +24,16 @@ namespace Magnum { namespace DebugTools { namespace Implementation { -template class AbstractBoxRenderer {}; +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; }; }}} diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp index a1cf63dbb..390ab8955 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp @@ -16,14 +16,84 @@ #include "AbstractShapeRenderer.h" #include "AbstractShaderProgram.h" +#include "Buffer.h" #include "Mesh.h" #include "DebugTools/ResourceManager.h" +#include "MeshTools/CompressIndices.h" #include "Shaders/FlatShader.h" +#include "Trade/MeshData2D.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace DebugTools { namespace Implementation { +namespace { + +template ResourceKey shaderName(); +template<> inline ResourceKey shaderName<2>() { return ResourceKey("FlatShader2D"); } +template<> inline ResourceKey shaderName<3>() { return ResourceKey("FlatShader3D"); } + +template void create(typename MeshData::Type&, Resource&, Resource&, Resource&); + +template<> void create<2>(Trade::MeshData2D& data, Resource& meshResource, Resource& indexBufferResource, Resource& vertexBufferResource) { + /* Vertex buffer */ + Buffer* buffer = new Buffer(Buffer::Target::Array); + buffer->setData(*data.positions(0), Buffer::Usage::StaticDraw); + ResourceManager::instance()->set(vertexBufferResource.key(), buffer, ResourceDataState::Final, ResourcePolicy::Manual); + + /* Mesh configuration */ + Mesh* mesh = new Mesh; + mesh->setPrimitive(data.primitive()) + ->setVertexCount(data.positions(0)->size()) + ->addVertexBuffer(buffer, 0, Shaders::FlatShader2D::Position()); + ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); + + /* Index buffer, if present */ + if(data.indices()) { + Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray); + MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *data.indices()); + ResourceManager::instance()->set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); + } +} + +template<> void create<3>(Trade::MeshData3D& data, Resource& meshResource, Resource& indexBufferResource, Resource& vertexBufferResource) { + /* Vertex buffer */ + Buffer* vertexBuffer = new Buffer(Buffer::Target::Array); + vertexBuffer->setData(*data.positions(0), Buffer::Usage::StaticDraw); + ResourceManager::instance()->set(vertexBufferResource.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); + + /* Mesh configuration */ + Mesh* mesh = new Mesh; + mesh->setPrimitive(data.primitive()) + ->setVertexCount(data.positions(0)->size()) + ->addVertexBuffer(vertexBuffer, 0, Shaders::FlatShader3D::Position()); + ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); + + /* Index buffer, if needed */ + if(data.indices()) { + Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray); + MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *data.indices()); + ResourceManager::instance()->set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); + } +} + +} + +template AbstractShapeRenderer::AbstractShapeRenderer(ResourceKey meshKey, ResourceKey vertexBufferKey, ResourceKey indexBufferKey) { + shader = ResourceManager::instance()->get>(shaderName()); + mesh = ResourceManager::instance()->get(meshKey); + vertexBuffer = ResourceManager::instance()->get(vertexBufferKey); + indexBuffer = ResourceManager::instance()->get(indexBufferKey); + + if(!shader) ResourceManager::instance()->set(shaderName(), + new Shaders::FlatShader, ResourceDataState::Final, ResourcePolicy::Resident); +} + template AbstractShapeRenderer::~AbstractShapeRenderer() {} +template void AbstractShapeRenderer::createResources(typename MeshData::Type data) { + create(data, this->mesh, this->vertexBuffer, this->indexBuffer); +} + template class AbstractShapeRenderer<2>; template class AbstractShapeRenderer<3>; diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.h b/src/DebugTools/Implementation/AbstractShapeRenderer.h index ee2c15a23..3d384f6e2 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.h +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.h @@ -16,16 +16,35 @@ */ #include "DimensionTraits.h" -#include "SceneGraph/SceneGraph.h" +#include "Resource.h" #include "DebugTools/DebugTools.h" +#include "SceneGraph/SceneGraph.h" +#include "Shaders/Shaders.h" +#include "Trade/Trade.h" namespace Magnum { namespace DebugTools { namespace Implementation { +template struct MeshData; + +template<> struct MeshData<2> { typedef Trade::MeshData2D Type; }; +template<> struct MeshData<3> { typedef Trade::MeshData3D Type; }; + template class AbstractShapeRenderer { public: + AbstractShapeRenderer(ResourceKey mesh, ResourceKey vertexBuffer, ResourceKey indexBuffer); virtual ~AbstractShapeRenderer(); virtual void draw(Resource& options, const typename DimensionTraits::MatrixType& transformationMatrix, SceneGraph::AbstractCamera* camera) = 0; + + protected: + /* Call only if the mesh resource isn't already present */ + void createResources(typename MeshData::Type data); + + Resource> shader; + Resource mesh; + + private: + Resource indexBuffer, vertexBuffer; }; }}} diff --git a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp index 25a69c435..07544a5a5 100644 --- a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp @@ -23,6 +23,8 @@ namespace Magnum { namespace DebugTools { namespace Implementation { +template AxisAlignedBoxRenderer::AxisAlignedBoxRenderer(Physics::AxisAlignedBox& axisAlignedBox): axisAlignedBox(axisAlignedBox) {} + template void AxisAlignedBoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractCamera* camera) { /* Half scale, because the box is 2x2(x2) */ typename DimensionTraits::MatrixType transformation = diff --git a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.h b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.h index cf1120433..4a8b75665 100644 --- a/src/DebugTools/Implementation/AxisAlignedBoxRenderer.h +++ b/src/DebugTools/Implementation/AxisAlignedBoxRenderer.h @@ -25,7 +25,7 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template class AxisAlignedBoxRenderer: public AbstractBoxRenderer { public: - inline AxisAlignedBoxRenderer(Physics::AxisAlignedBox& axisAlignedBox): axisAlignedBox(axisAlignedBox) {} + AxisAlignedBoxRenderer(Physics::AxisAlignedBox& axisAlignedBox); void draw(Resource& options, const typename DimensionTraits::MatrixType& transformation, typename SceneGraph::AbstractCamera* camera) override; diff --git a/src/DebugTools/Implementation/BoxRenderer.cpp b/src/DebugTools/Implementation/BoxRenderer.cpp index 8fc1a7dcf..821c056ff 100644 --- a/src/DebugTools/Implementation/BoxRenderer.cpp +++ b/src/DebugTools/Implementation/BoxRenderer.cpp @@ -23,6 +23,8 @@ namespace Magnum { namespace DebugTools { namespace Implementation { +template BoxRenderer::BoxRenderer(Physics::Box& box): box(box) {} + template void BoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractCamera* camera) { this->shader->setTransformationProjectionMatrix(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation()* DimensionTraits::MatrixType::scaling(typename DimensionTraits::VectorType(0.5f))) diff --git a/src/DebugTools/Implementation/BoxRenderer.h b/src/DebugTools/Implementation/BoxRenderer.h index acaf154f6..6d69c1d56 100644 --- a/src/DebugTools/Implementation/BoxRenderer.h +++ b/src/DebugTools/Implementation/BoxRenderer.h @@ -25,7 +25,7 @@ namespace Magnum { namespace DebugTools { namespace Implementation { template class BoxRenderer: public AbstractBoxRenderer { public: - inline BoxRenderer(Physics::Box& box): box(box) {} + BoxRenderer(Physics::Box& box); void draw(Resource& options, const typename DimensionTraits::MatrixType& transformation, typename SceneGraph::AbstractCamera* camera) override;