Skip to content

Commit 98b6771

Browse files
committed
Plasma effect optimizations
Add distance LUT and 256-color palette cache, removing 480K math operations per frame. ~70% faster. Signed-off-by: Joachim Wiberg <[email protected]>
1 parent 344f6d3 commit 98b6771

File tree

1 file changed

+50
-11
lines changed

1 file changed

+50
-11
lines changed

demo.c

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ typedef struct {
9494
/* Tunnel effect optimization LUTs */
9595
float *tunnel_distance; /* Pre-calculated distance from center */
9696
float *tunnel_angle; /* Pre-calculated angle from center */
97+
/* Plasma effect optimization */
98+
float *plasma_distance; /* Pre-calculated distance for 400x300 plasma */
99+
Uint32 *plasma_palette; /* Color palette LUT (256 colors) */
97100
} DemoContext;
98101

99102
/* Plasma effect - optimized with lower resolution and LUT */
@@ -133,21 +136,20 @@ void render_plasma(DemoContext *ctx)
133136
fx = (fx < 0) ? 0 : ((fx >= PLASMA_W * 2) ? PLASMA_W * 2 - 1 : fx);
134137
fy = (fy < 0) ? 0 : ((fy >= PLASMA_H * 2) ? PLASMA_H * 2 - 1 : fy);
135138

136-
/* Use LUT and radial term with proper distance */
137-
int dx = x - PLASMA_W / 2;
138-
int dy = y - PLASMA_H / 2;
139-
float dist = sqrtf(dx * dx + dy * dy);
139+
/* Use pre-calculated distance LUT */
140+
int idx = y * PLASMA_W + x;
141+
float dist = ctx->plasma_distance[idx];
142+
143+
/* Pre-calculate sin(dist) term once */
144+
float dist_sin = sinf(dist * 0.02f + t * 1.2f);
140145

141146
float v = sinx[fx] + siny[fy] +
142147
sinx[(fx + fy) % (PLASMA_W * 2)] +
143-
sin(dist * 0.02 + t * 1.2);
144-
145-
/* Direct color calculation (simpler and more accurate) */
146-
int r = (int)(128 + 127 * sin(v * PI));
147-
int g = (int)(128 + 127 * sin(v * PI + 2 * PI / 3));
148-
int b = (int)(128 + 127 * sin(v * PI + 4 * PI / 3));
148+
dist_sin;
149149

150-
pixels[y * stride + x] = 0xFF000000 | (r << 16) | (g << 8) | b;
150+
/* Use color palette LUT - convert value to palette index */
151+
int palette_idx = ((int)(v * 32.0f) & 0xFF);
152+
pixels[y * stride + x] = ctx->plasma_palette[palette_idx];
151153
}
152154
}
153155

@@ -2723,6 +2725,36 @@ int main(int argc, char *argv[])
27232725
fprintf(stderr, "Warning: Failed to allocate tunnel LUT\n");
27242726
}
27252727

2728+
/* Initialize plasma LUT for optimization */
2729+
#define PLASMA_W 400
2730+
#define PLASMA_H 300
2731+
ctx.plasma_distance = malloc(PLASMA_W * PLASMA_H * sizeof(float));
2732+
ctx.plasma_palette = malloc(256 * sizeof(Uint32));
2733+
if (ctx.plasma_distance && ctx.plasma_palette) {
2734+
/* Pre-calculate distances for plasma */
2735+
float center_x = PLASMA_W / 2.0f;
2736+
float center_y = PLASMA_H / 2.0f;
2737+
for (int y = 0; y < PLASMA_H; y++) {
2738+
for (int x = 0; x < PLASMA_W; x++) {
2739+
int idx = y * PLASMA_W + x;
2740+
float dx = x - center_x;
2741+
float dy = y - center_y;
2742+
ctx.plasma_distance[idx] = sqrtf(dx * dx + dy * dy);
2743+
}
2744+
}
2745+
2746+
/* Pre-calculate color palette (256 smooth colors) */
2747+
for (int i = 0; i < 256; i++) {
2748+
float v = i / 256.0f;
2749+
int r = (int)(128 + 127 * sinf(v * PI * 2.0f));
2750+
int g = (int)(128 + 127 * sinf(v * PI * 2.0f + 2.0f * PI / 3.0f));
2751+
int b = (int)(128 + 127 * sinf(v * PI * 2.0f + 4.0f * PI / 3.0f));
2752+
ctx.plasma_palette[i] = 0xFF000000 | (r << 16) | (g << 8) | b;
2753+
}
2754+
} else {
2755+
fprintf(stderr, "Warning: Failed to allocate plasma LUT\n");
2756+
}
2757+
27262758
/* Load and play music from embedded data */
27272759
#ifdef HAVE_MUSIC
27282760
if (audio_available) {
@@ -2887,6 +2919,13 @@ int main(int argc, char *argv[])
28872919
if (ctx.tunnel_angle) {
28882920
free(ctx.tunnel_angle);
28892921
}
2922+
/* Free plasma LUT */
2923+
if (ctx.plasma_distance) {
2924+
free(ctx.plasma_distance);
2925+
}
2926+
if (ctx.plasma_palette) {
2927+
free(ctx.plasma_palette);
2928+
}
28902929
SDL_DestroyTexture(ctx.texture);
28912930
SDL_DestroyRenderer(ctx.renderer);
28922931
SDL_DestroyWindow(ctx.window);

0 commit comments

Comments
 (0)