comparison Framework/Scene2D/Internals/OpenGLInfoPanelRenderer.cpp @ 1325:be17fed8c7c5 broker

Added flag in InfoPanelSceneLayer to apply the scene rotation to the displayed image.
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 24 Mar 2020 20:34:28 +0100
parents 2d8ab34c8c91
children
comparison
equal deleted inserted replaced
1324:4d8d642f7036 1325:be17fed8c7c5
30 if (!context_.IsContextLost()) 30 if (!context_.IsContextLost())
31 { 31 {
32 context_.MakeCurrent(); 32 context_.MakeCurrent();
33 texture_.reset(new OpenGL::OpenGLTexture(context_)); 33 texture_.reset(new OpenGL::OpenGLTexture(context_));
34 texture_->Load(layer.GetTexture(), layer.IsLinearInterpolation()); 34 texture_->Load(layer.GetTexture(), layer.IsLinearInterpolation());
35 applySceneRotation_ = layer.ShouldApplySceneRotation();
35 anchor_ = layer.GetAnchor(); 36 anchor_ = layer.GetAnchor();
36 } 37 }
37 } 38 }
38 39
39 OpenGLInfoPanelRenderer::OpenGLInfoPanelRenderer(OpenGL::IOpenGLContext& context, 40 OpenGLInfoPanelRenderer::OpenGLInfoPanelRenderer(OpenGL::IOpenGLContext& context,
40 OpenGLColorTextureProgram& program, 41 OpenGLColorTextureProgram& program,
41 const InfoPanelSceneLayer& layer) : 42 const InfoPanelSceneLayer& layer) :
42 context_(context), 43 context_(context),
43 program_(program), 44 program_(program),
44 anchor_(BitmapAnchor_TopLeft) 45 anchor_(BitmapAnchor_TopLeft),
46 applySceneRotation_(false)
45 { 47 {
46 LoadTexture(layer); 48 LoadTexture(layer);
47 } 49 }
48
49 50
50 void OpenGLInfoPanelRenderer::Render(const AffineTransform2D& transform, 51 void OpenGLInfoPanelRenderer::Render(const AffineTransform2D& transform,
51 unsigned int canvasWidth, 52 unsigned int canvasWidth,
52 unsigned int canvasHeight) 53 unsigned int canvasHeight)
53 { 54 {
58 dx, dy, anchor_, texture_->GetWidth(), texture_->GetHeight(), 59 dx, dy, anchor_, texture_->GetWidth(), texture_->GetHeight(),
59 canvasWidth, canvasHeight); 60 canvasWidth, canvasHeight);
60 61
61 // The position of this type of layer is layer: Ignore the 62 // The position of this type of layer is layer: Ignore the
62 // "transform" coming from the scene 63 // "transform" coming from the scene
63 program_.Apply(*texture_, AffineTransform2D::CreateOffset(dx, dy), true); 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);
64 } 114 }
65 } 115 }
66 } 116 }
67 } 117 }