From 6cf0fcea26bf046b4f2b35100578bbd05a6d4b59 Mon Sep 17 00:00:00 2001 From: Pavel V Date: Mon, 3 Apr 2023 21:20:39 +0300 Subject: [PATCH] minskytron --- CMakeLists.txt | 3 +- art.hpp | 4 ++- main.cpp | 45 ++++++++++++++++------- mtron.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ mtron.hpp | 75 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 210 insertions(+), 15 deletions(-) create mode 100644 mtron.cpp create mode 100644 mtron.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c3c98d..015ce44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ target_sources(cloudlife PUBLIC settings.cpp imgui_elements.cpp random.c - cloudlife.cpp) + cloudlife.cpp + mtron.cpp) target_link_libraries(cloudlife IMGUI glfw GL colormap) set_target_properties(cloudlife PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/art.hpp b/art.hpp index c32dbc4..25079fa 100644 --- a/art.hpp +++ b/art.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -7,7 +9,7 @@ class Art { Art(std::string _name) : name(_name) {} virtual bool render_gui() = 0; - virtual void resize(int _w, int _h) = 0; + virtual void resize(int _w, int _h) {}; virtual void render(uint32_t *p) = 0; virtual void load(std::string json) {}; virtual std::string save() { return ""; }; diff --git a/main.cpp b/main.cpp index 5d472ec..371c66a 100644 --- a/main.cpp +++ b/main.cpp @@ -22,6 +22,7 @@ #include "cloudlife.hpp" +#include "mtron.hpp" std::unique_ptr art; @@ -71,18 +72,26 @@ void make_pbos() { // http://www.songho.ca/opengl/gl_pbo.html glGenTextures(1, &image_texture); glBindTexture(GL_TEXTURE_2D, image_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sw, sh, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)image_data); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexImage2D(GL_TEXTURE_2D, + 0, GL_RGBA, tex_w, tex_h, + 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)image_data); glBindTexture(GL_TEXTURE_2D, 0); glGenBuffers(2, pboIds); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, texture_size, 0, GL_STREAM_DRAW); + glBufferData(GL_PIXEL_UNPACK_BUFFER, texture_size, + 0, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, texture_size, 0, GL_STREAM_DRAW); + glBufferData(GL_PIXEL_UNPACK_BUFFER, texture_size, + 0, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } @@ -150,11 +159,12 @@ int main(int argc, char *argv[]) glfwSwapInterval(vsync); art.reset(new Cloudlife); - make_pbos(); + //art.reset(new Minskytron); get_window_size(0,0); art->resize(sw, sh); + make_pbos(); IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -198,22 +208,31 @@ int main(int argc, char *argv[]) pbo_index = pbo_index ? 0 : 1; glBindTexture(GL_TEXTURE_2D, image_texture); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[pbo_index]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + tex_w, tex_h, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[nexti]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, texture_size, 0, GL_STREAM_DRAW); + glBufferData(GL_PIXEL_UNPACK_BUFFER, texture_size, + 0, GL_STREAM_DRAW); uint32_t* ptr = (uint32_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); assert(ptr); art->render(ptr); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - ImGui::GetBackgroundDrawList()->AddImage((void*)(intptr_t)image_texture, - ImVec2(0, 0), ImVec2(tex_w, tex_h)); + //ImGui::GetBackgroundDrawList()->AddImage((void*)(intptr_t)image_texture, + // ImVec2(0, 0), ImVec2(tex_w, tex_h)); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + ImGui::GetBackgroundDrawList()->AddImage((void*)(intptr_t)image_texture, + ImVec2(0, 0), ImVec2(display_w, display_h), + ImVec2(0, 0), ImVec2((float)display_w/tex_w, (float)display_h/tex_h)); ImGui::Render(); - glViewport(0, 0, sw, sh); + //glViewport(0, 0, sw, sh); + glViewport(0, 0, display_w, display_h); + //glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); //glClear(GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); diff --git a/mtron.cpp b/mtron.cpp new file mode 100644 index 0000000..86df42b --- /dev/null +++ b/mtron.cpp @@ -0,0 +1,98 @@ +#include +#include +#include +#include + +#include // exp + +#include "imgui.h" +#include "imgui_elements.h" +#include "mtron.hpp" + + +void Minskytron::reinit() { + ya=0; xa=0737777< t(tb); + std::cout << t << std::endl; + + auto mask = ~(~unsigned(0) << SVBW); + sh0 = ((tb >> SVBW*5) & mask) + CSA; + sh1 = ((tb >> SVBW*4) & mask) + CSA; + sh2 = ((tb >> SVBW*3) & mask) + CSA; + sh3 = ((tb >> SVBW*2) & mask) + CSA; + sh4 = ((tb >> SVBW*1) & mask) + CSA; + sh5 = ((tb >> SVBW*0) & mask) + CSA; + osc.clear(); +} + + +void Minskytron::dt(uint32_t *p, int x, int y, double o, uint32_t c) { + // keep 10 bits to wrap around 1024 screen pixels +#define SB (32-10) + x = (x>>SB) + W/2; + y = (y>>SB) + H/2; + + p[ y*W + x ] = c | ((unsigned)(0xff*o)<<24); +} + +void Minskytron::render(uint32_t *p) { + //clear(); + //std::fill(p, p+TEXTURE_SIZE, 0); + memset(p, 0, TEXTURE_SIZE); + + for (int i = 0; i> sh0; + xa -= (ya - yb) >> sh1; + + yb += (xb - xc) >> sh2; + xb -= (yb - yc) >> sh3; + + yc += (xc - xa) >> sh4; + xc -= (yc - ya) >> sh5; + + osc.emplace_back(odot{xa, ya, xb, yb, xc, yc}); + } + + if (osc.size() > maxodots) + osc.erase(osc.begin(), osc.end() - maxodots); + + const double N = osc.size(); + double i = 0; + + for (auto & oi : osc) { + double o = (1-std::exp(-i*gm/N))/(1-std::exp(-gm)); + if (dots_clamped > 0) o /= 2; + if (i > N - dots_clamped) o = 1; + if (o<0) o=0; + + dt(p, oi.ax, oi.ay, o, ImGui::GetColorU32(ocolor1)); + dt(p, oi.bx, oi.by, o, ImGui::GetColorU32(ocolor2)); + dt(p, oi.cx, oi.cy, o, ImGui::GetColorU32(ocolor3)); + ++i; + } + + //std::copy(pixels.begin(), pixels.end(), p); +} + +bool Minskytron::render_gui() { + bool up = false; + + ScrollableSliderInt("Max dots", &maxodots, 1024, 1024*16, "%d", 256); + ScrollableSliderInt("Dots per frame", &maxdots_perframe, 0, 4096, "%d", 8); + ScrollableSliderInt("Dots clamped gamma", &dots_clamped, 0, maxodots, "%d", 8); + ScrollableSliderFloat("Gamma", &gm, -8, 8, "%.2f", 0.2); + + if (BitField("Test word", &tb, 0)) + reinit(); + + ImGui::ColorEdit3("clear color", (float*)&clear_color); + + ImGui::ColorEdit3("osc1 color", (float*)&ocolor1); + ImGui::ColorEdit3("osc2 color", (float*)&ocolor2); + ImGui::ColorEdit3("osc3 color", (float*)&ocolor3); + + return up; +} diff --git a/mtron.hpp b/mtron.hpp new file mode 100644 index 0000000..42303c1 --- /dev/null +++ b/mtron.hpp @@ -0,0 +1,75 @@ +#include "art.hpp" +#include +#include "imgui.h" + +#include "settings.hpp" + +#include +#include +#include + + +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: + + void reinit(); + void dt(uint32_t *p, int x, int y, double o, uint32_t c); + + struct odot { + int ax, ay, bx, by, cx, cy; + }; + + std::deque osc; + + int maxodots = 1024*6; + int filler_sleep = 100; + int maxdots_perframe = 64; + //float gm = -2.5; + float gm = 3.5; + int dots_clamped = 64; + ImVec4 ocolor1 = ImVec4(1, 0, 0, 0); + ImVec4 ocolor2 = ImVec4(0, 1, 0, 0); + ImVec4 ocolor3 = ImVec4(0, 0, 1, 0); + + int density = 32, cycles=0; + ImVec4 clear_color = ImVec4(1, 0, 0, 1.00f); + ImVec4 background = ImVec4(0, 0, 0, 1); + ImVec4 foreground = ImVec4(0, 1, 0, 1); + + + //unsigned int tb = 0b011000111001110011100010000010; + unsigned int tb = 0b001100011100111001110001000001; // original + //unsigned int tb = 0b001110011100111001110001000001; + //unsigned int tb = 0b000110001100111001110001000010; // alt1 + //unsigned int tb = 0b001100010100011001110001100001; + // ....|....|....|....|....|....| + + int ya, xa, yb, xb, yc, xc; + + int sh0, sh1, sh2, sh3, sh4, sh5; + + static constexpr int W = 1024; + static constexpr int H = 1024; + static constexpr int TEXTURE_SIZE = W*H*4; + // constatnt shift add + static constexpr int CSA = 1; + // initial constant multiplier + static constexpr int ICM = 10; + // shift value bit width + static constexpr int SVBW = 5; + + PaletteSetting pal; + +}; +