OpenGL modernization: draw the left scales the new way

This commit is contained in:
f4exb 2016-03-05 06:45:05 +01:00
parent 9ac3150c0c
commit f78206defc
7 changed files with 235 additions and 32 deletions

View File

@ -118,6 +118,7 @@ set(sdrbase_SOURCES
sdrbase/gui/glscope.cpp
sdrbase/gui/glscopegui.cpp
sdrbase/gui/glshadersimple.cpp
sdrbase/gui/glshadertextured.cpp
sdrbase/gui/glspectrum.cpp
sdrbase/gui/glspectrumgui.cpp
sdrbase/gui/indicator.cpp
@ -201,6 +202,7 @@ set(sdrbase_HEADERS
include/gui/glscope.h
include/gui/glscopegui.h
include/gui/glshadersimple.h
include/gui/glshadertextured.h
include/gui/glspectrum.h
include/gui/glspectrumgui.h
include/gui/indicator.h

View File

@ -0,0 +1,52 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 F4EXB //
// written by Edouard Griffiths //
// //
// See: http://glslstudio.com/primer/#gl2frag //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// 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 General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDE_GUI_GLSHADERTEXTURED_H_
#define INCLUDE_GUI_GLSHADERTEXTURED_H_
#include <QString>
class QOpenGLShaderProgram;
class QMatrix4x4;
class QOpenGLTexture;
class QImage;
class GLShaderTextured
{
public:
GLShaderTextured();
~GLShaderTextured();
void initializeGL();
void initTexture(const QImage& image);
void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices);
void cleanup();
private:
void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices);
QOpenGLShaderProgram *m_program;
QOpenGLTexture *m_texture;
int m_matrixLoc;
int m_textureLoc;
static const QString m_vertexShaderSourceTextured;
static const QString m_fragmentShaderSourceTextured;
};
#endif /* INCLUDE_GUI_GLSHADERTEXTURED_H_ */

View File

@ -30,6 +30,7 @@
#include "dsp/dsptypes.h"
#include "gui/scaleengine.h"
#include "gui/glshadersimple.h"
#include "gui/glshadertextured.h"
#include "dsp/channelmarker.h"
#include "util/export.h"
@ -127,15 +128,17 @@ private:
Real m_waterfallShare;
QPixmap m_leftMarginPixmap;
#ifdef GL_DEPRECATED
bool m_leftMarginTextureAllocated;
GLuint m_leftMarginTexture;
QRectF m_glLeftScaleRect;
#endif
QPixmap m_frequencyPixmap;
bool m_frequencyTextureAllocated;
GLuint m_frequencyTexture;
ScaleEngine m_timeScale;
ScaleEngine m_powerScale;
ScaleEngine m_frequencyScale;
QRectF m_glLeftScaleRect;
QRectF m_glFrequencyScaleRect;
QRect m_frequencyScaleRect;
QMatrix4x4 m_glFrequencyScaleBoxMatrix;
@ -171,7 +174,7 @@ private:
bool m_displayChanged;
GLShaderSimple m_glShaderSimple;
QOpenGLShaderProgram *m_program;
GLShaderTextured m_glShaderLeftScale;
int m_matrixLoc;
int m_colorLoc;

View File

@ -1,8 +1,8 @@
#-------------------------------------------------
#--------------------------------------------------------
#
# Pro file for Android build with Qt Creator
# Pro file for Android and Windows builds with Qt Creator
#
#-------------------------------------------------
#--------------------------------------------------------
QT += core gui
@ -64,6 +64,8 @@ SOURCES += main.cpp\
sdrbase/gui/colormapper.cpp\
sdrbase/gui/glscope.cpp\
sdrbase/gui/glscopegui.cpp\
sdrbase/gui/glshadersimple.cpp\
sdrbase/gui/glshadertextured.cpp\
sdrbase/gui/glspectrum.cpp\
sdrbase/gui/glspectrumgui.cpp\
sdrbase/gui/indicator.cpp\
@ -135,6 +137,8 @@ HEADERS += include/mainwindow.h\
include/gui/colormapper.h\
include/gui/glscope.h\
include/gui/glscopegui.h\
include/gui/glshadersimple.h\
include/gui/glshadertextured.h\
include/gui/glspectrum.h\
include/gui/glspectrumgui.h\
include/gui/indicator.h\

View File

@ -20,6 +20,7 @@
#include <QOpenGLContext>
#include <QMatrix4x4>
#include <QVector4D>
#include <QDebug>
#include "gui/glshadersimple.h"
@ -35,10 +36,21 @@ GLShaderSimple::~GLShaderSimple()
void GLShaderSimple::initializeGL()
{
m_program = new QOpenGLShaderProgram;
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored);
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple)) {
qDebug() << "GLShaderSimple::initializeGL: error in vertex shader: " << m_program->log();
}
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) {
qDebug() << "GLShaderSimple::initializeGL: error in fragment shader: " << m_program->log();
}
m_program->bindAttributeLocation("vertex", 0);
m_program->link();
if (!m_program->link()) {
qDebug() << "GLShaderSimple::initializeGL: error linking shader: " << m_program->log();
}
m_program->bind();
m_matrixLoc = m_program->uniformLocation("uMatrix");
m_colorLoc = m_program->uniformLocation("uColour");

View File

@ -0,0 +1,133 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 F4EXB //
// written by Edouard Griffiths //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// 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 General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions>
#include <QOpenGLContext>
#include <QOpenGLTexture>
#include <QImage>
#include <QMatrix4x4>
#include <QVector4D>
#include <QDebug>
#include "gui/glshadertextured.h"
GLShaderTextured::GLShaderTextured() :
m_program(0),
m_texture(0)
{ }
GLShaderTextured::~GLShaderTextured()
{
cleanup();
}
void GLShaderTextured::initializeGL()
{
m_program = new QOpenGLShaderProgram;
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceTextured)) {
qDebug() << "GLShaderTextured::initializeGL: error in vertex shader: " << m_program->log();
}
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceTextured)) {
qDebug() << "GLShaderTextured::initializeGL: error in fragment shader: " << m_program->log();
}
m_program->bindAttributeLocation("vertex", 0);
m_program->bindAttributeLocation("texCoord", 1);
if (!m_program->link()) {
qDebug() << "GLShaderTextured::initializeGL: error linking shader: " << m_program->log();
}
m_program->bind();
m_matrixLoc = m_program->uniformLocation("uMatrix");
m_textureLoc = m_program->uniformLocation("uTexture");
m_program->release();
}
void GLShaderTextured::initTexture(const QImage& image)
{
if (m_texture) {
delete m_texture;
}
m_texture = new QOpenGLTexture(image);
m_texture->setMinificationFilter(QOpenGLTexture::Linear);
m_texture->setMagnificationFilter(QOpenGLTexture::Linear);
m_texture->setWrapMode(QOpenGLTexture::Repeat);
}
void GLShaderTextured::drawSurface(const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices)
{
draw(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices);
}
void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices)
{
if (!m_texture) {
qDebug("GLShaderTextured::draw: no texture defined. Doing nothing");
return;
}
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
m_program->bind();
m_program->setUniformValue(m_matrixLoc, transformMatrix);
m_texture->bind();
m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture
f->glEnableVertexAttribArray(0); // vertex
f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
f->glEnableVertexAttribArray(1); // texture coordinates
f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);
f->glDrawArrays(mode, 0, nbVertices);
f->glDisableVertexAttribArray(0);
m_program->release();
}
void GLShaderTextured::cleanup()
{
if (m_program) {
delete m_program;
m_program = 0;
}
if (m_texture) {
delete m_texture;
m_texture = 0;
}
}
const QString GLShaderTextured::m_vertexShaderSourceTextured = QString(
"uniform mat4 uMatrix;\n"
"attribute vec4 vertex;\n"
"attribute vec2 texCoord;\n"
"varying vec2 texCoordVar;\n"
"void main() {\n"
" gl_Position = uMatrix * vertex;\n"
" texCoordVar = texCoord;\n"
"}\n"
);
const QString GLShaderTextured::m_fragmentShaderSourceTextured = QString(
"uniform sampler2D uTexture;\n"
"varying vec2 texCoordVar;\n"
"void main() {\n"
" gl_FragColor = texture2D(uTexture, texCoordVar);\n"
"}\n"
);

View File

@ -48,7 +48,9 @@ GLSpectrum::GLSpectrum(QWidget* parent) :
m_displayMaxHold(false),
m_currentSpectrum(0),
m_displayCurrent(false),
#ifdef GL_DEPRECATED
m_leftMarginTextureAllocated(false),
#endif
m_frequencyTextureAllocated(false),
m_waterfallBuffer(NULL),
m_waterfallTextureAllocated(false),
@ -60,8 +62,7 @@ GLSpectrum::GLSpectrum(QWidget* parent) :
m_histogramHoldoff(NULL),
m_histogramTextureAllocated(false),
m_displayHistogram(true),
m_displayChanged(false),
m_program(0)
m_displayChanged(false)
{
setAutoFillBackground(false);
setAttribute(Qt::WA_OpaquePaintEvent, true);
@ -149,10 +150,12 @@ GLSpectrum::~GLSpectrum()
deleteTexture(m_histogramTexture);
m_histogramTextureAllocated = false;
}
#ifdef GL_DEPRECATED
if(m_leftMarginTextureAllocated) {
deleteTexture(m_leftMarginTexture);
m_leftMarginTextureAllocated = false;
}
#endif
if(m_frequencyTextureAllocated) {
deleteTexture(m_frequencyTexture);
m_frequencyTextureAllocated = false;
@ -507,6 +510,7 @@ void GLSpectrum::initializeGL()
connect(glCurrentContext, &QOpenGLContext::aboutToBeDestroyed, this, &GLSpectrum::cleanup); // TODO: when migrating to QOpenGLWidget
glDisable(GL_DEPTH_TEST);
m_glShaderSimple.initializeGL();
m_glShaderLeftScale.initializeGL();
}
void GLSpectrum::resizeGL(int width, int height)
@ -876,6 +880,7 @@ void GLSpectrum::paintGL()
// paint left scales (time and power)
if (m_displayWaterfall || m_displayMaxHold || m_displayCurrent || m_displayHistogram )
{
#ifdef GL_DEPRECATED
glPushMatrix();
glTranslatef(m_glLeftScaleRect.x(), m_glLeftScaleRect.y(), 0);
glScalef(m_glLeftScaleRect.width(), m_glLeftScaleRect.height(), 1);
@ -886,7 +891,6 @@ void GLSpectrum::paintGL()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_2D);
#ifdef GL_DEPRECATED
glBegin(GL_QUADS);
glTexCoord2f(0, 1);
glVertex2f(0, 1);
@ -897,6 +901,9 @@ void GLSpectrum::paintGL()
glTexCoord2f(0, 0);
glVertex2f(0, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
#else
{
GLfloat vtx1[] = {
@ -911,28 +918,10 @@ void GLSpectrum::paintGL()
1, 0,
0, 0
};
#ifdef GL_ANDROID
glEnableVertexAttribArray(GL_VERTEX_ARRAY);
glEnableVertexAttribArray(GL_TEXTURE_COORD_ARRAY);
glVertexAttribPointer(GL_VERTEX_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, vtx1);
glVertexAttribPointer(GL_TEXTURE_COORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, tex1);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(GL_VERTEX_ARRAY);
glDisableVertexAttribArray(GL_TEXTURE_COORD_ARRAY);
#else
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vtx1);
glTexCoordPointer(2, GL_FLOAT, 0, tex1);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#endif
m_glShaderLeftScale.drawSurface(m_glLeftScaleBoxMatrix, tex1, vtx1, 4);
}
#endif
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
// paint frequency scale
@ -1561,12 +1550,14 @@ void GLSpectrum::applyChanges()
(float) -2*frequencyScaleHeight / (float) height()
);
#ifdef GL_DEPRECATED
m_glLeftScaleRect = QRectF(
(float)0,
(float)0,
(float)(leftMargin - 1) / (float)width(),
(float)1
);
#endif
m_glLeftScaleBoxMatrix.setToIdentity();
m_glLeftScaleBoxMatrix.translate(-1.0f, 1.0f);
@ -1657,12 +1648,14 @@ void GLSpectrum::applyChanges()
(float) -2*frequencyScaleHeight / (float) height()
);
#ifdef GL_DEPRECATED
m_glLeftScaleRect = QRectF(
(float)0,
(float)0,
(float)(leftMargin - 1) / (float)width(),
(float)1
);
#endif
m_glLeftScaleBoxMatrix.setToIdentity();
m_glLeftScaleBoxMatrix.translate(-1.0f, 1.0f);
@ -1738,13 +1731,14 @@ void GLSpectrum::applyChanges()
(float) -2*frequencyScaleHeight / (float) height()
);
#ifdef GL_DEPRECATED
m_glLeftScaleRect = QRectF(
(float)0,
(float)0,
(float)(leftMargin - 1) / (float)width(),
(float)1
);
#endif
m_glLeftScaleBoxMatrix.setToIdentity();
m_glLeftScaleBoxMatrix.translate(-1.0f, 1.0f);
m_glLeftScaleBoxMatrix.scale(
@ -1934,6 +1928,7 @@ void GLSpectrum::applyChanges()
}
}
}
#ifdef GL_DEPRECATED
if(m_leftMarginTextureAllocated)
deleteTexture(m_leftMarginTexture);
m_leftMarginTexture = bindTexture(m_leftMarginPixmap,
@ -1942,6 +1937,8 @@ void GLSpectrum::applyChanges()
QGLContext::LinearFilteringBindOption |
QGLContext::MipmapBindOption);
m_leftMarginTextureAllocated = true;
#endif
m_glShaderLeftScale.initTexture(m_leftMarginPixmap.toImage());
}
// prepare frequency scale
if(m_displayWaterfall || m_displayHistogram || m_displayMaxHold || m_displayCurrent){