comparison OrthancStone/Sources/Scene2D/OpenGLCompositor.cpp @ 1512:244ad1e4e76a

reorganization of folders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 Jul 2020 16:21:02 +0200
parents Framework/Scene2D/OpenGLCompositor.cpp@5c96bf3f1d32
children 85e117739eca
comparison
equal deleted inserted replaced
1511:9dfeee74c1e6 1512:244ad1e4e76a
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-2020 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 #include "OpenGLCompositor.h"
22
23 #include "Internals/OpenGLAdvancedPolylineRenderer.h"
24 #include "Internals/OpenGLBasicPolylineRenderer.h"
25 #include "Internals/OpenGLColorTextureRenderer.h"
26 #include "Internals/OpenGLFloatTextureRenderer.h"
27 #include "Internals/OpenGLInfoPanelRenderer.h"
28 #include "Internals/OpenGLLookupTableTextureRenderer.h"
29 #include "Internals/OpenGLTextRenderer.h"
30
31 namespace OrthancStone
32 {
33 class OpenGLCompositor::Font : public boost::noncopyable
34 {
35 private:
36 std::unique_ptr<GlyphTextureAlphabet> alphabet_;
37 std::unique_ptr<OpenGL::OpenGLTexture> texture_;
38
39 public:
40 Font(OpenGL::IOpenGLContext& context, const GlyphBitmapAlphabet& dict)
41 {
42 alphabet_.reset(new GlyphTextureAlphabet(dict));
43 texture_.reset(new OpenGL::OpenGLTexture(context));
44
45 std::unique_ptr<Orthanc::ImageAccessor> bitmap(alphabet_->ReleaseTexture());
46 texture_->Load(*bitmap, true /* enable linear interpolation */);
47 }
48
49 OpenGL::OpenGLTexture& GetTexture() const
50 {
51 assert(texture_.get() != NULL);
52 return *texture_;
53 }
54
55 const GlyphTextureAlphabet& GetAlphabet() const
56 {
57 assert(alphabet_.get() != NULL);
58 return *alphabet_;
59 }
60 };
61
62 const OpenGLCompositor::Font* OpenGLCompositor::GetFont(size_t fontIndex) const
63 {
64 Fonts::const_iterator found = fonts_.find(fontIndex);
65
66 if (found == fonts_.end())
67 {
68 return NULL; // Unknown font, nothing should be drawn
69 }
70 else
71 {
72 assert(found->second != NULL);
73 return found->second;
74 }
75 }
76
77 Internals::CompositorHelper::ILayerRenderer* OpenGLCompositor::Create(const ISceneLayer& layer)
78 {
79 if (!context_.IsContextLost())
80 {
81 switch (layer.GetType())
82 {
83 case ISceneLayer::Type_InfoPanel:
84 return new Internals::OpenGLInfoPanelRenderer
85 (context_, colorTextureProgram_, dynamic_cast<const InfoPanelSceneLayer&>(layer));
86
87 case ISceneLayer::Type_ColorTexture:
88 return new Internals::OpenGLColorTextureRenderer
89 (context_, colorTextureProgram_, dynamic_cast<const ColorTextureSceneLayer&>(layer));
90
91 case ISceneLayer::Type_FloatTexture:
92 return new Internals::OpenGLFloatTextureRenderer
93 (context_, floatTextureProgram_, dynamic_cast<const FloatTextureSceneLayer&>(layer));
94
95 case ISceneLayer::Type_LookupTableTexture:
96 return new Internals::OpenGLLookupTableTextureRenderer
97 (context_, colorTextureProgram_, dynamic_cast<const LookupTableTextureSceneLayer&>(layer));
98
99 case ISceneLayer::Type_Polyline:
100 return new Internals::OpenGLAdvancedPolylineRenderer
101 (context_, linesProgram_, dynamic_cast<const PolylineSceneLayer&>(layer));
102 //return new Internals::OpenGLBasicPolylineRenderer(context_, dynamic_cast<const PolylineSceneLayer&>(layer));
103
104 case ISceneLayer::Type_Text:
105 {
106 const TextSceneLayer& l = dynamic_cast<const TextSceneLayer&>(layer);
107 const Font* font = GetFont(l.GetFontIndex());
108 if (font == NULL)
109 {
110 LOG(WARNING) << "There is no font at index " << l.GetFontIndex();
111 return NULL;
112 }
113 else
114 {
115 return new Internals::OpenGLTextRenderer
116 (context_, textProgram_, font->GetAlphabet(), font->GetTexture(), l);
117 }
118 }
119
120 default:
121 return NULL;
122 }
123 }
124 else
125 {
126 // context is lost. returning null.
127 return NULL;
128 }
129 }
130
131 OpenGLCompositor::OpenGLCompositor(OpenGL::IOpenGLContext& context) :
132 context_(context),
133 colorTextureProgram_(context),
134 floatTextureProgram_(context),
135 linesProgram_(context),
136 textProgram_(context),
137 canvasWidth_(0),
138 canvasHeight_(0)
139 {
140 if (!context_.IsContextLost())
141 {
142 canvasWidth_ = context_.GetCanvasWidth();
143 canvasHeight_ = context_.GetCanvasHeight();
144 }
145
146 ResetScene();
147 }
148
149 OpenGLCompositor::~OpenGLCompositor()
150 {
151 if (!context_.IsContextLost())
152 {
153 try
154 {
155 try
156 {
157 context_.MakeCurrent(); // this can throw if context lost!
158 }
159 catch (...)
160 {
161 LOG(ERROR) << "context_.MakeCurrent() failed in OpenGLCompositor::~OpenGLCompositor()!";
162 }
163
164 for (Fonts::iterator it = fonts_.begin(); it != fonts_.end(); ++it)
165 {
166 try
167 {
168
169 assert(it->second != NULL);
170 delete it->second;
171 }
172 catch (...)
173 {
174 LOG(ERROR) << "Exception thrown while deleting OpenGL-based font!";
175 }
176 }
177 }
178 catch (...)
179 {
180 // logging threw an exception!
181 }
182 }
183 }
184
185 void OpenGLCompositor::Refresh(const Scene2D& scene)
186 {
187 if (!context_.IsContextLost())
188 {
189 context_.MakeCurrent(); // this can throw if context lost!
190 canvasWidth_ = context_.GetCanvasWidth();
191 canvasHeight_ = context_.GetCanvasHeight();
192
193 glViewport(0, 0, canvasWidth_, canvasHeight_);
194 glClearColor(0, 0, 0, 1);
195 glClear(GL_COLOR_BUFFER_BIT);
196
197 helper_->Refresh(scene, canvasWidth_, canvasHeight_);
198
199 context_.SwapBuffer();
200 }
201 }
202
203 void OpenGLCompositor::SetFont(size_t index,
204 const GlyphBitmapAlphabet& dict)
205 {
206 if (!context_.IsContextLost())
207 {
208 context_.MakeCurrent(); // this can throw if context lost
209
210 std::unique_ptr<Font> font(new Font(context_, dict));
211
212 Fonts::iterator found = fonts_.find(index);
213
214 if (found == fonts_.end())
215 {
216 fonts_[index] = font.release();
217 }
218 else
219 {
220 assert(found->second != NULL);
221 delete found->second;
222
223 found->second = font.release();
224 }
225 }
226 }
227
228 #if ORTHANC_ENABLE_LOCALE == 1
229 void OpenGLCompositor::SetFont(size_t index,
230 const std::string& ttf,
231 unsigned int fontSize,
232 Orthanc::Encoding codepage)
233 {
234 if (!context_.IsContextLost())
235 {
236 FontRenderer renderer;
237 renderer.LoadFont(ttf, fontSize);
238
239 GlyphBitmapAlphabet dict;
240 dict.LoadCodepage(renderer, codepage);
241
242 SetFont(index, dict);
243 }
244 }
245 #endif
246
247
248 void OpenGLCompositor::RefreshCanvasSize()
249 {
250 if (!context_.IsContextLost())
251 {
252 context_.MakeCurrent(); // this can throw if context lost!
253 context_.RefreshCanvasSize(); // Difference with Refresh(scene)
254 canvasWidth_ = context_.GetCanvasWidth();
255 canvasHeight_ = context_.GetCanvasHeight();
256 }
257 }
258 }