comparison Samples/WebAssembly/BasicScene.cpp @ 616:97926984d5d0

WebAssembly sample using Scene2D
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 02 May 2019 13:27:41 +0200
parents
children 7efa2543699d
comparison
equal deleted inserted replaced
615:b4de8272e8fb 616:97926984d5d0
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22
23 #include <emscripten.h>
24 #include <emscripten/html5.h>
25
26 // From Stone
27 #include "../../Applications/Sdl/SdlOpenGLWindow.h"
28 #include "../../Framework/Scene2D/CairoCompositor.h"
29 #include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
30 #include "../../Framework/Scene2D/OpenGLCompositor.h"
31 #include "../../Framework/Scene2D/PanSceneTracker.h"
32 #include "../../Framework/Scene2D/RotateSceneTracker.h"
33 #include "../../Framework/Scene2D/Scene2D.h"
34 #include "../../Framework/Scene2D/ZoomSceneTracker.h"
35 #include "../../Framework/StoneInitialization.h"
36 #include "../../Framework/OpenGL/WebAssemblyOpenGLContext.h"
37
38 // From Orthanc framework
39 #include <Core/Images/Image.h>
40
41 #include <stdio.h>
42
43 static const unsigned int FONT_SIZE = 32;
44
45
46 void PrepareScene(OrthancStone::Scene2D& scene)
47 {
48 using namespace OrthancStone;
49
50 // Texture of 2x2 size
51 if (1)
52 {
53 Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false);
54
55 uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0));
56 p[0] = 255;
57 p[1] = 0;
58 p[2] = 0;
59
60 p[3] = 0;
61 p[4] = 255;
62 p[5] = 0;
63
64 p = reinterpret_cast<uint8_t*>(i.GetRow(1));
65 p[0] = 0;
66 p[1] = 0;
67 p[2] = 255;
68
69 p[3] = 255;
70 p[4] = 0;
71 p[5] = 0;
72
73 scene.SetLayer(12, new ColorTextureSceneLayer(i));
74
75 std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
76 l->SetOrigin(-3, 2);
77 l->SetPixelSpacing(1.5, 1);
78 l->SetAngle(20.0 / 180.0 * M_PI);
79 scene.SetLayer(14, l.release());
80 }
81
82 // Texture of 1x1 size
83 if (1)
84 {
85 Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false);
86
87 uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0));
88 p[0] = 255;
89 p[1] = 0;
90 p[2] = 0;
91
92 std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
93 l->SetOrigin(-2, 1);
94 l->SetAngle(20.0 / 180.0 * M_PI);
95 scene.SetLayer(13, l.release());
96 }
97
98 // Some lines
99 {
100 std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer);
101
102 layer->SetThickness(1);
103
104 PolylineSceneLayer::Chain chain;
105 chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5));
106 chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5));
107 chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5));
108 chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5));
109 layer->AddChain(chain, true);
110
111 chain.clear();
112 chain.push_back(ScenePoint2D(-5, -5));
113 chain.push_back(ScenePoint2D(5, -5));
114 chain.push_back(ScenePoint2D(5, 5));
115 chain.push_back(ScenePoint2D(-5, 5));
116 layer->AddChain(chain, true);
117
118 double dy = 1.01;
119 chain.clear();
120 chain.push_back(ScenePoint2D(-4, -4));
121 chain.push_back(ScenePoint2D(4, -4 + dy));
122 chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy));
123 chain.push_back(ScenePoint2D(4, 2));
124 layer->AddChain(chain, false);
125
126 layer->SetColor(0,255, 255);
127 scene.SetLayer(50, layer.release());
128 }
129
130 // Some text
131 if (1)
132 {
133 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer);
134 layer->SetText("Hello");
135 scene.SetLayer(100, layer.release());
136 }
137 }
138
139
140
141
142
143 class WebAssemblyCanvas : public boost::noncopyable
144 {
145 private:
146 OrthancStone::OpenGL::WebAssemblyOpenGLContext context_;
147 OrthancStone::Scene2D scene_;
148 OrthancStone::OpenGLCompositor compositor_;
149
150 public:
151 WebAssemblyCanvas(const std::string& canvas) :
152 context_(canvas),
153 compositor_(context_, scene_)
154 {
155 compositor_.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
156 FONT_SIZE, Orthanc::Encoding_Latin1);
157 }
158
159 OrthancStone::Scene2D& GetScene()
160 {
161 return scene_;
162 }
163
164 void UpdateSize()
165 {
166 context_.UpdateSize();
167 compositor_.UpdateSize();
168 Refresh();
169 }
170
171 void Refresh()
172 {
173 compositor_.Refresh();
174 }
175 };
176
177
178
179 std::auto_ptr<WebAssemblyCanvas> canvas1_;
180 std::auto_ptr<WebAssemblyCanvas> canvas2_;
181 std::auto_ptr<WebAssemblyCanvas> canvas3_;
182
183
184 EM_BOOL OnWindowResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
185 {
186 if (canvas1_.get() != NULL)
187 {
188 canvas1_->UpdateSize();
189 }
190
191 if (canvas2_.get() != NULL)
192 {
193 canvas2_->UpdateSize();
194 }
195
196 if (canvas3_.get() != NULL)
197 {
198 canvas3_->UpdateSize();
199 }
200
201 return true;
202 }
203
204
205 EM_BOOL OnMouseClick(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
206 {
207 if (userData != NULL)
208 {
209 WebAssemblyCanvas& canvas = *reinterpret_cast<WebAssemblyCanvas*>(userData);
210
211 static unsigned int count = 0;
212 char buf[64];
213 sprintf(buf, "click %d", count++);
214
215 std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer);
216 layer->SetText(buf);
217 canvas.GetScene().SetLayer(100, layer.release());
218 canvas.Refresh();
219 }
220
221 return true;
222 }
223
224
225 extern "C"
226 {
227 int main(int argc, char const *argv[])
228 {
229 OrthancStone::StoneInitialize();
230 EM_ASM(window.dispatchEvent(new CustomEvent("WebAssemblyLoaded")););
231 }
232
233 EMSCRIPTEN_KEEPALIVE
234 void Initialize()
235 {
236 canvas1_.reset(new WebAssemblyCanvas("mycanvas1"));
237 PrepareScene(canvas1_->GetScene());
238 canvas1_->UpdateSize();
239
240 canvas2_.reset(new WebAssemblyCanvas("mycanvas2"));
241 PrepareScene(canvas2_->GetScene());
242 canvas2_->UpdateSize();
243
244 canvas3_.reset(new WebAssemblyCanvas("mycanvas3"));
245 PrepareScene(canvas3_->GetScene());
246 canvas3_->UpdateSize();
247
248 emscripten_set_resize_callback("#window", NULL, false, OnWindowResize);
249 emscripten_set_click_callback("mycanvas1", canvas1_.get(), false, OnMouseClick);
250 emscripten_set_click_callback("mycanvas2", canvas2_.get(), false, OnMouseClick);
251 emscripten_set_click_callback("mycanvas3", canvas3_.get(), false, OnMouseClick);
252 }
253 }