Mercurial > hg > orthanc-stone
comparison Framework/OpenGL/WebAssemblyOpenGLContext.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 #include "WebAssemblyOpenGLContext.h" | |
23 | |
24 #if ORTHANC_ENABLE_WASM == 1 | |
25 | |
26 #include <Core/OrthancException.h> | |
27 | |
28 #include <emscripten/html5.h> | |
29 #include <boost/math/special_functions/round.hpp> | |
30 | |
31 namespace OrthancStone | |
32 { | |
33 namespace OpenGL | |
34 { | |
35 class WebAssemblyOpenGLContext::PImpl | |
36 { | |
37 private: | |
38 std::string canvas_; | |
39 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context_; | |
40 unsigned int canvasWidth_; | |
41 unsigned int canvasHeight_; | |
42 | |
43 public: | |
44 PImpl(const std::string& canvas) : | |
45 canvas_(canvas) | |
46 { | |
47 // Context configuration | |
48 EmscriptenWebGLContextAttributes attr; | |
49 emscripten_webgl_init_context_attributes(&attr); | |
50 | |
51 context_ = emscripten_webgl_create_context(canvas.c_str(), &attr); | |
52 if (context_ < 0) | |
53 { | |
54 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, | |
55 "Cannot create an OpenGL context for canvas: " + canvas); | |
56 } | |
57 | |
58 UpdateSize(); | |
59 } | |
60 | |
61 ~PImpl() | |
62 { | |
63 emscripten_webgl_destroy_context(context_); | |
64 } | |
65 | |
66 void MakeCurrent() | |
67 { | |
68 if (emscripten_webgl_make_context_current(context_) != EMSCRIPTEN_RESULT_SUCCESS) | |
69 { | |
70 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, | |
71 "Cannot set the OpenGL context"); | |
72 } | |
73 } | |
74 | |
75 void SwapBuffer() | |
76 { | |
77 /** | |
78 * "Rendered WebGL content is implicitly presented (displayed to | |
79 * the user) on the canvas when the event handler that renders with | |
80 * WebGL returns back to the browser event loop." | |
81 * https://emscripten.org/docs/api_reference/html5.h.html#webgl-context | |
82 * | |
83 * Could call "emscripten_webgl_commit_frame()" if | |
84 * "explicitSwapControl" option were set to "true". | |
85 **/ | |
86 } | |
87 | |
88 unsigned int GetCanvasWidth() const | |
89 { | |
90 return canvasWidth_; | |
91 } | |
92 | |
93 unsigned int GetCanvasHeight() const | |
94 { | |
95 return canvasHeight_; | |
96 } | |
97 | |
98 void UpdateSize() | |
99 { | |
100 double w, h; | |
101 emscripten_get_element_css_size(canvas_.c_str(), &w, &h); | |
102 | |
103 /** | |
104 * Emscripten has the function emscripten_get_element_css_size() | |
105 * to query the width and height of a named HTML element. I'm | |
106 * calling this first to get the initial size of the canvas DOM | |
107 * element, and then call emscripten_set_canvas_size() to | |
108 * initialize the framebuffer size of the canvas to the same | |
109 * size as its DOM element. | |
110 * https://floooh.github.io/2017/02/22/emsc-html.html | |
111 **/ | |
112 | |
113 if (w <= 0 || | |
114 h <= 0) | |
115 { | |
116 canvasWidth_ = 0; | |
117 canvasHeight_ = 0; | |
118 } | |
119 else | |
120 { | |
121 canvasWidth_ = static_cast<unsigned int>(boost::math::iround(w)); | |
122 canvasHeight_ = static_cast<unsigned int>(boost::math::iround(h)); | |
123 } | |
124 | |
125 emscripten_set_canvas_element_size(canvas_.c_str(), canvasWidth_, canvasHeight_); | |
126 } | |
127 }; | |
128 | |
129 | |
130 WebAssemblyOpenGLContext::WebAssemblyOpenGLContext(const std::string& canvas) : | |
131 pimpl_(new PImpl(canvas)) | |
132 { | |
133 } | |
134 | |
135 void WebAssemblyOpenGLContext::MakeCurrent() | |
136 { | |
137 assert(pimpl_.get() != NULL); | |
138 pimpl_->MakeCurrent(); | |
139 } | |
140 | |
141 | |
142 void WebAssemblyOpenGLContext::SwapBuffer() | |
143 { | |
144 assert(pimpl_.get() != NULL); | |
145 pimpl_->SwapBuffer(); | |
146 } | |
147 | |
148 unsigned int WebAssemblyOpenGLContext::GetCanvasWidth() const | |
149 { | |
150 assert(pimpl_.get() != NULL); | |
151 return pimpl_->GetCanvasWidth(); | |
152 } | |
153 | |
154 unsigned int WebAssemblyOpenGLContext::GetCanvasHeight() const | |
155 { | |
156 assert(pimpl_.get() != NULL); | |
157 return pimpl_->GetCanvasHeight(); | |
158 } | |
159 | |
160 void WebAssemblyOpenGLContext::UpdateSize() | |
161 { | |
162 assert(pimpl_.get() != NULL); | |
163 pimpl_->UpdateSize(); | |
164 } | |
165 } | |
166 } | |
167 | |
168 #endif |