Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Scene2D/Internals/OpenGLInfoPanelRenderer.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/Internals/OpenGLInfoPanelRenderer.cpp@be17fed8c7c5 |
children | 92fca2b3ba3d |
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 | |
22 #include "OpenGLInfoPanelRenderer.h" | |
23 | |
24 namespace OrthancStone | |
25 { | |
26 namespace Internals | |
27 { | |
28 void OpenGLInfoPanelRenderer::LoadTexture(const InfoPanelSceneLayer& layer) | |
29 { | |
30 if (!context_.IsContextLost()) | |
31 { | |
32 context_.MakeCurrent(); | |
33 texture_.reset(new OpenGL::OpenGLTexture(context_)); | |
34 texture_->Load(layer.GetTexture(), layer.IsLinearInterpolation()); | |
35 applySceneRotation_ = layer.ShouldApplySceneRotation(); | |
36 anchor_ = layer.GetAnchor(); | |
37 } | |
38 } | |
39 | |
40 OpenGLInfoPanelRenderer::OpenGLInfoPanelRenderer(OpenGL::IOpenGLContext& context, | |
41 OpenGLColorTextureProgram& program, | |
42 const InfoPanelSceneLayer& layer) : | |
43 context_(context), | |
44 program_(program), | |
45 anchor_(BitmapAnchor_TopLeft), | |
46 applySceneRotation_(false) | |
47 { | |
48 LoadTexture(layer); | |
49 } | |
50 | |
51 void OpenGLInfoPanelRenderer::Render(const AffineTransform2D& transform, | |
52 unsigned int canvasWidth, | |
53 unsigned int canvasHeight) | |
54 { | |
55 if (!context_.IsContextLost() && texture_.get() != NULL) | |
56 { | |
57 int dx = 0, dy = 0; | |
58 InfoPanelSceneLayer::ComputeAnchorLocation( | |
59 dx, dy, anchor_, texture_->GetWidth(), texture_->GetHeight(), | |
60 canvasWidth, canvasHeight); | |
61 | |
62 // The position of this type of layer is layer: Ignore the | |
63 // "transform" coming from the scene | |
64 AffineTransform2D actualTransform = | |
65 AffineTransform2D::CreateOffset(dx, dy); | |
66 | |
67 if (applySceneRotation_) | |
68 { | |
69 // the transformation is as follows: | |
70 // - originally, the image is aligned so that its top left corner | |
71 // is at 0,0 | |
72 // - first, we translate the image by -w/2,-h/2 | |
73 // - then we rotate it, so that the next rotation will make the | |
74 // image rotate around its center. | |
75 // - then, we translate the image by +w/2,+h/2 to put it | |
76 // back in place | |
77 // - the fourth and last transform is the one that brings the | |
78 // image to its desired anchored location. | |
79 | |
80 int32_t halfWidth = | |
81 static_cast<int32_t>(0.5 * texture_->GetWidth()); | |
82 | |
83 int32_t halfHeight= | |
84 static_cast<int32_t>(0.5 * texture_->GetHeight()); | |
85 | |
86 AffineTransform2D translation1 = | |
87 AffineTransform2D::CreateOffset(-halfWidth, -halfHeight); | |
88 | |
89 const Matrix& sceneTransformM = transform.GetHomogeneousMatrix(); | |
90 Matrix r; | |
91 Matrix q; | |
92 LinearAlgebra::RQDecomposition3x3(r, q, sceneTransformM); | |
93 | |
94 // counterintuitively, q is the rotation and r is the upper | |
95 // triangular | |
96 AffineTransform2D rotation(q); | |
97 | |
98 AffineTransform2D translation2 = | |
99 AffineTransform2D::CreateOffset(halfWidth, halfHeight); | |
100 | |
101 // please note that the last argument is the 1st applied | |
102 // transformation (rationale: if arguments are a, b and c, then | |
103 // the resulting matrix is a*b*c: | |
104 // x2 = (a*b*c)*x1 = (a*(b*(c*x1))) (you can see that the result | |
105 // of c*x1 is transformed by b, and the result of b*c*x1 is trans- | |
106 // formed by a) | |
107 actualTransform = AffineTransform2D::Combine(actualTransform, | |
108 translation2, | |
109 rotation, | |
110 translation1); | |
111 } | |
112 | |
113 program_.Apply(*texture_, actualTransform, true); | |
114 } | |
115 } | |
116 } | |
117 } |