diff --git a/src/waveform/renderers/allshader/waveformrendererrgb.cpp b/src/waveform/renderers/allshader/waveformrendererrgb.cpp index ff1ad60f88fb..e7099c4d55c6 100644 --- a/src/waveform/renderers/allshader/waveformrendererrgb.cpp +++ b/src/waveform/renderers/allshader/waveformrendererrgb.cpp @@ -26,6 +26,7 @@ void WaveformRendererRGB::onSetup(const QDomNode& node) { void WaveformRendererRGB::initializeGL() { WaveformRendererSignalBase::initializeGL(); m_shader.init(); + m_shader_ghost.init(); } void WaveformRendererRGB::paintGL() { @@ -94,6 +95,10 @@ void WaveformRendererRGB::paintGL() { m_vertices.reserve(reserved); m_colors.clear(); m_colors.reserve(reserved); + m_vertices_ghost.clear(); + m_vertices_ghost.reserve(reserved); + m_colors_ghost.clear(); + m_colors_ghost.reserve(reserved); m_vertices.addRectangle(0.f, halfBreadth - 0.5f * devicePixelRatio, @@ -140,6 +145,12 @@ void WaveformRendererRGB::paintGL() { float maxMid = static_cast(u8maxMid); float maxHigh = static_cast(u8maxHigh); float maxAllChn[2]{static_cast(u8maxAllChn[0]), static_cast(u8maxAllChn[1])}; + + float ghostLow = maxLow; + float ghostMid = maxMid; + float ghostHigh = maxHigh; + float maxAllChn_ghost[2]{static_cast(u8maxAllChn[0]), + static_cast(u8maxAllChn[1])}; // Uncomment to undo scaling with pow(value, 2.0f * 0.316f) done in analyzerwaveform.h // float maxAllChn[2]{unscale(u8maxAllChn[0]), unscale(u8maxAllChn[1])}; @@ -147,7 +158,7 @@ void WaveformRendererRGB::paintGL() { // We take the square root to get the magnitude below. const float sum = math_pow2(maxLow) + math_pow2(maxMid) + math_pow2(maxHigh); - // Apply the gains + // Apply the gains (non-ghosted version only) maxLow *= lowGain; maxMid *= midGain; maxHigh *= highGain; @@ -155,6 +166,8 @@ void WaveformRendererRGB::paintGL() { // Calculate the squared magnitude of the gained maxLow, maxMid and maxHigh values // We take the square root to get the magnitude below. const float sumGained = math_pow2(maxLow) + math_pow2(maxMid) + math_pow2(maxHigh); + const float sumGained_ghost = math_pow2(ghostLow) + + math_pow2(ghostMid) + math_pow2(ghostHigh); // The maxAll values will be used to draw the amplitude. We scale them according to // magnitude of the gained maxLow, maxMid and maxHigh values @@ -164,6 +177,10 @@ void WaveformRendererRGB::paintGL() { const float factor = std::sqrt(sumGained / sum); maxAllChn[0] *= factor; maxAllChn[1] *= factor; + + const float factor_ghost = std::sqrt(sumGained_ghost / sum); + maxAllChn_ghost[0] *= factor_ghost; + maxAllChn_ghost[1] *= factor_ghost; } // Use the gained maxLow, maxMid and maxHigh values to calculate the color components @@ -185,6 +202,22 @@ void WaveformRendererRGB::paintGL() { blue *= normFactor; } + float red_ghost = ghostLow * low_r + ghostMid * mid_r + ghostHigh * high_r; + float green_ghost = ghostLow * low_g + ghostMid * mid_g + ghostHigh * high_g; + float blue_ghost = ghostLow * low_b + ghostMid * mid_b + ghostHigh * high_b; + const float maxComponent_ghost = math_max3(red_ghost, green_ghost, blue_ghost); + if (maxComponent_ghost == 0.f) { + // Avoid division by 0 + red_ghost = 0.f; + green_ghost = 0.f; + blue_ghost = 0.f; + } else { + const float normFactor_ghost = 1.f / maxComponent_ghost; + red_ghost *= normFactor_ghost; + green_ghost *= normFactor_ghost; + blue_ghost *= normFactor_ghost; + } + // Lines are thin rectangles m_vertices.addRectangle(fpos - 0.5f, halfBreadth - heightFactor * maxAllChn[0], @@ -192,6 +225,12 @@ void WaveformRendererRGB::paintGL() { halfBreadth + heightFactor * maxAllChn[1]); m_colors.addForRectangle(red, green, blue); + m_vertices_ghost.addRectangle(fpos - 0.5f, + halfBreadth - heightFactor * maxAllChn_ghost[0], + fpos + 0.5f, + halfBreadth + heightFactor * maxAllChn_ghost[1]); + m_colors_ghost.addForRectangle(red_ghost, green_ghost, blue_ghost, ghost_alpha); + xVisualFrame += visualIncrementPerPixel; } @@ -200,6 +239,28 @@ void WaveformRendererRGB::paintGL() { const QMatrix4x4 matrix = matrixForWidgetGeometry(m_waveformRenderer, true); + // Draw the ghost version first so the solid version is on top. + const int matrixLocation_ghost = m_shader_ghost.matrixLocation(); + const int positionLocation_ghost = m_shader_ghost.positionLocation(); + const int colorLocation_ghost = m_shader_ghost.colorLocation(); + + m_shader_ghost.bind(); + m_shader_ghost.enableAttributeArray(positionLocation_ghost); + m_shader_ghost.enableAttributeArray(colorLocation_ghost); + + m_shader_ghost.setUniformValue(matrixLocation_ghost, matrix); + + m_shader_ghost.setAttributeArray( + positionLocation_ghost, GL_FLOAT, m_vertices_ghost.constData(), 2); + m_shader_ghost.setAttributeArray( + colorLocation_ghost, GL_FLOAT, m_colors_ghost.constData(), 4); + + glDrawArrays(GL_TRIANGLES, 0, m_vertices_ghost.size()); + + m_shader_ghost.disableAttributeArray(positionLocation_ghost); + m_shader_ghost.disableAttributeArray(colorLocation_ghost); + m_shader_ghost.release(); + const int matrixLocation = m_shader.matrixLocation(); const int positionLocation = m_shader.positionLocation(); const int colorLocation = m_shader.colorLocation(); diff --git a/src/waveform/renderers/allshader/waveformrendererrgb.h b/src/waveform/renderers/allshader/waveformrendererrgb.h index 49178842d339..097829ce3aec 100644 --- a/src/waveform/renderers/allshader/waveformrendererrgb.h +++ b/src/waveform/renderers/allshader/waveformrendererrgb.h @@ -1,7 +1,9 @@ #pragma once +#include "shaders/rgbashader.h" #include "shaders/rgbshader.h" #include "util/class.h" +#include "waveform/renderers/allshader/rgbadata.h" #include "waveform/renderers/allshader/rgbdata.h" #include "waveform/renderers/allshader/vertexdata.h" #include "waveform/renderers/allshader/waveformrenderersignalbase.h" @@ -22,8 +24,13 @@ class allshader::WaveformRendererRGB final : public allshader::WaveformRendererS private: mixxx::RGBShader m_shader; + mixxx::RGBAShader m_shader_ghost; VertexData m_vertices; RGBData m_colors; + VertexData m_vertices_ghost; + RGBAData m_colors_ghost; + + const float ghost_alpha = 0.25f; DISALLOW_COPY_AND_ASSIGN(WaveformRendererRGB); };