From 5ee000861400c8041f80b45059a7c58e9f826301 Mon Sep 17 00:00:00 2001 From: shylie Date: Fri, 8 Aug 2025 16:21:46 -0400 Subject: [PATCH] Add adjustable per-layer offset --- examples/basic.cpp | 4 +- include/sprstk/sprstk.h | 4 +- src/sprstk.cpp | 97 ++++++++++++++++++++++++++++------------- 3 files changed, 71 insertions(+), 34 deletions(-) diff --git a/examples/basic.cpp b/examples/basic.cpp index 1162f41..89e5c40 100644 --- a/examples/basic.cpp +++ b/examples/basic.cpp @@ -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])); } } } diff --git a/include/sprstk/sprstk.h b/include/sprstk/sprstk.h index 1bc83fd..b46a4a5 100644 --- a/include/sprstk/sprstk.h +++ b/include/sprstk/sprstk.h @@ -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); diff --git a/src/sprstk.cpp b/src/sprstk.cpp index 136690e..d57e22b 100644 --- a/src/sprstk.cpp +++ b/src/sprstk.cpp @@ -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)