SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
glshadertvarray.cpp
Go to the documentation of this file.
1 // Copyright (C) 2017 F4HKW //
3 // for F4EXB / SDRAngel //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #include <gui/glshadertvarray.h>
20 
21 const QString GLShaderTVArray::m_strVertexShaderSourceArray = QString(
22  "uniform highp mat4 uMatrix;\n"
23  "attribute highp vec4 vertex;\n"
24  "attribute highp vec2 texCoord;\n"
25  "varying mediump vec2 texCoordVar;\n"
26  "void main() {\n"
27  " gl_Position = uMatrix * vertex;\n"
28  " texCoordVar = texCoord;\n"
29  "}\n");
30 
32  "uniform lowp sampler2D uTexture;\n"
33  "varying mediump vec2 texCoordVar;\n"
34  "void main() {\n"
35  " gl_FragColor = texture2D(uTexture, texCoordVar);\n"
36  "}\n");
37 
38 GLShaderTVArray::GLShaderTVArray(bool blnColor) : m_blnColor(blnColor)
39 {
40  m_blnAlphaBlend = false;
41  m_blnAlphaReset = false;
42  m_objProgram = 0;
43  m_objImage = 0;
44  m_objTexture = 0;
45  m_intCols = 0;
46  m_intRows = 0;
47  m_blnInitialized = false;
48  m_objCurrentRow = 0;
49 
50  m_objTextureLoc = 0;
51  m_objMatrixLoc = 0;
52 }
53 
55 {
56  Cleanup();
57 }
58 
59 void GLShaderTVArray::InitializeGL(int intCols, int intRows)
60 {
61  QMatrix4x4 objQMatrix;
62 
63  m_blnInitialized = false;
64 
65  m_intCols = 0;
66  m_intRows = 0;
67 
68  m_objCurrentRow = 0;
69 
70  if (m_objProgram == 0)
71  {
72  m_objProgram = new QOpenGLShaderProgram();
73 
74  if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,
76  {
77  qDebug() << "GLShaderArray::initializeGL: error in vertex shader: "
78  << m_objProgram->log();
79  }
80 
81  if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Fragment,
83  {
84  qDebug()
85  << "GLShaderArray::initializeGL: error in fragment shader: "
86  << m_objProgram->log();
87  }
88 
89  m_objProgram->bindAttributeLocation("vertex", 0);
90 
91  if (!m_objProgram->link())
92  {
93  qDebug() << "GLShaderArray::initializeGL: error linking shader: "
94  << m_objProgram->log();
95  }
96 
97  m_objProgram->bind();
98  m_objProgram->setUniformValue(m_objMatrixLoc, objQMatrix);
99  m_objProgram->setUniformValue(m_objTextureLoc, 0);
100  m_objProgram->release();
101  }
102 
103  m_objMatrixLoc = m_objProgram->uniformLocation("uMatrix");
104  m_objTextureLoc = m_objProgram->uniformLocation("uTexture");
105 
106  if (m_objTexture != 0)
107  {
108  delete m_objTexture;
109  m_objTexture = 0;
110  }
111 
112  //Image container
113  m_objImage = new QImage(intCols, intRows, QImage::Format_RGBA8888);
114  m_objImage->fill(QColor(0, 0, 0));
115 
116  m_objTexture = new QOpenGLTexture(*m_objImage);
117  //m_objTexture->setFormat(QOpenGLTexture::RGBA8_UNorm); avoids OpenGL warning and in fact is useless
118  m_objTexture->setMinificationFilter(QOpenGLTexture::Linear);
119  m_objTexture->setMagnificationFilter(QOpenGLTexture::Linear);
120  m_objTexture->setWrapMode(QOpenGLTexture::ClampToEdge);
121 
122  m_intCols = intCols;
123  m_intRows = intRows;
124 
125  m_blnInitialized = true;
126 
127 }
128 
130 {
131  if (!m_blnInitialized)
132  {
133  return 0;
134  }
135 
136  if (m_objImage == 0)
137  {
138  return 0;
139  }
140 
141  if (intRow > m_intRows)
142  {
143  return 0;
144  }
145 
146  return (QRgb *) m_objImage->scanLine(intRow);
147 }
148 
149 void GLShaderTVArray::RenderPixels(unsigned char *chrData)
150 {
151  QOpenGLFunctions *ptrF;
152  int intI;
153  int intJ;
154  int intNbVertices = 6;
155 
156  QMatrix4x4 objQMatrix;
157 
158  GLfloat arrVertices[] =
159  // 2 3
160  // 1 4
161  //1 2 3 3 4 1
162  { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f };
163 
164  GLfloat arrTextureCoords[] =
165  // 1 4
166  // 2 3
167  //1 2 3 3 4 1
168  { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
169 
170  QRgb *ptrLine;
171  int intVal;
172 
173  if (!m_blnInitialized)
174  {
175  return;
176  }
177 
178  if (m_objImage == 0)
179  {
180  return;
181  }
182 
183  if (chrData != 0)
184  {
185  for (intJ = 0; intJ < m_intRows; intJ++)
186  {
187  ptrLine = (QRgb *) m_objImage->scanLine(intJ);
188 
189  for (intI = 0; intI < m_intCols; intI++)
190  {
191  if (m_blnColor)
192  {
193  *ptrLine = qRgb((int) (*(chrData+2)), (int) (*(chrData+1)), (int) (*chrData));
194  chrData+=3;
195  }
196  else
197  {
198  intVal = (int) (*chrData);
199  *ptrLine = qRgb(intVal, intVal, intVal);
200  chrData++;
201  }
202 
203  ptrLine++;
204  }
205  }
206  }
207 
208  //Affichage
209  ptrF = QOpenGLContext::currentContext()->functions();
210 
211  m_objProgram->bind();
212 
213  m_objProgram->setUniformValue(m_objMatrixLoc, objQMatrix);
214  m_objProgram->setUniformValue(m_objTextureLoc, 0);
215 
216  if (m_blnAlphaReset) {
217  ptrF->glClear(GL_COLOR_BUFFER_BIT);
218  m_blnAlphaReset = false;
219  }
220 
221  if (m_blnAlphaBlend) {
222  ptrF->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
223  ptrF->glEnable(GL_BLEND);
224  } else {
225  ptrF->glDisable(GL_BLEND);
226  }
227 
228  m_objTexture->bind();
229 
230  ptrF->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_intCols, m_intRows, GL_RGBA,
231  GL_UNSIGNED_BYTE, m_objImage->bits());
232 
233  ptrF->glEnableVertexAttribArray(0); // vertex
234  ptrF->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, arrVertices);
235 
236  ptrF->glEnableVertexAttribArray(1); // texture coordinates
237  ptrF->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords);
238 
239  ptrF->glDrawArrays(GL_TRIANGLES, 0, intNbVertices);
240 
241  //cleanup
242  ptrF->glDisableVertexAttribArray(0);
243  ptrF->glDisableVertexAttribArray(1);
244 
245  //*********************//
246 
247  m_objTexture->release();
248  m_objProgram->release();
249 }
250 
252 {
253  if (m_objImage != 0)
254  {
255  m_objImage->fill(0);
256  }
257 }
258 
260 {
261  if (m_objImage != 0)
262  {
263  m_objImage->fill(qRgba(0, 0, 0, alpha));
264  }
265 }
266 
268 {
269  m_blnInitialized = false;
270 
271  m_intCols = 0;
272  m_intRows = 0;
273 
274  m_objCurrentRow = 0;
275 
276  if (m_objProgram)
277  {
278  delete m_objProgram;
279  m_objProgram = 0;
280  }
281 
282  if (m_objTexture != 0)
283  {
284  delete m_objTexture;
285  m_objTexture = 0;
286  }
287 
288  if (m_objImage != 0)
289  {
290  delete m_objImage;
291  m_objImage = 0;
292  }
293 }
294 
295 bool GLShaderTVArray::SelectRow(int intLine)
296 {
297  bool blnRslt = false;
298 
299  if (m_blnInitialized)
300  {
301  if ((intLine < m_intRows) && (intLine >= 0))
302  {
303  m_objCurrentRow = (QRgb *) m_objImage->scanLine(intLine);
304  blnRslt = true;
305  }
306  else
307  {
308  m_objCurrentRow = 0;
309  }
310  }
311 
312  return blnRslt;
313 }
314 
315 bool GLShaderTVArray::SetDataColor(int intCol, QRgb objColor)
316 {
317  bool blnRslt = false;
318 
319  if (m_blnInitialized)
320  {
321  if ((intCol < m_intCols) && (intCol >= 0) && (m_objCurrentRow != 0))
322  {
323  m_objCurrentRow[intCol] = objColor;
324  blnRslt = true;
325  }
326  }
327 
328  return blnRslt;
329 }
330 
QRgb * GetRowBuffer(int intRow)
bool SelectRow(int intLine)
GLShaderTVArray(bool blnColor)
void RenderPixels(unsigned char *chrData)
bool SetDataColor(int intCol, QRgb objColor)
void InitializeGL(int intCols, int intRows)
static const QString m_strVertexShaderSourceArray
static const QString m_strFragmentShaderSourceColored
QOpenGLTexture * m_objTexture
QOpenGLShaderProgram * m_objProgram