Palette lookup
This commit is contained in:
parent
43fd84b50d
commit
d5ef14c64d
@ -3,11 +3,31 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void init(sprstk* instance, void* userdata)
|
||||||
|
{
|
||||||
|
sprstk_palette pal = {};
|
||||||
|
|
||||||
|
for (int i = 0; i < 28; i++)
|
||||||
|
{
|
||||||
|
pal.colors[i] = 0x7F4F0040;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 28; i < 32; i++)
|
||||||
|
{
|
||||||
|
pal.colors[i] = 0x00FF0040;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprstk_set_palette(instance, 0, &pal);
|
||||||
|
}
|
||||||
|
|
||||||
void update(sprstk* instance, float dt, void* userdata)
|
void update(sprstk* instance, float dt, void* userdata)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 10; i += 2)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
sprstk_put(instance, i, 0);
|
for (int j = 15; j >= 0; j--)
|
||||||
|
{
|
||||||
|
sprstk_put(instance, i - 8, j - 8, i + j + 1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,7 +35,7 @@ void update(sprstk* instance, float dt, void* userdata)
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
sprstk* instance = sprstk_new({.update = update}, nullptr);
|
sprstk* instance = sprstk_new({.init = init, .update = update}, nullptr);
|
||||||
|
|
||||||
sprstk_run(instance);
|
sprstk_run(instance);
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef SPRSTK_H
|
#ifndef SPRSTK_H
|
||||||
#define SPRSTK_H
|
#define SPRSTK_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -18,14 +20,20 @@ typedef struct {
|
|||||||
sprstk_quit_fn quit;
|
sprstk_quit_fn quit;
|
||||||
} sprstk_callbacks;
|
} sprstk_callbacks;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t colors[32];
|
||||||
|
} sprstk_palette;
|
||||||
|
|
||||||
sprstk* sprstk_new(sprstk_callbacks callbacks, void* userdata);
|
sprstk* sprstk_new(sprstk_callbacks callbacks, void* userdata);
|
||||||
void sprstk_del(sprstk* instance);
|
void sprstk_del(sprstk* instance);
|
||||||
|
|
||||||
void sprstk_run(sprstk* instance);
|
void sprstk_run(sprstk* instance);
|
||||||
void sprstk_stop(sprstk* instance);
|
void sprstk_stop(sprstk* instance);
|
||||||
|
|
||||||
void sprstk_put(sprstk* instance, unsigned int x, unsigned int y);
|
void sprstk_put(sprstk* instance, int x, int y, unsigned int layers, unsigned int palette_lookup);
|
||||||
void sprstk_putz(sprstk* instance, unsigned int x, unsigned int y, unsigned int z_offset);
|
void sprstk_putz(sprstk* instance, int x, int y, unsigned int layers, unsigned int palette_lookup, unsigned int z_offset);
|
||||||
|
|
||||||
|
void sprstk_set_palette(sprstk* instance, unsigned int index, const sprstk_palette* palette);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -30,14 +30,26 @@ layout (std430, binding = 0) restrict readonly buffer TileInfos
|
|||||||
TileInfo[] tile_infos;
|
TileInfo[] tile_infos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ColorInfo
|
||||||
|
{
|
||||||
|
uint color[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std430, binding = 1) restrict readonly buffer ColorInfos
|
||||||
|
{
|
||||||
|
ColorInfo[] color_infos;
|
||||||
|
};
|
||||||
|
|
||||||
const uint indices[6] = { 0, 1, 2, 2, 1, 3 };
|
const uint indices[6] = { 0, 1, 2, 2, 1, 3 };
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
TileInfo info = tile_infos[gl_WorkGroupID.x];
|
TileInfo t_info = tile_infos[gl_WorkGroupID.x];
|
||||||
uint position_x = bitfieldExtract(info.position, 0, 13);
|
uint position_x = bitfieldExtract(t_info.position, 0, 10);
|
||||||
uint position_y = bitfieldExtract(info.position, 13, 13);
|
uint position_y = bitfieldExtract(t_info.position, 10, 10);
|
||||||
vec2 stack_position = vec2(position_x, position_y);
|
vec2 stack_position = vec2(position_x, position_y) - vec2(512, 512);
|
||||||
|
|
||||||
|
uint layer_count = bitfieldExtract(t_info.position, 20, 5);
|
||||||
|
|
||||||
vec2 positions[4] = { vec2(0, 0), vec2(1, 0), vec2(0, 1), vec2(1, 1) };
|
vec2 positions[4] = { vec2(0, 0), vec2(1, 0), vec2(0, 1), vec2(1, 1) };
|
||||||
for (uint i = 0; i < 4; i++)
|
for (uint i = 0; i < 4; i++)
|
||||||
@ -47,15 +59,22 @@ void main()
|
|||||||
positions[i] /= screen_size_and_pixel_scale.xy;
|
positions[i] /= screen_size_and_pixel_scale.xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint z_offset = bitfieldExtract(info.position, 26, 6);
|
uint z_offset = bitfieldExtract(t_info.position, 25, 2);
|
||||||
|
|
||||||
|
uint palette_lookup = bitfieldExtract(t_info.position, 27, 5);
|
||||||
|
ColorInfo c_info = color_infos[palette_lookup];
|
||||||
|
float a = bitfieldExtract(c_info.color[int(ceil(gl_LocalInvocationID.x * (32.0 / layer_count)))], 0, 8);
|
||||||
|
float b = bitfieldExtract(c_info.color[int(ceil(gl_LocalInvocationID.x * (32.0 / layer_count)))], 8, 8);
|
||||||
|
float g = bitfieldExtract(c_info.color[int(ceil(gl_LocalInvocationID.x * (32.0 / layer_count)))], 16, 8);
|
||||||
|
float r = bitfieldExtract(c_info.color[int(ceil(gl_LocalInvocationID.x * (32.0 / layer_count)))], 24, 8);
|
||||||
|
|
||||||
for (uint i = 4 * gl_LocalInvocationID.x; i < 4 * gl_LocalInvocationID.x + 4; i++)
|
for (uint i = 4 * gl_LocalInvocationID.x; i < 4 * gl_LocalInvocationID.x + 4; i++)
|
||||||
{
|
{
|
||||||
vec4 position = vec4(positions[i % 4], float(4 * gl_LocalInvocationID.x + z_offset) / 128, 1);
|
vec4 position = vec4(positions[i % 4], float(4 * gl_LocalInvocationID.x + z_offset) / 128, 1);
|
||||||
position.y += 8 * position.z / screen_size_and_pixel_scale.z;
|
position.y += 24 * position.z / screen_size_and_pixel_scale.z;
|
||||||
gl_MeshVerticesNV[i].gl_Position = position;
|
gl_MeshVerticesNV[i].gl_Position = position;
|
||||||
|
|
||||||
v_out[i].color = vec4(1, 1, 1, 0.1);
|
v_out[i].color = vec4(r, g, b, a) / vec4(256, 256, 256, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint i = 6 * gl_LocalInvocationID.x; i < 6 * gl_LocalInvocationID.x + 6; i++)
|
for (uint i = 6 * gl_LocalInvocationID.x; i < 6 * gl_LocalInvocationID.x + 6; i++)
|
||||||
@ -63,7 +82,7 @@ void main()
|
|||||||
gl_PrimitiveIndicesNV[i] = 4 * gl_LocalInvocationID.x + indices[i % 6];
|
gl_PrimitiveIndicesNV[i] = 4 * gl_LocalInvocationID.x + indices[i % 6];
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_PrimitiveCountNV = 64;
|
gl_PrimitiveCountNV = layer_count * 2;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@ -163,14 +182,32 @@ public:
|
|||||||
should_stop = true;
|
should_stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void put(unsigned int x, unsigned int y, unsigned int z_offset = 0)
|
void put(int x, int y, unsigned int layers, unsigned int palette_lookup, unsigned int z_offset = 0)
|
||||||
{
|
{
|
||||||
x &= 0b0001111111111111;
|
x += 512;
|
||||||
y &= 0b0001111111111111;
|
x &= 0b1111111111;
|
||||||
y <<= 13;
|
|
||||||
z_offset &= 0b111111;
|
y += 512;
|
||||||
z_offset <<= 26;
|
y &= 0b1111111111;
|
||||||
gl.tile_buffer_map[gl.tile_count++] = { x | y | z_offset };
|
y <<= 10;
|
||||||
|
|
||||||
|
layers &= 0b11111;
|
||||||
|
layers <<= 20;
|
||||||
|
|
||||||
|
z_offset &= 0b11;
|
||||||
|
z_offset <<= 25;
|
||||||
|
|
||||||
|
palette_lookup &= 0b11111;
|
||||||
|
palette_lookup <<= 27;
|
||||||
|
|
||||||
|
gl.tile_buffer_map[gl.tile_count++] = { x | y | layers | z_offset | palette_lookup };
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_palette(unsigned int index, const sprstk_palette* palette)
|
||||||
|
{
|
||||||
|
if (index > (1 << 5)) { return; }
|
||||||
|
|
||||||
|
gl.color_info_map[index] = *palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -191,6 +228,8 @@ private:
|
|||||||
unsigned int tile_buffer;
|
unsigned int tile_buffer;
|
||||||
TileInfo* tile_buffer_map;
|
TileInfo* tile_buffer_map;
|
||||||
unsigned int tile_count;
|
unsigned int tile_count;
|
||||||
|
unsigned int color_buffer;
|
||||||
|
sprstk_palette* color_info_map;
|
||||||
} gl;
|
} gl;
|
||||||
|
|
||||||
void init_sdl()
|
void init_sdl()
|
||||||
@ -300,6 +339,12 @@ private:
|
|||||||
|
|
||||||
gl.tile_count = 0;
|
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 << 26), 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);
|
||||||
|
|
||||||
|
gl.color_info_map = (sprstk_palette*)glMapNamedBufferRange(gl.color_buffer, 0, sizeof(sprstk_palette) * (1 << 5), GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_gl()
|
void destroy_gl()
|
||||||
@ -354,14 +399,19 @@ void sprstk_stop(sprstk* instance)
|
|||||||
instance->stop();
|
instance->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprstk_put(sprstk* instance, unsigned int x, unsigned int y)
|
void sprstk_put(sprstk* instance, int x, int y, unsigned int layers, unsigned int palette_lookup)
|
||||||
{
|
{
|
||||||
instance->put(x, y);
|
instance->put(x, y, layers, palette_lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprstk_putz(sprstk* instance, unsigned int x, unsigned int y, unsigned int z_offset)
|
void sprstk_putz(sprstk* instance, int x, int y, unsigned int layers, unsigned int palette_lookup, unsigned int z_offset)
|
||||||
{
|
{
|
||||||
instance->put(x, y, z_offset);
|
instance->put(x, y, layers, palette_lookup, z_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sprstk_set_palette(sprstk* instance, unsigned int index, const sprstk_palette* palette)
|
||||||
|
{
|
||||||
|
instance->set_palette(index, palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user