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.
glshadertextured.cpp
Go to the documentation of this file.
1 // Copyright (C) 2016 F4EXB //
3 // written by Edouard Griffiths //
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 <QOpenGLShaderProgram>
20 #include <QOpenGLFunctions>
21 #include <QOpenGLContext>
22 #include <QImage>
23 #include <QMatrix4x4>
24 #include <QVector4D>
25 #include <QDebug>
26 
27 #include "gui/glshadertextured.h"
28 
30  m_program(0),
31  m_texture(0),
32  m_matrixLoc(0),
33  m_textureLoc(0)
34 { }
35 
37 {
38  cleanup();
39 }
40 
42 {
43  m_program = new QOpenGLShaderProgram;
44 
45  if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceTextured)) {
46  qDebug() << "GLShaderTextured::initializeGL: error in vertex shader: " << m_program->log();
47  }
48 
49  if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceTextured)) {
50  qDebug() << "GLShaderTextured::initializeGL: error in fragment shader: " << m_program->log();
51  }
52 
53  m_program->bindAttributeLocation("vertex", 0);
54  m_program->bindAttributeLocation("texCoord", 1);
55 
56  if (!m_program->link()) {
57  qDebug() << "GLShaderTextured::initializeGL: error linking shader: " << m_program->log();
58  }
59 
60  m_program->bind();
61  m_matrixLoc = m_program->uniformLocation("uMatrix");
62  m_textureLoc = m_program->uniformLocation("uTexture");
63  m_program->release();
64 }
65 
66 void GLShaderTextured::initTexture(const QImage& image, QOpenGLTexture::WrapMode wrapMode)
67 {
68  if (m_texture) {
69  delete m_texture;
70  }
71 
72  m_texture = new QOpenGLTexture(image);
73 
74  m_texture->setMinificationFilter(QOpenGLTexture::Linear);
75  m_texture->setMagnificationFilter(QOpenGLTexture::Linear);
76  m_texture->setWrapMode(wrapMode);
77 }
78 
79 void GLShaderTextured::subTexture(int xOffset, int yOffset, int width, int height, const void *pixels)
80 {
81  if (!m_texture) {
82  qDebug("GLShaderTextured::subTexture: no texture defined. Doing nothing");
83  return;
84  }
85 
86  QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
87  m_texture->bind();
88  f->glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
89 }
90 
91 void GLShaderTextured::drawSurface(const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices)
92 {
93  draw(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices);
94 }
95 
96 void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices)
97 {
98  if (!m_texture) {
99  qDebug("GLShaderTextured::draw: no texture defined. Doing nothing");
100  return;
101  }
102 
103  QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
104  m_program->bind();
105  m_program->setUniformValue(m_matrixLoc, transformMatrix);
106  m_texture->bind();
107  m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture
108  f->glEnableVertexAttribArray(0); // vertex
109  f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
110  f->glEnableVertexAttribArray(1); // texture coordinates
111  f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);
112  f->glDrawArrays(mode, 0, nbVertices);
113  f->glDisableVertexAttribArray(0);
114  m_program->release();
115 }
116 
118 {
119  if (m_program) {
120  delete m_program;
121  m_program = 0;
122  }
123 
124  if (m_texture) {
125  delete m_texture;
126  m_texture = 0;
127  }
128 }
129 
130 const QString GLShaderTextured::m_vertexShaderSourceTextured = QString(
131  "uniform highp mat4 uMatrix;\n"
132  "attribute highp vec4 vertex;\n"
133  "attribute highp vec2 texCoord;\n"
134  "varying mediump vec2 texCoordVar;\n"
135  "void main() {\n"
136  " gl_Position = uMatrix * vertex;\n"
137  " texCoordVar = texCoord;\n"
138  "}\n"
139  );
140 
142  "uniform lowp sampler2D uTexture;\n"
143  "varying mediump vec2 texCoordVar;\n"
144  "void main() {\n"
145  " gl_FragColor = texture2D(uTexture, texCoordVar);\n"
146  "}\n"
147  );
QOpenGLShaderProgram * m_program
void initTexture(const QImage &image, QOpenGLTexture::WrapMode wrapMode=QOpenGLTexture::Repeat)
void drawSurface(const QMatrix4x4 &transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices)
void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels)
static const QString m_vertexShaderSourceTextured
QOpenGLTexture * m_texture
void draw(unsigned int mode, const QMatrix4x4 &transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices)
static const QString m_fragmentShaderSourceTextured