mandelbrot set is drawn in blue to red, added ui for iterations and diverge-threshold

master
Benjamin Kraft 3 years ago
parent 0548e61f8a
commit 9f7f9e4124
  1. 29
      Fragment.glsl
  2. 12
      Vertex.glsl
  3. 2
      headers/MainWindow.h
  4. 6
      headers/Mandelbrot.h
  5. 6
      headers/OutputWidget.h
  6. 50
      src/MainWindow.cpp
  7. 20
      src/Mandelbrot.cpp
  8. 11
      src/OutputWidget.cpp

@ -1,6 +1,31 @@
#version 330 core
out vec4 pixColor;
uniform int iterationCount;
uniform float divergeThreshold;
in vec2 complexPos;
vec2 mul(in vec2 a, in vec2 b) {
return vec2(a.x * b.x - a.y * b.y, a.y * b.x + a.x * b.y);
}
vec3 getColor(in float value){
vec3 red = vec3(0.5, 0, 0);
vec3 blue = vec3(0, 0, 0.5);
return value * red + (1 - value) * blue;
}
void main(){
pixColor = vec4(1., 0., 0., 1);
}
vec2 z;
float stepsNeeded = 0;
while (stepsNeeded < iterationCount && length(z) < divergeThreshold){
z = mul(z, z) + complexPos;
++stepsNeeded;
}
float value = stepsNeeded / iterationCount;
pixColor = vec4(getColor(value), 1);
}

@ -1,6 +1,14 @@
#version 330 core
layout (location = 0) in vec2 position;
layout (location = 0) in vec2 pos;
uniform vec2 origin;
uniform vec2 size;
out vec2 complexPos;
void main(){
gl_Position = vec4(position.x, position.y, 0.0, 1.);
vec2 offset = (pos + 1) / 2 * size;
offset.y *= -1;
complexPos = origin + offset;
gl_Position = vec4(pos.xy, 0.0, 1.);
}

@ -9,9 +9,9 @@ public:
explicit MainWindow();
private slots:
void iterationsSliderChanged(int);
void limitSliderChanged(int);
private:
void buildUI();
OutputWidget* outputWidget = new OutputWidget(this);
};

@ -1,4 +1,3 @@
#pragma once
#include <QVector2D>
@ -9,14 +8,17 @@ class Mandelbrot : public QObject, protected QOpenGLExtraFunctions {
Q_OBJECT
public:
void init();
void draw(GLuint, int, QOpenGLShaderProgram&);
void draw(GLuint, QOpenGLShaderProgram&);
void zoom(double);
public slots:
void setIterations(int);
void updateLimit(int);
private:
int iterations = 0;
float divergeThreshold = 0;
double scale = 1;
QVector2D translation;
void setShaderValues(QOpenGLShaderProgram&);
};

@ -1,9 +1,11 @@
#pragma once
#include <QWidget>
#include <QOpenGLWidget>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QKeyEvent>
#include "Mandelbrot.h"
class OutputWidget : public QOpenGLWidget, protected QOpenGLExtraFunctions {
@ -22,6 +24,8 @@ private:
void mouseReleaseEvent(QMouseEvent*) override;
void keyPressEvent(QKeyEvent*) override;
QPoint mousePos;
void initShader();
static std::vector<QVector2D> genVertices();
GLuint createVAO();

@ -1,5 +1,6 @@
#include <QVBoxLayout>
#include <QSlider>
#include <QLabel>
#include <iostream>
#include "../headers/MainWindow.h"
@ -10,25 +11,45 @@ MainWindow::MainWindow() {
void MainWindow::buildUI() {
resize(700, 700);
auto iterationsCaption = new QLabel("Iteration count:");
auto iterationsLabel = new QLabel;
//iterationsLabel->setAlignment(Qt::AlignRight);
auto iterationsSlider = new QSlider(Qt::Horizontal);
iterationsSlider->setRange(5, 300);
QSlider::connect(
iterationsSlider,
&QSlider::valueChanged,
this->outputWidget->getMandelbrot(),
&Mandelbrot::setIterations
);
QSlider::connect(
connect(
iterationsSlider,
&QSlider::valueChanged,
this,
&MainWindow::iterationsSliderChanged
);
[iterationsLabel, this](int value) -> void {
this->outputWidget->getMandelbrot()->setIterations(value);
this->outputWidget->update();
iterationsLabel->setNum(value);
});
iterationsSlider->setValue(100);
auto limitCaption = new QLabel("Diverge threshold:");
auto limitLabel = new QLabel;
//limitLabel->setAlignment(Qt::AlignRight);
auto limitSlider = new QSlider(Qt::Horizontal);
limitSlider->setRange(100, 500);
connect(
limitSlider,
&QSlider::valueChanged,
this,
[limitLabel, this](int value) -> void {
this->outputWidget->getMandelbrot()->updateLimit(value);
this->outputWidget->update();
limitLabel->setNum(double(value) / 100);
});
limitSlider->setValue(200);
auto controls = new QGridLayout;
controls->addWidget(iterationsSlider);
controls->addWidget(iterationsCaption, 1, 1);
controls->addWidget(iterationsLabel, 1, 2);
controls->addWidget(iterationsSlider, 1, 3);
controls->addWidget(limitCaption, 2, 1);
controls->addWidget(limitLabel, 2, 2);
controls->addWidget(limitSlider, 2, 3);
auto lyt = new QVBoxLayout(this);
lyt->addWidget(outputWidget);
@ -37,5 +58,10 @@ void MainWindow::buildUI() {
void MainWindow::iterationsSliderChanged(int newValue) {
//TODO update text label
update();
outputWidget->update();
}
void MainWindow::limitSliderChanged(int newValue) {
//TODO update text label
outputWidget->update();
}

@ -1,17 +1,25 @@
#include "../headers/Mandelbrot.h"
void Mandelbrot::init() {
initializeOpenGLFunctions();
}
void Mandelbrot::draw(GLuint vao, int vertCount, QOpenGLShaderProgram& shader) {
void Mandelbrot::draw(GLuint vao, QOpenGLShaderProgram& shader) {
glClear(GL_COLOR_BUFFER_BIT);
shader.bind();
setShaderValues(shader);
glBindVertexArray(vao);
glDrawArrays(GL_QUADS, 0, vertCount);
glDrawArrays(GL_QUADS, 0, 4);
glBindVertexArray(0);
}
void Mandelbrot::setShaderValues(QOpenGLShaderProgram &shader) {
shader.setUniformValue("origin", QVector2D(-1, 1));
shader.setUniformValue("size", QVector2D(2, 2));
shader.setUniformValue("iterationCount", iterations);
shader.setUniformValue("divergeThreshold", divergeThreshold);
}
void Mandelbrot::zoom(double delta) {
scale *= delta;
}
@ -20,4 +28,10 @@ void Mandelbrot::setIterations(int value) {
iterations = value;
}
void Mandelbrot::updateLimit(int value) {
divergeThreshold = float(value) / 100;
}

@ -1,4 +1,3 @@
#include <iostream>
#include <QResource>
#include "../headers/OutputWidget.h"
@ -16,18 +15,15 @@ void OutputWidget::initializeGL() {
vao = createVAO();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
}
void OutputWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT);
getMandelbrot()->draw(vao, vertCount, shader);
getMandelbrot()->draw(vao, shader);
}
void OutputWidget::resizeGL(int w, int h) {
//glViewport(0, 0, w, h);
}
GLuint OutputWidget::createVAO() {
@ -74,7 +70,8 @@ void OutputWidget::wheelEvent(QWheelEvent *e) {
}
void OutputWidget::mouseMoveEvent(QMouseEvent *e) {
QPoint newMousePos = e->pos();
QPoint diff = newMousePos - mousePos;
}
void OutputWidget::mousePressEvent(QMouseEvent *e) {

Loading…
Cancel
Save