# HG changeset patch # User Sebastien Jodogne # Date 1556276696 -7200 # Node ID 6bf8f881fcb56a10c24a5744ca3c0a085fe928db # Parent bbe29efd3d1c8aff3d3bf1ab78fb53792d29a77c OpenGLBasicPolylineRenderer diff -r bbe29efd3d1c -r 6bf8f881fcb5 Framework/Scene2D/CompositorHelper.cpp --- a/Framework/Scene2D/CompositorHelper.cpp Fri Apr 26 12:55:43 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#include "CompositorHelper.h" - -#include - -namespace OrthancStone -{ - class CompositorHelper::Item : public boost::noncopyable - { - private: - std::auto_ptr renderer_; - const ISceneLayer& layer_; - uint64_t lastRevision_; - - public: - Item(ILayerRenderer* renderer, // Takes ownership - const ISceneLayer& layer) : - renderer_(renderer), - layer_(layer), - lastRevision_(layer.GetRevision()) - { - if (renderer == NULL) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); - } - } - - ILayerRenderer& GetRenderer() const - { - assert(renderer_.get() != NULL); - return *renderer_; - } - - const ISceneLayer& GetLayer() const - { - return layer_; - } - - uint64_t GetLastRevision() const - { - return lastRevision_; - } - - void UpdateRenderer() - { - assert(renderer_.get() != NULL); - renderer_->Update(layer_); - lastRevision_ = layer_.GetRevision(); - } - }; - - - void CompositorHelper::Visit(const ISceneLayer& layer, - int depth) - { - Content::iterator found = content_.find(depth); - - assert(found == content_.end() || - found->second != NULL); - - if (found == content_.end() || - &found->second->GetLayer() != &layer) - { - // This is the first time this layer is rendered, or the layer - // is not the same as before - if (found != content_.end()) - { - delete found->second; - content_.erase(found); - } - - std::auto_ptr renderer(factory_.Create(layer)); - - if (renderer.get() != NULL) - { - renderer->Render(sceneTransform_); - content_[depth] = new Item(renderer.release(), layer); - } - } - else - { - // This layer has already been rendered - if (found->second->GetLastRevision() < layer.GetRevision()) - { - found->second->UpdateRenderer(); - } - - found->second->GetRenderer().Render(sceneTransform_); - } - - // Check invariants - assert(content_.find(depth) == content_.end() || - (&content_[depth]->GetLayer() == &layer && - content_[depth]->GetLastRevision() == layer.GetRevision())); - } - - - CompositorHelper::~CompositorHelper() - { - for (Content::iterator it = content_.begin(); it != content_.end(); ++it) - { - assert(it->second != NULL); - delete it->second; - } - } - - - void CompositorHelper::Refresh(unsigned int canvasWidth, - unsigned int canvasHeight) - { - // Bring coordinate (0,0) to the center of the canvas - AffineTransform2D offset = AffineTransform2D::CreateOffset( - static_cast(canvasWidth) / 2.0, - static_cast(canvasHeight) / 2.0); - - sceneTransform_ = AffineTransform2D::Combine(offset, scene_.GetSceneToCanvasTransform()); - scene_.Apply(*this); - } -} diff -r bbe29efd3d1c -r 6bf8f881fcb5 Framework/Scene2D/CompositorHelper.h --- a/Framework/Scene2D/CompositorHelper.h Fri Apr 26 12:55:43 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program 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 - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - **/ - - -#pragma once - -#include "Scene2D.h" - -namespace OrthancStone -{ - class CompositorHelper : protected Scene2D::IVisitor - { - public: - class ILayerRenderer : public boost::noncopyable - { - public: - virtual ~ILayerRenderer() - { - } - - virtual void Render(const AffineTransform2D& transform) = 0; - - // "Update()" is only called if the type of the layer has not changed - virtual void Update(const ISceneLayer& layer) = 0; - }; - - class IRendererFactory : public boost::noncopyable - { - public: - virtual ~IRendererFactory() - { - } - - virtual ILayerRenderer* Create(const ISceneLayer& layer) = 0; - }; - - private: - class Item; - - typedef std::map Content; - - Scene2D& scene_; - IRendererFactory& factory_; - Content content_; - AffineTransform2D sceneTransform_; - - protected: - virtual void Visit(const ISceneLayer& layer, - int depth); - - public: - CompositorHelper(Scene2D& scene, - IRendererFactory& factory) : - scene_(scene), - factory_(factory) - { - } - - ~CompositorHelper(); - - void Refresh(unsigned int canvasWidth, - unsigned int canvasHeight); - }; -} diff -r bbe29efd3d1c -r 6bf8f881fcb5 Framework/Scene2D/Internals/CompositorHelper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/CompositorHelper.cpp Fri Apr 26 13:04:56 2019 +0200 @@ -0,0 +1,142 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "CompositorHelper.h" + +#include + +namespace OrthancStone +{ + namespace Internals + { + class CompositorHelper::Item : public boost::noncopyable + { + private: + std::auto_ptr renderer_; + const ISceneLayer& layer_; + uint64_t lastRevision_; + + public: + Item(ILayerRenderer* renderer, // Takes ownership + const ISceneLayer& layer) : + renderer_(renderer), + layer_(layer), + lastRevision_(layer.GetRevision()) + { + if (renderer == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + } + } + + ILayerRenderer& GetRenderer() const + { + assert(renderer_.get() != NULL); + return *renderer_; + } + + const ISceneLayer& GetLayer() const + { + return layer_; + } + + uint64_t GetLastRevision() const + { + return lastRevision_; + } + + void UpdateRenderer() + { + assert(renderer_.get() != NULL); + renderer_->Update(layer_); + lastRevision_ = layer_.GetRevision(); + } + }; + + + void CompositorHelper::Visit(const ISceneLayer& layer, + int depth) + { + Content::iterator found = content_.find(depth); + + assert(found == content_.end() || + found->second != NULL); + + if (found == content_.end() || + &found->second->GetLayer() != &layer) + { + // This is the first time this layer is rendered, or the layer + // is not the same as before + if (found != content_.end()) + { + delete found->second; + content_.erase(found); + } + + std::auto_ptr renderer(factory_.Create(layer)); + + if (renderer.get() != NULL) + { + renderer->Render(sceneTransform_); + content_[depth] = new Item(renderer.release(), layer); + } + } + else + { + // This layer has already been rendered + if (found->second->GetLastRevision() < layer.GetRevision()) + { + found->second->UpdateRenderer(); + } + + found->second->GetRenderer().Render(sceneTransform_); + } + + // Check invariants + assert(content_.find(depth) == content_.end() || + (&content_[depth]->GetLayer() == &layer && + content_[depth]->GetLastRevision() == layer.GetRevision())); + } + + + CompositorHelper::~CompositorHelper() + { + for (Content::iterator it = content_.begin(); it != content_.end(); ++it) + { + assert(it->second != NULL); + delete it->second; + } + } + + + void CompositorHelper::Refresh(unsigned int canvasWidth, + unsigned int canvasHeight) + { + // Bring coordinate (0,0) to the center of the canvas + AffineTransform2D offset = AffineTransform2D::CreateOffset( + static_cast(canvasWidth) / 2.0, + static_cast(canvasHeight) / 2.0); + + sceneTransform_ = AffineTransform2D::Combine(offset, scene_.GetSceneToCanvasTransform()); + scene_.Apply(*this); + } + } +} diff -r bbe29efd3d1c -r 6bf8f881fcb5 Framework/Scene2D/Internals/CompositorHelper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/CompositorHelper.h Fri Apr 26 13:04:56 2019 +0200 @@ -0,0 +1,84 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "../Scene2D.h" + +namespace OrthancStone +{ + namespace Internals + { + class CompositorHelper : protected Scene2D::IVisitor + { + public: + class ILayerRenderer : public boost::noncopyable + { + public: + virtual ~ILayerRenderer() + { + } + + virtual void Render(const AffineTransform2D& transform) = 0; + + // "Update()" is only called if the type of the layer has not changed + virtual void Update(const ISceneLayer& layer) = 0; + }; + + class IRendererFactory : public boost::noncopyable + { + public: + virtual ~IRendererFactory() + { + } + + virtual ILayerRenderer* Create(const ISceneLayer& layer) = 0; + }; + + private: + class Item; + + typedef std::map Content; + + Scene2D& scene_; + IRendererFactory& factory_; + Content content_; + AffineTransform2D sceneTransform_; + + protected: + virtual void Visit(const ISceneLayer& layer, + int depth); + + public: + CompositorHelper(Scene2D& scene, + IRendererFactory& factory) : + scene_(scene), + factory_(factory) + { + } + + ~CompositorHelper(); + + void Refresh(unsigned int canvasWidth, + unsigned int canvasHeight); + }; + } +} diff -r bbe29efd3d1c -r 6bf8f881fcb5 Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.cpp Fri Apr 26 13:04:56 2019 +0200 @@ -0,0 +1,86 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#include "OpenGLBasicPolylineRenderer.h" + +#include "../../OpenGL/OpenGLIncludes.h" + +namespace OrthancStone +{ + namespace Internals + { + OpenGLBasicPolylineRenderer::OpenGLBasicPolylineRenderer(OpenGL::IOpenGLContext& context, + const PolylineSceneLayer& layer) : + context_(context) + { + layer_.Copy(layer); + } + + + void OpenGLBasicPolylineRenderer::Render(const AffineTransform2D& transform) + { + AffineTransform2D t = AffineTransform2D::Combine( + AffineTransform2D::CreateOpenGLClipspace(context_.GetCanvasWidth(), context_.GetCanvasHeight()), + transform); + + glUseProgram(0); + glColor3ub(layer_.GetRed(), layer_.GetGreen(), layer_.GetBlue()); + + glBegin(GL_LINES); + + for (size_t i = 0; i < layer_.GetChainsCount(); i++) + { + const PolylineSceneLayer::Chain& chain = layer_.GetChain(i); + + if (chain.size() > 1) + { + ScenePoint2D previous = chain[0].Apply(t); + + for (size_t j = 1; j < chain.size(); j++) + { + ScenePoint2D p = chain[j].Apply(t); + + glVertex2f(previous.GetX(), previous.GetY()); + glVertex2f(p.GetX(), p.GetY()); + + previous = p; + } + + if (layer_.IsClosedChain(i)) + { + ScenePoint2D p = chain[0].Apply(t); + + glVertex2f(previous.GetX(), previous.GetY()); + glVertex2f(p.GetX(), p.GetY()); + } + } + } + + glEnd(); + } + + + void OpenGLBasicPolylineRenderer::Update(const ISceneLayer& layer) + { + layer_.Copy(dynamic_cast(layer)); + } + } +} diff -r bbe29efd3d1c -r 6bf8f881fcb5 Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.h Fri Apr 26 13:04:56 2019 +0200 @@ -0,0 +1,47 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program 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 + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "../../OpenGL/IOpenGLContext.h" +#include "../PolylineSceneLayer.h" +#include "CompositorHelper.h" + +namespace OrthancStone +{ + namespace Internals + { + class OpenGLBasicPolylineRenderer : public CompositorHelper::ILayerRenderer + { + private: + OpenGL::IOpenGLContext& context_; + PolylineSceneLayer layer_; + + public: + OpenGLBasicPolylineRenderer(OpenGL::IOpenGLContext& context, + const PolylineSceneLayer& layer); + + virtual void Render(const AffineTransform2D& transform); + + virtual void Update(const ISceneLayer& layer); + }; + } +} diff -r bbe29efd3d1c -r 6bf8f881fcb5 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 26 12:55:43 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 26 13:04:56 2019 +0200 @@ -257,9 +257,9 @@ #${ORTHANC_STONE_ROOT}/Framework/Layers/SingleFrameRendererFactory.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/ColorTextureSceneLayer.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2D/CompositorHelper.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/FloatTextureSceneLayer.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/InfoPanelSceneLayer.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/CompositorHelper.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/PolylineSceneLayer.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Scene2D.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/TextSceneLayer.cpp @@ -389,6 +389,7 @@ ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLProgram.cpp ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLShader.cpp ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLTexture.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/OpenGLColorTextureProgram.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/OpenGLFloatTextureProgram.cpp ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/OpenGLLinesProgram.cpp