diff Samples/Sdl/RtViewer/RtViewerSdl.cpp @ 1386:dfb48f0794b1

Ongoing splitting SDL vs WASM (preparing RtViewer WASM)
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 27 Apr 2020 16:48:19 +0200
parents 24bcff8ea58f
children 5c83be3a6be5
line wrap: on
line diff
--- a/Samples/Sdl/RtViewer/RtViewerSdl.cpp	Mon Apr 27 16:47:46 2020 +0200
+++ b/Samples/Sdl/RtViewer/RtViewerSdl.cpp	Mon Apr 27 16:48:19 2020 +0200
@@ -0,0 +1,191 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2020 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 "RtViewer.h"
+#include "SampleHelpers.h"
+
+#include <Framework/StoneException.h>
+
+#include <boost/program_options.hpp>
+#include <SDL.h>
+
+#include <string>
+
+static void GLAPIENTRY
+OpenGLMessageCallback(GLenum source,
+                      GLenum type,
+                      GLuint id,
+                      GLenum severity,
+                      GLsizei length,
+                      const GLchar* message,
+                      const void* userParam)
+{
+  if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
+  {
+    fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
+            (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
+            type, severity, message);
+  }
+}
+
+namespace OrthancStone
+{
+  void RtViewerApp::ProcessOptions(int argc, char* argv[])
+  {
+    namespace po = boost::program_options;
+    po::options_description desc("Usage:");
+
+    //ctLoader->LoadSeries("a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa");  // CT
+    //doseLoader->LoadInstance("830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb");  // RT-DOSE
+    //rtstructLoader->LoadInstance("54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9");  // RT-STRUCT
+
+
+    desc.add_options()
+      ("loglevel", po::value<std::string>()->default_value("WARNING"),
+       "You can choose WARNING, INFO or TRACE for the logging level: Errors and warnings will always be displayed. (default: WARNING)")
+
+      ("orthanc", po::value<std::string>()->default_value("http://localhost:8042"),
+       "Base URL of the Orthanc instance")
+
+      ("ctseries", po::value<std::string>()->default_value("a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa"),
+       "Orthanc ID of the CT series to load")
+
+      ("rtdose", po::value<std::string>()->default_value("830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb"),
+       "Orthanc ID of the RTDOSE instance to load")
+
+      ("rtstruct", po::value<std::string>()->default_value("54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9"),
+       "Orthanc ID of the RTSTRUCT instance to load")
+      ;
+
+    po::variables_map vm;
+    try
+    {
+      po::store(po::parse_command_line(argc, argv, desc), vm);
+      po::notify(vm);
+    }
+    catch (std::exception& e)
+    {
+      std::cerr << "Please check your command line options! (\"" << e.what() << "\")" << std::endl;
+    }
+
+    if (vm.count("loglevel") > 0)
+    {
+      std::string logLevel = vm["loglevel"].as<std::string>();
+      OrthancStoneHelpers::SetLogLevel(logLevel);
+    }
+
+    if (vm.count("orthanc") > 0)
+    {
+      // maybe check URL validity here
+      orthancUrl_ = vm["orthanc"].as<std::string>();
+    }
+
+    if (vm.count("ctseries") > 0)
+    {
+      ctSeriesId_ = vm["ctseries"].as<std::string>();
+    }
+
+    if (vm.count("rtdose") > 0)
+    {
+      doseInstanceId_ = vm["rtdose"].as<std::string>();
+    }
+
+    if (vm.count("rtstruct") > 0)
+    {
+      rtStructInstanceId_ = vm["rtstruct"].as<std::string>();
+    }
+  }
+
+  void RtViewerApp::RunSdl(int argc, char* argv[])
+  {
+    ProcessOptions(argc, argv);
+
+    {
+      std::unique_ptr<IViewport::ILock> lock(viewport_->Lock());
+      ViewportController& controller = lock->GetController();
+      Scene2D& scene = controller.GetScene();
+      ICompositor& compositor = lock->GetCompositor();
+
+      // False means we do NOT let Windows treat this as a legacy application
+      // that needs to be scaled
+      controller.FitContent(compositor.GetCanvasWidth(), compositor.GetCanvasHeight());
+
+      glEnable(GL_DEBUG_OUTPUT);
+      glDebugMessageCallback(OpenGLMessageCallback, 0);
+
+      compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
+                         FONT_SIZE_0, Orthanc::Encoding_Latin1);
+      compositor.SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT,
+                         FONT_SIZE_1, Orthanc::Encoding_Latin1);
+    }
+                     //////// from loader
+    
+    loadersContext_.reset(new GenericLoadersContext(1, 4, 1));
+    loadersContext_->StartOracle();
+
+    /**
+    It is very important that the Oracle (responsible for network I/O be started before creating and firing the 
+    loaders, for any command scheduled by the loader before the oracle is started will be lost.
+    */
+    PrepareLoadersAndSlicers();
+
+    bool stopApplication = false;
+
+    while (!stopApplication)
+    {
+      //compositor.Refresh(scene);
+
+      SDL_Event event;
+      while (!stopApplication && SDL_PollEvent(&event))
+      {
+        if (event.type == SDL_QUIT)
+        {
+          stopApplication = true;
+          break;
+        }
+        else if (event.type == SDL_WINDOWEVENT &&
+                 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
+        {
+          DisableTracker(); // was: tracker.reset(NULL);
+        }
+        else if (event.type == SDL_KEYDOWN &&
+                 event.key.repeat == 0 /* Ignore key bounce */)
+        {
+          switch (event.key.keysym.sym)
+          {
+          case SDLK_f:
+            // TODO: implement GetWindow!!!
+            // viewport_->GetContext()->GetWindow().ToggleMaximize();
+            ORTHANC_ASSERT(false, "Please implement GetWindow()");
+            break;
+          case SDLK_q:
+            stopApplication = true;
+            break;
+          default:
+            break;
+          }
+        }
+        HandleApplicationEvent(event);
+      }
+      SDL_Delay(1);
+    }
+    loadersContext_->StopOracle();
+  }
+}