mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-22 16:08:39 -05:00
Merge pull request #1299 from srcejon/spectrum_gradient
Spectrum fill/gradient
This commit is contained in:
commit
8b443037d1
@ -66,7 +66,8 @@ void SpectrumSettings::resetToDefaults()
|
||||
m_useCalibration = false;
|
||||
m_calibrationInterpMode = CalibInterpLinear;
|
||||
m_3DSpectrogramStyle = Outline;
|
||||
m_3DSpectrogramColorMap = "Angel";
|
||||
m_colorMap = "Angel";
|
||||
m_spectrumStyle = Line;
|
||||
}
|
||||
|
||||
QByteArray SpectrumSettings::serialize() const
|
||||
@ -104,8 +105,9 @@ QByteArray SpectrumSettings::serialize() const
|
||||
s.writeS32(30, (int) m_calibrationInterpMode);
|
||||
s.writeBool(31, m_display3DSpectrogram);
|
||||
s.writeS32(32, (int) m_3DSpectrogramStyle);
|
||||
s.writeString(33, m_3DSpectrogramColorMap);
|
||||
s.writeS32(100, m_histogramMarkers.size());
|
||||
s.writeString(33, m_colorMap);
|
||||
s.writeS32(34, (int) m_spectrumStyle);
|
||||
s.writeS32(100, m_histogramMarkers.size());
|
||||
|
||||
for (int i = 0; i < m_histogramMarkers.size(); i++) {
|
||||
s.writeBlob(101+i, m_histogramMarkers[i].serialize());
|
||||
@ -204,7 +206,8 @@ bool SpectrumSettings::deserialize(const QByteArray& data)
|
||||
m_calibrationInterpMode = (CalibrationInterpolationMode) tmp;
|
||||
d.readBool(31, &m_display3DSpectrogram, false);
|
||||
d.readS32(32, (int*)&m_3DSpectrogramStyle, (int)Outline);
|
||||
d.readString(33, &m_3DSpectrogramColorMap, "Angel");
|
||||
d.readString(33, &m_colorMap, "Angel");
|
||||
d.readS32(34, (int*)&m_spectrumStyle, (int)Line);
|
||||
|
||||
int histogramMarkersSize;
|
||||
d.readS32(100, &histogramMarkersSize, 0);
|
||||
|
@ -61,6 +61,13 @@ public:
|
||||
Shaded
|
||||
};
|
||||
|
||||
enum SpectrumStyle
|
||||
{
|
||||
Line,
|
||||
Fill,
|
||||
Gradient
|
||||
};
|
||||
|
||||
int m_fftSize;
|
||||
int m_fftOverlap;
|
||||
FFTWindow::Function m_fftWindow;
|
||||
@ -97,7 +104,8 @@ public:
|
||||
bool m_useCalibration;
|
||||
CalibrationInterpolationMode m_calibrationInterpMode; //!< How is power interpolated between calibration points
|
||||
SpectrogramStyle m_3DSpectrogramStyle;
|
||||
QString m_3DSpectrogramColorMap;
|
||||
QString m_colorMap;
|
||||
SpectrumStyle m_spectrumStyle;
|
||||
static const int m_log2FFTSizeMin = 6; // 64
|
||||
static const int m_log2FFTSizeMax = 15; // 32k
|
||||
|
||||
|
@ -315,6 +315,7 @@ const float ColorMap::m_angel[m_size] =
|
||||
1.0, 1.0, 1.0,
|
||||
1.0, 1.0, 1.0,
|
||||
1.0, 1.0, 1.0,
|
||||
1.0, 1.0, 1.0,
|
||||
};
|
||||
|
||||
const float ColorMap::m_jet[m_size] =
|
||||
|
@ -44,6 +44,7 @@ set(sdrgui_SOURCES
|
||||
gui/glscope.cpp
|
||||
gui/glscopegui.cpp
|
||||
gui/glshadercolors.cpp
|
||||
gui/glshadercolormap.cpp
|
||||
gui/glshadersimple.cpp
|
||||
gui/glshaderspectrogram.cpp
|
||||
gui/glshadertextured.cpp
|
||||
@ -145,6 +146,7 @@ set(sdrgui_HEADERS
|
||||
gui/glscope.h
|
||||
gui/glscopegui.h
|
||||
gui/glshadercolors.h
|
||||
gui/glshadercolormap.h
|
||||
gui/glshadersimple.h
|
||||
gui/glshaderspectrogram.h
|
||||
gui/glshadertvarray.h
|
||||
|
283
sdrgui/gui/glshadercolormap.cpp
Normal file
283
sdrgui/gui/glshadercolormap.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2022 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// 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 <QImage>
|
||||
#include <QMatrix4x4>
|
||||
#include <QVector4D>
|
||||
#include <QDebug>
|
||||
|
||||
#include "gui/glshadercolormap.h"
|
||||
#include "util/colormap.h"
|
||||
|
||||
GLShaderColorMap::GLShaderColorMap() :
|
||||
m_program(nullptr),
|
||||
m_vao(nullptr),
|
||||
m_verticesBuf(nullptr),
|
||||
m_colorMapTexture(nullptr),
|
||||
m_colorMapTextureId(0),
|
||||
m_vertexLoc(0),
|
||||
m_matrixLoc(0),
|
||||
m_colorMapLoc(0),
|
||||
m_scaleLoc(0),
|
||||
m_alphaLoc(0),
|
||||
m_useImmutableStorage(true)
|
||||
{ }
|
||||
|
||||
GLShaderColorMap::~GLShaderColorMap()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void GLShaderColorMap::initializeGL(int majorVersion, int minorVersion)
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
m_useImmutableStorage = useImmutableStorage();
|
||||
qDebug() << "GLShaderColorMap::initializeGL: m_useImmutableStorage: " << m_useImmutableStorage;
|
||||
|
||||
m_program = new QOpenGLShaderProgram;
|
||||
if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3)))
|
||||
{
|
||||
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceColorMap)) {
|
||||
qDebug() << "GLShaderColorMap::initializeGL: error in vertex shader: " << m_program->log();
|
||||
}
|
||||
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColorMap)) {
|
||||
qDebug() << "GLShaderColorMap::initializeGL: error in fragment shader: " << m_program->log();
|
||||
}
|
||||
|
||||
m_vao = new QOpenGLVertexArrayObject();
|
||||
m_vao->create();
|
||||
m_vao->bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceColorMap2)) {
|
||||
qDebug() << "GLShaderColorMap::initializeGL: error in vertex shader: " << m_program->log();
|
||||
}
|
||||
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColorMap2)) {
|
||||
qDebug() << "GLShaderColorMap::initializeGL: error in fragment shader: " << m_program->log();
|
||||
}
|
||||
}
|
||||
|
||||
m_program->bindAttributeLocation("vertex", 0);
|
||||
|
||||
if (!m_program->link()) {
|
||||
qDebug() << "GLShaderColorMap::initializeGL: error linking shader: " << m_program->log();
|
||||
}
|
||||
|
||||
m_program->bind();
|
||||
m_vertexLoc = m_program->attributeLocation("vertex");
|
||||
m_matrixLoc = m_program->uniformLocation("uMatrix");
|
||||
m_colorMapLoc = m_program->uniformLocation("colorMap");
|
||||
m_scaleLoc = m_program->uniformLocation("scale");
|
||||
m_alphaLoc = m_program->uniformLocation("alpha");
|
||||
if (m_vao)
|
||||
{
|
||||
m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
|
||||
m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw);
|
||||
m_verticesBuf->create();
|
||||
m_vao->release();
|
||||
}
|
||||
m_program->release();
|
||||
}
|
||||
|
||||
void GLShaderColorMap::initColorMapTexture(const QString &colorMapName)
|
||||
{
|
||||
if (m_useImmutableStorage) {
|
||||
initColorMapTextureImmutable(colorMapName);
|
||||
} else {
|
||||
initColorMapTextureMutable(colorMapName);
|
||||
}
|
||||
}
|
||||
|
||||
void GLShaderColorMap::initColorMapTextureImmutable(const QString &colorMapName)
|
||||
{
|
||||
if (!m_colorMapTexture)
|
||||
{
|
||||
m_colorMapTexture = new QOpenGLTexture(QOpenGLTexture::Target1D);
|
||||
m_colorMapTexture->setFormat(QOpenGLTexture::RGB32F);
|
||||
m_colorMapTexture->setSize(256);
|
||||
m_colorMapTexture->allocateStorage();
|
||||
m_colorMapTexture->setMinificationFilter(QOpenGLTexture::Linear);
|
||||
m_colorMapTexture->setMagnificationFilter(QOpenGLTexture::Linear);
|
||||
m_colorMapTexture->setWrapMode(QOpenGLTexture::ClampToEdge);
|
||||
}
|
||||
|
||||
GLfloat *colorMap = (GLfloat *)ColorMap::getColorMap(colorMapName);
|
||||
if (colorMap) {
|
||||
m_colorMapTexture->setData(QOpenGLTexture::RGB, QOpenGLTexture::Float32, colorMap);
|
||||
} else {
|
||||
qDebug() << "GLShaderColorMap::initColorMapTextureImmutable: colorMap " << colorMapName << " not supported";
|
||||
}
|
||||
}
|
||||
|
||||
void GLShaderColorMap::initColorMapTextureMutable(const QString &colorMapName)
|
||||
{
|
||||
if (m_colorMapTextureId)
|
||||
{
|
||||
glDeleteTextures(1, &m_colorMapTextureId);
|
||||
m_colorMapTextureId = 0;
|
||||
}
|
||||
|
||||
glGenTextures(1, &m_colorMapTextureId);
|
||||
glBindTexture(GL_TEXTURE_1D, m_colorMapTextureId);
|
||||
GLfloat *colorMap = (GLfloat *)ColorMap::getColorMap(colorMapName);
|
||||
if (colorMap) {
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_RGB, GL_FLOAT, colorMap);
|
||||
} else {
|
||||
qDebug() << "GLShaderColorMap::initColorMapTextureMutable: colorMap " << colorMapName << " not supported";
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, QOpenGLTexture::Repeat);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, QOpenGLTexture::Repeat);
|
||||
}
|
||||
|
||||
void GLShaderColorMap::drawSurfaceStrip(const QMatrix4x4& transformMatrix, GLfloat *vertices, int nbVertices, float scale, float alpha)
|
||||
{
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
m_program->bind();
|
||||
m_program->setUniformValue(m_matrixLoc, transformMatrix);
|
||||
m_colorMapTexture->bind();
|
||||
m_program->setUniformValue(m_colorMapLoc, 0); // Texture unit 0 for color map
|
||||
m_program->setUniformValue(m_scaleLoc, scale);
|
||||
m_program->setUniformValue(m_alphaLoc, alpha);
|
||||
if (m_vao)
|
||||
{
|
||||
m_vao->bind();
|
||||
|
||||
m_verticesBuf->bind();
|
||||
m_verticesBuf->allocate(vertices, nbVertices * 2 * sizeof(GL_FLOAT));
|
||||
m_program->enableAttributeArray(m_vertexLoc);
|
||||
m_program->setAttributeBuffer(m_vertexLoc, GL_FLOAT, 0, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
f->glEnableVertexAttribArray(m_vertexLoc);
|
||||
f->glVertexAttribPointer(m_vertexLoc, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
}
|
||||
|
||||
f->glEnable(GL_BLEND);
|
||||
f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
f->glDrawArrays(GL_TRIANGLE_STRIP, 0, nbVertices);
|
||||
|
||||
if (m_vao)
|
||||
{
|
||||
m_vao->release();
|
||||
}
|
||||
else
|
||||
{
|
||||
f->glDisableVertexAttribArray(m_vertexLoc);
|
||||
}
|
||||
m_program->release();
|
||||
}
|
||||
|
||||
void GLShaderColorMap::cleanup()
|
||||
{
|
||||
delete m_program;
|
||||
m_program = nullptr;
|
||||
delete m_vao;
|
||||
m_vao = nullptr;
|
||||
delete m_verticesBuf;
|
||||
m_verticesBuf = nullptr;
|
||||
delete m_colorMapTexture;
|
||||
m_colorMapTexture = nullptr;
|
||||
|
||||
if (!QOpenGLContext::currentContext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_colorMapTextureId)
|
||||
{
|
||||
glDeleteTextures(1, &m_colorMapTextureId);
|
||||
m_colorMapTextureId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool GLShaderColorMap::useImmutableStorage()
|
||||
{
|
||||
QOpenGLContext* ctx = QOpenGLContext::currentContext();
|
||||
QSurfaceFormat sf = ctx->format();
|
||||
|
||||
if (sf.version() >= qMakePair(4, 2)
|
||||
|| ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage"))
|
||||
|| ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage")))
|
||||
{
|
||||
void (QOPENGLF_APIENTRYP glTexStorage2D)(
|
||||
GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height);
|
||||
glTexStorage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(
|
||||
GLenum, GLsizei, GLenum, GLsizei, GLsizei)>(ctx->getProcAddress("glTexStorage2D"));
|
||||
int data = 0;
|
||||
GLuint textureId;
|
||||
glGenTextures(1, &textureId);
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data);
|
||||
GLenum err = glGetError();
|
||||
glDeleteTextures(1, &textureId);
|
||||
return err == GL_NO_ERROR;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString GLShaderColorMap::m_vertexShaderSourceColorMap2 = QString(
|
||||
"uniform highp mat4 uMatrix;\n"
|
||||
"attribute highp vec4 vertex;\n"
|
||||
"varying float y;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = uMatrix * vertex;\n"
|
||||
" y = vertex.y;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
const QString GLShaderColorMap::m_vertexShaderSourceColorMap = QString(
|
||||
"#version 330\n"
|
||||
"uniform highp mat4 uMatrix;\n"
|
||||
"in highp vec4 vertex;\n"
|
||||
"out float y;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = uMatrix * vertex;\n"
|
||||
" y = vertex.y;\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
const QString GLShaderColorMap::m_fragmentShaderSourceColorMap2 = QString(
|
||||
"uniform float alpha;\n"
|
||||
"uniform float scale;\n"
|
||||
"uniform highp sampler1D colorMap;\n"
|
||||
"varying float y;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = vec4(texture1D(colorMap, 1.0-(y/scale)).rgb, alpha);\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
const QString GLShaderColorMap::m_fragmentShaderSourceColorMap = QString(
|
||||
"#version 330\n"
|
||||
"uniform float alpha;\n"
|
||||
"uniform float scale;\n"
|
||||
"uniform sampler1D colorMap;\n"
|
||||
"in float y;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"void main() {\n"
|
||||
" fragColor = vec4(texture(colorMap, 1.0-(y/scale)).rgb, alpha);\n"
|
||||
"}\n"
|
||||
);
|
69
sdrgui/gui/glshadercolormap.h
Normal file
69
sdrgui/gui/glshadercolormap.h
Normal file
@ -0,0 +1,69 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2022 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// 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_GLSHADERCOLORMAP_H_
|
||||
#define INCLUDE_GUI_GLSHADERCOLORMAP_H_
|
||||
|
||||
#include <QString>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
class QOpenGLShaderProgram;
|
||||
class QMatrix4x4;
|
||||
class QVector4D;
|
||||
|
||||
// Shader to fill with a gradient from a color map
|
||||
// Used for filling the area under the spectrum
|
||||
class SDRGUI_API GLShaderColorMap : protected QOpenGLFunctions
|
||||
{
|
||||
public:
|
||||
GLShaderColorMap();
|
||||
~GLShaderColorMap();
|
||||
|
||||
void initializeGL(int majorVersion, int minorVersion);
|
||||
void initColorMapTexture(const QString &colorMapName);
|
||||
void drawSurfaceStrip(const QMatrix4x4& transformMatrix, GLfloat *vertices, int nbVertices, float scale, float alpha);
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
void initColorMapTextureMutable(const QString &colorMapName);
|
||||
void initColorMapTextureImmutable(const QString &colorMapName);
|
||||
bool useImmutableStorage();
|
||||
|
||||
QOpenGLShaderProgram *m_program;
|
||||
QOpenGLVertexArrayObject *m_vao;
|
||||
QOpenGLBuffer *m_verticesBuf;
|
||||
QOpenGLTexture *m_colorMapTexture;
|
||||
unsigned int m_colorMapTextureId;
|
||||
int m_vertexLoc;
|
||||
int m_matrixLoc;
|
||||
int m_colorMapLoc;
|
||||
int m_scaleLoc;
|
||||
int m_alphaLoc;
|
||||
bool m_useImmutableStorage;
|
||||
static const QString m_vertexShaderSourceColorMap2;
|
||||
static const QString m_vertexShaderSourceColorMap;
|
||||
static const QString m_fragmentShaderSourceColorMap2;
|
||||
static const QString m_fragmentShaderSourceColorMap;
|
||||
};
|
||||
|
||||
#endif /* INCLUDE_GUI_GLSHADERCOLORMAP_H_ */
|
@ -111,6 +111,11 @@ void GLShaderSimple::drawSurface(const QMatrix4x4& transformMatrix, const QVecto
|
||||
draw(GL_TRIANGLE_FAN, transformMatrix, color, vertices, nbVertices, nbComponents);
|
||||
}
|
||||
|
||||
void GLShaderSimple::drawSurfaceStrip(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents)
|
||||
{
|
||||
draw(GL_TRIANGLE_STRIP, transformMatrix, color, vertices, nbVertices, nbComponents);
|
||||
}
|
||||
|
||||
void GLShaderSimple::draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents)
|
||||
{
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
void drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2);
|
||||
void drawContour(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2);
|
||||
void drawSurface(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2);
|
||||
void drawSurfaceStrip(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2);
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
|
@ -91,7 +91,7 @@ GLSpectrum::GLSpectrum(QWidget* parent) :
|
||||
m_pan3DSpectrogram(false),
|
||||
m_scaleZ3DSpectrogram(false),
|
||||
m_3DSpectrogramStyle(SpectrumSettings::Outline),
|
||||
m_3DSpectrogramColorMap("Angel"),
|
||||
m_colorMapName("Angel"),
|
||||
m_histogramBuffer(nullptr),
|
||||
m_histogram(nullptr),
|
||||
m_displayHistogram(true),
|
||||
@ -345,16 +345,22 @@ void GLSpectrum::setDisplay3DSpectrogram(bool display)
|
||||
update();
|
||||
}
|
||||
|
||||
void GLSpectrum::setSpectrumStyle(SpectrumSettings::SpectrumStyle style)
|
||||
{
|
||||
m_spectrumStyle = style;
|
||||
update();
|
||||
}
|
||||
|
||||
void GLSpectrum::set3DSpectrogramStyle(SpectrumSettings::SpectrogramStyle style)
|
||||
{
|
||||
m_3DSpectrogramStyle = style;
|
||||
update();
|
||||
}
|
||||
|
||||
void GLSpectrum::set3DSpectrogramColorMap(const QString &colorMap)
|
||||
void GLSpectrum::setColorMapName(const QString &colorMapName)
|
||||
{
|
||||
m_mutex.lock();
|
||||
m_3DSpectrogramColorMap = colorMap;
|
||||
m_colorMapName = colorMapName;
|
||||
m_changesPending = true;
|
||||
m_mutex.unlock();
|
||||
update();
|
||||
@ -824,6 +830,7 @@ void GLSpectrum::initializeGL()
|
||||
m_glShaderFrequencyScale.initializeGL(majorVersion, minorVersion);
|
||||
m_glShaderWaterfall.initializeGL(majorVersion, minorVersion);
|
||||
m_glShaderHistogram.initializeGL(majorVersion, minorVersion);
|
||||
m_glShaderColorMap.initializeGL(majorVersion, minorVersion);
|
||||
m_glShaderTextOverlay.initializeGL(majorVersion, minorVersion);
|
||||
m_glShaderInfo.initializeGL(majorVersion, minorVersion);
|
||||
m_glShaderSpectrogram.initializeGL(majorVersion, minorVersion);
|
||||
@ -1264,6 +1271,30 @@ void GLSpectrum::paintGL()
|
||||
// m_referenceLevel - m_powerRange : bottom
|
||||
m_maxHold[i] = ((j - 99) * m_powerRange) / 99.0 + m_referenceLevel;
|
||||
}
|
||||
// Fill under max hold line
|
||||
if (m_spectrumStyle != SpectrumSettings::Line)
|
||||
{
|
||||
GLfloat *q3 = m_q3ColorMap.m_array;
|
||||
for (int i = 0; i < m_nbBins; i++)
|
||||
{
|
||||
Real v = m_maxHold[i] - m_referenceLevel;
|
||||
|
||||
if (v > 0) {
|
||||
v = 0;
|
||||
} else if (v < -m_powerRange) {
|
||||
v = -m_powerRange;
|
||||
}
|
||||
|
||||
q3[4*i] = (GLfloat)i;
|
||||
q3[4*i+1] = -m_powerRange;
|
||||
q3[4*i+2] = (GLfloat)i;
|
||||
q3[4*i+3] = v;
|
||||
}
|
||||
|
||||
QVector4D color(0.5f, 0.0f, 0.0f, (float) m_displayTraceIntensity / 100.0f);
|
||||
m_glShaderSimple.drawSurfaceStrip(m_glHistogramSpectrumMatrix, color, q3, 2*m_nbBins);
|
||||
}
|
||||
// Max hold line
|
||||
{
|
||||
GLfloat *q3 = m_q3FFT.m_array;
|
||||
|
||||
@ -1289,10 +1320,40 @@ void GLSpectrum::paintGL()
|
||||
// paint current spectrum line on top of histogram
|
||||
if ((m_displayCurrent) && m_currentSpectrum)
|
||||
{
|
||||
{
|
||||
Real bottom = -m_powerRange;
|
||||
GLfloat *q3 = m_q3FFT.m_array;
|
||||
Real bottom = -m_powerRange;
|
||||
GLfloat *q3;
|
||||
|
||||
if (m_spectrumStyle != SpectrumSettings::Line)
|
||||
{
|
||||
q3 = m_q3ColorMap.m_array;
|
||||
// Fill under line
|
||||
for (int i = 0; i < m_nbBins; i++)
|
||||
{
|
||||
Real v = m_currentSpectrum[i] - m_referenceLevel;
|
||||
|
||||
if (v > 0) {
|
||||
v = 0;
|
||||
} else if (v < bottom) {
|
||||
v = bottom;
|
||||
}
|
||||
|
||||
q3[4*i] = (GLfloat)i;
|
||||
q3[4*i+1] = bottom;
|
||||
q3[4*i+2] = (GLfloat)i;
|
||||
q3[4*i+3] = v;
|
||||
}
|
||||
|
||||
QVector4D color(1.0f, 1.0f, 0.25f, (float) m_displayTraceIntensity / 100.0f);
|
||||
if (m_spectrumStyle == SpectrumSettings::Gradient) {
|
||||
m_glShaderColorMap.drawSurfaceStrip(m_glHistogramSpectrumMatrix, q3, 2*m_nbBins, bottom, 0.75f);
|
||||
} else {
|
||||
m_glShaderSimple.drawSurfaceStrip(m_glHistogramSpectrumMatrix, color, q3, 2*m_nbBins);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Draw line
|
||||
q3 = m_q3FFT.m_array;
|
||||
for (int i = 0; i < m_nbBins; i++)
|
||||
{
|
||||
Real v = m_currentSpectrum[i] - m_referenceLevel;
|
||||
@ -1305,9 +1366,15 @@ void GLSpectrum::paintGL()
|
||||
|
||||
q3[2*i] = (Real) i;
|
||||
q3[2*i+1] = v;
|
||||
|
||||
}
|
||||
|
||||
QVector4D color(1.0f, 1.0f, 0.25f, (float) m_displayTraceIntensity / 100.0f);
|
||||
QVector4D color;
|
||||
if (m_spectrumStyle == SpectrumSettings::Gradient) {
|
||||
color = QVector4D(m_colorMap[255*3], m_colorMap[255*3+1], m_colorMap[255*3+2], (float) m_displayTraceIntensity / 100.0f);
|
||||
} else {
|
||||
color = QVector4D(1.0f, 1.0f, 0.25f, (float) m_displayTraceIntensity / 100.0f);
|
||||
}
|
||||
m_glShaderSimple.drawPolyline(m_glHistogramSpectrumMatrix, color, q3, m_nbBins);
|
||||
}
|
||||
}
|
||||
@ -2598,7 +2665,17 @@ void GLSpectrum::applyChanges()
|
||||
}
|
||||
m_3DSpectrogramBufferPos = 0;
|
||||
}
|
||||
m_glShaderSpectrogram.initColorMapTexture(m_3DSpectrogramColorMap);
|
||||
m_glShaderSpectrogram.initColorMapTexture(m_colorMapName);
|
||||
m_glShaderColorMap.initColorMapTexture(m_colorMapName);
|
||||
m_colorMap = ColorMap::getColorMap(m_colorMapName);
|
||||
// Why only 240 entries in the palette?
|
||||
for (int i = 0; i <= 239; i++)
|
||||
{
|
||||
((quint8*)&m_waterfallPalette[i])[0] = (quint8)(m_colorMap[i*3] * 255.0);
|
||||
((quint8*)&m_waterfallPalette[i])[1] = (quint8)(m_colorMap[i*3+1] * 255.0);
|
||||
((quint8*)&m_waterfallPalette[i])[2] = (quint8)(m_colorMap[i*3+2] * 255.0);
|
||||
((quint8*)&m_waterfallPalette[i])[3] = 255;
|
||||
}
|
||||
|
||||
if (fftSizeChanged)
|
||||
{
|
||||
@ -2622,6 +2699,9 @@ void GLSpectrum::applyChanges()
|
||||
memset(m_histogram, 0x00, 100 * m_nbBins);
|
||||
|
||||
m_q3FFT.allocate(2*m_nbBins);
|
||||
|
||||
m_q3ColorMap.allocate(4*m_nbBins);
|
||||
std::fill(m_q3ColorMap.m_array, m_q3ColorMap.m_array+4*m_nbBins, 0.0f);
|
||||
}
|
||||
|
||||
if (fftSizeChanged || windowSizeChanged)
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "gui/scaleengine.h"
|
||||
#include "gui/glshadersimple.h"
|
||||
#include "gui/glshadertextured.h"
|
||||
#include "gui/glshadercolormap.h"
|
||||
#include "dsp/glspectruminterface.h"
|
||||
#include "gui/glshaderspectrogram.h"
|
||||
#include "dsp/spectrummarkers.h"
|
||||
@ -41,6 +42,7 @@
|
||||
#include "export.h"
|
||||
#include "util/incrementalarray.h"
|
||||
#include "util/message.h"
|
||||
#include "util/colormap.h"
|
||||
|
||||
class QOpenGLShaderProgram;
|
||||
class MessageQueue;
|
||||
@ -146,7 +148,8 @@ public:
|
||||
void setDisplayWaterfall(bool display);
|
||||
void setDisplay3DSpectrogram(bool display);
|
||||
void set3DSpectrogramStyle(SpectrumSettings::SpectrogramStyle style);
|
||||
void set3DSpectrogramColorMap(const QString &colorMap);
|
||||
void setColorMapName(const QString &colorMapName);
|
||||
void setSpectrumStyle(SpectrumSettings::SpectrumStyle style);
|
||||
void setSsbSpectrum(bool ssbSpectrum);
|
||||
void setLsbDisplay(bool lsbDisplay);
|
||||
void setInvertedWaterfall(bool inv);
|
||||
@ -312,7 +315,9 @@ private:
|
||||
QPixmap m_spectrogramTimePixmap;
|
||||
QPixmap m_spectrogramPowerPixmap;
|
||||
SpectrumSettings::SpectrogramStyle m_3DSpectrogramStyle;
|
||||
QString m_3DSpectrogramColorMap;
|
||||
QString m_colorMapName;
|
||||
SpectrumSettings::SpectrumStyle m_spectrumStyle;
|
||||
const float *m_colorMap;
|
||||
|
||||
QRgb m_histogramPalette[240];
|
||||
QImage* m_histogramBuffer;
|
||||
@ -336,6 +341,7 @@ private:
|
||||
GLShaderTextured m_glShaderFrequencyScale;
|
||||
GLShaderTextured m_glShaderWaterfall;
|
||||
GLShaderTextured m_glShaderHistogram;
|
||||
GLShaderColorMap m_glShaderColorMap;
|
||||
GLShaderTextured m_glShaderTextOverlay;
|
||||
GLShaderTextured m_glShaderInfo;
|
||||
GLShaderSpectrogram m_glShaderSpectrogram;
|
||||
@ -351,6 +357,7 @@ private:
|
||||
IncrementalArray<GLfloat> m_q3TickFrequency;
|
||||
IncrementalArray<GLfloat> m_q3TickPower;
|
||||
IncrementalArray<GLfloat> m_q3FFT;
|
||||
IncrementalArray<GLfloat> m_q3ColorMap;
|
||||
|
||||
MessageQueue *m_messageQueueToGUI;
|
||||
QOpenGLDebugLogger *m_openGLLogger;
|
||||
|
@ -71,8 +71,8 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) :
|
||||
ui->levelRange->setStyleSheet(levelStyle);
|
||||
ui->fftOverlap->setStyleSheet(levelStyle);
|
||||
|
||||
ui->spectrogramColorMap->addItems(ColorMap::getColorMapNames());
|
||||
ui->spectrogramColorMap->setCurrentText("Angel");
|
||||
ui->colorMap->addItems(ColorMap::getColorMapNames());
|
||||
ui->colorMap->setCurrentText("Angel");
|
||||
|
||||
connect(&m_messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
|
||||
@ -161,8 +161,8 @@ void GLSpectrumGUI::displaySettings()
|
||||
ui->spectrogram->setChecked(m_settings.m_display3DSpectrogram);
|
||||
ui->spectrogramStyle->setCurrentIndex((int) m_settings.m_3DSpectrogramStyle);
|
||||
ui->spectrogramStyle->setVisible(m_settings.m_display3DSpectrogram);
|
||||
ui->spectrogramColorMap->setCurrentText(m_settings.m_3DSpectrogramColorMap);
|
||||
ui->spectrogramColorMap->setVisible(m_settings.m_display3DSpectrogram);
|
||||
ui->colorMap->setCurrentText(m_settings.m_colorMap);
|
||||
ui->spectrumStyle->setCurrentIndex((int) m_settings.m_spectrumStyle);
|
||||
ui->maxHold->setChecked(m_settings.m_displayMaxHold);
|
||||
ui->current->setChecked(m_settings.m_displayCurrent);
|
||||
ui->histogram->setChecked(m_settings.m_displayHistogram);
|
||||
@ -246,7 +246,8 @@ void GLSpectrumGUI::applySpectrumSettings()
|
||||
m_glSpectrum->setDisplayWaterfall(m_settings.m_displayWaterfall);
|
||||
m_glSpectrum->setDisplay3DSpectrogram(m_settings.m_display3DSpectrogram);
|
||||
m_glSpectrum->set3DSpectrogramStyle(m_settings.m_3DSpectrogramStyle);
|
||||
m_glSpectrum->set3DSpectrogramColorMap(m_settings.m_3DSpectrogramColorMap);
|
||||
m_glSpectrum->setColorMapName(m_settings.m_colorMap);
|
||||
m_glSpectrum->setSpectrumStyle(m_settings.m_spectrumStyle);
|
||||
m_glSpectrum->setInvertedWaterfall(m_settings.m_invertedWaterfall);
|
||||
m_glSpectrum->setDisplayMaxHold(m_settings.m_displayMaxHold);
|
||||
m_glSpectrum->setDisplayCurrent(m_settings.m_displayCurrent);
|
||||
@ -463,16 +464,22 @@ void GLSpectrumGUI::on_stroke_valueChanged(int index)
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void GLSpectrumGUI::on_spectrumStyle_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_spectrumStyle = (SpectrumSettings::SpectrumStyle)index;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void GLSpectrumGUI::on_spectrogramStyle_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_3DSpectrogramStyle = (SpectrumSettings::SpectrogramStyle)index;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void GLSpectrumGUI::on_spectrogramColorMap_currentIndexChanged(int index)
|
||||
void GLSpectrumGUI::on_colorMap_currentIndexChanged(int index)
|
||||
{
|
||||
(void) index;
|
||||
m_settings.m_3DSpectrogramColorMap = ui->spectrogramColorMap->currentText();
|
||||
m_settings.m_colorMap = ui->colorMap->currentText();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
@ -498,7 +505,6 @@ void GLSpectrumGUI::on_spectrogram_toggled(bool checked)
|
||||
blockApplySettings(false);
|
||||
}
|
||||
ui->spectrogramStyle->setVisible(m_settings.m_display3DSpectrogram);
|
||||
ui->spectrogramColorMap->setVisible(m_settings.m_display3DSpectrogram);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
|
@ -96,8 +96,9 @@ private slots:
|
||||
void on_decay_valueChanged(int index);
|
||||
void on_decayDivisor_valueChanged(int index);
|
||||
void on_stroke_valueChanged(int index);
|
||||
void on_spectrumStyle_currentIndexChanged(int index);
|
||||
void on_spectrogramStyle_currentIndexChanged(int index);
|
||||
void on_spectrogramColorMap_currentIndexChanged(int index);
|
||||
void on_colorMap_currentIndexChanged(int index);
|
||||
void on_gridIntensity_valueChanged(int index);
|
||||
void on_traceIntensity_valueChanged(int index);
|
||||
void on_averagingMode_currentIndexChanged(int index);
|
||||
|
@ -723,6 +723,40 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="spectrumStyle">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Spectrum Style</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Line</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Fill</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Gradient</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDial" name="traceIntensity">
|
||||
<property name="maximumSize">
|
||||
@ -865,7 +899,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="spectrogramColorMap">
|
||||
<widget class="QComboBox" name="colorMap">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
@ -879,7 +913,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>3D Spectrogram Color Map</string>
|
||||
<string>Color Map</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
Loading…
Reference in New Issue
Block a user