examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

commit 668df50c1aeb24bafe3fc66e4b81b0458ff35ad3
parent d184871cba902bde048ad1e56752ae451cafc2c3
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Mon, 24 Jun 2024 00:25:18 +0100

sdl-gl: Make stars have random colour and spin

Diffstat:
Msrc/sdl-gl.cpp | 98++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 75 insertions(+), 23 deletions(-)

diff --git a/src/sdl-gl.cpp b/src/sdl-gl.cpp @@ -14,6 +14,8 @@ #include <memory> #include <numbers> #include <print> +#include <random> +#include <ranges> #include <vector> extern "C" char const* __asan_default_options() { return "detect_leaks=0"; } @@ -82,7 +84,7 @@ void initSDL(void) if (SDL_Init(SDL_INIT_VIDEO) < 0) errx(1, "Couldn't initialize SDL: %s\n", SDL_GetError()); - window = SDL_CreateWindow("Pong", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width, screen_height, windowFlags); + window = SDL_CreateWindow("SDL OpenGL example", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width, screen_height, windowFlags); if (!window) errx(1, "Failed to open %d x %d window: %s\n", screen_width, screen_height, SDL_GetError()); @@ -94,11 +96,30 @@ void initSDL(void) errx(1, "Failed to make OpenGL context current: %s", SDL_GetError()); } +std::mt19937 gen; +std::lognormal_distribution<float> dis(-1, .75); +std::normal_distribution<float> norm_dis; struct rgb { float r,g,b; + + rgb operator + (rgb const& rhs) const + { + return {r + rhs.r, g + rhs.g, b + rhs.b}; + } + + static rgb random() + { + return {dis(gen), dis(gen), dis(gen)}; + } }; +void glColor(rgb const& c) +{ + glColor3f(c.r, c.g, c.b); +} + + struct coord { int x, y; @@ -178,36 +199,37 @@ struct object { point pos; rgb col; + float spin; + float rotation; }; std::vector<std::shared_ptr<object>> objs = { - std::make_shared<object>(point{0, 0}, rgb{.7,.2,.2}), - std::make_shared<object>(point{4, 0}, rgb{.2,.7,.2}), - std::make_shared<object>(point{0, 5}, rgb{.2,.2,.7}), + std::make_shared<object>(point{0, 0}, rgb{.7,.2,.2}, .2), + std::make_shared<object>(point{4, 0}, rgb{.2,.7,.2}, 0), + std::make_shared<object>(point{0, 5}, rgb{.2,.2,.7}, -.2), }; std::vector<point> shape; +constexpr auto deref = std::views::transform([](auto const& p) -> auto& { return *p; }); + void presentScene(void) { - static double turns = 0; - turns += 1./60/4; - rotor r = rotor::angle(turns); - float x_scale = (float)screen_height / screen_width; glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); circle mouse_area{mouse_pos, 1}; - for (auto& optr : objs) { - auto& op = *optr; - if (mouse_area.colliding(op.pos)) - glColor3d(op.col.r + .25,op.col.g + .25,op.col.b + .25); + for (auto& o : objs | deref) { + o.rotation += o.spin / 60; + rotor r = rotor::angle(o.rotation); + if (mouse_area.colliding(o.pos)) + glColor(o.col + rgb{.25f, .25f, .25f,}); else - glColor3f(op.col.r, op.col.g, op.col.b); + glColor(o.col); glBegin(GL_TRIANGLE_FAN); for (auto& p : shape) { - auto pp = (p * r + pan + op.pos) * scale; + auto pp = (p * r + pan + o.pos) * scale; glVertex2f(pp.x * x_scale, pp.y); } glEnd(); @@ -218,6 +240,8 @@ void presentScene(void) void key(SDL_KeyboardEvent& e) { + if (e.repeat) + return; static uint8_t ctrls; switch (e.keysym.sym) { @@ -233,7 +257,7 @@ void key(SDL_KeyboardEvent& e) case SDLK_a: if (e.state) - objs.push_back(std::make_shared<object>(mouse_pos, rgb{.5, .5, .2})); + objs.push_back(std::make_shared<object>(mouse_pos, rgb::random(), norm_dis(gen), 0)); break; case SDLK_d: @@ -244,6 +268,31 @@ void key(SDL_KeyboardEvent& e) } break; + case SDLK_r: + if (e.state) + { + circle mouse_area{mouse_pos, 1}; + for (auto& obj : objs | deref) + if (mouse_area.colliding(obj.pos)) + { + std::swap(obj.col.r, obj.col.g); + std::swap(obj.col.g, obj.col.b); + } + + } + break; + + case SDLK_s: + if (e.state) + { + circle mouse_area{mouse_pos, 1}; + for (auto& obj : objs | deref) + if (mouse_area.colliding(obj.pos)) + obj.spin *= -1; + + } + break; + case SDLK_ESCAPE: exit(0); } @@ -295,15 +344,17 @@ coroutine_task mouse_task() auto it = std::ranges::find_if(objs, [drag_pos, mouse_area](auto const& o){return mouse_area.colliding(o->pos);}); if (it == std::end(objs)) break; - auto obj = *it; - std::swap(obj->col.r, obj->col.g); - std::swap(obj->col.g, obj->col.b); - drag_pos = obj->pos - mouse_to_local(e.x, e.y); + + drag_pos = (*it)->pos - mouse_to_local(e.x, e.y); + std::weak_ptr<object> wp = *it; + for (;;) { SDL_Event const& e2 = co_await motion_or_release_event; - if (e2.type == SDL_MOUSEMOTION) - obj->pos = drag_pos + mouse_to_local(e2.motion.x, e2.motion.y); + if (wp.expired()) + break; + else if (e2.type == SDL_MOUSEMOTION) + wp.lock()->pos = drag_pos + mouse_to_local(e2.motion.x, e2.motion.y); else if (auto& b = e2.button; b.button == SDL_BUTTON_LEFT) break; } @@ -371,9 +422,10 @@ void doInput() void init_shape() { + constexpr int n = 10; shape.emplace_back(0,0); - for (int i = 0; i <= 8; ++i) - shape.push_back(point{1, 0} * rotor::angle((float)i / 8)); + for (int i = 0; i <= n; ++i) + shape.push_back(point{0, (.65f + i % 2) / -1.65f} * rotor::angle((float)i / n)); } int main()