aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ogl.cpp12
-rw-r--r--src/ogl.hpp2
-rw-r--r--src/sandbox.cpp88
-rw-r--r--src/sandbox.hpp16
-rw-r--r--src/ui.cpp5
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);
diff --git a/src/ui.cpp b/src/ui.cpp
index bc88394..43ecb09 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -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();
}