diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ogl.cpp | 12 | ||||
-rw-r--r-- | src/ogl.hpp | 2 | ||||
-rw-r--r-- | src/sandbox.cpp | 88 | ||||
-rw-r--r-- | src/sandbox.hpp | 16 | ||||
-rw-r--r-- | src/ui.cpp | 5 |
5 files changed, 87 insertions, 36 deletions
diff --git a/src/ogl.cpp b/src/ogl.cpp index a7b2dfa..19e49cc 100644 --- a/src/ogl.cpp +++ b/src/ogl.cpp @@ -2,8 +2,16 @@ #include <imgui_impl_opengl3_loader.h> +// These constants are omitted from the ImGui loader +#define GL_NEAREST 0x2600 + OglImage::OglImage() { glGenTextures(1, &glHandle); + glBindTexture(GL_TEXTURE_2D, glHandle); + + // Setup filtering parameters for display + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } OglImage::~OglImage() { @@ -14,3 +22,7 @@ void OglImage::upload(const char* data, int w, int h) { glBindTexture(GL_TEXTURE_2D, glHandle); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } + +ImTextureID OglImage::as_imgui() const { + return static_cast<ImTextureID>(reinterpret_cast<uint32_t>(glHandle)); +} diff --git a/src/ogl.hpp b/src/ogl.hpp index 126b21f..b220f76 100644 --- a/src/ogl.hpp +++ b/src/ogl.hpp @@ -1,5 +1,6 @@ #pragma once +#include <imgui.h> #include <cstdint> struct OglImage { @@ -7,4 +8,5 @@ struct OglImage { OglImage(); ~OglImage(); void upload(const char* data, int w, int h); + ImTextureID as_imgui() const; }; diff --git a/src/sandbox.cpp b/src/sandbox.cpp index f71be9b..27cd654 100644 --- a/src/sandbox.cpp +++ b/src/sandbox.cpp @@ -1,6 +1,7 @@ #include "sandbox.hpp" #include "common.hpp" +#include <cstring> #include <utility> // Copied from IM_COL32 @@ -14,7 +15,7 @@ static constexpr uint32_t MAT_COLOR_LUT[] = { }; uint32_t Tile::get_color() const { - return MAT_COLOR_LUT[std::to_underlying(mat)]; + return MAT_COLOR_LUT[std::to_underlying(so)]; } Sandbox::Sandbox(int w, int h) @@ -22,65 +23,90 @@ Sandbox::Sandbox(int w, int h) , _a(w * h) // TODO random seed , _pcg() - , _solid_tile{ Tile::SOLID } + , _wall_tile{ Tile::ROCK } , width{ w } , height{ h } // { + memset(_bitmap.data(), 0xff, _bitmap.size() * sizeof(_bitmap[0])); + set_sand(10, 10, Tile{ .so = Tile::SAND }); } static void simulate_sand_tile(Sandbox& self, int x, int y) { - auto& at0 = self.gs(x, y); - switch (at0.mat) { + const auto at0 = self.gs(x, y); + if (at0.updated) { + // Clear update bit for next cycle + self.gs(x, y).updated = false; + return; + } + + switch (at0.so) { case Tile::AIR: break; - case Tile::SOLID: break; + case Tile::ROCK: break; case Tile::SAND: { - auto& below = self.gs(x, y - 1); - if (below.mat == Tile::AIR) { - below = at0; - below.updated = true; - at0 = {}; - at0.updated = true; - } else if (below.mat == Tile::WATER) { - Pt neighs[]{ Pt(x - 1, y), Pt(x + 1, y), Pt(x, y + 1), Pt(x, y - 1) }; - int max_pressure = 0; - for (auto [x1, y1] : neighs) { - auto& neigh = self.gs(x1, y1); - if (neigh.mat == Tile::WATER) { - auto p = neigh.pressure; - max_pressure = max_pressure > p ? max_pressure : p; + const auto below = self.gs(x, y - 1); + if (below.so == Tile::AIR) { + self.set_sand(x, y, below); + self.set_sand(x, y - 1, at0); + } else { + Pt loc1[]{ Pt(x - 1, y + 1), Pt(x + 1, y + 1) }; + auto bound = 2; + auto which = self._pcg.next_u32(bound); + for (int i = 0; i < bound; ++i) { + // Try going to a side + auto at1 = self.gs(loc1[i].x, loc1[i].y); + if (at1.so == Tile::AIR) { + self.set_sand(x, y, at1); + self.set_sand(loc1[i].x, loc1[i].y, at0); } + which = (which + 1) % bound; } - } else { - // Try going to a side - // TODO } } break; - - case Tile::WATER: { - // TODO pressure system - } break; } + + if (at0.so == Tile::AIR) + switch (at0.fl) { + case Tile::NOTHING: break; + + case Tile::WATER: { + // Pt neighs[]{ Pt(x - 1, y), Pt(x + 1, y), Pt(x, y + 1), Pt(x, y - 1) }; + // int max_pressure = 0; + // for (auto [x1, y1] : neighs) { + // auto& neigh = self.gs(x1, y1); + // if (neigh.fl == Tile::WATER) { + // auto p = neigh.fmass; + // max_pressure = max_pressure > p ? max_pressure : p; + // } + // } + } break; + } } void Sandbox::simulate_step() { - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - simulate_sand_tile(*this, x, y); + _x = _y = 0; + for (; _y < height; ++_y) { + for (; _x < width; ++_x) { + simulate_sand_tile(*this, _x, _y); } + _x = 0; } ++ncycle; } Tile& Sandbox::gs(int x, int y) { if (x < 0 || x >= width || y < 0 || y >= height) - return _solid_tile; + return _wall_tile; return _a[y * width + x]; } void Sandbox::set_sand(int x, int y, Tile sand) { - _a[y * width + x] = std::move(sand); + auto& target = _a[y * width + x]; + target = sand; + // Set update bit if the target is after cursor + if (y > _y || x > _x) + target.updated = true; _bitmap[y * width + x] = sand.get_color(); } diff --git a/src/sandbox.hpp b/src/sandbox.hpp index c6453c7..f65caaf 100644 --- a/src/sandbox.hpp +++ b/src/sandbox.hpp @@ -8,15 +8,20 @@ const int MBIT_DISPLACABLE = 1; struct Tile { - enum Material : unsigned char { + enum Solid : unsigned char { AIR = 0, - SOLID, + ROCK, SAND, + }; + + enum Fluid : unsigned char { + NOTHING = 0, WATER, }; - Material mat; - uint8_t pressure = 0; + Solid so = {}; + Fluid fl = {}; + uint8_t fmass = 0; bool updated = false; uint32_t get_color() const; @@ -26,8 +31,9 @@ struct Sandbox { std::vector<uint32_t> _bitmap; std::vector<Tile> _a; Pcg32 _pcg; - Tile _solid_tile; + Tile _wall_tile; int width, height; + int _x, _y; int ncycle = 0; Sandbox(int w, int h); @@ -13,5 +13,10 @@ void ShowEverything() { static OglImage gl; sandbox.simulate_step(); gl.upload(reinterpret_cast<const char*>(sandbox._bitmap.data()), kWidth, kHeight); + constexpr float kScale = 4.0f; + constexpr ImVec2 kSize(kWidth * kScale, kHeight * kScale); + ImGui::Image(gl.as_imgui(), kSize); ImGui::End(); + + ImGui::ShowDemoWindow(); } |