From 57526f17b791d16f1d4faccf3b0c30f94446d142 Mon Sep 17 00:00:00 2001 From: Pavel V Date: Sun, 11 Jun 2023 19:56:51 +0300 Subject: [PATCH] nvi and pixelbuffer for thornbird --- art.hpp | 55 ++++++++++++++++++++++++++++++++++++-------- cloudlife.hpp | 2 +- discrete.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++---- ifs.h | 2 +- main.cpp | 13 +++++++---- mtron.hpp | 6 ++--- vermiculate.h | 3 +-- 7 files changed, 118 insertions(+), 26 deletions(-) diff --git a/art.hpp b/art.hpp index ae96727..fd438b7 100644 --- a/art.hpp +++ b/art.hpp @@ -3,6 +3,11 @@ #include #include #include +#include + + +#include "pixelbuffer.h" +#include "imgui_elements.h" template @@ -16,9 +21,21 @@ class Art { Art(std::string _name) : m_name(_name) {} const char * name() {return m_name.c_str();} - virtual bool render_gui() = 0; - virtual void resize(int _w, int _h) {default_resize(_w, _h);}; - virtual void render(uint32_t *p) = 0; + void resized(int _w, int _h) { + resize(_w, _h); + } + bool gui() { + if (pb) + ScrollableSliderUInt("Max pixels", &pixel_buffer_maximum, 1, pixel_buffer_maximum_max, "%d", pixel_buffer_maximum/16); + return render_gui(); + } + void draw(uint32_t *p) { + if (pb) { + pb->trunc(pixel_buffer_maximum); + render_pixel_buffer(p); + } + render(p); + } virtual void load(std::string json) {}; virtual std::string save() { return ""; }; @@ -29,12 +46,15 @@ class Art { } void drawdot(uint32_t x, uint32_t y, uint32_t c) { + drawdot(data(), x, y, c); + } + + void drawdot(uint32_t *screen, uint32_t x, uint32_t y, uint32_t c) { if (x >= w || y >= h) { ++pixels_discarded; return; } - uint32_t *p = data(); - p[ y*w + x ] = c; + screen[ y*w + x ] = c; ++pixels_drawn; } @@ -44,6 +64,24 @@ class Art { unsigned pixels_drawn = 0; unsigned pixels_discarded = 0; + unsigned frame_number = 0, clear_every = 0; + unsigned pixel_buffer_maximum = 1024*10, pixel_buffer_maximum_max = 1024*64; + + void clear() { + fill0(pixels); + pixels_drawn = 0; + pixels_discarded = 0; + } +private: + virtual void resize(int _w, int _h) {default_resize(_w, _h);}; + virtual bool render_gui() = 0; + virtual void render(uint32_t *p) = 0; + + void render_pixel_buffer(uint32_t *screen) { + for (auto &p : pb->buffer) + drawdot(screen, p.x, p.y, p.color); + } + protected: void default_resize(int _w, int _h) { @@ -59,15 +97,12 @@ class Art { */ } - void clear() { - fill0(pixels); - pixels_drawn = 0; - pixels_discarded = 0; - } int w, h; //uint8_t *data() { return reinterpret_cast(pixels.data()); } uint32_t *data() { return pixels.data(); } std::vector pixels; std::string m_name; + std::unique_ptr pb; + }; diff --git a/cloudlife.hpp b/cloudlife.hpp index 9eb8ee8..f207ea6 100644 --- a/cloudlife.hpp +++ b/cloudlife.hpp @@ -22,10 +22,10 @@ class Cloudlife : public Art { Cloudlife() : Art("Cloudlife from xscreensaver") , f(new field) {} +private: virtual bool render_gui() override; virtual void resize(int _w, int _h) override; virtual void render(uint32_t *p) override; -private: std::unique_ptr f; unsigned ncolors=512; diff --git a/discrete.cpp b/discrete.cpp index dccc7bd..227fdea 100644 --- a/discrete.cpp +++ b/discrete.cpp @@ -34,6 +34,7 @@ // from yarandom.h #define LRAND() ((long) (xoshiro256plus() & 0x7fffffff)) #define MAXRAND (2147483648.0) /* unsigned 1<<31 as a float */ +#define balance_rand(v) ((LRAND()/MAXRAND*(v))-((v)/2)) /* random around 0 */ #include @@ -170,6 +171,21 @@ void Discrete::init_discrete() hp->i = hp->j = 0.1; break; } + case THORNBIRD: + hp->b = 0.1; + hp->i = hp->j = 0.1; + + /* select frequencies for parameter variation */ + hp->liss.f1 = LRAND() % 5000; + hp->liss.f2 = LRAND() % 2000; + + /* choose random 3D tumbling */ + hp->tumble.theta = 0; + hp->tumble.phi = 0; + hp->tumble.dtheta = balance_rand(0.001); + hp->tumble.dphi = balance_rand(0.005); + + break; } hp->inc = 0; @@ -186,9 +202,27 @@ void Discrete::draw_discrete_1() int k = count; discretestruct *hp = &discrete; unsigned x, y; + double sint, cost, sinp, cosp; hp->inc++; + if (hp->op == THORNBIRD) { + /* vary papameters */ + hp->a = 1.99 + (0.4 * sin(hp->inc / hp->liss.f1) + + 0.05 * cos(hp->inc / hp->liss.f2)); + hp->c = 0.80 + (0.15 * cos(hp->inc / hp->liss.f1) + + 0.05 * sin(hp->inc / hp->liss.f2)); + + /* vary view */ + hp->tumble.theta += hp->tumble.dtheta; + hp->tumble.phi += hp->tumble.dphi; + sint = sin(hp->tumble.theta); + cost = cos(hp->tumble.theta); + sinp = sin(hp->tumble.phi); + cosp = cos(hp->tumble.phi); + + } + while (k--) { oldj = hp->j; oldi = hp->i; @@ -279,9 +313,25 @@ void Discrete::draw_discrete_1() hp->i = (hp->i > 0.0) ? 0.00000001 : -0.00000001; hp->j = (oldj - hp->b) / (2 * hp->i); break; + case THORNBIRD: + oldj = hp->j; + oldi = hp->i; + + hp->j = oldi; + hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b; + hp->b = oldj; + break; + } + if (hp->op == THORNBIRD) { + x = (short) (hp->maxx / 2 * (1 + + sint*hp->j + cost*cosp*hp->i - cost*sinp*hp->b)); + y = (short) (hp->maxy / 2 * (1 + - cost*hp->j + sint*cosp*hp->i - sint*sinp*hp->b)); + } + else { + x = hp->maxx / 2 + (int) ((hp->i - hp->ic) * hp->is); + y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js); } - x = hp->maxx / 2 + (int) ((hp->i - hp->ic) * hp->is); - y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js); drawdot(x, y, pal.get_color(k)); } @@ -292,12 +342,14 @@ void Discrete::render(uint32_t *p) discretestruct *hp = &discrete; int i; - for (i = 0; i < 10; i++) { + for (i = 0; i < iterations; i++) { draw_discrete_1(); hp->count++; } std::copy(pixels.begin(), pixels.end(), p); + //if (hp->op == THORNBIRD) + // clear(); if (hp->count > cycles) { resize(w, h); @@ -310,9 +362,10 @@ bool Discrete::render_gui () bool up = false; discretestruct *hp = &discrete; - up |= ScrollableSliderInt("cycles", &cycles, 0, 1024*10, "%d", 256); + ScrollableSliderInt("cycles", &cycles, 0, 1024*10, "%d", 256); up |= ScrollableSliderInt("count", &count, 0, 1024*10, "%d", 256); - up |= ScrollableSliderInt("bias", &bias, 0, 8, "%d", 1); + ScrollableSliderInt("iterations", &iterations, 1, 256, "%d", 1); + up |= ScrollableSliderInt("bias", &bias, 0, 9, "%d", 1); up |= pal.RenderGui(); ImGui::Text("hp->count %d, bias %d", hp->count, hp->op); diff --git a/ifs.h b/ifs.h index cf9c259..9696507 100644 --- a/ifs.h +++ b/ifs.h @@ -19,10 +19,10 @@ class IFS : public Art { public: IFS() : Art("IFS") {} +private: virtual bool render_gui() override; virtual void resize(int _w, int _h) override; virtual void render(uint32_t *p) override; -private: int ncolours = 1024; int ccolour; diff --git a/main.cpp b/main.cpp index 703aa12..90e1648 100644 --- a/main.cpp +++ b/main.cpp @@ -182,7 +182,7 @@ int main(int argc, char *argv[]) ImGui_ImplOpenGL3_Init(glsl_version); get_window_size(0,0); - art->resize(sw, sh); + art->resized(sw, sh); make_pbos(); while (!glfwWindowShouldClose(window)) @@ -197,8 +197,9 @@ int main(int argc, char *argv[]) ImGui::Begin(art->name()); ImGui::ColorEdit4("Clear color", (float*)&clear_color); + ScrollableSliderUInt("force clear every N frames", &art->clear_every, 0, 1024, "%d", 2); - art->render_gui(); + bool reinit = art->gui(); ImGui::Text("pixels drawn %d, discarded %d", art->pixels_drawn, art->pixels_discarded); @@ -214,7 +215,7 @@ int main(int argc, char *argv[]) if (get_window_size(0,0)) { destroy_pbos(); make_pbos(); - art->resize(sw, sh); + art->resized(sw, sh); } int nexti = pbo_index; @@ -229,7 +230,7 @@ int main(int argc, char *argv[]) 0, GL_STREAM_DRAW); uint32_t* ptr = (uint32_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); assert(ptr); - art->render(ptr); + art->draw(ptr); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); @@ -251,6 +252,10 @@ int main(int argc, char *argv[]) ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); + + ++art->frame_number; + if (art->clear_every != 0 && art->frame_number % art->clear_every == 0) + art->clear(); } ImGui_ImplOpenGL3_Shutdown(); diff --git a/mtron.hpp b/mtron.hpp index 42303c1..44e1a01 100644 --- a/mtron.hpp +++ b/mtron.hpp @@ -13,15 +13,15 @@ class Minskytron : public Art { public: Minskytron() : Art("Minskytron") { reinit(); } - virtual bool render_gui() override; - //virtual void resize(int _w, int _h) override; - virtual void render(uint32_t *p) override; virtual bool override_texture_size(int &_w, int &_h) { _w = W; _h = H; return true; } private: + virtual bool render_gui() override; + //virtual void resize(int _w, int _h) override; + virtual void render(uint32_t *p) override; void reinit(); void dt(uint32_t *p, int x, int y, double o, uint32_t c); diff --git a/vermiculate.h b/vermiculate.h index 5ec0fc4..eed6cb0 100644 --- a/vermiculate.h +++ b/vermiculate.h @@ -34,11 +34,10 @@ class Vermiculate : public Art { public: Vermiculate() : Art("Vermiculate") {} +private: virtual bool render_gui() override; virtual void resize(int _w, int _h) override; virtual void render(uint32_t *p) override; -private: - int speed = 1; bool erasing, cleared, autopal;