Mercurial > hg > orthanc-stone
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLInfoPanelRenderer.cpp Tue Jul 07 16:21:02 2020 +0200 @@ -0,0 +1,117 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2020 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "OpenGLInfoPanelRenderer.h" + +namespace OrthancStone +{ + namespace Internals + { + void OpenGLInfoPanelRenderer::LoadTexture(const InfoPanelSceneLayer& layer) + { + if (!context_.IsContextLost()) + { + context_.MakeCurrent(); + texture_.reset(new OpenGL::OpenGLTexture(context_)); + texture_->Load(layer.GetTexture(), layer.IsLinearInterpolation()); + applySceneRotation_ = layer.ShouldApplySceneRotation(); + anchor_ = layer.GetAnchor(); + } + } + + OpenGLInfoPanelRenderer::OpenGLInfoPanelRenderer(OpenGL::IOpenGLContext& context, + OpenGLColorTextureProgram& program, + const InfoPanelSceneLayer& layer) : + context_(context), + program_(program), + anchor_(BitmapAnchor_TopLeft), + applySceneRotation_(false) + { + LoadTexture(layer); + } + + void OpenGLInfoPanelRenderer::Render(const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight) + { + if (!context_.IsContextLost() && texture_.get() != NULL) + { + int dx = 0, dy = 0; + InfoPanelSceneLayer::ComputeAnchorLocation( + dx, dy, anchor_, texture_->GetWidth(), texture_->GetHeight(), + canvasWidth, canvasHeight); + + // The position of this type of layer is layer: Ignore the + // "transform" coming from the scene + AffineTransform2D actualTransform = + AffineTransform2D::CreateOffset(dx, dy); + + if (applySceneRotation_) + { + // the transformation is as follows: + // - originally, the image is aligned so that its top left corner + // is at 0,0 + // - first, we translate the image by -w/2,-h/2 + // - then we rotate it, so that the next rotation will make the + // image rotate around its center. + // - then, we translate the image by +w/2,+h/2 to put it + // back in place + // - the fourth and last transform is the one that brings the + // image to its desired anchored location. + + int32_t halfWidth = + static_cast<int32_t>(0.5 * texture_->GetWidth()); + + int32_t halfHeight= + static_cast<int32_t>(0.5 * texture_->GetHeight()); + + AffineTransform2D translation1 = + AffineTransform2D::CreateOffset(-halfWidth, -halfHeight); + + const Matrix& sceneTransformM = transform.GetHomogeneousMatrix(); + Matrix r; + Matrix q; + LinearAlgebra::RQDecomposition3x3(r, q, sceneTransformM); + + // counterintuitively, q is the rotation and r is the upper + // triangular + AffineTransform2D rotation(q); + + AffineTransform2D translation2 = + AffineTransform2D::CreateOffset(halfWidth, halfHeight); + + // please note that the last argument is the 1st applied + // transformation (rationale: if arguments are a, b and c, then + // the resulting matrix is a*b*c: + // x2 = (a*b*c)*x1 = (a*(b*(c*x1))) (you can see that the result + // of c*x1 is transformed by b, and the result of b*c*x1 is trans- + // formed by a) + actualTransform = AffineTransform2D::Combine(actualTransform, + translation2, + rotation, + translation1); + } + + program_.Apply(*texture_, actualTransform, true); + } + } + } +}