Add OpenMP support
This commit is contained in:
parent
8193df09e0
commit
f9caf21322
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.20)
|
|||||||
|
|
||||||
project(sand)
|
project(sand)
|
||||||
|
|
||||||
|
find_package(OpenMP REQUIRED)
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
pkg_check_modules(LUAJIT REQUIRED luajit)
|
pkg_check_modules(LUAJIT REQUIRED luajit)
|
||||||
|
|
||||||
@ -14,7 +16,7 @@ target_include_directories(sand
|
|||||||
PUBLIC include
|
PUBLIC include
|
||||||
PRIVATE ${LUAJIT_INCLUDE_DIRS}
|
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
|
set_target_properties(sand PROPERTIES
|
||||||
CXX_STANDARD 20
|
CXX_STANDARD 20
|
||||||
CXX_STANDARD_REQUIRED ON
|
CXX_STANDARD_REQUIRED ON
|
||||||
|
|||||||
32
src/main.cpp
32
src/main.cpp
@ -7,6 +7,12 @@
|
|||||||
#include <SDL3/SDL_video.h>
|
#include <SDL3/SDL_video.h>
|
||||||
#include <sand.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]
|
uint8_t lookup[][3]
|
||||||
= { { 0, 0, 0 }, { 50, 0, 0 }, { 100, 100, 100 }, { 200, 200, 200 } };
|
= { { 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"; });
|
.top_middle([](const auto& t) { return t == "stone1"; });
|
||||||
|
|
||||||
rb.add_rule("stone1", "air")
|
rb.add_rule("stone1", "air")
|
||||||
.top_middle([](const auto& t) { return t == "air" || t == "offgrid"; })
|
|
||||||
.bottom_middle([](const auto& t) { return t == "air"; });
|
.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_Init(SDL_INIT_VIDEO);
|
||||||
SDL_Window* window = SDL_CreateWindow("sand test", 512, 512, 0);
|
SDL_Window* window
|
||||||
SDL_Surface* surface = SDL_CreateSurface(64, 64, SDL_PIXELFORMAT_RGB24);
|
= SDL_CreateWindow("sand test", WINDOW_WIDTH, WINDOW_HEIGHT, 0);
|
||||||
|
SDL_Surface* surface
|
||||||
|
= SDL_CreateSurface(WIDTH, HEIGHT, SDL_PIXELFORMAT_RGB24);
|
||||||
|
|
||||||
int prev_ms = SDL_GetTicks();
|
int prev_ms = SDL_GetTicks();
|
||||||
float time = 0;
|
float time = 0;
|
||||||
@ -55,16 +62,22 @@ int main(int argc, char** argv)
|
|||||||
int state;
|
int state;
|
||||||
if (time > 0.008 && (state = SDL_GetMouseState(&x, &y)))
|
if (time > 0.008 && (state = SDL_GetMouseState(&x, &y)))
|
||||||
{
|
{
|
||||||
time = 0;
|
int ix = x * WIDTH / WINDOW_WIDTH;
|
||||||
s.set(x * 64 / 512, y * 64 / 512, state == 1 ? "stone1" : "stone2");
|
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);
|
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);
|
lookup[s.get(i, j)], 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,6 +89,7 @@ int main(int argc, char** argv)
|
|||||||
s.update();
|
s.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_DestroySurface(surface);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
SDL_Quit();
|
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()
|
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)];
|
neighbors += get(i - 1, j - 1);
|
||||||
|
|
||||||
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 <<= 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;
|
iter = !iter;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user