Add adjustable per-layer offset

This commit is contained in:
shylie 2025-08-08 16:21:46 -04:00
parent 429db38cb2
commit 5ee0008614
3 changed files with 71 additions and 34 deletions

View File

@ -84,7 +84,7 @@ void init(sprstk* instance, void* userdata)
sprstk_set_palette(instance, 2, &pal);
sprstk_set_scale(instance, 0.4f);
sprstk_set_scale(instance, 1.0f);
SimplexNoise1234 simplex;
for (int i = 0; i < SIZE; i++)
@ -100,7 +100,7 @@ void init(sprstk* instance, void* userdata)
{
for (int j = 0; j < SIZE; j++)
{
sprstk_put(instance, i - SIZE / 2, j - SIZE / 2, data[i + SIZE * j], pick_pal(data[i + SIZE * j]));
sprstk_put(instance, i - SIZE / 2, j - SIZE / 2, data[i + SIZE * j], 7, 7, pick_pal(data[i + SIZE * j]));
}
}
}

View File

@ -32,8 +32,8 @@ void sprstk_stop(sprstk* instance);
void sprstk_clear(sprstk* instance);
void sprstk_put(sprstk* instance, int x, int y, unsigned int layers, unsigned int palette_lookup);
void sprstk_putz(sprstk* instance, int x, int y, unsigned int layers, unsigned int palette_lookup, unsigned int z_offset);
void sprstk_put(sprstk* instance, int x, int y, unsigned int layers, int layer_dx, int layer_dy, unsigned int palette_lookup);
void sprstk_put_lo(sprstk* instance, int x, int y, unsigned int layers, int layer_dx, int layer_dy, unsigned int palette_lookup, unsigned int layer_order_offset);
void sprstk_set_palette(sprstk* instance, unsigned int index, const sprstk_palette* palette);

View File

@ -29,9 +29,31 @@ layout (location = 1) uniform vec3 screen_size_and_pixel_scale;
layout (location = 2) uniform float scale;
layout (location = 3) uniform mat2 rotation_matrix;
/*
'position'
0 -- 7 8 -- 15 16 -- 23 24 -- 32
[xxxxxxxx][xyyyyyyy][yylllllo][aaaabbbb]
x | x position
y | y position
l | layer count
o | layer order offset
a | x offset per layer
b | y offset per layer
'color'
0 -- 7 8 -- 15 16 -- 23 24 -- 32
[pppppppp][--------][--------][--------]
p | palette index
- | reserved
*/
struct TileInfo
{
uint position;
uint color;
};
layout (std430, binding = 0) restrict readonly buffer TileInfos
@ -54,11 +76,11 @@ const uint indices[6] = { 0, 1, 2, 2, 1, 3 };
void main()
{
TileInfo t_info = tile_infos[gl_WorkGroupID.x];
uint position_x = bitfieldExtract(t_info.position, 0, 10);
uint position_y = bitfieldExtract(t_info.position, 10, 10);
vec2 stack_position = vec2(position_x, position_y) - vec2(512, 512);
uint position_x = bitfieldExtract(t_info.position, 0, 9);
uint position_y = bitfieldExtract(t_info.position, 9, 9);
vec2 stack_position = vec2(position_x, position_y) - vec2(256, 256);
uint layer_count = bitfieldExtract(t_info.position, 20, 5);
uint layer_count = bitfieldExtract(t_info.position, 18, 5);
float minsize = min(screen_size_and_pixel_scale.x, screen_size_and_pixel_scale.y);
@ -69,21 +91,25 @@ void main()
positions[i] *= screen_size_and_pixel_scale.zz;
}
uint z_offset = bitfieldExtract(t_info.position, 25, 2);
uint layer_order_offset = bitfieldExtract(t_info.position, 23, 1);
uint palette_lookup = bitfieldExtract(t_info.position, 27, 5);
uint x_offset_per_layer = bitfieldExtract(t_info.position, 24, 4);
uint y_offset_per_layer = bitfieldExtract(t_info.position, 28, 4);
vec2 offset_per_layer = vec2(x_offset_per_layer, y_offset_per_layer) - vec2(8);
uint palette_lookup = bitfieldExtract(t_info.color, 0, 8);
ColorInfo c_info = color_infos[palette_lookup];
uint c = c_info.color[gl_LocalInvocationID.x];
for (uint i = 4 * gl_LocalInvocationID.x; i < 4 * gl_LocalInvocationID.x + 4; i++)
{
vec4 position = vec4(rotation_matrix * positions[i % 4], float(4 * gl_LocalInvocationID.x + z_offset) / 128, 1);
vec4 position = vec4(rotation_matrix * positions[i % 4], float(4 * gl_LocalInvocationID.x + layer_order_offset) / 128, 1);
position.xy /= screen_size_and_pixel_scale.xy;
position.xy *= scale;
position.y += 20 * gl_LocalInvocationID.x * scale / screen_size_and_pixel_scale.y;
position.xy += offset_per_layer * vec2(2 * gl_LocalInvocationID.x * scale / screen_size_and_pixel_scale.xy);
gl_MeshVerticesNV[i].gl_Position = position;
v_out[i].layer = 4 * gl_LocalInvocationID.x + z_offset;
v_out[i].layer = 4 * gl_LocalInvocationID.x + layer_order_offset;
v_out[i].color = c;
}
@ -183,6 +209,7 @@ void main()
struct TileInfo
{
uint32_t position;
uint32_t color;
};
class application_error : public std::runtime_error
@ -302,30 +329,40 @@ public:
gl.tile_count = 0;
}
void put(int x, int y, unsigned int layers, unsigned int palette_lookup, unsigned int z_offset = 0)
void put(int x, int y, unsigned int layers, unsigned int palette_lookup, int layer_dx, int layer_dy, unsigned int layer_order_offset = 0)
{
x += 512;
x &= 0b1111111111;
x += 256;
x &= 0b111111111;
y += 512;
y &= 0b1111111111;
y <<= 10;
y += 256;
y &= 0b111111111;
y <<= 9;
layers &= 0b11111;
layers <<= 20;
layers <<= 18;
z_offset &= 0b11;
z_offset <<= 25;
layer_order_offset &= 0b1;
layer_order_offset <<= 23;
palette_lookup &= 0b11111;
palette_lookup <<= 27;
layer_dx += 8;
layer_dx &= 0b1111;
layer_dx <<= 24;
gl.tile_buffer_map[gl.tile_count++] = { x | y | layers | z_offset | palette_lookup };
layer_dy += 8;
layer_dy &= 0b1111;
layer_dy <<= 28;
palette_lookup &= 0b11111111;
gl.tile_buffer_map[gl.tile_count++] = {
.position = x | y | layers | layer_order_offset | layer_dx | layer_dy,
.color = palette_lookup
};
}
void set_palette(unsigned int index, const sprstk_palette* palette)
{
if (index > (1 << 5)) { return; }
if (index > (1 << 8)) { return; }
gl.color_info_map[index] = *palette;
}
@ -507,16 +544,16 @@ private:
glGenBuffers(1, &gl.tile_buffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, gl.tile_buffer);
glNamedBufferStorage(gl.tile_buffer, sizeof(TileInfo) * (1 << 26), nullptr, GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT);
glNamedBufferStorage(gl.tile_buffer, sizeof(TileInfo) * (1 << 20), nullptr, GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT);
gl.tile_count = 0;
gl.tile_buffer_map = (TileInfo*)glMapNamedBufferRange(gl.tile_buffer, 0, sizeof(TileInfo) * (1 << 26), GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);
gl.tile_buffer_map = (TileInfo*)glMapNamedBufferRange(gl.tile_buffer, 0, sizeof(TileInfo) * (1 << 20), GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);
glGenBuffers(1, &gl.color_buffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, gl.color_buffer);
glNamedBufferStorage(gl.color_buffer, sizeof(sprstk_palette) * (1 << 5), nullptr, GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT);
glNamedBufferStorage(gl.color_buffer, sizeof(sprstk_palette) * (1 << 8), nullptr, GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT);
gl.color_info_map = (sprstk_palette*)glMapNamedBufferRange(gl.color_buffer, 0, sizeof(sprstk_palette) * (1 << 5), GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);
gl.color_info_map = (sprstk_palette*)glMapNamedBufferRange(gl.color_buffer, 0, sizeof(sprstk_palette) * (1 << 8), GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);
const float arr[4] = {1, 0, 0, 1};
glProgramUniformMatrix2fv(gl.az_pass_program, 3, 1, false, arr);
@ -613,14 +650,14 @@ void sprstk_clear(sprstk* instance)
instance->clear();
}
void sprstk_put(sprstk* instance, int x, int y, unsigned int layers, unsigned int palette_lookup)
void sprstk_put(sprstk* instance, int x, int y, unsigned int layers, int layer_dx, int layer_dy, unsigned int palette_lookup)
{
instance->put(x, y, layers, palette_lookup);
instance->put(x, y, layers, palette_lookup, layer_dx, layer_dy);
}
void sprstk_putz(sprstk* instance, int x, int y, unsigned int layers, unsigned int palette_lookup, unsigned int z_offset)
void sprstk_put_lo(sprstk* instance, int x, int y, unsigned int layers, int layer_dx, int layer_dy, unsigned int palette_lookup, unsigned int layer_order_offset)
{
instance->put(x, y, layers, palette_lookup, z_offset);
instance->put(x, y, layers, layer_dx, layer_dy, palette_lookup, layer_order_offset);
}
void sprstk_set_palette(sprstk* instance, unsigned int index, const sprstk_palette* palette)