changeset 593:6bf8f881fcb5

OpenGLBasicPolylineRenderer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 26 Apr 2019 13:04:56 +0200
parents bbe29efd3d1c
children 9807ed3d3e03
files Framework/Scene2D/CompositorHelper.cpp Framework/Scene2D/CompositorHelper.h Framework/Scene2D/Internals/CompositorHelper.cpp Framework/Scene2D/Internals/CompositorHelper.h Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.cpp Framework/Scene2D/Internals/OpenGLBasicPolylineRenderer.h Resources/CMake/OrthancStoneConfiguration.cmake
diffstat 7 files changed, 361 insertions(+), 221 deletions(-) [+]
line wrap: on
line diff
--- 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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "CompositorHelper.h"
-
-#include <Core/OrthancException.h>
-
-namespace OrthancStone
-{
-  class CompositorHelper::Item : public boost::noncopyable
-  {
-  private:
-    std::auto_ptr<ILayerRenderer>  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<ILayerRenderer> 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<double>(canvasWidth) / 2.0,
-      static_cast<double>(canvasHeight) / 2.0);
-
-    sceneTransform_ = AffineTransform2D::Combine(offset, scene_.GetSceneToCanvasTransform());
-    scene_.Apply(*this);
-  }
-}
--- 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 <http://www.gnu.org/licenses/>.
- **/
-
-
-#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<int, Item*>  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);
-  };
-}
--- /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 <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "CompositorHelper.h"
+
+#include <Core/OrthancException.h>
+
+namespace OrthancStone
+{
+  namespace Internals
+  {
+    class CompositorHelper::Item : public boost::noncopyable
+    {
+    private:
+      std::auto_ptr<ILayerRenderer>  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<ILayerRenderer> 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<double>(canvasWidth) / 2.0,
+        static_cast<double>(canvasHeight) / 2.0);
+
+      sceneTransform_ = AffineTransform2D::Combine(offset, scene_.GetSceneToCanvasTransform());
+      scene_.Apply(*this);
+    }
+  }
+}
--- /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 <http://www.gnu.org/licenses/>.
+ **/
+
+
+#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<int, Item*>  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);
+    };
+  }
+}
--- /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 <http://www.gnu.org/licenses/>.
+ **/
+
+
+#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<const PolylineSceneLayer&>(layer));
+    }
+  }
+}
--- /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 <http://www.gnu.org/licenses/>.
+ **/
+
+
+#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);
+    };
+  }
+}
--- 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