52 lines
1.4 KiB
GLSL
52 lines
1.4 KiB
GLSL
#version 430
|
|
|
|
// Game of life transfert shader
|
|
|
|
#define GOL_WIDTH 768
|
|
|
|
// Game Of Life Update Command
|
|
// NOTE: matches the structure defined on main program
|
|
struct GolUpdateCmd {
|
|
uint x; // x coordinate of the gol command
|
|
uint y; // y coordinate of the gol command
|
|
uint w; // width of the filled zone
|
|
uint enabled; // whether to enable or disable zone
|
|
};
|
|
|
|
// Local compute unit size
|
|
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
|
|
|
// Output game of life grid buffer
|
|
layout(std430, binding = 1) buffer golBufferLayout
|
|
{
|
|
uint golBuffer[]; // golBuffer[x, y] = golBuffer[x + GOL_WIDTH * y]
|
|
};
|
|
|
|
// Command buffer
|
|
layout(std430, binding = 3) readonly restrict buffer golUpdateLayout
|
|
{
|
|
uint count;
|
|
GolUpdateCmd commands[];
|
|
};
|
|
|
|
#define isInside(x, y) (((x) >= 0) && ((y) >= 0) && ((x) < GOL_WIDTH) && ((y) < GOL_WIDTH))
|
|
#define getBufferIndex(x, y) ((x) + GOL_WIDTH * (y))
|
|
|
|
void main()
|
|
{
|
|
uint cmdIndex = gl_GlobalInvocationID.x;
|
|
GolUpdateCmd cmd = commands[cmdIndex];
|
|
|
|
for (uint x = cmd.x; x < (cmd.x + cmd.w); x++)
|
|
{
|
|
for (uint y = cmd.y; y < (cmd.y + cmd.w); y++)
|
|
{
|
|
if (isInside(x, y))
|
|
{
|
|
if (cmd.enabled != 0) atomicOr(golBuffer[getBufferIndex(x, y)], 1);
|
|
else atomicAnd(golBuffer[getBufferIndex(x, y)], 0);
|
|
}
|
|
}
|
|
}
|
|
}
|