mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 00:35:05 +00:00
Basic OpenGL Graph Rendering (#1432)
This commit is contained in:
parent
0583b06191
commit
14c64e01f3
@ -7,10 +7,30 @@
|
|||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
#include <QOpenGLContext>
|
||||||
|
#include <QOpenGLWidget>
|
||||||
|
#include <QOpenGLPaintDevice>
|
||||||
|
#include <QOpenGLExtraFunctions>
|
||||||
|
#endif
|
||||||
|
|
||||||
GraphView::GraphView(QWidget *parent)
|
GraphView::GraphView(QWidget *parent)
|
||||||
: QAbstractScrollArea(parent)
|
: QAbstractScrollArea(parent)
|
||||||
, graphLayoutSystem(new GraphGridLayout())
|
, graphLayoutSystem(new GraphGridLayout())
|
||||||
|
, useGL(false)
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
, cacheTexture(0)
|
||||||
|
, cacheFBO(0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
if (useGL) {
|
||||||
|
glWidget = new QOpenGLWidget(this);
|
||||||
|
setViewport(glWidget);
|
||||||
|
} else {
|
||||||
|
glWidget = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphView::~GraphView()
|
GraphView::~GraphView()
|
||||||
@ -113,19 +133,88 @@ QPolygonF GraphView::recalculatePolygon(QPolygonF polygon)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphView::paintEvent(QPaintEvent *event)
|
void GraphView::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
#ifndef QT_NO_OPENGL
|
||||||
qreal dpr = devicePixelRatioF();
|
if (useGL) {
|
||||||
if (useCache && qFuzzyCompare(dpr, pixmap.devicePixelRatioF())) {
|
glWidget->makeCurrent();
|
||||||
drawGraph();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!useCache || !qFuzzyCompare(devicePixelRatioF(), pixmap.devicePixelRatioF())) {
|
||||||
|
paintGraphCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useGL) {
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
auto gl = glWidget->context()->extraFunctions();
|
||||||
|
gl->glBindFramebuffer(GL_READ_FRAMEBUFFER, cacheFBO);
|
||||||
|
gl->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glWidget->defaultFramebufferObject());
|
||||||
|
gl->glBlitFramebuffer(0, 0, viewport()->width(), viewport()->height(),
|
||||||
|
0, 0, viewport()->width(), viewport()->height(),
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
glWidget->doneCurrent();
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
QRectF target(0.0, 0.0, viewport()->width(), viewport()->height());
|
||||||
|
QRectF source(0.0, 0.0, viewport()->width() * pixmap.devicePixelRatioF(),
|
||||||
|
viewport()->height() * pixmap.devicePixelRatioF());
|
||||||
|
QPainter p(viewport());
|
||||||
|
p.drawPixmap(target, pixmap, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!useCache) { // TODO: does this condition make sense?
|
||||||
|
emit refreshBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphView::paintGraphCache()
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
QOpenGLPaintDevice *paintDevice = nullptr;
|
||||||
|
#endif
|
||||||
|
QPainter p;
|
||||||
|
if (useGL) {
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
auto gl = QOpenGLContext::currentContext()->functions();
|
||||||
|
|
||||||
|
bool resizeTex = false;
|
||||||
|
if (!cacheTexture) {
|
||||||
|
gl->glGenTextures(1, &cacheTexture);
|
||||||
|
gl->glBindTexture(GL_TEXTURE_2D, cacheTexture);
|
||||||
|
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
gl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
resizeTex = true;
|
||||||
|
} else if(cacheSize != viewport()->size()) {
|
||||||
|
gl->glBindTexture(GL_TEXTURE_2D, cacheTexture);
|
||||||
|
resizeTex = true;
|
||||||
|
}
|
||||||
|
if (resizeTex) {
|
||||||
|
cacheSize = viewport()->size();
|
||||||
|
gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport()->width(), viewport()->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
gl->glGenFramebuffers(1, &cacheFBO);
|
||||||
|
gl->glBindFramebuffer(GL_FRAMEBUFFER, cacheFBO);
|
||||||
|
gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, cacheTexture, 0);
|
||||||
|
} else {
|
||||||
|
gl->glBindFramebuffer(GL_FRAMEBUFFER, cacheFBO);
|
||||||
|
}
|
||||||
|
gl->glViewport(0, 0, viewport()->width(), viewport()->height());
|
||||||
|
gl->glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
gl->glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
paintDevice = new QOpenGLPaintDevice(viewport()->size());
|
||||||
|
p.begin(paintDevice);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
auto dpr = devicePixelRatioF();
|
||||||
pixmap = QPixmap(int(viewport()->width() * dpr), int(viewport()->height() * dpr));
|
pixmap = QPixmap(int(viewport()->width() * dpr), int(viewport()->height() * dpr));
|
||||||
pixmap.setDevicePixelRatio(dpr);
|
pixmap.setDevicePixelRatio(dpr);
|
||||||
QPainter p(&pixmap);
|
p.begin(&pixmap);
|
||||||
|
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
p.setRenderHint(QPainter::Antialiasing);
|
||||||
|
}
|
||||||
|
|
||||||
int render_width = viewport()->width();
|
int render_width = viewport()->width();
|
||||||
int render_height = viewport()->height();
|
int render_height = viewport()->height();
|
||||||
@ -190,17 +279,11 @@ void GraphView::paintEvent(QPaintEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drawGraph();
|
|
||||||
emit refreshBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GraphView::drawGraph()
|
p.end();
|
||||||
{
|
#ifndef QT_NO_OPENGL
|
||||||
QRectF target(0.0, 0.0, viewport()->width(), viewport()->height());
|
delete paintDevice;
|
||||||
QRectF source(0.0, 0.0, viewport()->width() * pixmap.devicePixelRatioF(),
|
#endif
|
||||||
viewport()->height() * pixmap.devicePixelRatioF());
|
|
||||||
QPainter p(viewport());
|
|
||||||
p.drawPixmap(target, pixmap, source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
#include "widgets/GraphLayout.h"
|
#include "widgets/GraphLayout.h"
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
class QOpenGLWidget;
|
||||||
|
#endif
|
||||||
|
|
||||||
class GraphView : public QAbstractScrollArea
|
class GraphView : public QAbstractScrollArea
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -36,6 +40,7 @@ public:
|
|||||||
|
|
||||||
explicit GraphView(QWidget *parent);
|
explicit GraphView(QWidget *parent);
|
||||||
~GraphView() override;
|
~GraphView() override;
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
void showBlock(GraphBlock &block);
|
void showBlock(GraphBlock &block);
|
||||||
@ -80,7 +85,6 @@ protected:
|
|||||||
virtual void wheelEvent(QWheelEvent *event) override;
|
virtual void wheelEvent(QWheelEvent *event) override;
|
||||||
virtual EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to);
|
virtual EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to);
|
||||||
|
|
||||||
void drawGraph();
|
|
||||||
bool event(QEvent *event) override;
|
bool event(QEvent *event) override;
|
||||||
|
|
||||||
// Mouse events
|
// Mouse events
|
||||||
@ -95,12 +99,9 @@ protected:
|
|||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief pixmap that caches the graph nodes
|
|
||||||
*/
|
|
||||||
QPixmap pixmap;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void paintGraphCache();
|
||||||
|
|
||||||
bool checkPointClicked(QPointF &point, int x, int y, bool above_y = false);
|
bool checkPointClicked(QPointF &point, int x, int y, bool above_y = false);
|
||||||
|
|
||||||
ut64 entry;
|
ut64 entry;
|
||||||
@ -117,6 +118,20 @@ private:
|
|||||||
// Todo: remove charheight/charwidth cause it should be handled in child class
|
// Todo: remove charheight/charwidth cause it should be handled in child class
|
||||||
qreal charWidth = 10.0;
|
qreal charWidth = 10.0;
|
||||||
|
|
||||||
|
bool useGL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief pixmap that caches the graph nodes
|
||||||
|
*/
|
||||||
|
QPixmap pixmap;
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
|
uint32_t cacheTexture;
|
||||||
|
uint32_t cacheFBO;
|
||||||
|
QSize cacheSize;
|
||||||
|
QOpenGLWidget *glWidget;
|
||||||
|
#endif
|
||||||
|
|
||||||
QPolygonF recalculatePolygon(QPolygonF polygon);
|
QPolygonF recalculatePolygon(QPolygonF polygon);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user