mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-18 10:35:25 +00:00
Basic OpenGL Graph Rendering (#1432)
This commit is contained in:
parent
0583b06191
commit
14c64e01f3
@ -7,10 +7,30 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QPropertyAnimation>
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLPaintDevice>
|
||||
#include <QOpenGLExtraFunctions>
|
||||
#endif
|
||||
|
||||
GraphView::GraphView(QWidget *parent)
|
||||
: QAbstractScrollArea(parent)
|
||||
, 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()
|
||||
@ -113,19 +133,88 @@ QPolygonF GraphView::recalculatePolygon(QPolygonF polygon)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GraphView::paintEvent(QPaintEvent *event)
|
||||
void GraphView::paintEvent(QPaintEvent *)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
qreal dpr = devicePixelRatioF();
|
||||
if (useCache && qFuzzyCompare(dpr, pixmap.devicePixelRatioF())) {
|
||||
drawGraph();
|
||||
return;
|
||||
#ifndef QT_NO_OPENGL
|
||||
if (useGL) {
|
||||
glWidget->makeCurrent();
|
||||
}
|
||||
pixmap = QPixmap(int(viewport()->width() * dpr), int(viewport()->height() * dpr));
|
||||
pixmap.setDevicePixelRatio(dpr);
|
||||
QPainter p(&pixmap);
|
||||
#endif
|
||||
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
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.setDevicePixelRatio(dpr);
|
||||
p.begin(&pixmap);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
}
|
||||
|
||||
int render_width = viewport()->width();
|
||||
int render_height = viewport()->height();
|
||||
@ -190,17 +279,11 @@ void GraphView::paintEvent(QPaintEvent *event)
|
||||
}
|
||||
}
|
||||
}
|
||||
drawGraph();
|
||||
emit refreshBlock();
|
||||
}
|
||||
|
||||
void GraphView::drawGraph()
|
||||
{
|
||||
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);
|
||||
p.end();
|
||||
#ifndef QT_NO_OPENGL
|
||||
delete paintDevice;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,6 +17,10 @@
|
||||
#include "core/Cutter.h"
|
||||
#include "widgets/GraphLayout.h"
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
class QOpenGLWidget;
|
||||
#endif
|
||||
|
||||
class GraphView : public QAbstractScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -36,6 +40,7 @@ public:
|
||||
|
||||
explicit GraphView(QWidget *parent);
|
||||
~GraphView() override;
|
||||
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
void showBlock(GraphBlock &block);
|
||||
@ -80,7 +85,6 @@ protected:
|
||||
virtual void wheelEvent(QWheelEvent *event) override;
|
||||
virtual EdgeConfiguration edgeConfiguration(GraphView::GraphBlock &from, GraphView::GraphBlock *to);
|
||||
|
||||
void drawGraph();
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
// Mouse events
|
||||
@ -95,12 +99,9 @@ protected:
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
/**
|
||||
* @brief pixmap that caches the graph nodes
|
||||
*/
|
||||
QPixmap pixmap;
|
||||
|
||||
private:
|
||||
void paintGraphCache();
|
||||
|
||||
bool checkPointClicked(QPointF &point, int x, int y, bool above_y = false);
|
||||
|
||||
ut64 entry;
|
||||
@ -117,6 +118,20 @@ private:
|
||||
// Todo: remove charheight/charwidth cause it should be handled in child class
|
||||
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);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user