Mercurial > hg > orthanc-stone
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 } |