summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c119
1 files changed, 65 insertions, 54 deletions
diff --git a/main.c b/main.c
index e4bd106..5c8b5d9 100644
--- a/main.c
+++ b/main.c
@@ -38,10 +38,10 @@
#define USE_GL_DEBUG false
// number of particles
-#define NUM_PARTICLES 1024
+#define NUM_PARTICLES 2048
// size of compute shader workgroups
-#define WORKGROUP_SIZE 128
+#define WORKGROUP_SIZE 1024
typedef struct {
const GLuint type;
@@ -72,17 +72,25 @@ verts[] = {
};
typedef struct {
- float positions[4 * NUM_PARTICLES],
- velocities[4 * NUM_PARTICLES],
- colors[4 * NUM_PARTICLES];
+ float x, y;
+} vec2_t;
+
+typedef struct {
+ vec2_t positions[NUM_PARTICLES],
+ velocities[NUM_PARTICLES];
+ uint32_t colors[NUM_PARTICLES];
+ struct {
+ float r, g, b, a;
+ } palette[256];
} particles_t;
// shared particle shader storage buffer definition
#define PARTICLE_BUFFER \
"layout (std430, binding = 1) buffer particles {\n" \
- " mediump vec4 positions[" S(NUM_PARTICLES) "];\n" \
- " mediump vec4 velocities[" S(NUM_PARTICLES) "];\n" \
- " mediump vec4 colors[" S(NUM_PARTICLES) "];\n" \
+ " mediump vec2 positions[" S(NUM_PARTICLES) "];\n" \
+ " mediump vec2 velocities[" S(NUM_PARTICLES) "];\n" \
+ " mediump uint colors[" S(NUM_PARTICLES) "];\n" \
+ " mediump vec4 palette[256];\n" \
"};\n"
// real compute shader
@@ -101,7 +109,7 @@ cs_src[] =
"\n"
"void main() {\n"
" mediump uint i = gl_GlobalInvocationID.x;\n"
- " positions[i].xy += delta * velocities[i].xy;\n"
+ " positions[i] += delta * velocities[i];\n"
"\n"
" if (positions[i].x > 1.1) {\n"
" positions[i].x -= 2.2;\n"
@@ -127,7 +135,7 @@ vs_src[] =
"out mediump flat int instance_id;\n"
"\n"
"void main() {\n"
- " gl_Position = positions[gl_InstanceID] + 0.025 * vec4(pos, 1);\n"
+ " gl_Position = vec4(positions[gl_InstanceID], 0, 1) + 0.025 * vec4(pos, 1);\n"
" instance_id = gl_InstanceID;\n"
"}\n";
@@ -145,7 +153,7 @@ fs_src[] =
"\n"
"void main() {\n"
" mediump float alpha = 0.5f + 0.5f * (0.5f + 0.5 * sin(time * 3.141));\n"
- " color = vec4(colors[instance_id].rgb, 1) * alpha;\n"
+ " color = palette[colors[instance_id]] * alpha;\n"
"}\n";
static const shader_t
@@ -267,12 +275,32 @@ color_map(uint8_t bits) {
}
}
+static void
+init_palette(
+ particles_t * const data
+) {
+ // generate palette seed data
+ uint8_t seeds[256];
+ if (!RAND_bytes(seeds, 256)) {
+ LOG_C("RAND_bytes() failed");
+ exit(EXIT_FAILURE);
+ }
+
+ #pragma omp parallel for
+ for (int i = 0; i < 256; i++) {
+ // get seed
+ const uint8_t cs = seeds[i];
+
+ // set color
+ data->palette[i].r = color_map(cs & 0x3);
+ data->palette[i].g = color_map((cs >> 2) & 0x3);
+ data->palette[i].b = color_map((cs >> 4) & 0x3);
+ data->palette[i].a = 1.0;
+ }
+}
+
static GLuint
init_particles(void) {
- // create shader storage buffer
- GLuint ssbo;
- glGenBuffers(1, &ssbo);
-
// generate seed data
uint8_t seeds[5 * NUM_PARTICLES];
if (!RAND_bytes(seeds, 5 * NUM_PARTICLES)) {
@@ -282,44 +310,27 @@ init_particles(void) {
// populate particle data
particles_t data;
-
#pragma omp parallel for
for (int i = 0; i < NUM_PARTICLES; i++) {
- // calculate position
- const float px = 2.0 * seeds[5 * i + 0] / 0xFF - 1.0,
- py = 2.0 * seeds[5 * i + 1] / 0xFF - 1.0;
-
- // LOG_D("%f,%f", px, py);
-
// set position
- data.positions[4 * i + 0] = px;
- data.positions[4 * i + 1] = py;
- data.positions[4 * i + 2] = 0.0;
- data.positions[4 * i + 3] = 1.0;
-
- // calculate velocity
- const float vx = 2.0 * seeds[5 * i + 2] / 0xFF - 1.0,
- vy = 2.0 * seeds[5 * i + 3] / 0xFF - 1.0;
+ data.positions[i].x = 2.0 * seeds[5 * i + 0] / 0xFF - 1.0;
+ data.positions[i].y = 2.0 * seeds[5 * i + 1] / 0xFF - 1.0;
// set velocity
- data.velocities[4 * i + 0] = vx;
- data.velocities[4 * i + 1] = vy;
- data.velocities[4 * i + 2] = 0;
- data.velocities[4 * i + 3] = 0;
-
- // calculate color
- const uint8_t cs = seeds[5 * i + 4];
- const float r = color_map(cs & 0x3),
- g = color_map((cs >> 2) & 0x3),
- b = color_map((cs >> 4) & 0x3);
+ data.velocities[i].x = 2.0 * seeds[5 * i + 2] / 0xFF - 1.0;
+ data.velocities[i].y = 2.0 * seeds[5 * i + 3] / 0xFF - 1.0;
// set color
- data.colors[4 * i + 0] = r;
- data.colors[4 * i + 1] = g;
- data.colors[4 * i + 2] = b;
- data.colors[4 * i + 3] = 1.0;
+ data.colors[i] = seeds[5 * i + 4] & 0x3f;
}
+ // generate palette
+ init_palette(&data);
+
+ // create shader storage buffer
+ GLuint ssbo;
+ glGenBuffers(1, &ssbo);
+
// populate buffer
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(particles_t), &data, GL_DYNAMIC_DRAW);
@@ -391,19 +402,19 @@ update_particles(
#pragma omp parallel for
for (int i = 0; i < NUM_PARTICLES; i++) {
// update x coordinate
- data->positions[4 * i + 0] += delta * data->velocities[4 * i + 0];
- if (data->positions[4 * i + 0] < -1.1) {
- data->positions[4 * i + 0] += 2.2;
- } else if (data->positions[4 * i + 0] > 1.1) {
- data->positions[4 * i + 0] -= 2.2;
+ data->positions[i].x += delta * data->velocities[i].x;
+ if (data->positions[i].x < -1.1) {
+ data->positions[i].x += 2.2;
+ } else if (data->positions[i].x > 1.1) {
+ data->positions[i].x -= 2.2;
}
// update y coordinate
- data->positions[4 * i + 1] += delta * data->velocities[4 * i + 1];
- if (data->positions[4 * i + 1] < -1.1) {
- data->positions[4 * i + 1] += 2.2;
- } else if (data->positions[4 * i + 1] > 1.1) {
- data->positions[4 * i + 1] -= 2.2;
+ data->positions[i].y += delta * data->velocities[i].y;
+ if (data->positions[i].y < -1.1) {
+ data->positions[i].y += 2.2;
+ } else if (data->positions[i].y > 1.1) {
+ data->positions[i].y -= 2.2;
}
}