CVB++ 15.0
detail_opengl_image_renderer.hpp
1#pragma once
2
3#include "../../global.hpp"
4
5#include "../_decl/decl_opengl_image_renderer.hpp"
6
7namespace Cvb
8{
9
10 CVB_BEGIN_INLINE_NS
11
12 namespace UI
13 {
14
15 inline void OpenGLImageRenderer::UpdateMaping(const QRectF &sourceRect, Size2D<int> textureRect) noexcept
16 {
17
18 OpenGLCoordArray coordArray;
19
20 coordArray.TopLeft.VerPoint =
21 QVector2D(static_cast<float>(sourceRect.left()), static_cast<float>(sourceRect.top()));
22 coordArray.BottomLeft.VerPoint =
23 QVector2D(static_cast<float>(sourceRect.left()), static_cast<float>(sourceRect.bottom()));
24 coordArray.BottomRight.VerPoint =
25 QVector2D(static_cast<float>(sourceRect.right()), static_cast<float>(sourceRect.bottom()));
26 coordArray.TopRight.VerPoint =
27 QVector2D(static_cast<float>(sourceRect.right()), static_cast<float>(sourceRect.top()));
28
29 auto topAdjust = static_cast<float>(sourceRect.top() - qFloor(sourceRect.top()));
30 auto leftAdjust = static_cast<float>(sourceRect.left() - qFloor(sourceRect.left()));
31 auto bottomAdjust = static_cast<float>(qCeil(sourceRect.bottom()) - sourceRect.bottom());
32 auto rightAdjust = static_cast<float>(qCeil(sourceRect.right()) - sourceRect.right());
33
34 if (textureRect.Width() && textureRect.Height())
35 {
36 topAdjust /= static_cast<float>(textureRect.Height());
37 leftAdjust /= static_cast<float>(textureRect.Width());
38 bottomAdjust /= static_cast<float>(textureRect.Height());
39 rightAdjust /= static_cast<float>(textureRect.Width());
40 }
41
42 coordArray.TopLeft.TexPoint = QVector2D(0.0f + leftAdjust, 0.0f + topAdjust);
43 coordArray.BottomLeft.TexPoint = QVector2D(0.0f + leftAdjust, 1.0f - bottomAdjust);
44 coordArray.BottomRight.TexPoint = QVector2D(1.0f - rightAdjust, 1.0f - bottomAdjust);
45 coordArray.TopRight.TexPoint = QVector2D(1.0f - rightAdjust, 0.0f + topAdjust);
46
47 coordBuffer_->Bind();
48 coordBuffer_->Data(static_cast<int>(sizeof(OpenGLCoordArray)), &coordArray);
49 coordBuffer_->Release();
50 }
51
52 inline void OpenGLImageRenderer::Render(const QRectF &rect) noexcept
53 {
54 if (!coordBuffer_ || !texture_)
55 return;
56
57 float nr = -10.0f;
58 float fr = 10.0f;
59 float r_l = static_cast<float>(rect.right() - rect.left());
60 float t_b = static_cast<float>(rect.top() - rect.bottom());
61 float f_n = fr - nr;
62 float tx = static_cast<float>(-(rect.right() + rect.left()) / (rect.right() - rect.left()));
63 float ty = static_cast<float>(-(rect.top() + rect.bottom()) / (rect.top() - rect.bottom()));
64 float tz = -(fr + nr) / (fr - nr);
65
66 QMatrix4x4 modelView; // NOLINT(cppcoreguidelines-init-variables)
67 auto modelViewData = modelView.data();
68
69 modelViewData[0] = 2.0f / r_l;
70 modelViewData[1] = 0.0f;
71 modelViewData[2] = 0.0f;
72 modelViewData[3] = 0.0f;
73
74 modelViewData[4] = 0.0f;
75 modelViewData[5] = 2.0f / t_b;
76 modelViewData[6] = 0.0f;
77 modelViewData[7] = 0.0f;
78
79 modelViewData[8] = 0.0f;
80 modelViewData[9] = 0.0f;
81 modelViewData[10] = 2.0f / f_n;
82 modelViewData[11] = 0.0f;
83
84 modelViewData[12] = tx;
85 modelViewData[13] = ty;
86 modelViewData[14] = tz;
87 modelViewData[15] = 1.0;
88
89 coordBuffer_->Bind();
90 texture_->Bind();
91 program_.bind();
92
93 program_.setUniformValue(unifModelView_, modelView);
94 program_.setUniformValue(unifTexture_, 0);
95 program_.enableAttributeArray(attrVertex_);
96 program_.enableAttributeArray(attrTexcoord_);
97
98 program_.setAttributeBuffer(attrVertex_, GL_FLOAT, 0, 2,
99 4 * sizeof(GL_FLOAT)); // NOLINT(bugprone-sizeof-expression)
100 program_.setAttributeBuffer(attrTexcoord_, GL_FLOAT, 2 * sizeof(GL_FLOAT), 2,
101 4 * sizeof(GL_FLOAT)); // NOLINT(bugprone-sizeof-expression)
102
103 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
104
105 program_.disableAttributeArray(attrTexcoord_);
106 program_.disableAttributeArray(attrVertex_);
107
108 program_.release();
109 texture_->Release();
110 coordBuffer_->Release();
111 }
112
113 inline OpenGLImageRenderer::OpenGLImageRenderer() noexcept
114 {
115 initializeOpenGLFunctions();
116
117 program_.addShaderFromSourceCode(QOpenGLShader::Vertex,
118 "#ifdef GL_ES\n"
119 "// Set default precision to medium\n"
120 "precision mediump int;\n"
121 "precision mediump float;\n"
122 "#endif\n"
123 "\n"
124 "uniform mat4 matrix;"
125 "attribute vec2 coord2d;\n"
126 "attribute vec2 texcoord;\n"
127 "varying vec2 f_texcoord;\n"
128 "void main(void)\n"
129 "{\n"
130 " gl_Position = matrix * vec4(coord2d, 0.0, 1.0);\n"
131 " f_texcoord = texcoord;\n"
132 "}");
133
134 program_.addShaderFromSourceCode(QOpenGLShader::Fragment,
135 "#ifdef GL_ES\n"
136 "// Set default precision to medium\n"
137 "precision mediump int;\n"
138 "precision mediump float;\n"
139 "#endif\n"
140 "\n"
141 "varying vec2 f_texcoord;"
142 "uniform sampler2D texture;"
143 "void main(void)"
144 "{"
145 "gl_FragColor = texture2D(texture, f_texcoord);"
146 "}");
147
148 program_.link();
149
150 attrVertex_ = program_.attributeLocation("coord2d"); // NOLINT(cppcoreguidelines-prefer-member-initializer)
151 attrTexcoord_ = program_.attributeLocation("texcoord"); // NOLINT(cppcoreguidelines-prefer-member-initializer)
152 unifModelView_ = program_.uniformLocation("matrix"); // NOLINT(cppcoreguidelines-prefer-member-initializer)
153 unifTexture_ = program_.uniformLocation("texture"); // NOLINT(cppcoreguidelines-prefer-member-initializer)
154
155 program_.bind();
156
157 coordBuffer_.reset(new (std::nothrow) GLCoordBuffer); // NOLINT(cppcoreguidelines-owning-memory)
158 if (coordBuffer_)
159 {
160 coordBuffer_->Bind();
161 OpenGLCoordArray coordArray;
162 coordBuffer_->Data(static_cast<int>(sizeof(OpenGLCoordArray)), &coordArray);
163 coordBuffer_->Release();
164 }
165
166 texture_.reset(new (std::nothrow) GLTexture); // NOLINT(cppcoreguidelines-owning-memory)
167
168 program_.release();
169 }
170
171 inline void OpenGLImageRenderer::BindTexture() noexcept
172 {
173 texture_->Bind();
174 }
175
176 inline void OpenGLImageRenderer::ReleaseTexture() noexcept
177 {
178 texture_->Release();
179 }
180
181 inline void OpenGLImageRenderer::Image2DTexture(const OpenGLBufferFormat &pixelBufferFormat, void *pixels,
182 bool swizzleSupport) noexcept
183 {
184 texture_->Image2D(pixelBufferFormat, pixels, swizzleSupport);
185 }
186
187 inline void OpenGLImageRenderer::Image2DTexture(void *pixels, bool swizzleSupport) noexcept
188 {
189 texture_->Image2D(pixels, swizzleSupport);
190 }
191
192 inline OpenGLImageRenderer::GLTexture::GLTexture() noexcept
193 {
194 initializeOpenGLFunctions();
195 glGenTextures(1, &handle_);
196 }
197
198 inline OpenGLImageRenderer::GLTexture::~GLTexture()
199 {
200 glDeleteTextures(1, &handle_);
201 }
202
203 inline void OpenGLImageRenderer::GLTexture::Bind() noexcept
204 {
205 glBindTexture(GL_TEXTURE_2D, handle_);
206 }
207
208 inline void OpenGLImageRenderer::GLTexture::Release() noexcept
209 {
210 glBindTexture(GL_TEXTURE_2D, 0);
211 }
212
213 inline void OpenGLImageRenderer::GLTexture::Image2D(const OpenGLBufferFormat &pixelBufferFormat, void *pixels,
214 bool swizzleSupport) noexcept
215 {
216 pixelBufferFormat_ = pixelBufferFormat;
217 Image2D(pixels, swizzleSupport);
218 }
219
220 inline void OpenGLImageRenderer::GLTexture::Image2D(void *pixels, bool swizzleSupport) noexcept
221 {
222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
224
225 if (swizzleSupport)
226 {
227 if (pixelBufferFormat_.TextureFormat == OpenGLTextureFormat::Mono)
228 {
229
230 std::array<GLint, 4> swizzleMask = {GL_RED, GL_RED, GL_RED, GL_ALPHA};
231 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, &swizzleMask[0]);
232 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, &swizzleMask[1]);
233 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, &swizzleMask[2]);
234 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, &swizzleMask[3]);
235 }
236 else
237 {
238 std::array<GLint, 4> swizzleMask = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
239 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, &swizzleMask[0]);
240 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, &swizzleMask[1]);
241 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, &swizzleMask[2]);
242 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, &swizzleMask[3]);
243 }
244 }
245
246 glTexImage2D(GL_TEXTURE_2D, 0,
247 (pixelBufferFormat_.TextureFormat == OpenGLTextureFormat::RGB || !swizzleSupport) ? GL_RGBA : GL_RED,
248 static_cast<GLsizei>(pixelBufferFormat_.Width), static_cast<GLsizei>(pixelBufferFormat_.Height), 0,
249 (pixelBufferFormat_.TextureFormat == OpenGLTextureFormat::RGB || !swizzleSupport) ? GL_RGBA : GL_RED,
250 GL_UNSIGNED_BYTE, pixels);
251 }
252
253 inline OpenGLImageRenderer::GLCoordBuffer::GLCoordBuffer() noexcept
254 {
255 initializeOpenGLFunctions();
256 glGenBuffers(1, &handle_);
257 }
258
259 inline OpenGLImageRenderer::GLCoordBuffer::~GLCoordBuffer()
260 {
261 glDeleteBuffers(1, &handle_);
262 }
263
264 inline void OpenGLImageRenderer::GLCoordBuffer::Bind() noexcept
265 {
266 glBindBuffer(GL_ARRAY_BUFFER, handle_);
267 }
268
269 inline void OpenGLImageRenderer::GLCoordBuffer::Release() noexcept
270 {
271 glBindBuffer(GL_ARRAY_BUFFER, 0);
272 }
273
274 inline void OpenGLImageRenderer::GLCoordBuffer::Data(int size, void *buffer) noexcept
275 {
276 glBufferData(GL_ARRAY_BUFFER, static_cast<qopengl_GLsizeiptr>(size), buffer, GL_STREAM_DRAW);
277 }
278
279 } // namespace UI
280
281 CVB_END_INLINE_NS
282
283} // namespace Cvb
Stores a pair of numbers that represents the width and the height of a subject, typically a rectangle...
Definition size_2d.hpp:20
void Render(const QRectF &viewportRect) noexcept
Actually renders the image.
Definition detail_opengl_image_renderer.hpp:52
void UpdateMaping(const QRectF &sourceRect, Size2D< int > textureSize) noexcept
Updates the vertex and texture coordinates before rendering.
Definition detail_opengl_image_renderer.hpp:15
Namespace for user interface components.
Definition decl_image_scene.hpp:39
@ Mono
Definition ui.hpp:144
@ RGB
Definition ui.hpp:140
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
Buffer format description for a texture to hold the pixel data.
Definition ui.hpp:151
Set of all coordinates required to render a texture.
Definition ui.hpp:217
OpenGLCoord BottomRight
Definition ui.hpp:229
OpenGLCoord TopRight
Definition ui.hpp:233
OpenGLCoord TopLeft
Definition ui.hpp:221
OpenGLCoord BottomLeft
Definition ui.hpp:225
QVector2D VerPoint
Definition ui.hpp:206
QVector2D TexPoint
Definition ui.hpp:210