Add OpenMP support
This commit is contained in:
parent
8193df09e0
commit
f9caf21322
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(sand)
|
||||
|
||||
find_package(OpenMP REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LUAJIT REQUIRED luajit)
|
||||
|
||||
@ -14,7 +16,7 @@ target_include_directories(sand
|
||||
PUBLIC include
|
||||
PRIVATE ${LUAJIT_INCLUDE_DIRS}
|
||||
)
|
||||
target_link_libraries(sand PRIVATE ${LUAJIT_LIBRARIES})
|
||||
target_link_libraries(sand PRIVATE ${LUAJIT_LIBRARIES} OpenMP::OpenMP_CXX)
|
||||
set_target_properties(sand PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
|
||||
32
src/main.cpp
32
src/main.cpp
@ -7,6 +7,12 @@
|
||||
#include <SDL3/SDL_video.h>
|
||||
#include <sand.h>
|
||||
|
||||
constexpr uint16_t WIDTH = 128;
|
||||
constexpr uint16_t HEIGHT = 128;
|
||||
|
||||
constexpr int WINDOW_WIDTH = 1024;
|
||||
constexpr int WINDOW_HEIGHT = 1024;
|
||||
|
||||
uint8_t lookup[][3]
|
||||
= { { 0, 0, 0 }, { 50, 0, 0 }, { 100, 100, 100 }, { 200, 200, 200 } };
|
||||
|
||||
@ -23,14 +29,15 @@ int main(int argc, char** argv)
|
||||
.top_middle([](const auto& t) { return t == "stone1"; });
|
||||
|
||||
rb.add_rule("stone1", "air")
|
||||
.top_middle([](const auto& t) { return t == "air" || t == "offgrid"; })
|
||||
.bottom_middle([](const auto& t) { return t == "air"; });
|
||||
|
||||
auto s = rb.build(64, 64, "air");
|
||||
auto s = rb.build(WIDTH, HEIGHT, "air");
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_Window* window = SDL_CreateWindow("sand test", 512, 512, 0);
|
||||
SDL_Surface* surface = SDL_CreateSurface(64, 64, SDL_PIXELFORMAT_RGB24);
|
||||
SDL_Window* window
|
||||
= SDL_CreateWindow("sand test", WINDOW_WIDTH, WINDOW_HEIGHT, 0);
|
||||
SDL_Surface* surface
|
||||
= SDL_CreateSurface(WIDTH, HEIGHT, SDL_PIXELFORMAT_RGB24);
|
||||
|
||||
int prev_ms = SDL_GetTicks();
|
||||
float time = 0;
|
||||
@ -55,16 +62,22 @@ int main(int argc, char** argv)
|
||||
int state;
|
||||
if (time > 0.008 && (state = SDL_GetMouseState(&x, &y)))
|
||||
{
|
||||
time = 0;
|
||||
s.set(x * 64 / 512, y * 64 / 512, state == 1 ? "stone1" : "stone2");
|
||||
int ix = x * WIDTH / WINDOW_WIDTH;
|
||||
int iy = y * HEIGHT / WINDOW_HEIGHT;
|
||||
|
||||
if (ix >= 0 && ix < WIDTH && iy >= 0 && iy < HEIGHT)
|
||||
{
|
||||
time = 0;
|
||||
s.set(ix, iy, state == 1 ? "stone1" : "stone2");
|
||||
}
|
||||
}
|
||||
|
||||
SDL_LockSurface(surface);
|
||||
for (int i = 0; i < 64; i++)
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
{
|
||||
for (int j = 0; j < 64; j++)
|
||||
for (int j = 0; j < HEIGHT; j++)
|
||||
{
|
||||
memcpy(&static_cast<uint8_t*>(surface->pixels)[3 * (i + j * 64)],
|
||||
memcpy(&static_cast<uint8_t*>(surface->pixels)[3 * (i + j * WIDTH)],
|
||||
lookup[s.get(i, j)], 3);
|
||||
}
|
||||
}
|
||||
@ -76,6 +89,7 @@ int main(int argc, char** argv)
|
||||
s.update();
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
|
||||
|
||||
138
src/sand.cpp
138
src/sand.cpp
@ -267,77 +267,79 @@ uint16_t Sand::get(uint16_t x, uint16_t y)
|
||||
|
||||
void Sand::update()
|
||||
{
|
||||
for (uint32_t i = 0; i < width; i++)
|
||||
int n;
|
||||
#pragma omp parallel for private(n)
|
||||
for (n = 0; n < width * height; n++)
|
||||
{
|
||||
for (uint32_t j = 0; j < height; j++)
|
||||
int i = n % width;
|
||||
int j = n / height;
|
||||
|
||||
auto& current_rule = rules[get(i, j)];
|
||||
|
||||
unsigned __int128 neighbors = 0;
|
||||
if (i > 0 && j > 0)
|
||||
{
|
||||
auto& current_rule = rules[get(i, j)];
|
||||
|
||||
unsigned __int128 neighbors = 0;
|
||||
if (i > 0 && j > 0)
|
||||
{
|
||||
neighbors += get(i - 1, j - 1);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (j > 0)
|
||||
{
|
||||
neighbors += get(i, j - 1);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i < width - 1 && j > 0)
|
||||
{
|
||||
neighbors += get(i + 1, j);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
neighbors += get(i - 1, j);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i < width - 1)
|
||||
{
|
||||
neighbors += get(i + 1, j);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i > 0 && j < height - 1)
|
||||
{
|
||||
neighbors += get(i - 1, j + 1);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (j < height - 1)
|
||||
{
|
||||
neighbors += get(i, j + 1);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i < width - 1 && j < height - 1)
|
||||
{
|
||||
neighbors += get(i + 1, j + 1);
|
||||
}
|
||||
|
||||
uint16_t result = default_conversions[get(i, j)];
|
||||
if (!current_rule.empty())
|
||||
{
|
||||
std::pair<unsigned __int128, uint16_t> element = { neighbors, 0 };
|
||||
bool (*fn)(decltype(element), decltype(element))
|
||||
= [](decltype(element) a, decltype(element) b) -> bool
|
||||
{ return a.first > b.first; };
|
||||
const auto& found = binary_search(element, current_rule.data(), 0,
|
||||
current_rule.size(), fn);
|
||||
if (found.first == neighbors)
|
||||
{
|
||||
result = found.second;
|
||||
}
|
||||
}
|
||||
|
||||
elements[i + j * width + !iter * width * height] = result;
|
||||
neighbors += get(i - 1, j - 1);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (j > 0)
|
||||
{
|
||||
neighbors += get(i, j - 1);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i < width - 1 && j > 0)
|
||||
{
|
||||
neighbors += get(i + 1, j);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
neighbors += get(i - 1, j);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i < width - 1)
|
||||
{
|
||||
neighbors += get(i + 1, j);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i > 0 && j < height - 1)
|
||||
{
|
||||
neighbors += get(i - 1, j + 1);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (j < height - 1)
|
||||
{
|
||||
neighbors += get(i, j + 1);
|
||||
}
|
||||
neighbors <<= 16;
|
||||
|
||||
if (i < width - 1 && j < height - 1)
|
||||
{
|
||||
neighbors += get(i + 1, j + 1);
|
||||
}
|
||||
|
||||
uint16_t result = default_conversions[get(i, j)];
|
||||
if (!current_rule.empty())
|
||||
{
|
||||
std::pair<unsigned __int128, uint16_t> element = { neighbors, 0 };
|
||||
bool (*fn)(decltype(element), decltype(element))
|
||||
= [](decltype(element) a, decltype(element) b) -> bool
|
||||
{ return a.first > b.first; };
|
||||
const auto& found = binary_search(element, current_rule.data(), 0,
|
||||
current_rule.size(), fn);
|
||||
if (found.first == neighbors)
|
||||
{
|
||||
result = found.second;
|
||||
}
|
||||
}
|
||||
|
||||
elements[i + j * width + !iter * width * height] = result;
|
||||
}
|
||||
|
||||
iter = !iter;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user