diff --git a/includes/noise/perlin.hpp b/includes/noise/perlin.hpp index 88d1cc2..a92e230 100644 --- a/includes/noise/perlin.hpp +++ b/includes/noise/perlin.hpp @@ -11,7 +11,7 @@ public: private: void initializeGradients(); - Vector2 grad[256]; + Vector2 grad[512]; Vector2 randoGradient(int ix, int iy); float dotGridGradient(int ix, int iy, float x, float y); float interpolate(float a, float a1, float w); diff --git a/includes/window.hpp b/includes/window.hpp new file mode 100644 index 0000000..9a1b049 --- /dev/null +++ b/includes/window.hpp @@ -0,0 +1,13 @@ +#ifndef WINDOW_HPP +#define WINDOW_HPP + +#define WIDTH 720 +#define HEIGHT 420 + +int graph(uint32_t *img, bool &needUpdate); +int cloud(uint32_t *img, bool &needUpdate); +int marble(uint32_t *img, bool &needUpdate); +int random(uint32_t *img, bool &needUpdate); +int wood(uint32_t *img, bool &needUpdate); + +#endif \ No newline at end of file diff --git a/includes/windowManager/WindowManager.hpp b/includes/windowManager/WindowManager.hpp index 54a2c69..01e6a81 100644 --- a/includes/windowManager/WindowManager.hpp +++ b/includes/windowManager/WindowManager.hpp @@ -5,22 +5,26 @@ #include #include #include +#include #include "err.h" class WindowManager { public: - WindowManager(int width, int height, int (*)(u_int32_t *img)); + WindowManager(int width, int height, int (*)(u_int32_t *img, bool &needUpdate)); ~WindowManager(); u_int32_t *get_image_addr() { return img; } + void load_render(int (*)(u_int32_t *img, bool &needUpdate)); void loop(); private: - void update_image(int (*)(u_int32_t *img)); + void update_image(int (*)(u_int32_t *img, bool &needUpdate)); void display_image(); void handle_events(XEvent &GeneralEvent); - int (*render)(u_int32_t *img); + int (*render)(u_int32_t *img, bool &needUpdate); + std::vector renderFunctions; + uint8_t ptrTabIndex; u_int32_t *img; int WindowX; int WindowY; @@ -38,6 +42,7 @@ private: Atom wmDelete; bool isWindowOpen; bool isDisplayReady; + bool needUpdate; }; #endif //NOISE_GENERATOR_WINDOWMANAGER_HPP diff --git a/srcs/effects/cloud.cpp b/srcs/effects/cloud.cpp new file mode 100644 index 0000000..26ecad1 --- /dev/null +++ b/srcs/effects/cloud.cpp @@ -0,0 +1,25 @@ + +#include +#include "window.hpp" +#include "noise/perlin.hpp" + +int cloud(uint32_t *img, bool &needUpdate) { + if (!needUpdate) + return 0; + needUpdate = false; + static PerlinNoise PerlinNoise; + static float time = 0.0; + for (int y = 0; y < HEIGHT; y++) { + for (int x = 0; x < WIDTH; x++) { + float n = PerlinNoise.noise(x / 100.0 + time, (y / 100.0) + time) * 0.5; + n += PerlinNoise.noise(x / 50.0 + time, (y / 50.0) + time) * 0.25; + + int color = static_cast((n + 1) * 127.5); + img[y * WIDTH + x] = (color << 16) | (color << 8) | color ; + } + } + time += 0.1; + needUpdate = true; + return 0; +} + diff --git a/srcs/effects/graph.cpp b/srcs/effects/graph.cpp new file mode 100644 index 0000000..45e2492 --- /dev/null +++ b/srcs/effects/graph.cpp @@ -0,0 +1,26 @@ +#include +#include "window.hpp" +#include "noise/perlin.hpp" + +int graph(uint32_t *img, bool &needUpdate) { + if (!needUpdate) + return 0; + needUpdate = false; + static PerlinNoise PerlinNoise; + static float time = 0.0; + for (int x = 0; x < WIDTH; x++) { + float n = PerlinNoise.noise(x / 100.0 + time, 0.0) * 0.5; + + int y = static_cast((n + 1) * (HEIGHT >> 1)); + for (int i = 0; i < HEIGHT; ++i) { + if (i == y) + img[i * WIDTH + x] = 0xFFFFFF; + else + img[i * WIDTH + x] = 0; + } + } + time += 0.001; + needUpdate = true; + return 0; +} + diff --git a/srcs/effects/marble.cpp b/srcs/effects/marble.cpp new file mode 100644 index 0000000..5f0bb90 --- /dev/null +++ b/srcs/effects/marble.cpp @@ -0,0 +1,24 @@ +#include +#include +#include "window.hpp" +#include "noise/perlin.hpp" + +int marble(uint32_t *img, bool &needUpdate) { + if (!needUpdate) + return 0; + needUpdate = false; + static PerlinNoise perlinNoise; + static float time = 0.0; + for (int y = 0; y < HEIGHT; y++) { + for (int x = 0; x < WIDTH; x++) { + float n = perlinNoise.noise(x / 100.0 + time, y / 100.0 + time); + float marble = sin((x * 0.05 + n * 10.0)); + int color = static_cast((marble + 1) * 127.5); + img[y * WIDTH + x] = (color << 16) | (color << 8) | color; + } + } + time += 0.01; + needUpdate = true; + return 0; +} + diff --git a/srcs/effects/random.cpp b/srcs/effects/random.cpp new file mode 100644 index 0000000..7700633 --- /dev/null +++ b/srcs/effects/random.cpp @@ -0,0 +1,23 @@ +#include +#include "window.hpp" +#include "noise/perlin.hpp" + +int random(uint32_t *img, bool &needUpdate) { + if (!needUpdate) + return 0; + needUpdate = false; + static PerlinNoise PerlinNoise; + static float time = 0.0; + for (int y = 0; y < HEIGHT; y++) { + for (int x = 0; x < WIDTH; x++) { + float r = (PerlinNoise.noise(x * 0.0001 + time, (y * 00.001) + time)) * 0.5; + + int color = static_cast((r + 1) * 127.5); + img[y * WIDTH + x] = (color << 16) >> 1| (color << 8) | 0; + } + } + time += 0.01; + needUpdate = true; + return 0; +} + diff --git a/srcs/effects/wood.cpp b/srcs/effects/wood.cpp new file mode 100644 index 0000000..115bba0 --- /dev/null +++ b/srcs/effects/wood.cpp @@ -0,0 +1,23 @@ +#include +#include +#include "window.hpp" +#include "noise/perlin.hpp" + +int wood(uint32_t *img, bool &needUpdate) { + if (!needUpdate) + return 0; + needUpdate = false; + static PerlinNoise perlinNoise; + static float time = 0.0; + for (int y = 0; y < HEIGHT; y++) { + for (int x = 0; x < WIDTH; x++) { + float n = perlinNoise.noise(x / 100.0 + time, y / 100.0 + time); + float wood = sin((x * 0.1 + n * 5.0)); + int color = static_cast((wood + 1) * 127.5); + img[y * WIDTH + x] = (color << 16) | (color << 8) | color; + } + } + time += 0.01; + needUpdate = true; + return 0; +} diff --git a/srcs/main.cpp b/srcs/main.cpp index 114ee98..79777a9 100644 --- a/srcs/main.cpp +++ b/srcs/main.cpp @@ -1,28 +1,16 @@ #include "windowManager/WindowManager.hpp" -#include "noise/perlin.hpp" +#include "window.hpp" -#define WIDTH 720 -#define HEIGHT 420 - -int render(uint32_t *img) { - static PerlinNoise PerlinNoise; - static float time = 0.0; - for (int y = 0; y < HEIGHT; y++) { - for (int x = 0; x < WIDTH; x++) { - float n = (PerlinNoise.noise(x / 100.0 + time, (y / 100.0) + time)); - - int color = static_cast((n + 1) * 127.5); - img[y * WIDTH + x] = (color << 16) | (color << 8) | color ; - } - } - time += 0.1; - return 0; -} int main() { - WindowManager window(WIDTH, HEIGHT, render); + WindowManager window(WIDTH, HEIGHT, graph); + window.load_render(cloud); + window.load_render(marble); + window.load_render(random); + window.load_render(wood); + window.loop(); return 0; -} +} \ No newline at end of file diff --git a/srcs/noise/perlin.cpp b/srcs/noise/perlin.cpp index 0695d24..25d5523 100644 --- a/srcs/noise/perlin.cpp +++ b/srcs/noise/perlin.cpp @@ -11,10 +11,10 @@ PerlinNoise::PerlinNoise() { } void PerlinNoise::initializeGradients() { - std::mt19937 gen(0); + std::mt19937 gen(512); std::uniform_real_distribution dis(0.0, 2 * M_PI); - for (int i = 0; i < 256; ++i) { + for (int i = 0; i < 512; ++i) { float angle = dis(gen); grad[i] = Vector2(cos(angle), sin(angle)); } diff --git a/srcs/windowManager/WindowManager.cpp b/srcs/windowManager/WindowManager.cpp index 922dd64..60009e4 100644 --- a/srcs/windowManager/WindowManager.cpp +++ b/srcs/windowManager/WindowManager.cpp @@ -5,8 +5,9 @@ #include #include -WindowManager::WindowManager(int width, int height, int (*render)(u_int32_t *img)) : +WindowManager::WindowManager(int width, int height, int (*render)(u_int32_t *img, bool &needUpdate)) : render(render), + ptrTabIndex(0), WindowX(0), WindowY(0), WindowWidth(width), WindowHeight(height), BorderWidth(0), @@ -14,7 +15,8 @@ WindowManager::WindowManager(int width, int height, int (*render)(u_int32_t *img WindowClass(CopyFromParent), WindowVisual(CopyFromParent), AttributeValueMask(CWBackPixel | CWEventMask), - isDisplayReady(false) + isDisplayReady(false), + needUpdate(true) { img = new u_int32_t[width * height]; MainDisplay = XOpenDisplay(0); @@ -30,7 +32,7 @@ WindowManager::WindowManager(int width, int height, int (*render)(u_int32_t *img XMapWindow(MainDisplay, MainWindow); wmDelete = XInternAtom(MainDisplay, "WM_DELETE_WINDOW", false); XSetWMProtocols(MainDisplay, MainWindow, &wmDelete, 1); - + load_render(render); isWindowOpen = true; } @@ -44,11 +46,17 @@ WindowManager::~WindowManager() { void WindowManager::handle_events(XEvent &GeneralEvent) { switch(GeneralEvent.type) { case KeyPress: + { + + } break; case KeyRelease: { XKeyPressedEvent *event = (XKeyPressedEvent *)&GeneralEvent; if (event->keycode == XKeysymToKeycode(this->MainDisplay, XK_Escape)) { this->isWindowOpen = false; + } else if (event->keycode == XKeysymToKeycode(this->MainDisplay, XK_space)) { + this->ptrTabIndex = (this->ptrTabIndex + 1) % this->renderFunctions.size(); + this->render = this->renderFunctions[this->ptrTabIndex]; } } break; case ClientMessage: { @@ -76,6 +84,7 @@ void WindowManager::loop() { if (isDisplayReady) { update_image(this->render); display_image(); + XSync(this->MainDisplay, false); } } } @@ -99,8 +108,11 @@ void WindowManager::display_image() { XFlush(MainDisplay); } -void WindowManager::update_image(int (*func)(u_int32_t *img)) { - if (func(this->img)) +void WindowManager::update_image(int (*func)(u_int32_t *img, bool &needUpdate)) { + if (func(this->img, this->needUpdate)) this->isWindowOpen = false; +} +void WindowManager::load_render(int (*func)(u_int32_t *img, bool &needUpdate)) { + this->renderFunctions.push_back(func); } \ No newline at end of file