Skip to content

Commit

Permalink
Merge pull request #14188 from m0dB/rg-wr-mark
Browse files Browse the repository at this point in the history
mark waveformrenderer using rendergraph
  • Loading branch information
acolombier authored Feb 3, 2025
2 parents 91100d7 + e226365 commit 5e13601
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 277 deletions.
126 changes: 65 additions & 61 deletions src/waveform/renderers/allshader/digitsrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
#include <QGraphicsBlurEffect>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QOpenGLTexture>
#include <QPainter>
#include <QPainterPath>
#include <cmath>

#include "rendergraph/context.h"
#include "rendergraph/geometry.h"
#include "rendergraph/material/texturematerial.h"
#include "rendergraph/vertexupdaters/texturedvertexupdater.h"
#include "util/assert.h"
#include "util/roundtopixel.h"
#include "waveform/renderers/allshader/matrixforwidgetgeometry.h"
#include "waveform/renderers/allshader/vertexdata.h"

// Render digits using a texture (generated) with digits with blurred dark outline

using namespace rendergraph;

namespace {

// The texture will contain 12 characters: 10 digits, colon and dot
Expand Down Expand Up @@ -57,23 +60,22 @@ static_assert(checkCharToIndex());

} // namespace

allshader::DigitsRenderer::~DigitsRenderer() = default;

void allshader::DigitsRenderer::init() {
initializeOpenGLFunctions();
m_shader.init();
allshader::DigitsRenderNode::DigitsRenderNode() {
setGeometry(std::make_unique<Geometry>(TextureMaterial::attributes(), 0));
setMaterial(std::make_unique<TextureMaterial>());
geometry().setDrawingMode(Geometry::DrawingMode::Triangles);
}

float allshader::DigitsRenderer::height() const {
allshader::DigitsRenderNode::~DigitsRenderNode() = default;

float allshader::DigitsRenderNode::height() const {
return m_height;
}

void allshader::DigitsRenderer::updateTexture(
float fontPointSize, float maxHeight, float devicePixelRatio) {
if (std::lround(maxHeight * devicePixelRatio) <= 0) {
return;
}

void allshader::DigitsRenderNode::updateTexture(rendergraph::Context* pContext,
float fontPointSize,
float maxHeight,
float devicePixelRatio) {
if (fontPointSize == m_fontPointSize && maxHeight == m_maxHeight) {
return;
}
Expand Down Expand Up @@ -184,12 +186,12 @@ void allshader::DigitsRenderer::updateTexture(
blur->setBlurRadius(static_cast<float>(m_penWidth) / 3);

QGraphicsScene scene;
auto item = std::make_unique<QGraphicsPixmapItem>();
item->setPixmap(QPixmap::fromImage(image));
item->setGraphicsEffect(blur.release());
QGraphicsPixmapItem item;
item.setPixmap(QPixmap::fromImage(image));
item.setGraphicsEffect(blur.release());
image.fill(Qt::transparent);
QPainter painter(&image);
scene.addItem(item.release());
scene.addItem(&item);
scene.render(&painter, QRectF(), QRectF(0, 0, image.width(), image.height()));
}

Expand All @@ -210,64 +212,66 @@ void allshader::DigitsRenderer::updateTexture(
painter.drawPath(path);
}

m_texture.setData(image);
dynamic_cast<TextureMaterial&>(material())
.setTexture(std::make_unique<Texture>(pContext, image));
}

float allshader::DigitsRenderer::draw(const QMatrix4x4& matrix,
void allshader::DigitsRenderNode::update(
float x,
float y,
bool multiLine,
const QString& s1,
const QString& s2) {
const int numVerticesPerRectangle = 6;
const int reserved = (s1.length() + s2.length()) * numVerticesPerRectangle;
geometry().allocate(reserved);
TexturedVertexUpdater vertexUpdater{geometry().vertexDataAs<Geometry::TexturedPoint2D>()};

const float ch = height();
if (!s1.isEmpty()) {
const auto w = addVertices(vertexUpdater,
x,
y,
s1);
if (multiLine) {
y += ch;
} else {
x += w + ch * 0.75f;
}
}
if (!s2.isEmpty()) {
addVertices(vertexUpdater,
x,
y,
s2);
}

DEBUG_ASSERT(reserved == vertexUpdater.index());
}

void allshader::DigitsRenderNode::clear() {
geometry().allocate(0);
}

float allshader::DigitsRenderNode::addVertices(TexturedVertexUpdater& vertexUpdater,
float x,
float y,
const QString& s) {
const int n = s.length();
const float x0 = x;
const float space = static_cast<float>(m_penWidth) / 2;

VertexData posVertices;
VertexData texVertices;

posVertices.reserve(n * 6); // two triangles per character
texVertices.reserve(n * 6);

for (QChar c : s) {
if (x != x0) {
x -= space;
}
int index = charToIndex(c);

texVertices.addRectangle(m_offset[index], 0.f, m_offset[index + 1], 1.f);
posVertices.addRectangle(x,
y,
x + m_width[index],
y + height());
vertexUpdater.addRectangle({x, y},
{x + m_width[index], y + height()},
{m_offset[index], 0.f},
{m_offset[index + 1], 1.f});
x += m_width[index];
}

m_shader.bind();

const int matrixLocation = m_shader.uniformLocation("matrix");
const int textureLocation = m_shader.uniformLocation("texture");
const int positionLocation = m_shader.attributeLocation("position");
const int texcoordLocation = m_shader.attributeLocation("texcoord");

m_shader.setUniformValue(matrixLocation, matrix);

m_shader.enableAttributeArray(positionLocation);
m_shader.setAttributeArray(
positionLocation, GL_FLOAT, posVertices.constData(), 2);
m_shader.enableAttributeArray(texcoordLocation);
m_shader.setAttributeArray(
texcoordLocation, GL_FLOAT, texVertices.constData(), 2);

m_shader.setUniformValue(textureLocation, 0);

m_texture.bind();

glDrawArrays(GL_TRIANGLES, 0, posVertices.size());

m_texture.release();

m_shader.disableAttributeArray(positionLocation);
m_shader.disableAttributeArray(texcoordLocation);
m_shader.release();

return x - x0;
}
44 changes: 29 additions & 15 deletions src/waveform/renderers/allshader/digitsrenderer.h
Original file line number Diff line number Diff line change
@@ -1,36 +1,50 @@
#pragma once

#include <QOpenGLFunctions>
#include "rendergraph/context.h"
#include "rendergraph/geometrynode.h"
#include "util/class.h"

#include "shaders/textureshader.h"
#include "util/opengltexture2d.h"
namespace rendergraph {
class TexturedVertexUpdater;
} // namespace rendergraph

namespace allshader {
class DigitsRenderer;
}
class DigitsRenderNode;
} // namespace allshader

class allshader::DigitsRenderer : public QOpenGLFunctions {
class allshader::DigitsRenderNode : public rendergraph::GeometryNode {
public:
DigitsRenderer() = default;
~DigitsRenderer();
DigitsRenderNode();
~DigitsRenderNode();

void init();
void updateTexture(float fontPointSize, float maxHeight, float devicePixelRatio);
float draw(const QMatrix4x4& matrix,
void updateTexture(rendergraph::Context* pContext,
float fontPointSize,
float maxHeight,
float devicePixelRatio);

void update(
float x,
float y,
const QString& s);
bool multiLine,
const QString& s1,
const QString& s2);

void clear();

float height() const;

private:
mixxx::TextureShader m_shader;
OpenGLTexture2D m_texture;
float addVertices(rendergraph::TexturedVertexUpdater& vertexUpdater,
float x,
float y,
const QString& s);

int m_penWidth;
float m_offset[13];
float m_width[12];
float m_fontPointSize{};
float m_height{};
float m_maxHeight{};
float m_adjustedFontPointSize{};
DISALLOW_COPY_AND_ASSIGN(DigitsRenderer);
DISALLOW_COPY_AND_ASSIGN(DigitsRenderNode);
};
Loading

0 comments on commit 5e13601

Please sign in to comment.