Interactive Mandelbrot viewer with Qt and OpenGL.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.7 KiB

3 years ago
#include <iostream>
#include <QResource>
#include "../headers/OutputWidget.h"
3 years ago
3 years ago
using std::cout, std::endl;
3 years ago
void OutputWidget::initializeGL() {
3 years ago
cout << "Initialize OpenGL" << endl;
3 years ago
initializeOpenGLFunctions();
getMandelbrot().init();
initShader();
3 years ago
3 years ago
auto format = this->format();
3 years ago
cout << "OpenGL version: " << format.majorVersion() << "." << format.minorVersion() << endl;
3 years ago
vao = createVAO();
3 years ago
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
3 years ago
}
void OutputWidget::paintGL() {
getMandelbrot().draw(vao, shader);
}
GLuint OutputWidget::createVAO() {
GLuint vboId;
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
auto vertices = genVertices();
size_t size = vertices.size() * sizeof(QVector2D);
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)size, &vertices[0], GL_STATIC_DRAW);
GLuint vaoId;
glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
3 years ago
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(QVector2D), (void*) nullptr);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
return vaoId;
}
std::vector<QVector2D> OutputWidget::genVertices() {
return {
{-1, -1},
{1, -1},
{1, 1},
{-1, 1}
};
}
3 years ago
void OutputWidget::initShader() {
if (!shader.addShaderFromSourceFile(QOpenGLShader::Vertex, "Vertex.glsl")) close();
if (!shader.addShaderFromSourceFile(QOpenGLShader::Fragment, "Fragment.glsl")) close();
if (!shader.link()) close();
if (!shader.bind()) close();
3 years ago
}
QVector2D divide(QPoint p, QSize s){
return {
float(p.x()) / float(s.width()),
float(p.y()) / float(s.height())
};
}
QVector2D divide(QSize s1, QSize s2){
return divide(QPoint(s1.width(), s1.height()), s2);
}
void OutputWidget::resizeGL(int w, int h) {
QSize newSize = QSize(w, h);
if (oldSize == QSize(0, 0)){
oldSize = newSize;
return;
}
QSize diff = oldSize - newSize;
QVector2D relative = QVector2D(1, 1) - divide(diff, oldSize);
getMandelbrot().resizeRelative(relative);
oldSize = newSize;
}
3 years ago
void OutputWidget::wheelEvent(QWheelEvent *e) {
QPoint pos = e->position().toPoint();
int direction = e->angleDelta().y() > 0 ? 1 : -1;
QVector2D relativePos = divide(pos, size());
relativePos.setY(1 - relativePos.y());
getMandelbrot().zoomRelative(direction, relativePos);
update();
3 years ago
}
void OutputWidget::mouseMoveEvent(QMouseEvent *e) {
QPoint newMousePos = e->pos();
QPoint diff = newMousePos - mousePos;
mousePos = newMousePos;
QVector2D relativeDiff = divide(diff, size());
relativeDiff.setY(-relativeDiff.y());
getMandelbrot().translateRelative(relativeDiff);
update();
3 years ago
}
void OutputWidget::mousePressEvent(QMouseEvent *e) {
mousePos = e->pos();
3 years ago
}
void OutputWidget::mouseReleaseEvent(QMouseEvent *e) {
}
void OutputWidget::keyPressEvent(QKeyEvent *e) {
}