commit 37e6ac5b19048e4bd2e0a220cce26fb1ab5da611
parent cf735b6b145557a74db354879fc3c94593106b3d
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Sat, 22 Jun 2024 11:06:50 +0100
sdl-gl: Drag objects around
Diffstat:
M | src/sdl-gl.cpp | | | 82 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- |
1 file changed, 60 insertions(+), 22 deletions(-)
diff --git a/src/sdl-gl.cpp b/src/sdl-gl.cpp
@@ -8,13 +8,12 @@
#include "coroutine_owner.hpp"
+#include <algorithm>
#include <cassert>
#include <exception>
#include <numbers>
#include <print>
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
-#define ARRAY_SSIZE(a) ((ssize_t)ARRAY_SIZE(a))
+#include <vector>
extern "C" char const* __asan_default_options() { return "detect_leaks=0"; }
@@ -174,28 +173,38 @@ point pan = {1, 0};
point mouse_pos;
+struct object
+{
+ point pos;
+ rgb col;
+} objs[] = {
+ {{0, 0}, {.7,.2,.2}},
+ {{4, 0}, {.2,.7,.2}},
+ {{0, 5}, {.2,.2,.7}},
+};
+
+std::vector<point> shape;
+
void presentScene(void)
{
static double turns = 0;
turns += 1./60/4;
rotor r = rotor::angle(turns);
- static point const square[4] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
- point objs[] = {{0, 0}, {4, 0}, {0, 5}};
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 op : objs) {
- if (mouse_area.colliding(op))
- glColor3d(1,1,0);
+ for (auto& op : objs) {
+ if (mouse_area.colliding(op.pos))
+ glColor3d(op.col.r + .25,op.col.g + .25,op.col.b + .25);
else
- glColor3d(.5,.5,.5);
+ glColor3f(op.col.r, op.col.g, op.col.b);
- glBegin(GL_TRIANGLE_STRIP);
- for (auto& p : square) {
- auto pp = (p * r + pan + op) * scale;
+ glBegin(GL_TRIANGLE_FAN);
+ for (auto& p : shape) {
+ auto pp = (p * r + pan + op.pos) * scale;
glVertex2f(pp.x * x_scale, pp.y);
}
glEnd();
@@ -249,20 +258,41 @@ coroutine_task mouse_task()
for (;;)
{
SDL_MouseButtonEvent const& e = co_await click_event;
- if (e.button != SDL_BUTTON_RIGHT)
- continue;
-
point drag_pos = pan - mouse_to_local(e.x, e.y);
-
- for (;;)
+ switch (e.button)
+ {
+ case SDL_BUTTON_RIGHT:
{
- SDL_Event const& e2 = co_await motion_or_release_event;
- if (e2.type == SDL_MOUSEMOTION)
- pan = drag_pos + mouse_to_local(e2.motion.x, e2.motion.y);
- else if (auto& b = e2.button; b.button == SDL_BUTTON_RIGHT)
+ for (;;)
+ {
+ SDL_Event const& e2 = co_await motion_or_release_event;
+ if (e2.type == SDL_MOUSEMOTION)
+ pan = drag_pos + mouse_to_local(e2.motion.x, e2.motion.y);
+ else if (auto& b = e2.button; b.button == SDL_BUTTON_RIGHT)
+ break;
+ }
+ break;
+ }
+ case SDL_BUTTON_LEFT:
+ {
+ circle mouse_area{mouse_pos, 1};
+ auto obj = std::ranges::find_if(objs, [drag_pos, mouse_area](auto const& o){return mouse_area.colliding(o.pos);});
+ if (obj == std::end(objs))
break;
+ 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);
+ 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);
+ else if (auto& b = e2.button; b.button == SDL_BUTTON_LEFT)
+ break;
+ }
+ break;
+ }
}
-
}
}
@@ -322,8 +352,16 @@ void doInput()
}
}
+void init_shape()
+{
+ shape.emplace_back(0,0);
+ for (int i = 0; i <= 8; ++i)
+ shape.push_back(point{1, 0} * rotor::angle((float)i / 8));
+}
+
int main()
{
+ init_shape();
mouse_task();
initSDL();
atexit(SDL_Quit);