#include #include #include "../headers/OutputWidget.h" using std::cout, std::endl; void OutputWidget::initializeGL() { cout << "Initialize OpenGL" << endl; initializeOpenGLFunctions(); getMandelbrot().init(); initShader(); auto format = this->format(); cout << "OpenGL version: " << format.majorVersion() << "." << format.minorVersion() << endl; vao = createVAO(); glClearColor(0.5f, 0.5f, 0.5f, 1.0f); } 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); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(QVector2D), (void*) nullptr); glEnableVertexAttribArray(0); glBindVertexArray(0); return vaoId; } std::vector OutputWidget::genVertices() { return { {-1, -1}, {1, -1}, {1, 1}, {-1, 1} }; } 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(); } 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; } 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(); } 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(); } void OutputWidget::mousePressEvent(QMouseEvent *e) { mousePos = e->pos(); } void OutputWidget::mouseReleaseEvent(QMouseEvent *e) { } void OutputWidget::keyPressEvent(QKeyEvent *e) { }