diff --git a/res/mixxx.qrc b/res/mixxx.qrc index e2cef8820d56..bf31f950ab96 100644 --- a/res/mixxx.qrc +++ b/res/mixxx.qrc @@ -61,6 +61,7 @@ shaders/filteredsignal.frag shaders/passthrough.vert shaders/rgbsignal.frag + shaders/stackedsignal.frag skins/default.qss diff --git a/res/shaders/stackedsignal.frag b/res/shaders/stackedsignal.frag new file mode 100644 index 000000000000..d5207ac6ef22 --- /dev/null +++ b/res/shaders/stackedsignal.frag @@ -0,0 +1,168 @@ +#version 120 + +uniform vec2 framebufferSize; +uniform vec4 axesColor; +uniform vec4 lowColor; +uniform vec4 midColor; +uniform vec4 highColor; +uniform vec4 lowFilteredColor; +uniform vec4 midFilteredColor; +uniform vec4 highFilteredColor; + +uniform int waveformLength; +uniform int textureSize; +uniform int textureStride; + +uniform float allGain; +uniform float lowGain; +uniform float midGain; +uniform float highGain; +uniform float firstVisualIndex; +uniform float lastVisualIndex; + +uniform sampler2D waveformDataTexture; + +vec4 getWaveformData(float index) { + vec2 uv_data; + uv_data.y = floor(index / float(textureStride)); + uv_data.x = floor(index - uv_data.y * float(textureStride)); + // Divide again to convert to normalized UV coordinates. + return texture2D(waveformDataTexture, uv_data / float(textureStride)); +} + +bool nearBorder(float target, float test, float epsilon) { + float dist = target - test; + return (abs(dist) <= epsilon && dist > 0); +} + +void main(void) { + vec2 uv = gl_TexCoord[0].st; + vec4 pixel = gl_FragCoord; + + float new_currentIndex = + floor(firstVisualIndex + + uv.x * (lastVisualIndex - firstVisualIndex)) * + 2; + + // Texture coordinates put (0,0) at the bottom left, so show the right + // channel if we are in the bottom half. + if (uv.y < 0.5) { + new_currentIndex += 1; + } + + vec4 outputColor = vec4(0.0, 0.0, 0.0, 0.0); + bool showing = false; + bool showingUnscaled = false; + vec4 showingColor = vec4(0.0, 0.0, 0.0, 0.0); + vec4 mixColor = vec4(0.0, 0.0, 0.0, 0.0); + bool mixin = true; + float alpha = 0.75; + + // We don't exit early if the waveform data is not valid because we may want + // to show other things (e.g. the axes lines) even when we are on a pixel + // that does not have valid waveform data. + if (new_currentIndex >= 0 && new_currentIndex <= waveformLength - 1) { + // Since the magnitude of the (low, mid, high) vector is used as the + // waveform height, re-scale the maximum height to 1. + const float scaleFactor = 1.0 / sqrt(3.0); + + vec4 new_currentDataUnscaled = getWaveformData(new_currentIndex) * allGain; + new_currentDataUnscaled.x *= scaleFactor; + new_currentDataUnscaled.y *= scaleFactor; + new_currentDataUnscaled.z *= scaleFactor; + + vec4 new_currentData = new_currentDataUnscaled; + new_currentData.x *= lowGain; + new_currentData.y *= midGain; + new_currentData.z *= highGain; + + vec4 new_currentDataTop = vec4(0.0, 0.0, 0.0, 0.0); + new_currentDataTop.x = max(new_currentData.x, new_currentDataUnscaled.x); + new_currentDataTop.y = max(new_currentData.y, new_currentDataUnscaled.y); + new_currentDataTop.z = max(new_currentData.z, new_currentDataUnscaled.z); + + // Represents the [-1, 1] distance of this pixel. Subtracting this from + // the signal data in new_currentData, we can tell if a signal band should + // show in this pixel if the component is > 0. + float ourDistance = abs((uv.y - 0.5) * 2.0); + + float signalDistance = sqrt(new_currentData.x * new_currentData.x + + new_currentData.y * new_currentData.y + + new_currentData.z * new_currentData.z) * + scaleFactor; + + bool drawBorder = false; + showing = true; + if (drawBorder && nearBorder(new_currentDataUnscaled.x, ourDistance, 0.04)) { + showingColor = lowColor; + mixin = false; + alpha = 0.90; + } else if (ourDistance <= new_currentData.x) { + showingColor = lowColor; + } else if (ourDistance <= new_currentDataUnscaled.x) { + showingColor = lowFilteredColor; + alpha = 0.6; + } else if (drawBorder && + nearBorder( + new_currentDataUnscaled.x + new_currentDataUnscaled.y, + ourDistance, + 0.04)) { + showingColor = midColor; + mixin = false; + alpha = 0.90; + } else if (ourDistance <= new_currentDataTop.x + new_currentData.y) { + showingColor = midColor; + } else if (ourDistance <= new_currentDataTop.x + new_currentDataTop.y) { + showingColor = midFilteredColor; + alpha = 0.6; + } else if (drawBorder && + nearBorder(new_currentDataTop.x + new_currentDataTop.y + + new_currentDataUnscaled.z, + ourDistance, + 0.04)) { + showingColor = highColor; + mixin = false; + alpha = 0.90; + } else if (ourDistance <= new_currentDataTop.x + new_currentDataTop.y + + new_currentData.z) { + showingColor = highColor; + } else if (ourDistance <= new_currentDataTop.x + new_currentDataTop.y + + new_currentDataUnscaled.z) { + showingColor = highFilteredColor; + alpha = 0.6; + } else { + showing = false; + } + + // Linearly combine the low, mid, and high colors according to the low, + // mid, and high components of the unfiltered signal. + mixColor = lowColor * new_currentDataUnscaled.x + + midColor * new_currentDataUnscaled.y + + highColor * new_currentDataUnscaled.z; + + // Re-scale the color by the maximum component. + float showingMax = max(mixColor.x, max(mixColor.y, mixColor.z)); + mixColor = mixColor / showingMax; + mixColor.w = 1.0; + } + // Draw the axes color as the lowest item on the screen. + // TODO(owilliams): The "4" in this line makes sure the axis gets + // rendered even when the waveform is fairly short. Really this + // value should be based on the size of the widget. + if (abs(framebufferSize.y / 2 - pixel.y) <= 4) { + outputColor.xyz = mix(outputColor.xyz, axesColor.xyz, axesColor.w); + outputColor.w = 1.0; + } + + if (showing) { + outputColor.xyz = mix(outputColor.xyz, showingColor.xyz, alpha); + // we mix in the sum color to smoothen the look and give it the + // general color tone. + if (mixin == true) { + outputColor.xyz = mix(outputColor.xyz, mixColor.xyz, 0.53f); + } + outputColor.w = 1.0; + } + + gl_FragColor = outputColor; +} diff --git a/src/waveform/renderers/glslwaveformrenderersignal.cpp b/src/waveform/renderers/glslwaveformrenderersignal.cpp index 8777ff0e5ad5..d89c3d990d52 100644 --- a/src/waveform/renderers/glslwaveformrenderersignal.cpp +++ b/src/waveform/renderers/glslwaveformrenderersignal.cpp @@ -9,14 +9,16 @@ #include "waveform/waveformwidgetfactory.h" GLSLWaveformRendererSignal::GLSLWaveformRendererSignal(WaveformWidgetRenderer* waveformWidgetRenderer, - bool rgbShader) + ColorType colorType, + const QString& fragShader) : WaveformRendererSignalBase(waveformWidgetRenderer), m_unitQuadListId(-1), m_textureId(0), m_textureRenderedWaveformCompletion(0), m_bDumpPng(false), m_shadersValid(false), - m_rgbShader(rgbShader) { + m_colorType(colorType), + m_pFragShader(fragShader) { initializeOpenGLFunctions(); } @@ -51,11 +53,9 @@ bool GLSLWaveformRendererSignal::loadShaders() { << m_frameShaderProgram->log(); return false; } - QString fragmentShader = m_rgbShader ? - ":/shaders/rgbsignal.frag" : - ":/shaders/filteredsignal.frag"; + if (!m_frameShaderProgram->addShaderFromSourceFile( - QGLShader::Fragment, fragmentShader)) { + QGLShader::Fragment, m_pFragShader)) { qDebug() << "GLWaveformRendererSignalShader::loadShaders - " << m_frameShaderProgram->log(); return false; @@ -339,36 +339,56 @@ void GLSLWaveformRendererSignal::draw(QPainter* painter, QPaintEvent* /*event*/) static_cast(m_axesColor_b), static_cast(m_axesColor_a))); - QVector4D lowColor = m_rgbShader - ? QVector4D(static_cast(m_rgbLowColor_r), - static_cast(m_rgbLowColor_g), - static_cast(m_rgbLowColor_b), - 1.0f) - : QVector4D(static_cast(m_lowColor_r), - static_cast(m_lowColor_g), - static_cast(m_lowColor_b), - 1.0f); - QVector4D midColor = m_rgbShader - ? QVector4D(static_cast(m_rgbMidColor_r), - static_cast(m_rgbMidColor_g), - static_cast(m_rgbMidColor_b), - 1.0f) - : QVector4D(static_cast(m_midColor_r), - static_cast(m_midColor_g), - static_cast(m_midColor_b), - 1.0f); - QVector4D highColor = m_rgbShader - ? QVector4D(static_cast(m_rgbHighColor_r), - static_cast(m_rgbHighColor_g), - static_cast(m_rgbHighColor_b), - 1.0f) - : QVector4D(static_cast(m_highColor_r), - static_cast(m_highColor_g), - static_cast(m_highColor_b), - 1.0f); - m_frameShaderProgram->setUniformValue("lowColor", lowColor); - m_frameShaderProgram->setUniformValue("midColor", midColor); - m_frameShaderProgram->setUniformValue("highColor", highColor); + if (m_colorType == ColorType::RGBFiltered) { + m_frameShaderProgram->setUniformValue("lowFilteredColor", + QVector4D(static_cast(m_rgbLowFilteredColor_r), + static_cast(m_rgbLowFilteredColor_g), + static_cast(m_rgbLowFilteredColor_b), + 1.0)); + m_frameShaderProgram->setUniformValue("midFilteredColor", + QVector4D(static_cast(m_rgbMidFilteredColor_r), + static_cast(m_rgbMidFilteredColor_g), + static_cast(m_rgbMidFilteredColor_b), + 1.0)); + m_frameShaderProgram->setUniformValue("highFilteredColor", + QVector4D(static_cast(m_rgbHighFilteredColor_r), + static_cast(m_rgbHighFilteredColor_g), + static_cast(m_rgbHighFilteredColor_b), + 1.0)); + } + if (m_colorType == ColorType::RGB || m_colorType == ColorType::RGBFiltered) { + m_frameShaderProgram->setUniformValue("lowColor", + QVector4D(static_cast(m_rgbLowColor_r), + static_cast(m_rgbLowColor_g), + static_cast(m_rgbLowColor_b), + 1.0)); + m_frameShaderProgram->setUniformValue("midColor", + QVector4D(static_cast(m_rgbMidColor_r), + static_cast(m_rgbMidColor_g), + static_cast(m_rgbMidColor_b), + 1.0)); + m_frameShaderProgram->setUniformValue("highColor", + QVector4D(static_cast(m_rgbHighColor_r), + static_cast(m_rgbHighColor_g), + static_cast(m_rgbHighColor_b), + 1.0)); + } else { + m_frameShaderProgram->setUniformValue("lowColor", + QVector4D(static_cast(m_lowColor_r), + static_cast(m_lowColor_g), + static_cast(m_lowColor_b), + 1.0)); + m_frameShaderProgram->setUniformValue("midColor", + QVector4D(static_cast(m_midColor_r), + static_cast(m_midColor_g), + static_cast(m_midColor_b), + 1.0)); + m_frameShaderProgram->setUniformValue("highColor", + QVector4D(static_cast(m_highColor_r), + static_cast(m_highColor_g), + static_cast(m_highColor_b), + 1.0)); + } glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, m_textureId); diff --git a/src/waveform/renderers/glslwaveformrenderersignal.h b/src/waveform/renderers/glslwaveformrenderersignal.h index 8e5f3ca80335..e97431e4aeeb 100644 --- a/src/waveform/renderers/glslwaveformrenderersignal.h +++ b/src/waveform/renderers/glslwaveformrenderersignal.h @@ -16,8 +16,15 @@ class GLSLWaveformRendererSignal: public QObject, protected QOpenGLFunctions_2_1 { Q_OBJECT public: + enum class ColorType { + Filtered, + RGB, + RGBFiltered, + }; + GLSLWaveformRendererSignal(WaveformWidgetRenderer* waveformWidgetRenderer, - bool rgbShader); + ColorType colorType, + const QString& fragShader); ~GLSLWaveformRendererSignal() override; bool onInit() override; @@ -51,16 +58,19 @@ class GLSLWaveformRendererSignal: public QObject, // shaders bool m_shadersValid; - bool m_rgbShader; + ColorType m_colorType; + const QString m_pFragShader; std::unique_ptr m_frameShaderProgram; }; class GLSLWaveformRendererFilteredSignal: public GLSLWaveformRendererSignal { public: - GLSLWaveformRendererFilteredSignal( - WaveformWidgetRenderer* waveformWidgetRenderer) : - GLSLWaveformRendererSignal(waveformWidgetRenderer, false) { - } + GLSLWaveformRendererFilteredSignal( + WaveformWidgetRenderer* waveformWidgetRenderer) + : GLSLWaveformRendererSignal(waveformWidgetRenderer, + ColorType::Filtered, + QLatin1String(":/shaders/filteredsignal.frag")) { + } ~GLSLWaveformRendererFilteredSignal() override { } }; @@ -68,9 +78,24 @@ class GLSLWaveformRendererFilteredSignal: public GLSLWaveformRendererSignal { class GLSLWaveformRendererRGBSignal : public GLSLWaveformRendererSignal { public: GLSLWaveformRendererRGBSignal( - WaveformWidgetRenderer* waveformWidgetRenderer) - : GLSLWaveformRendererSignal(waveformWidgetRenderer, true) {} + WaveformWidgetRenderer* waveformWidgetRenderer) + : GLSLWaveformRendererSignal(waveformWidgetRenderer, + ColorType::RGB, + QLatin1String(":/shaders/rgbsignal.frag")) { + } ~GLSLWaveformRendererRGBSignal() override {} }; +class GLSLWaveformRendererStackedSignal : public GLSLWaveformRendererSignal { + public: + GLSLWaveformRendererStackedSignal( + WaveformWidgetRenderer* waveformWidgetRenderer) + : GLSLWaveformRendererSignal(waveformWidgetRenderer, + ColorType::RGBFiltered, + QLatin1String(":/shaders/stackedsignal.frag")) { + } + ~GLSLWaveformRendererStackedSignal() override { + } +}; + #endif // QT_NO_OPENGL && !QT_OPENGL_ES_2 diff --git a/src/waveform/renderers/waveformrenderersignalbase.cpp b/src/waveform/renderers/waveformrenderersignalbase.cpp index 5373ff5f774d..32bbe9e10c19 100644 --- a/src/waveform/renderers/waveformrenderersignalbase.cpp +++ b/src/waveform/renderers/waveformrenderersignalbase.cpp @@ -140,6 +140,21 @@ void WaveformRendererSignalBase::setup(const QDomNode& node, const QColor& rgbHigh = m_pColors->getRgbHighColor(); rgbHigh.getRgbF(&m_rgbHighColor_r, &m_rgbHighColor_g, &m_rgbHighColor_b); + const QColor& rgbFilteredLow = m_pColors->getRgbLowFilteredColor(); + rgbFilteredLow.getRgbF(&m_rgbLowFilteredColor_r, + &m_rgbLowFilteredColor_g, + &m_rgbLowFilteredColor_b); + + const QColor& rgbFilteredMid = m_pColors->getRgbMidFilteredColor(); + rgbFilteredMid.getRgbF(&m_rgbMidFilteredColor_r, + &m_rgbMidFilteredColor_g, + &m_rgbMidFilteredColor_b); + + const QColor& rgbFilteredHigh = m_pColors->getRgbHighFilteredColor(); + rgbFilteredHigh.getRgbF(&m_rgbHighFilteredColor_r, + &m_rgbHighFilteredColor_g, + &m_rgbHighFilteredColor_b); + const QColor& axes = m_pColors->getAxesColor(); axes.getRgbF(&m_axesColor_r, &m_axesColor_g, &m_axesColor_b, &m_axesColor_a); diff --git a/src/waveform/renderers/waveformrenderersignalbase.h b/src/waveform/renderers/waveformrenderersignalbase.h index ab47b753d94e..893a4cf6649f 100644 --- a/src/waveform/renderers/waveformrenderersignalbase.h +++ b/src/waveform/renderers/waveformrenderersignalbase.h @@ -46,6 +46,9 @@ class WaveformRendererSignalBase : public WaveformRendererAbstract { qreal m_rgbLowColor_r, m_rgbLowColor_g, m_rgbLowColor_b; qreal m_rgbMidColor_r, m_rgbMidColor_g, m_rgbMidColor_b; qreal m_rgbHighColor_r, m_rgbHighColor_g, m_rgbHighColor_b; + qreal m_rgbLowFilteredColor_r, m_rgbLowFilteredColor_g, m_rgbLowFilteredColor_b; + qreal m_rgbMidFilteredColor_r, m_rgbMidFilteredColor_g, m_rgbMidFilteredColor_b; + qreal m_rgbHighFilteredColor_r, m_rgbHighFilteredColor_g, m_rgbHighFilteredColor_b; }; #endif // WAVEFORMRENDERERSIGNALBASE_H diff --git a/src/waveform/renderers/waveformsignalcolors.cpp b/src/waveform/renderers/waveformsignalcolors.cpp index 198a5421ef09..e53272ba5c08 100644 --- a/src/waveform/renderers/waveformsignalcolors.cpp +++ b/src/waveform/renderers/waveformsignalcolors.cpp @@ -48,6 +48,27 @@ bool WaveformSignalColors::setup(const QDomNode &node, const SkinContext& contex } m_rgbHighColor = WSkinColor::getCorrectColor(m_rgbHighColor).toRgb(); + // filtered colors + m_rgbLowFilteredColor.setNamedColor(context.selectString(node, "SignalRGBLowFilteredColor")); + if (!m_rgbLowFilteredColor.isValid()) { + m_rgbLowFilteredColor = m_rgbLowColor.darker(300); + } + m_rgbLowFilteredColor = WSkinColor::getCorrectColor(m_rgbLowFilteredColor).toRgb(); + + m_rgbMidFilteredColor.setNamedColor(context.selectString(node, "SignalRGBMidFilteredColor")); + if (!m_rgbMidFilteredColor.isValid()) { + m_rgbMidFilteredColor = m_rgbMidColor.darker(300); + ; + } + m_rgbMidFilteredColor = WSkinColor::getCorrectColor(m_rgbMidFilteredColor).toRgb(); + + m_rgbHighFilteredColor.setNamedColor(context.selectString(node, "SignalRGBHighFilteredColor")); + if (!m_rgbHighFilteredColor.isValid()) { + m_rgbHighFilteredColor = m_rgbHighColor.darker(300); + ; + } + m_rgbHighFilteredColor = WSkinColor::getCorrectColor(m_rgbHighFilteredColor).toRgb(); + m_axesColor = context.selectColor(node, "AxesColor"); if (!m_axesColor.isValid()) { m_axesColor = QColor(245,245,245); diff --git a/src/waveform/renderers/waveformsignalcolors.h b/src/waveform/renderers/waveformsignalcolors.h index ae554b0cec3a..0293b8c8a00c 100644 --- a/src/waveform/renderers/waveformsignalcolors.h +++ b/src/waveform/renderers/waveformsignalcolors.h @@ -34,6 +34,15 @@ class WaveformSignalColors { inline const QColor& getRgbHighColor() const { return m_rgbHighColor; } + inline const QColor& getRgbLowFilteredColor() const { + return m_rgbLowFilteredColor; + } + inline const QColor& getRgbMidFilteredColor() const { + return m_rgbMidFilteredColor; + } + inline const QColor& getRgbHighFilteredColor() const { + return m_rgbHighFilteredColor; + } inline const QColor& getAxesColor() const { return m_axesColor; } @@ -67,6 +76,9 @@ class WaveformSignalColors { QColor m_rgbLowColor; QColor m_rgbMidColor; QColor m_rgbHighColor; + QColor m_rgbLowFilteredColor; + QColor m_rgbMidFilteredColor; + QColor m_rgbHighFilteredColor; QColor m_axesColor; QColor m_playPosColor; QColor m_playedOverlayColor; diff --git a/src/waveform/waveformwidgetfactory.cpp b/src/waveform/waveformwidgetfactory.cpp index cb16b633c32b..7386a942b033 100644 --- a/src/waveform/waveformwidgetfactory.cpp +++ b/src/waveform/waveformwidgetfactory.cpp @@ -818,6 +818,13 @@ void WaveformWidgetFactory::evaluateWidgets() { useOpenGLShaders = GLSLRGBWaveformWidget::useOpenGLShaders(); developerOnly = GLSLRGBWaveformWidget::developerOnly(); break; + case WaveformWidgetType::GLSLRGBStackedWaveform: + widgetName = GLSLRGBStackedWaveformWidget::getWaveformWidgetName(); + useOpenGl = GLSLRGBStackedWaveformWidget::useOpenGl(); + useOpenGles = GLSLRGBStackedWaveformWidget::useOpenGles(); + useOpenGLShaders = GLSLRGBStackedWaveformWidget::useOpenGLShaders(); + developerOnly = GLSLRGBStackedWaveformWidget::developerOnly(); + break; case WaveformWidgetType::GLVSyncTest: widgetName = GLVSyncTestWidget::getWaveformWidgetName(); useOpenGl = GLVSyncTestWidget::useOpenGl(); @@ -944,6 +951,9 @@ WaveformWidgetAbstract* WaveformWidgetFactory::createWaveformWidget( case WaveformWidgetType::GLSLRGBWaveform: widget = new GLSLRGBWaveformWidget(viewer->getGroup(), viewer); break; + case WaveformWidgetType::GLSLRGBStackedWaveform: + widget = new GLSLRGBStackedWaveformWidget(viewer->getGroup(), viewer); + break; case WaveformWidgetType::GLVSyncTest: widget = new GLVSyncTestWidget(viewer->getGroup(), viewer); break; diff --git a/src/waveform/widgets/glslwaveformwidget.cpp b/src/waveform/widgets/glslwaveformwidget.cpp index 6c8c22fc7b67..1e33ced32207 100644 --- a/src/waveform/widgets/glslwaveformwidget.cpp +++ b/src/waveform/widgets/glslwaveformwidget.cpp @@ -18,19 +18,25 @@ GLSLFilteredWaveformWidget::GLSLFilteredWaveformWidget( const QString& group, QWidget* parent) - : GLSLWaveformWidget(group, parent, false) { + : GLSLWaveformWidget(group, parent, GLSLWaveformWidget::GlslType::Filtered) { } GLSLRGBWaveformWidget::GLSLRGBWaveformWidget( const QString& group, QWidget* parent) - : GLSLWaveformWidget(group, parent, true) { + : GLSLWaveformWidget(group, parent, GLSLWaveformWidget::GlslType::RGB) { +} + +GLSLRGBStackedWaveformWidget::GLSLRGBStackedWaveformWidget( + const QString& group, + QWidget* parent) + : GLSLWaveformWidget(group, parent, GLSLWaveformWidget::GlslType::RGBStacked) { } GLSLWaveformWidget::GLSLWaveformWidget( const QString& group, QWidget* parent, - bool rgbRenderer) + GlslType type) : QGLWidget(parent, SharedGLContext::getWidget()), WaveformWidgetAbstract(group) { qDebug() << "Created QGLWidget. Context" @@ -45,10 +51,12 @@ GLSLWaveformWidget::GLSLWaveformWidget( addRenderer(); addRenderer(); #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) - if (rgbRenderer) { - m_signalRenderer = addRenderer(); - } else { + if (type == GlslType::Filtered) { m_signalRenderer = addRenderer(); + } else if (type == GlslType::RGB) { + m_signalRenderer = addRenderer(); + } else if (type == GlslType::RGBStacked) { + m_signalRenderer = addRenderer(); } #else Q_UNUSED(rgbRenderer); diff --git a/src/waveform/widgets/glslwaveformwidget.h b/src/waveform/widgets/glslwaveformwidget.h index 85baf50dcd64..5f9b526f4806 100644 --- a/src/waveform/widgets/glslwaveformwidget.h +++ b/src/waveform/widgets/glslwaveformwidget.h @@ -9,10 +9,15 @@ class GLSLWaveformRendererSignal; class GLSLWaveformWidget : public QGLWidget, public WaveformWidgetAbstract { Q_OBJECT public: + enum class GlslType { + Filtered, + RGB, + RGBStacked, + }; GLSLWaveformWidget( const QString& group, QWidget* parent, - bool rgbRenderer); + GlslType type); ~GLSLWaveformWidget() override = default; void resize(int width, int height) override; @@ -58,3 +63,30 @@ class GLSLRGBWaveformWidget : public GLSLWaveformWidget { static inline bool useOpenGLShaders() { return true; } static inline bool developerOnly() { return false; } }; + +class GLSLRGBStackedWaveformWidget : public GLSLWaveformWidget { + Q_OBJECT + public: + GLSLRGBStackedWaveformWidget(const QString& group, QWidget* parent); + ~GLSLRGBStackedWaveformWidget() override = default; + + WaveformWidgetType::Type getType() const override { + return WaveformWidgetType::GLSLRGBStackedWaveform; + } + + static inline QString getWaveformWidgetName() { + return tr("RGB Stacked"); + } + static inline bool useOpenGl() { + return true; + } + static inline bool useOpenGles() { + return false; + } + static inline bool useOpenGLShaders() { + return true; + } + static inline bool developerOnly() { + return false; + } +}; diff --git a/src/waveform/widgets/waveformwidgettype.h b/src/waveform/widgets/waveformwidgettype.h index 5d87a67ece17..cc7a8557a0be 100644 --- a/src/waveform/widgets/waveformwidgettype.h +++ b/src/waveform/widgets/waveformwidgettype.h @@ -22,6 +22,7 @@ class WaveformWidgetType { QtVSyncTest, QtHSVWaveform, QtRGBWaveform, + GLSLRGBStackedWaveform, Count_WaveformwidgetType // Also used as invalid value }; };