abstract multiple walkers

This commit is contained in:
Jakob Hördt 2024-08-08 00:13:13 +02:00
parent 9c58521ec6
commit 3212f868ec

View file

@ -62,9 +62,9 @@ auto operator+(SDL_Point a, SDL_Point b) {
using clock = std::chrono::steady_clock; using clock = std::chrono::steady_clock;
constexpr int width = 1000; constexpr int width = 2000;
constexpr int height = 500; constexpr int height = 1000;
constexpr auto steps_per_second = 3; constexpr auto steps_per_second = 100'000;
template <auto EF> template <auto EF>
struct [[nodiscard("give this a name so SDL_Quit is called at the end" struct [[nodiscard("give this a name so SDL_Quit is called at the end"
@ -83,6 +83,11 @@ auto poll_events(bool& continu) {
if (e.type == SDL_QUIT) { continu = false; } if (e.type == SDL_QUIT) { continu = false; }
} }
} }
struct Walker {
SDL_Point pos;
SDL_Color col;
};
} // namespace } // namespace
template <typename Loopdata> template <typename Loopdata>
@ -90,8 +95,7 @@ void mainloop(void* userData) {
constexpr SDL_Point directions[] = { constexpr SDL_Point directions[] = {
{.x = -1, .y = 0}, {.x = 1, .y = 0}, {.x = 0, .y = -1}, {.x = 0, .y = 1} {.x = -1, .y = 0}, {.x = 1, .y = 0}, {.x = 0, .y = -1}, {.x = 0, .y = 1}
}; };
constexpr auto batchsize = 1; auto& [renderer, texture, walkers, rne, dist, start_time, total_steps, next_poll_events_time, next_frame_render_time, frame_start, frame_time, continu] =
auto& [renderer, texture, pos, pos1, rne, dist, start_time, total_steps, next_poll_events_time, next_frame_render_time, frame_start, frame_time, continu] =
*static_cast<Loopdata*>(userData); *static_cast<Loopdata*>(userData);
// measure frame_time // measure frame_time
@ -101,52 +105,39 @@ void mainloop(void* userData) {
// possibly poll events // possibly poll events
if (now >= next_poll_events_time) { if (now >= next_poll_events_time) {
next_poll_events_time = now + std::chrono::milliseconds{200}; next_poll_events_time = now + std::chrono::milliseconds{20};
poll_events(continu); poll_events(continu);
} }
// simulate steps for passed time // simulate steps for passed time //
// roughly make a batch for every millisecond
constexpr auto batchsize =
std::clamp(steps_per_second / 1000 /*ms*/, 1, 1000);
const auto total_time = now - start_time; const auto total_time = now - start_time;
const auto target_total_steps = total_time * steps_per_second / const auto target_total_steps = total_time * steps_per_second /
clock::duration{std::chrono::seconds{1}}; clock::duration{std::chrono::seconds{1}};
std::print(
"total_time={} total_steps={} target={}\r", total_time, total_steps,
target_total_steps
);
for (; total_steps + batchsize <= target_total_steps; for (; total_steps + batchsize <= target_total_steps;
total_steps += batchsize) { total_steps += batchsize) {
sdl_check(SDL_SetRenderTarget(renderer, texture));
sdl_check(SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND));
for (auto& walker : walkers) {
sdl_check(SDL_SetRenderDrawColor(
renderer, walker.col.r, walker.col.g, walker.col.b, walker.col.a
));
std::array<SDL_Point, batchsize> point_batch; std::array<SDL_Point, batchsize> point_batch;
for (auto step = 0z; step < batchsize; ++step) { for (auto step = 0z; step < batchsize; ++step) {
SDL_Point newpoint; SDL_Point newpoint;
do { do {
newpoint = pos + directions[dist(rne)]; newpoint = walker.pos + directions[dist(rne)];
} while (newpoint.x < 0 or newpoint.x >= width or newpoint.y < 0 or } while (newpoint.x < 0 or newpoint.x >= width or
newpoint.y >= height); newpoint.y < 0 or newpoint.y >= height);
pos = newpoint; walker.pos = newpoint;
point_batch[step] = newpoint; point_batch[step] = newpoint;
} }
///// Render image
sdl_check(SDL_SetRenderTarget(renderer, texture));
sdl_check(SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND));
sdl_check(SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xff));
sdl_check(SDL_RenderDrawPoints( sdl_check(SDL_RenderDrawPoints(
renderer, point_batch.data(), point_batch.size() renderer, point_batch.data(), point_batch.size()
)); ));
for (auto step = 0z; step < batchsize; ++step) {
SDL_Point newpoint;
do {
newpoint = pos1 + directions[dist(rne)];
} while (newpoint.x < 0 or newpoint.x >= width or newpoint.y < 0 or
newpoint.y >= height);
pos1 = newpoint;
point_batch[step] = newpoint;
} }
sdl_check(SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff));
sdl_check(SDL_RenderDrawPoints(
renderer, point_batch.data(), point_batch.size()
));
} }
///// Render screen ///// Render screen
@ -193,8 +184,16 @@ int main() try {
); );
sdl_check(SDL_RenderClear(renderer)); sdl_check(SDL_RenderClear(renderer));
SDL_Point pos{.x = width / 2, .y = height / 2}; auto walkers = std::to_array<Walker>(
SDL_Point pos1{.x = width / 2, .y = height / 2}; {{.pos = {.x = width / 2, .y = height / 2},
.col = {.r = 0xff, .g = 0x00, .b = 0x00, .a = 0xff}},
{.pos = {.x = width / 2, .y = height / 2},
.col = {.r = 0x00, .g = 0xff, .b = 0x00, .a = 0xff}},
{.pos = {.x = width / 2, .y = height / 2},
.col = {.r = 0x00, .g = 0x00, .b = 0xff, .a = 0xff}},
{.pos = {.x = width / 2, .y = height / 2},
.col = {.r = 0x00, .g = 0x00, .b = 0x00, .a = 0xff}}}
);
std::mt19937_64 rne(std::random_device{}()); std::mt19937_64 rne(std::random_device{}());
std::uniform_int_distribution dist(0, 3); std::uniform_int_distribution dist(0, 3);
@ -207,7 +206,7 @@ int main() try {
auto total_steps = 0ll; auto total_steps = 0ll;
clock::duration frame_time; clock::duration frame_time;
auto loopdata = std::tie( auto loopdata = std::tie(
renderer, texture, pos, pos1, rne, dist, start_time, total_steps, renderer, texture, walkers, rne, dist, start_time, total_steps,
next_poll_events_time, next_frame_render_time, frame_start, frame_time, next_poll_events_time, next_frame_render_time, frame_start, frame_time,
continu continu
); );