Minimal working version
This commit is contained in:
parent
4f87a354c0
commit
43fd84b50d
@ -1,8 +1,21 @@
|
|||||||
#include <sprstk/sprstk.h>
|
#include <sprstk/sprstk.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void update(sprstk* instance, float dt, void* userdata)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 10; i += 2)
|
||||||
|
{
|
||||||
|
sprstk_put(instance, i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
sprstk* instance = sprstk_new({.update = [](sprstk*, float, void*) {}}, nullptr);
|
sprstk* instance = sprstk_new({.update = update}, nullptr);
|
||||||
|
|
||||||
sprstk_run(instance);
|
sprstk_run(instance);
|
||||||
|
|
||||||
|
@ -24,6 +24,9 @@ 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_putz(sprstk* instance, unsigned int x, unsigned int y, unsigned int z_offset);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
113
src/sprstk.cpp
113
src/sprstk.cpp
@ -10,32 +10,60 @@ const char* MESH_SHADER_CODE = R"(
|
|||||||
|
|
||||||
#extension GL_NV_mesh_shader : require
|
#extension GL_NV_mesh_shader : require
|
||||||
|
|
||||||
layout(local_size_x = 1) in;
|
layout (local_size_x = 32) in;
|
||||||
layout(triangles, max_vertices = 3, max_primitives = 1) out;
|
layout (triangles, max_vertices = 128, max_primitives = 64) out;
|
||||||
|
|
||||||
layout (location = 0) out PerVertexData
|
layout (location = 0) out PerVertexData
|
||||||
{
|
{
|
||||||
vec4 color;
|
vec4 color;
|
||||||
} v_out[];
|
} v_out[];
|
||||||
|
|
||||||
const vec3 vertices[3] = {vec3(-1, -1, 0), vec3(0, 1, 0), vec3(1, -1, 0)};
|
layout (location = 1) uniform vec3 screen_size_and_pixel_scale;
|
||||||
const vec3 colors[3] = {vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1)};
|
|
||||||
|
struct TileInfo
|
||||||
|
{
|
||||||
|
uint position;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std430, binding = 0) restrict readonly buffer TileInfos
|
||||||
|
{
|
||||||
|
TileInfo[] tile_infos;
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint indices[6] = { 0, 1, 2, 2, 1, 3 };
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_MeshVerticesNV[0].gl_Position = vec4(vertices[0], 1);
|
TileInfo info = tile_infos[gl_WorkGroupID.x];
|
||||||
gl_MeshVerticesNV[1].gl_Position = vec4(vertices[1], 1);
|
uint position_x = bitfieldExtract(info.position, 0, 13);
|
||||||
gl_MeshVerticesNV[2].gl_Position = vec4(vertices[2], 1);
|
uint position_y = bitfieldExtract(info.position, 13, 13);
|
||||||
|
vec2 stack_position = vec2(position_x, position_y);
|
||||||
|
|
||||||
v_out[0].color = vec4(colors[0], 1);
|
vec2 positions[4] = { vec2(0, 0), vec2(1, 0), vec2(0, 1), vec2(1, 1) };
|
||||||
v_out[1].color = vec4(colors[1], 1);
|
for (uint i = 0; i < 4; i++)
|
||||||
v_out[2].color = vec4(colors[2], 1);
|
{
|
||||||
|
positions[i] += stack_position;
|
||||||
|
positions[i] *= screen_size_and_pixel_scale.zz;
|
||||||
|
positions[i] /= screen_size_and_pixel_scale.xy;
|
||||||
|
}
|
||||||
|
|
||||||
gl_PrimitiveIndicesNV[0] = 0;
|
uint z_offset = bitfieldExtract(info.position, 26, 6);
|
||||||
gl_PrimitiveIndicesNV[1] = 1;
|
|
||||||
gl_PrimitiveIndicesNV[2] = 2;
|
|
||||||
|
|
||||||
gl_PrimitiveCountNV = 1;
|
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);
|
||||||
|
position.y += 8 * position.z / screen_size_and_pixel_scale.z;
|
||||||
|
gl_MeshVerticesNV[i].gl_Position = position;
|
||||||
|
|
||||||
|
v_out[i].color = vec4(1, 1, 1, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint i = 6 * gl_LocalInvocationID.x; i < 6 * gl_LocalInvocationID.x + 6; i++)
|
||||||
|
{
|
||||||
|
gl_PrimitiveIndicesNV[i] = 4 * gl_LocalInvocationID.x + indices[i % 6];
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_PrimitiveCountNV = 64;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@ -55,6 +83,11 @@ void main()
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
struct TileInfo
|
||||||
|
{
|
||||||
|
uint32_t position;
|
||||||
|
};
|
||||||
|
|
||||||
class application_error : public std::runtime_error
|
class application_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -105,15 +138,19 @@ public:
|
|||||||
int width, height;
|
int width, height;
|
||||||
SDL_GetWindowSizeInPixels(sdl.window, &width, &height);
|
SDL_GetWindowSizeInPixels(sdl.window, &width, &height);
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
|
glProgramUniform3f(gl.program, 1, width, height, 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t current_ticks = SDL_GetTicks();
|
uint64_t current_ticks = SDL_GetTicks();
|
||||||
float dt = (prev_ticks - current_ticks) / 1000.0f;
|
float dt = (prev_ticks - current_ticks) / 1000.0f;
|
||||||
|
|
||||||
|
gl.tile_count = 0;
|
||||||
callbacks.update(this, dt, userdata);
|
callbacks.update(this, dt, userdata);
|
||||||
|
|
||||||
glDrawMeshTasksNV(0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glDrawMeshTasksNV(0, gl.tile_count);
|
||||||
|
|
||||||
SDL_GL_SwapWindow(sdl.window);
|
SDL_GL_SwapWindow(sdl.window);
|
||||||
}
|
}
|
||||||
@ -126,6 +163,16 @@ public:
|
|||||||
should_stop = true;
|
should_stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void put(unsigned int x, unsigned int y, unsigned int z_offset = 0)
|
||||||
|
{
|
||||||
|
x &= 0b0001111111111111;
|
||||||
|
y &= 0b0001111111111111;
|
||||||
|
y <<= 13;
|
||||||
|
z_offset &= 0b111111;
|
||||||
|
z_offset <<= 26;
|
||||||
|
gl.tile_buffer_map[gl.tile_count++] = { x | y | z_offset };
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sprstk_callbacks callbacks;
|
sprstk_callbacks callbacks;
|
||||||
void* userdata;
|
void* userdata;
|
||||||
@ -141,6 +188,9 @@ private:
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned int program;
|
unsigned int program;
|
||||||
|
unsigned int tile_buffer;
|
||||||
|
TileInfo* tile_buffer_map;
|
||||||
|
unsigned int tile_count;
|
||||||
} gl;
|
} gl;
|
||||||
|
|
||||||
void init_sdl()
|
void init_sdl()
|
||||||
@ -155,6 +205,7 @@ private:
|
|||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
|
||||||
|
|
||||||
sdl.window = SDL_CreateWindow("sprstk", 640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
sdl.window = SDL_CreateWindow("sprstk", 640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
if (!sdl.window)
|
if (!sdl.window)
|
||||||
@ -186,6 +237,14 @@ private:
|
|||||||
throw application_error("Mesh shaders not supported");
|
throw application_error("Mesh shaders not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||||
|
|
||||||
|
glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userdata)
|
||||||
|
{
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "%s", message);
|
||||||
|
}, nullptr);
|
||||||
|
|
||||||
int success;
|
int success;
|
||||||
char info_log[512];
|
char info_log[512];
|
||||||
|
|
||||||
@ -229,10 +288,24 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
glUseProgram(gl.program);
|
glUseProgram(gl.program);
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
SDL_GetWindowSizeInPixels(sdl.window, &width, &height);
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
glProgramUniform3f(gl.program, 1, width, height, 32);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_gl()
|
void destroy_gl()
|
||||||
{
|
{
|
||||||
|
glDeleteProgram(gl.program);
|
||||||
|
glDeleteBuffers(1, &gl.tile_buffer);
|
||||||
SDL_GL_DestroyContext(sdl.context);
|
SDL_GL_DestroyContext(sdl.context);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -281,4 +354,14 @@ void sprstk_stop(sprstk* instance)
|
|||||||
instance->stop();
|
instance->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sprstk_put(sprstk* instance, unsigned int x, unsigned int y)
|
||||||
|
{
|
||||||
|
instance->put(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sprstk_putz(sprstk* instance, unsigned int x, unsigned int y, unsigned int z_offset)
|
||||||
|
{
|
||||||
|
instance->put(x, y, z_offset);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user