Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use geometrynode for waveformrendererpreroll #16

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 68 additions & 80 deletions src/waveform/renderers/allshader/waveformrendererpreroll.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#include "waveform/renderers/allshader/waveformrendererpreroll.h"

#include <QDomNode>
#include <QOpenGLTexture>
#include <QPainterPath>
#include <array>

#include "rendergraph/geometry.h"
#include "rendergraph/material/patternmaterial.h"
#include "rendergraph/vertexupdaters/texturedvertexupdater.h"
#include "skin/legacy/skincontext.h"
#include "waveform/renderers/allshader/matrixforwidgetgeometry.h"
#include "waveform/renderers/waveformwidgetrenderer.h"
#include "widget/wskincolor.h"

Expand All @@ -20,7 +21,7 @@ QImage drawPrerollImage(float markerLength,
const float imageW = static_cast<float>(imagePixelW) / devicePixelRatio;
const float imageH = static_cast<float>(imagePixelH) / devicePixelRatio;

QImage image(imagePixelW, imagePixelH, QImage::Format_ARGB32_Premultiplied);
QImage image(imagePixelW, imagePixelH, QImage::Format_RGBA8888_Premultiplied);
image.setDevicePixelRatio(devicePixelRatio);

const float penWidth = 1.5f;
Expand All @@ -47,7 +48,7 @@ QImage drawPrerollImage(float markerLength,
path.lineTo(p0);
path.closeSubpath();
QColor fillColor = color;
fillColor.setAlphaF(0.5f);
fillColor.setAlphaF(0.25f);
painter.fillPath(path, QBrush(fillColor));

painter.drawPath(path);
Expand All @@ -57,31 +58,52 @@ QImage drawPrerollImage(float markerLength,
}
} // anonymous namespace

using namespace rendergraph;

namespace allshader {

WaveformRendererPreroll::WaveformRendererPreroll(
WaveformWidgetRenderer* waveformWidget,
::WaveformRendererAbstract::PositionSource type)
: WaveformRenderer(waveformWidget),
: ::WaveformRendererAbstract(waveformWidget),
m_isSlipRenderer(type == ::WaveformRendererAbstract::Slip) {
setGeometry(std::make_unique<Geometry>(PatternMaterial::attributes(), 0));
setMaterial(std::make_unique<PatternMaterial>());
setUsePreprocess(true);
geometry().setDrawingMode(Geometry::DrawingMode::Triangles);
}

WaveformRendererPreroll::~WaveformRendererPreroll() = default;

void WaveformRendererPreroll::setup(
const QDomNode& node, const SkinContext& context) {
m_color = QColor(context.selectString(node, "SignalColor"));
const QDomNode& node, const SkinContext& skinContext) {
m_color = QColor(skinContext.selectString(node, "SignalColor"));
m_color = WSkinColor::getCorrectColor(m_color);
}

void WaveformRendererPreroll::initializeGL() {
m_shader.init();
void WaveformRendererPreroll::draw(QPainter* painter, QPaintEvent* event) {
Q_UNUSED(painter);
Q_UNUSED(event);
DEBUG_ASSERT(false);
}

void WaveformRendererPreroll::preprocess() {
if (!preprocessInner()) {
if (geometry().vertexCount() != 0) {
geometry().allocate(0);
markDirtyGeometry();
}
} else {
markDirtyMaterial();
markDirtyGeometry();
}
}

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

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

auto positionType = m_isSlipRenderer ? ::WaveformRendererAbstract::Slip
Expand All @@ -95,11 +117,15 @@ void WaveformRendererPreroll::paintGL() {
// to indicate the respective zones.
const bool preRollVisible = firstDisplayedPosition < 0;
const bool postRollVisible = lastDisplayedPosition > 1;
const int numVerticesPerRectangle = 6;

if (!(preRollVisible || postRollVisible)) {
return;
if (!preRollVisible && !postRollVisible) {
return false;
}

const int reserved = (preRollVisible ? numVerticesPerRectangle : 0) +
(postRollVisible ? numVerticesPerRectangle : 0);

const double playMarkerPosition = m_waveformRenderer->getPlayMarkerPosition();
const double vSamplesPerPixel = m_waveformRenderer->getVisualSamplePerPixel();
const double numberOfVSamples = m_waveformRenderer->getLength() * vSamplesPerPixel;
Expand All @@ -125,36 +151,20 @@ void WaveformRendererPreroll::paintGL() {
// has changed size last time.
m_markerLength = markerLength;
m_markerBreadth = markerBreadth;
m_texture.setData(drawPrerollImage(m_markerLength,
m_markerBreadth,
m_waveformRenderer->getDevicePixelRatio(),
m_color));
dynamic_cast<PatternMaterial&>(material())
.setTexture(std::make_unique<Texture>(m_waveformRenderer->getContext(),
drawPrerollImage(m_markerLength,
m_markerBreadth,
m_waveformRenderer->getDevicePixelRatio(),
m_color)));
}

if (!m_texture.isStorageAllocated()) {
return;
}

const int matrixLocation = m_shader.matrixLocation();
const int textureLocation = m_shader.textureLocation();
const int positionLocation = m_shader.positionLocation();
const int texcoordLocation = m_shader.texcoordLocation();

// Set up the shader
m_shader.bind();

m_shader.enableAttributeArray(positionLocation);
m_shader.enableAttributeArray(texcoordLocation);

const QMatrix4x4 matrix = matrixForWidgetGeometry(m_waveformRenderer, false);

m_shader.setUniformValue(matrixLocation, matrix);
m_shader.setUniformValue(textureLocation, 0);

m_texture.bind();
geometry().allocate(reserved);

const float end = m_waveformRenderer->getLength();

TexturedVertexUpdater vertexUpdater{geometry().vertexDataAs<Geometry::TexturedPoint2D>()};

if (preRollVisible) {
// VSample position of the right-most triangle's tip
const double triangleTipVSamplePosition =
Expand All @@ -168,11 +178,14 @@ void WaveformRendererPreroll::paintGL() {
x -= std::ceil((x - limit) / markerLength) * markerLength;
}

drawPattern(x,
halfBreadth - halfMarkerBreadth,
0.f,
m_isSlipRenderer ? halfBreadth : halfBreadth + halfMarkerBreadth,
x / markerLength);
const float repetitions = x / markerLength;

vertexUpdater.addRectangle({x, halfBreadth - halfMarkerBreadth},
{0,
m_isSlipRenderer ? halfBreadth
: halfBreadth + halfMarkerBreadth},
{0.f, 0.f},
{repetitions, m_isSlipRenderer ? 0.5f : 1.f});
}

if (postRollVisible) {
Expand All @@ -189,44 +202,19 @@ void WaveformRendererPreroll::paintGL() {
x += std::ceil((limit - x) / markerLength) * markerLength;
}

drawPattern(x,
halfBreadth - halfMarkerBreadth,
end,
m_isSlipRenderer ? halfBreadth : halfBreadth + halfMarkerBreadth,
(end - x) / markerLength);
}
const float repetitions = (end - x) / markerLength;

m_texture.release();
vertexUpdater.addRectangle({x, halfBreadth - halfMarkerBreadth},
{end,
m_isSlipRenderer ? halfBreadth
: halfBreadth + halfMarkerBreadth},
{0.f, 0.f},
{repetitions, m_isSlipRenderer ? 0.5f : 1.f});
}

m_shader.disableAttributeArray(positionLocation);
m_shader.disableAttributeArray(texcoordLocation);
m_shader.release();
}
DEBUG_ASSERT(reserved == vertexUpdater.index());

void WaveformRendererPreroll::drawPattern(
float x1, float y1, float x2, float y2, float repetitions) {
// Draw a large rectangle with a repeating pattern of the texture
const int repetitionsLocation = m_shader.repetitionsLocation();
const int positionLocation = m_shader.positionLocation();
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,
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(
positionLocation, GL_FLOAT, positionArray.data(), 2);
m_shader.setAttributeArray(
texcoordLocation, GL_FLOAT, texcoordArray.data(), 2);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
return true;
}

} // namespace allshader
28 changes: 12 additions & 16 deletions src/waveform/renderers/allshader/waveformrendererpreroll.h
Original file line number Diff line number Diff line change
@@ -1,48 +1,44 @@
#pragma once

#include <QColor>
#include <QImage>
#include <memory>

#include "rendergraph/openglnode.h"
#include "shaders/patternshader.h"
#include "rendergraph/geometrynode.h"
#include "util/class.h"
#include "util/opengltexture2d.h"
#include "waveform/renderers/allshader/vertexdata.h"
#include "waveform/renderers/allshader/waveformrenderer.h"
#include "waveform/renderers/waveformrendererabstract.h"

class QDomNode;
class SkinContext;
class QOpenGLTexture;

namespace allshader {
class WaveformRendererPreroll;
}

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

// Pure virtual from WaveformRendererAbstract, not used
void draw(QPainter* painter, QPaintEvent* event) override final;

void setup(const QDomNode& node, const SkinContext& skinContext) override;
void paintGL() override;
void initializeGL() override;

private:
void drawPattern(float x1, float y1, float x2, float y2, float repetitions);
// Virtual for rendergraph::Node
void preprocess() override;

mixxx::PatternShader m_shader;
private:
QColor m_color;
float m_markerBreadth{};
float m_markerLength{};
OpenGLTexture2D m_texture;

bool m_isSlipRenderer;

bool preprocessInner();

DISALLOW_COPY_AND_ASSIGN(WaveformRendererPreroll);
};
22 changes: 8 additions & 14 deletions src/waveform/renderers/waveformwidgetrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,11 @@ WaveformWidgetRenderer::WaveformWidgetRenderer(const QString& group)
// Really create some to manage those;
m_visualPlayPosition(nullptr),
m_totalVSamples(0),
m_pRateRatioCO(nullptr),
m_pGainControlObject(nullptr),
m_gain(1.0),
m_pTrackSamplesControlObject(nullptr),
m_trackSamples(0),
m_trackSamples(0.0),
m_scaleFactor(1.0),
m_playMarkerPosition(s_defaultPlayMarkerPosition),
m_pContext(nullptr),
m_passthroughEnabled(false) {
//qDebug() << "WaveformWidgetRenderer";
for (int type = ::WaveformRendererAbstract::Play;
Expand Down Expand Up @@ -79,10 +77,6 @@ WaveformWidgetRenderer::~WaveformWidgetRenderer() {
delete m_rendererStack[i];
}

delete m_pRateRatioCO;
delete m_pGainControlObject;
delete m_pTrackSamplesControlObject;

#ifdef WAVEFORMWIDGETRENDERER_DEBUG
delete m_timer;
#endif
Expand All @@ -93,11 +87,11 @@ bool WaveformWidgetRenderer::init() {

m_visualPlayPosition = VisualPlayPosition::getVisualPlayPosition(m_group);

m_pRateRatioCO = new ControlProxy(
m_pRateRatioCO = std::make_unique<ControlProxy>(
m_group, "rate_ratio");
m_pGainControlObject = new ControlProxy(
m_pGainControlObject = std::make_unique<ControlProxy>(
m_group, "total_gain");
m_pTrackSamplesControlObject = new ControlProxy(
m_pTrackSamplesControlObject = std::make_unique<ControlProxy>(
m_group, "track_samples");

for (int i = 0; i < m_rendererStack.size(); ++i) {
Expand Down Expand Up @@ -265,8 +259,8 @@ void WaveformWidgetRenderer::draw(QPainter* painter, QPaintEvent* event) {
}

void WaveformWidgetRenderer::drawPlayPosmarker(QPainter* painter) {
const int lineX = static_cast<int>(m_width * m_playMarkerPosition);
const int lineY = static_cast<int>(m_height * m_playMarkerPosition);
const int lineX = std::lround(m_width * m_playMarkerPosition);
const int lineY = std::lround(m_height * m_playMarkerPosition);

// draw dim outlines to increase playpos/waveform contrast
painter->setOpacity(0.5);
Expand Down Expand Up @@ -428,7 +422,7 @@ void WaveformWidgetRenderer::selectStem(mixxx::StemChannelSelection stemMask) {
void WaveformWidgetRenderer::setTrack(TrackPointer track) {
m_pTrack = track;
//used to postpone first display until track sample is actually available
m_trackSamples = -1;
m_trackSamples = -1.0;

for (int i = 0; i < m_rendererStack.size(); ++i) {
m_rendererStack[i]->onSetTrack();
Expand Down
Loading
Loading