Skip to content

Commit

Permalink
Merge pull request #13002 from acolombier/feat/slipmode-render
Browse files Browse the repository at this point in the history
SlipMode waveform visual for RGB GLSL
  • Loading branch information
daschuer authored May 6, 2024
2 parents 9c6b16e + 434cfab commit 7d03a12
Show file tree
Hide file tree
Showing 23 changed files with 449 additions and 73 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,7 @@ endif()
if(QOPENGL)
target_sources(mixxx-lib PRIVATE
src/shaders/endoftrackshader.cpp
src/shaders/slipmodeshader.cpp
src/shaders/patternshader.cpp
src/shaders/rgbashader.cpp
src/shaders/rgbshader.cpp
Expand All @@ -1515,6 +1516,7 @@ if(QOPENGL)
src/waveform/renderers/allshader/waveformrenderbeat.cpp
src/waveform/renderers/allshader/waveformrenderer.cpp
src/waveform/renderers/allshader/waveformrendererendoftrack.cpp
src/waveform/renderers/allshader/waveformrendererslipmode.cpp
src/waveform/renderers/allshader/waveformrendererfiltered.cpp
src/waveform/renderers/allshader/waveformrendererhsv.cpp
src/waveform/renderers/allshader/waveformrendererlrrgb.cpp
Expand Down
3 changes: 3 additions & 0 deletions res/skins/Deere/deck_waveform.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
<BeatColor>#ffffff</BeatColor>
<PlayPosColor>#00FF00</PlayPosColor>
<EndOfTrackColor>#EA0000</EndOfTrackColor>
<SlipBorderOutlineColor>#f08c00</SlipBorderOutlineColor>
<SlipBorderTopOutlineSize>10</SlipBorderTopOutlineSize>
<SlipBorderBottomOutlineSize>10</SlipBorderBottomOutlineSize>
<AxesColor></AxesColor>
<Align></Align>
<DefaultMark>
Expand Down
1 change: 1 addition & 0 deletions res/skins/LateNight/decks/overview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<PlayedOverlayColor><Variable name="PlayedOverlayColor"/></PlayedOverlayColor>
<PlayPosColor><Variable name="PlayPosColor"/></PlayPosColor>
<EndOfTrackColor><Variable name="EndOfTrackColor"/></EndOfTrackColor>
<SlipBorderOutlineColor><Variable name="SlipBorderOutlineColor"/></SlipBorderOutlineColor>
<PassthroughLabelColor><Variable name="PassthroughLabelColor"/></PassthroughLabelColor>
<LabelFontSize><Variable name="OverviewFontSize"/></LabelFontSize>
<DimBrightThreshold><Variable name="DimBrightThresholdOverview"/></DimBrightThreshold>
Expand Down
2 changes: 2 additions & 0 deletions res/skins/LateNight/skin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
<SetVariable name="IntroOutroColor">#2c5c9a</SetVariable>
<SetVariable name="PlayedOverlayColor">#dd151515</SetVariable>
<SetVariable name="EndOfTrackColor">#f856e7</SetVariable>
<SetVariable name="SlipBorderOutlineColor">#f08c00</SetVariable>
<SetVariable name="PassthroughLabelColor">#b24c12</SetVariable>
<SetVariable name="OverviewFontSizeDeck">13</SetVariable>
<SetVariable name="OverviewFontSizeDeckMini">11</SetVariable>
Expand Down Expand Up @@ -277,6 +278,7 @@
<SetVariable name="IntroOutroColor">#0000ff</SetVariable>
<SetVariable name="PlayedOverlayColor">#bb000000</SetVariable>
<SetVariable name="EndOfTrackColor">#f856e7</SetVariable>
<SetVariable name="SlipBorderOutlineColor">#1af000</SetVariable>
<SetVariable name="PassthroughLabelColor">#d09300</SetVariable>
<SetVariable name="OverviewFontSizeDeck">13</SetVariable>
<SetVariable name="OverviewFontSizeDeckMini">11</SetVariable>
Expand Down
3 changes: 3 additions & 0 deletions res/skins/LateNight/waveform.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
<BeatHighlightColor></BeatHighlightColor>
<PlayPosColor><Variable name="PlayPosColor"/></PlayPosColor>
<EndOfTrackColor><Variable name="EndOfTrackColor"/></EndOfTrackColor>
<SlipBorderOutlineColor><Variable name="SlipBorderOutlineColor"/></SlipBorderOutlineColor>
<SlipBorderTopOutlineSize>10</SlipBorderTopOutlineSize>
<SlipBorderBottomOutlineSize>20</SlipBorderBottomOutlineSize>
<PassthroughLabelColor><Variable name="PassthroughLabelColor"/></PassthroughLabelColor>
<DimBrightThreshold><Variable name="DimBrightThresholdWaveform"/></DimBrightThreshold>
<!--
Expand Down
3 changes: 3 additions & 0 deletions res/skins/Tango/decks/overview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ Variables:
<PlayPosColor>#FF4300</PlayPosColor>
<PlayedOverlayColor><Variable name="PlayedOverlayColor"/></PlayedOverlayColor>
<EndOfTrackColor><Variable name="EndOfTrackColor"/></EndOfTrackColor>
<SlipBorderOutlineColor><Variable name="SlipBorderOutlineColor"/></SlipBorderOutlineColor>
<SlipBorderTopOutlineSize><Variable name="SlipBorderTopOutlineSize"/></SlipBorderTopOutlineSize>
<SlipBorderBottomOutlineSize><Variable name="SlipBorderBottomOutlineSize"/></SlipBorderBottomOutlineSize>
<LabelTextColor>#ffffff</LabelTextColor>
<LabelBackgroundColor>#85000000</LabelBackgroundColor>
<DefaultMark>
Expand Down
3 changes: 3 additions & 0 deletions res/skins/Tango/waveform.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ Variables:
<BeatColor>#ffffff</BeatColor>
<PlayPosColor>#FF4300</PlayPosColor>
<EndOfTrackColor><Variable name="EndOfTrackColor"/></EndOfTrackColor>
<SlipBorderOutlineColor><Variable name="SlipBorderOutlineColor"/></SlipBorderOutlineColor>
<SlipBorderTopOutlineSize><Variable name="SlipBorderTopOutlineSize"/></SlipBorderTopOutlineSize>
<SlipBorderBottomOutlineSize><Variable name="SlipBorderBottomOutlineSize"/></SlipBorderBottomOutlineSize>
<DefaultMark>
<Align>bottom|right</Align>
<Color>#666666</Color>
Expand Down
60 changes: 60 additions & 0 deletions src/shaders/slipmodeshader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "shaders/slipmodeshader.h"

using namespace mixxx;

void SlipModeShader::init() {
QString vertexShaderCode = QStringLiteral(R"--(
#version 150
attribute highp vec4 position; // use vec4 here (will be padded) to assign directly to gl_Position
out highp vec4 vposition;
void main()
{
vposition = position;
gl_Position = position;
}
)--");

QString fragmentShaderCode = QStringLiteral(R"--(
#version 120
uniform highp vec4 color;
uniform highp vec2 borders;
uniform highp vec2 dimension;
in highp vec4 vposition;
void main()
{
float xBorder = abs(dimension.x * vposition.x);
float yBorder = dimension.y * vposition.y;
float upperBoard = borders.x;
float lowerBoard = borders.y;
if (yBorder < 0){
float borderAlpha = max(
0,
lowerBoard + yBorder
) / lowerBoard;
gl_FragColor = vec4(color.xyz, mix(0, color.w, borderAlpha));
} else if( (xBorder > dimension.x - upperBoard && yBorder >= 0) || yBorder > dimension.y - upperBoard)
{
float borderAlpha = max(0, max(
yBorder - dimension.y,
xBorder - dimension.x) + upperBoard) / upperBoard;
gl_FragColor = vec4(mix(vec3(0, 0, 0), color.rgb, min(color.w, borderAlpha)), 1);
} else {
gl_FragColor = vec4(0, 0, 0, 1);
}
}
)--");

load(vertexShaderCode, fragmentShaderCode);

m_positionLocation = attributeLocation("position");
m_boarderLocation = uniformLocation("borders");
m_dimensionLocation = uniformLocation("dimension");
m_colorLocation = uniformLocation("color");
}
35 changes: 35 additions & 0 deletions src/shaders/slipmodeshader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include "shaders/shader.h"

namespace mixxx {
class SlipModeShader;
}

class mixxx::SlipModeShader : public mixxx::Shader {
public:
SlipModeShader() = default;
~SlipModeShader() = default;
void init();

int positionLocation() const {
return m_positionLocation;
}
int dimensionLocation() const {
return m_dimensionLocation;
}
int colorLocation() const {
return m_colorLocation;
}
int boarderLocation() const {
return m_boarderLocation;
}

private:
int m_positionLocation;
int m_dimensionLocation;
int m_colorLocation;
int m_boarderLocation;

DISALLOW_COPY_AND_ASSIGN(SlipModeShader)
};
23 changes: 16 additions & 7 deletions src/waveform/renderers/allshader/waveformrenderbeat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

namespace allshader {

WaveformRenderBeat::WaveformRenderBeat(WaveformWidgetRenderer* waveformWidget)
: WaveformRenderer(waveformWidget) {
WaveformRenderBeat::WaveformRenderBeat(WaveformWidgetRenderer* waveformWidget,
::WaveformRendererAbstract::PositionSource type)
: WaveformRenderer(waveformWidget),
m_isSlipRenderer(type == ::WaveformRendererAbstract::Slip) {
}

void WaveformRenderBeat::initializeGL() {
Expand All @@ -27,10 +29,13 @@ void WaveformRenderBeat::setup(const QDomNode& node, const SkinContext& context)
void WaveformRenderBeat::paintGL() {
TrackPointer trackInfo = m_waveformRenderer->getTrackInfo();

if (!trackInfo) {
if (!trackInfo || (m_isSlipRenderer && !m_waveformRenderer->isSlipActive())) {
return;
}

auto positionType = m_isSlipRenderer ? ::WaveformRendererAbstract::Slip
: ::WaveformRendererAbstract::Play;

mixxx::BeatsPointer trackBeats = trackInfo->getBeats();
if (!trackBeats) {
return;
Expand All @@ -54,9 +59,9 @@ void WaveformRenderBeat::paintGL() {
}

const double firstDisplayedPosition =
m_waveformRenderer->getFirstDisplayedPosition();
m_waveformRenderer->getFirstDisplayedPosition(positionType);
const double lastDisplayedPosition =
m_waveformRenderer->getLastDisplayedPosition();
m_waveformRenderer->getLastDisplayedPosition(positionType);

const auto startPosition = mixxx::audio::FramePos::fromEngineSamplePos(
firstDisplayedPosition * trackSamples);
Expand Down Expand Up @@ -91,14 +96,18 @@ void WaveformRenderBeat::paintGL() {
++it) {
double beatPosition = it->toEngineSamplePos();
double xBeatPoint =
m_waveformRenderer->transformSamplePositionInRendererWorld(beatPosition);
m_waveformRenderer->transformSamplePositionInRendererWorld(
beatPosition, positionType);

xBeatPoint = qRound(xBeatPoint * devicePixelRatio) / devicePixelRatio;

const float x1 = static_cast<float>(xBeatPoint);
const float x2 = x1 + 1.f;

m_vertices.addRectangle(x1, 0.f, x2, rendererBreadth);
m_vertices.addRectangle(x1,
0.f,
x2,
m_isSlipRenderer ? rendererBreadth / 2 : rendererBreadth);
}

DEBUG_ASSERT(reserved == m_vertices.size());
Expand Down
6 changes: 5 additions & 1 deletion src/waveform/renderers/allshader/waveformrenderbeat.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ class WaveformRenderBeat;

class allshader::WaveformRenderBeat final : public allshader::WaveformRenderer {
public:
explicit WaveformRenderBeat(WaveformWidgetRenderer* waveformWidget);
explicit WaveformRenderBeat(WaveformWidgetRenderer* waveformWidget,
::WaveformRendererAbstract::PositionSource type =
::WaveformRendererAbstract::Play);

void setup(const QDomNode& node, const SkinContext& context) override;
void paintGL() override;
Expand All @@ -27,5 +29,7 @@ class allshader::WaveformRenderBeat final : public allshader::WaveformRenderer {
QColor m_color;
VertexData m_vertices;

bool m_isSlipRenderer;

DISALLOW_COPY_AND_ASSIGN(WaveformRenderBeat);
};
32 changes: 23 additions & 9 deletions src/waveform/renderers/allshader/waveformrendererpreroll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ QImage drawPrerollImage(float markerLength,

namespace allshader {

WaveformRendererPreroll::WaveformRendererPreroll(WaveformWidgetRenderer* waveformWidget)
: WaveformRenderer(waveformWidget) {
WaveformRendererPreroll::WaveformRendererPreroll(
WaveformWidgetRenderer* waveformWidget,
::WaveformRendererAbstract::PositionSource type)
: WaveformRenderer(waveformWidget),
m_isSlipRenderer(type == ::WaveformRendererAbstract::Slip) {
}

WaveformRendererPreroll::~WaveformRendererPreroll() = default;
Expand All @@ -78,12 +81,16 @@ void WaveformRendererPreroll::initializeGL() {

void WaveformRendererPreroll::paintGL() {
const TrackPointer track = m_waveformRenderer->getTrackInfo();
if (!track) {
if (!track || (m_isSlipRenderer && !m_waveformRenderer->isSlipActive())) {
return;
}

const double firstDisplayedPosition = m_waveformRenderer->getFirstDisplayedPosition();
const double lastDisplayedPosition = m_waveformRenderer->getLastDisplayedPosition();
auto positionType = m_isSlipRenderer ? ::WaveformRendererAbstract::Slip
: ::WaveformRendererAbstract::Play;

const double firstDisplayedPosition =
m_waveformRenderer->getFirstDisplayedPosition(positionType);
const double lastDisplayedPosition = m_waveformRenderer->getLastDisplayedPosition(positionType);

// Check if the pre- or post-roll is on screen. If so, draw little triangles
// to indicate the respective zones.
Expand All @@ -98,7 +105,7 @@ void WaveformRendererPreroll::paintGL() {
const double vSamplesPerPixel = m_waveformRenderer->getVisualSamplePerPixel();
const double numberOfVSamples = m_waveformRenderer->getLength() * vSamplesPerPixel;

const int currentVSamplePosition = m_waveformRenderer->getPlayPosVSample();
const int currentVSamplePosition = m_waveformRenderer->getPlayPosVSample(positionType);
const int totalVSamples = m_waveformRenderer->getTotalVSample();

const float markerBreadth = m_waveformRenderer->getBreadth() * 0.4f;
Expand Down Expand Up @@ -165,7 +172,7 @@ void WaveformRendererPreroll::paintGL() {
drawPattern(x,
halfBreadth - halfMarkerBreadth,
0.f,
halfBreadth + halfMarkerBreadth,
m_isSlipRenderer ? halfBreadth : halfBreadth + halfMarkerBreadth,
x / markerLength);
}

Expand All @@ -186,7 +193,7 @@ void WaveformRendererPreroll::paintGL() {
drawPattern(x,
halfBreadth - halfMarkerBreadth,
end,
halfBreadth + halfMarkerBreadth,
m_isSlipRenderer ? halfBreadth : halfBreadth + halfMarkerBreadth,
(end - x) / markerLength);
}

Expand All @@ -205,7 +212,14 @@ void WaveformRendererPreroll::drawPattern(
const int texcoordLocation = m_shader.texcoordLocation();

const std::array<float, 8> positionArray = {x1, y1, x2, y1, x1, y2, x2, y2};
const std::array<float, 8> texcoordArray = {0.f, 0.f, 1.f, 0.f, 0.f, 1.f, 1.f, 1.f};
const std::array<float, 8> texcoordArray = {0.f,
0.f,
1.f,
0.f,
0.f,
m_isSlipRenderer ? 0.5f : 1.f,
1.f,
m_isSlipRenderer ? 0.5f : 1.f};
m_shader.setUniformValue(repetitionsLocation, QVector2D(repetitions, 1.0));

m_shader.setAttributeArray(
Expand Down
10 changes: 8 additions & 2 deletions src/waveform/renderers/allshader/waveformrendererpreroll.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ class QOpenGLTexture;

namespace allshader {
class WaveformRendererPreroll;
class WaveformRendererSlipPreroll;
}

class allshader::WaveformRendererPreroll final : public allshader::WaveformRenderer {
class allshader::WaveformRendererPreroll : public allshader::WaveformRenderer {
public:
explicit WaveformRendererPreroll(WaveformWidgetRenderer* waveformWidgetRenderer);
explicit WaveformRendererPreroll(
WaveformWidgetRenderer* waveformWidgetRenderer,
::WaveformRendererAbstract::PositionSource type =
::WaveformRendererAbstract::Play);
~WaveformRendererPreroll() override;

void setup(const QDomNode& node, const SkinContext& context) override;
Expand All @@ -36,5 +40,7 @@ class allshader::WaveformRendererPreroll final : public allshader::WaveformRende
float m_markerLength{};
OpenGLTexture2D m_texture;

bool m_isSlipRenderer;

DISALLOW_COPY_AND_ASSIGN(WaveformRendererPreroll);
};
Loading

0 comments on commit 7d03a12

Please sign in to comment.