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

markrange waveformrenderer using rendergraph #14189

Merged
merged 1 commit into from
Feb 3, 2025
Merged
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
104 changes: 53 additions & 51 deletions src/waveform/renderers/allshader/waveformrendermarkrange.cpp
Original file line number Diff line number Diff line change
@@ -1,70 +1,46 @@
#include "waveform/renderers/allshader/waveformrendermarkrange.h"

#include "rendergraph/geometry.h"
#include "rendergraph/geometrynode.h"
#include "rendergraph/material/unicolormaterial.h"
#include "rendergraph/vertexupdaters/vertexupdater.h"
#include "skin/legacy/skincontext.h"
#include "waveform/renderers/allshader/matrixforwidgetgeometry.h"
#include "waveform/renderers/waveformwidgetrenderer.h"

allshader::WaveformRenderMarkRange::WaveformRenderMarkRange(WaveformWidgetRenderer* waveformWidget)
: WaveformRenderer(waveformWidget) {
}

void allshader::WaveformRenderMarkRange::initializeGL() {
m_shader.init();
}

void allshader::WaveformRenderMarkRange::fillRect(
const QRectF& rect, QColor color) {
const float posx1 = static_cast<float>(rect.x());
const float posx2 = static_cast<float>(rect.x() + rect.width());
const float posy1 = static_cast<float>(rect.y());
const float posy2 = static_cast<float>(rect.y() + rect.height());

const float posarray[] = {posx1, posy1, posx2, posy1, posx1, posy2, posx2, posy2};
using namespace rendergraph;

const int colorLocation = m_shader.colorLocation();
const int positionLocation = m_shader.positionLocation();
namespace allshader {

m_shader.setUniformValue(colorLocation, color);

m_shader.setAttributeArray(
positionLocation, GL_FLOAT, posarray, 2);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
WaveformRenderMarkRange::WaveformRenderMarkRange(WaveformWidgetRenderer* waveformWidget)
: ::WaveformRendererAbstract(waveformWidget) {
}

void allshader::WaveformRenderMarkRange::setup(const QDomNode& node, const SkinContext& context) {
void WaveformRenderMarkRange::setup(const QDomNode& node, const SkinContext& skinContext) {
m_markRanges.clear();
m_markRanges.reserve(1);

QDomNode child = node.firstChild();
while (!child.isNull()) {
if (child.nodeName() == "MarkRange") {
m_markRanges.push_back(
WaveformMarkRange(
m_waveformRenderer->getGroup(),
child,
context,
*m_waveformRenderer->getWaveformSignalColors()));
addRange(WaveformMarkRange(
m_waveformRenderer->getGroup(),
child,
skinContext,
*m_waveformRenderer->getWaveformSignalColors()));
}
child = child.nextSibling();
}
}

void allshader::WaveformRenderMarkRange::paintGL() {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

const QMatrix4x4 matrix = matrixForWidgetGeometry(m_waveformRenderer, false);

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

m_shader.bind();
m_shader.enableAttributeArray(positionLocation);
void WaveformRenderMarkRange::draw(QPainter* painter, QPaintEvent* event) {
Q_UNUSED(painter);
Q_UNUSED(event);
DEBUG_ASSERT(false);
}

m_shader.setUniformValue(matrixLocation, matrix);
void WaveformRenderMarkRange::update() {
GeometryNode* pChild = static_cast<GeometryNode*>(firstChild());

for (auto&& markRange : m_markRanges) {
for (const auto& markRange : m_markRanges) {
// If the mark range is not active we should not draw it.
if (!markRange.active()) {
continue;
Expand All @@ -88,8 +64,6 @@ void allshader::WaveformRenderMarkRange::paintGL() {
startPosition = std::floor(startPosition);
endPosition = std::floor(endPosition);

const double span = std::max(endPosition - startPosition, 1.0);

// range not in the current display
if (startPosition > m_waveformRenderer->getLength() || endPosition < 0) {
continue;
Expand All @@ -98,8 +72,36 @@ void allshader::WaveformRenderMarkRange::paintGL() {
QColor color = markRange.enabled() ? markRange.m_activeColor : markRange.m_disabledColor;
color.setAlphaF(0.3f);

fillRect(QRectF(startPosition, 0, span, m_waveformRenderer->getBreadth()), color);
if (!pChild) {
auto pNode = std::make_unique<GeometryNode>();
pChild = pNode.get();
pChild->initForRectangles<UniColorMaterial>(1);
appendChildNode(std::move(pNode));
}

updateNode(pChild,
color,
{static_cast<float>(startPosition), 0.f},
{static_cast<float>(endPosition) + 1.f,
static_cast<float>(m_waveformRenderer->getBreadth())});

pChild = static_cast<GeometryNode*>(pChild->nextSibling());
}
m_shader.disableAttributeArray(positionLocation);
m_shader.release();
while (pChild) {
auto pNode = detachChildNode(pChild);
pChild = static_cast<GeometryNode*>(pChild->nextSibling());
}
}

void WaveformRenderMarkRange::updateNode(GeometryNode* pChild,
QColor color,
QVector2D lt,
QVector2D rb) {
VertexUpdater vertexUpdater{pChild->geometry().vertexDataAs<Geometry::Point2D>()};
vertexUpdater.addRectangle(lt, rb);
pChild->material().setUniform(1, color);
pChild->markDirtyGeometry();
pChild->markDirtyMaterial();
}

} // namespace allshader
34 changes: 22 additions & 12 deletions src/waveform/renderers/allshader/waveformrendermarkrange.h
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
#pragma once

#include <QColor>
#include <vector>
#include <QVector2D>

#include "rendergraph/openglnode.h"
#include "shaders/unicolorshader.h"
#include "rendergraph/node.h"
#include "util/class.h"
#include "waveform/renderers/allshader/waveformrenderer.h"
#include "waveform/renderers/waveformmarkrange.h"
#include "waveform/renderers/waveformrendererabstract.h"

class QDomNode;
class SkinContext;

namespace rendergraph {
class GeometryNode;
} // namespace rendergraph

namespace allshader {
class WaveformRenderMarkRange;
}
} // namespace allshader

class allshader::WaveformRenderMarkRange final
: public allshader::WaveformRenderer,
public rendergraph::OpenGLNode {
class allshader::WaveformRenderMarkRange final : public ::WaveformRendererAbstract,
public rendergraph::Node {
public:
explicit WaveformRenderMarkRange(WaveformWidgetRenderer* waveformWidget);

void addRange(WaveformMarkRange&& range) {
m_markRanges.push_back(std::move(range));
}

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

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

void initializeGL() override;
void paintGL() override;
void update();

private:
void fillRect(const QRectF& rect, QColor color);
void updateNode(rendergraph::GeometryNode* pChild,
QColor color,
QVector2D lt,
QVector2D rb);

mixxx::UnicolorShader m_shader;
std::vector<WaveformMarkRange> m_markRanges;

DISALLOW_COPY_AND_ASSIGN(WaveformRenderMarkRange);
Expand Down
2 changes: 2 additions & 0 deletions src/waveform/widgets/allshader/waveformwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
type, options, ::WaveformRendererAbstract::Play);
m_pWaveformRendererSignal = pWaveformRendererSignal.get();
if (pWaveformRendererSignal) {
auto pNode = dynamic_cast<rendergraph::BaseNode*>(pWaveformRendererSignal.release());

Check warning on line 50 in src/waveform/widgets/allshader/waveformwidget.cpp

View workflow job for this annotation

GitHub Actions / clang-tidy

'auto pNode' can be declared as 'auto *pNode' [readability-qualified-auto]
DEBUG_ASSERT(pNode);
pOpacityNode->appendChildNode(std::unique_ptr<rendergraph::BaseNode>(pNode));
}
Expand All @@ -69,7 +69,7 @@
#endif
std::unique_ptr<WaveformRendererSignalBase> pSlipNode = addWaveformSignalRenderer(
type, options, ::WaveformRendererAbstract::Slip);
auto pNode = dynamic_cast<rendergraph::BaseNode*>(pSlipNode.release());

Check warning on line 72 in src/waveform/widgets/allshader/waveformwidget.cpp

View workflow job for this annotation

GitHub Actions / clang-tidy

'auto pNode' can be declared as 'auto *pNode' [readability-qualified-auto]
DEBUG_ASSERT(pNode);
pOpacityNode->appendChildNode(std::unique_ptr<rendergraph::BaseNode>(pNode));
pOpacityNode->appendChildNode(
Expand Down Expand Up @@ -146,6 +146,8 @@
// opacity of 0.f effectively skips the subtree rendering
m_pOpacityNode->setOpacity(shouldOnlyDrawBackground() ? 0.f : 1.f);

m_pWaveformRenderMarkRange->update();

m_pEngine->preprocess();
m_pEngine->render();
}
Expand Down
Loading