From b1894ad4d4a29baabef88fcf93b793c943936c00 Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Sat, 5 Feb 2022 21:41:59 +0100 Subject: [PATCH] added hue animation --- Fragment.glsl | 8 +++++--- headers/Mandelbrot.h | 5 +++++ src/MainWindow.cpp | 10 ++++++++++ src/Mandelbrot.cpp | 12 ++++++++++++ src/OutputWidget.cpp | 12 ++++++++++-- 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/Fragment.glsl b/Fragment.glsl index e23c85a..8c157e1 100644 --- a/Fragment.glsl +++ b/Fragment.glsl @@ -2,6 +2,7 @@ out vec4 pixColor; uniform int iterationCount; +uniform float hueAdd; in vec2 complexPos; @@ -27,7 +28,7 @@ vec3 hsvToRgb(in float h, in float s, in float v){ } vec3 getColor(in float modifier){ - float hue = modifier * 360; + float hue = mod(modifier * 360 + hueAdd, 360); float sat = 1; float value = modifier == 0 ? 0 : 1; @@ -45,7 +46,7 @@ vec2 m(in vec2 c){ float mandelbrot(in vec2 c){ vec2 z = vec2(0, 0); float steps = 0; - int escapeSquared = pow(1 << 8, 2); + float escapeSquared = pow(1 << 8, 2); while (steps < iterationCount && pow(z.x, 2) + pow(z.y, 2) < escapeSquared){ z = m(z); ++steps; @@ -55,7 +56,8 @@ float mandelbrot(in vec2 c){ float log_zn = log(z.x * z.x + z.y * z.y) / 2; float nu = log(log_zn / log(2)) / log(2); steps += 1 - nu; - return steps / iterationCount; + float t = steps / iterationCount; + return sqrt(t); } void main(){ diff --git a/headers/Mandelbrot.h b/headers/Mandelbrot.h index ea2519f..672b22c 100644 --- a/headers/Mandelbrot.h +++ b/headers/Mandelbrot.h @@ -9,6 +9,8 @@ class Mandelbrot : public QObject, protected QOpenGLExtraFunctions { public: void init(GLuint); void draw(); + void updateAnimation(); + void toggleAnimation(); void setIterations(int); void translateRelative(QVector2D); void zoomRelative(int, QVector2D); @@ -16,10 +18,13 @@ public: bool initShader(); private: int iterations = 0; + float hueAdd = 0.0; QVector2D origin {-2, -1}; QVector2D size {2, 2}; float zoomModifier = 1.05; + bool animating = true; + GLuint vao; QOpenGLShaderProgram shader; diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 79da82f..88b0ad4 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -46,12 +46,22 @@ void MainWindow::buildUI() { }); }); + auto animButton = new QPushButton("Toggle animation"); + connect( + animButton, + &QPushButton::clicked, + this, + [this](){ + this->outputWidget.getMandelbrot().toggleAnimation(); + }); + auto controls = new QGridLayout; controls->addWidget(iterationsCaption, 1, 1); controls->addWidget(iterationsLabel, 1, 2); controls->addWidget(iterationsSlider, 1, 3); controls->addWidget(saveInfo, 2, 1, 1, 2); controls->addWidget(saveButton, 2, 3, 1, 1); + controls->addWidget(animButton, 3, 1, 1, 3); auto lyt = new QVBoxLayout(this); lyt->addWidget(&outputWidget); diff --git a/src/Mandelbrot.cpp b/src/Mandelbrot.cpp index 994b51c..87cbec7 100644 --- a/src/Mandelbrot.cpp +++ b/src/Mandelbrot.cpp @@ -17,6 +17,17 @@ void Mandelbrot::draw() { glBindVertexArray(0); } +void Mandelbrot::updateAnimation() { + if (!animating) + return; + hueAdd += 1; + hueAdd -= hueAdd >= 360 ? 360 : 0; +} + +void Mandelbrot::toggleAnimation() { + animating = !animating; +} + bool Mandelbrot::initShader() { if (!shader.addShaderFromSourceFile(QOpenGLShader::Vertex, "Vertex.glsl")) return false; if (!shader.addShaderFromSourceFile(QOpenGLShader::Fragment, "Fragment.glsl")) return false; @@ -29,6 +40,7 @@ void Mandelbrot::setShaderValues() { shader.setUniformValue("origin", origin); shader.setUniformValue("size", size); shader.setUniformValue("iterationCount", iterations); + shader.setUniformValue("hueAdd", hueAdd); } void Mandelbrot::zoomRelative(int direction, QVector2D posRelative) { diff --git a/src/OutputWidget.cpp b/src/OutputWidget.cpp index 6ae4a42..136a894 100644 --- a/src/OutputWidget.cpp +++ b/src/OutputWidget.cpp @@ -5,7 +5,9 @@ #include #include #include +#include #include "../headers/OutputWidget.h" +#include using std::cout, std::endl; @@ -19,6 +21,14 @@ void OutputWidget::initializeGL() { cout << "OpenGL version: " << format.majorVersion() << "." << format.minorVersion() << endl; glClearColor(0.5f, 0.5f, 0.5f, 1.0f); + + auto timer = new QTimer(this); + timer->setInterval(17); + timer->start(); + connect(timer, &QTimer::timeout, this, [this](){ + this->getMandelbrot().updateAnimation(); + update(); + }); } void OutputWidget::paintGL() { @@ -86,7 +96,6 @@ void OutputWidget::wheelEvent(QWheelEvent *e) { QVector2D relativePos = divide(pos, size()); relativePos.setY(1 - relativePos.y()); getMandelbrot().zoomRelative(direction, relativePos); - update(); } void OutputWidget::mouseMoveEvent(QMouseEvent *e) { @@ -96,7 +105,6 @@ void OutputWidget::mouseMoveEvent(QMouseEvent *e) { QVector2D relativeDiff = divide(diff, size()); relativeDiff.setY(-relativeDiff.y()); getMandelbrot().translateRelative(relativeDiff); - update(); } void OutputWidget::mousePressEvent(QMouseEvent *e) {