Skip to content

Commit e300b8e

Browse files
committed
Render Jack sphere with particle burst from behind
Signed-off-by: Joachim Wiberg <[email protected]>
1 parent fec25d1 commit e300b8e

File tree

1 file changed

+100
-31
lines changed

1 file changed

+100
-31
lines changed

demo.c

Lines changed: 100 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,16 @@ void render_starfield(DemoContext *ctx)
191191
}
192192
}
193193

194-
/* Periodic particle bursts from center */
194+
/* Update texture first for stars */
195+
SDL_UpdateTexture(ctx->texture, NULL, ctx->pixels, WIDTH * sizeof(Uint32));
196+
SDL_RenderClear(ctx->renderer);
197+
SDL_RenderCopy(ctx->renderer, ctx->texture, NULL, NULL);
198+
199+
/* Periodic particle bursts from center (draw before sphere) */
195200
static float last_burst_time = -999.0f;
196201
static int burst_style = 0;
197202
float burst_interval = 2.5f; /* Burst every 2.5 seconds */
203+
198204
int cx = WIDTH / 2;
199205
int cy = HEIGHT / 2;
200206

@@ -211,7 +217,7 @@ void render_starfield(DemoContext *ctx)
211217
int num_particles = 80;
212218

213219
for (int i = 0; i < num_particles; i++) {
214-
float angle, radius, px_f, py_f;
220+
float angle, radius;
215221
int px, py, r, g, b;
216222
float life = 1.0f - (time_since_burst / 2.0f);
217223
if (life < 0.0f) life = 0.0f;
@@ -262,43 +268,106 @@ void render_starfield(DemoContext *ctx)
262268
b = (int)(50 * ring_life);
263269
}
264270

265-
/* Draw particle with glow */
266-
for (int dy = -2; dy <= 2; dy++) {
267-
for (int dx = -2; dx <= 2; dx++) {
268-
int x = px + dx;
269-
int y = py + dy;
271+
/* Draw particle with glow using SDL rendering */
272+
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_ADD);
273+
274+
/* Draw glow layers */
275+
for (int layer = 3; layer >= 1; layer--) {
276+
int alpha = (int)((255.0f / (layer + 1)) * life);
277+
SDL_SetRenderDrawColor(ctx->renderer, r, g, b, alpha);
270278

271-
if (x >= 0 && x < WIDTH && y >= 0 && y < HEIGHT) {
272-
float dist = sqrtf(dx * dx + dy * dy);
273-
if (dist <= 2.0f) {
274-
float glow = (1.0f - dist / 2.0f) * 0.7f;
279+
SDL_Rect rect = {px - layer, py - layer, layer * 2 + 1, layer * 2 + 1};
280+
SDL_RenderFillRect(ctx->renderer, &rect);
281+
}
275282

276-
int pr = (int)(r * glow);
277-
int pg = (int)(g * glow);
278-
int pb = (int)(b * glow);
283+
/* Bright center */
284+
SDL_SetRenderDrawColor(ctx->renderer, r, g, b, 255);
285+
SDL_RenderDrawPoint(ctx->renderer, px, py);
279286

280-
/* Blend with existing pixel */
281-
Uint32 existing = ctx->pixels[y * WIDTH + x];
282-
int er = (existing >> 16) & 0xFF;
283-
int eg = (existing >> 8) & 0xFF;
284-
int eb = existing & 0xFF;
287+
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_BLEND);
288+
}
289+
}
285290

286-
int nr = (pr + er > 255) ? 255 : pr + er;
287-
int ng = (pg + eg > 255) ? 255 : pg + eg;
288-
int nb = (pb + eb > 255) ? 255 : pb + eb;
291+
/* Rotating textured sphere in center with Jack image */
292+
if (!ctx->jack_texture) return;
289293

290-
ctx->pixels[y * WIDTH + x] = 0xFF000000 | (nr << 16) | (ng << 8) | nb;
291-
}
292-
}
293-
}
294+
float sphere_radius = 80.0f;
295+
float rotation_y = ctx->global_time * 0.8f;
296+
297+
/* Create sphere mesh using latitude/longitude grid */
298+
int lat_segments = 20;
299+
int lon_segments = 30;
300+
301+
for (int lat = 0; lat < lat_segments; lat++) {
302+
for (int lon = 0; lon < lon_segments; lon++) {
303+
/* Calculate four corners of this quad */
304+
float lat0 = (lat / (float)lat_segments) * PI;
305+
float lat1 = ((lat + 1) / (float)lat_segments) * PI;
306+
float lon0 = (lon / (float)lon_segments) * 2 * PI + rotation_y;
307+
float lon1 = ((lon + 1) / (float)lon_segments) * 2 * PI + rotation_y;
308+
309+
/* Four vertices of quad */
310+
SDL_Vertex verts[4];
311+
312+
/* Vertex 0: lat0, lon0 */
313+
float x0 = sphere_radius * sinf(lat0) * sinf(lon0);
314+
float y0 = sphere_radius * cosf(lat0);
315+
float z0 = sphere_radius * sinf(lat0) * cosf(lon0);
316+
verts[0].position.x = cx + x0;
317+
verts[0].position.y = cy - y0;
318+
verts[0].tex_coord.x = lon / (float)lon_segments;
319+
verts[0].tex_coord.y = lat / (float)lat_segments;
320+
321+
/* Vertex 1: lat0, lon1 */
322+
float x1 = sphere_radius * sinf(lat0) * sinf(lon1);
323+
float y1 = sphere_radius * cosf(lat0);
324+
float z1 = sphere_radius * sinf(lat0) * cosf(lon1);
325+
verts[1].position.x = cx + x1;
326+
verts[1].position.y = cy - y1;
327+
verts[1].tex_coord.x = (lon + 1) / (float)lon_segments;
328+
verts[1].tex_coord.y = lat / (float)lat_segments;
329+
330+
/* Vertex 2: lat1, lon1 */
331+
float x2 = sphere_radius * sinf(lat1) * sinf(lon1);
332+
float y2 = sphere_radius * cosf(lat1);
333+
float z2 = sphere_radius * sinf(lat1) * cosf(lon1);
334+
verts[2].position.x = cx + x2;
335+
verts[2].position.y = cy - y2;
336+
verts[2].tex_coord.x = (lon + 1) / (float)lon_segments;
337+
verts[2].tex_coord.y = (lat + 1) / (float)lat_segments;
338+
339+
/* Vertex 3: lat1, lon0 */
340+
float x3 = sphere_radius * sinf(lat1) * sinf(lon0);
341+
float y3 = sphere_radius * cosf(lat1);
342+
float z3 = sphere_radius * sinf(lat1) * cosf(lon0);
343+
verts[3].position.x = cx + x3;
344+
verts[3].position.y = cy - y3;
345+
verts[3].tex_coord.x = lon / (float)lon_segments;
346+
verts[3].tex_coord.y = (lat + 1) / (float)lat_segments;
347+
348+
/* Backface culling - only render front-facing quads */
349+
float avg_z = (z0 + z1 + z2 + z3) / 4.0f;
350+
351+
/* Skip if quad is facing away (back side of sphere) */
352+
if (avg_z < 0) continue;
353+
354+
/* Lighting based on Z depth */
355+
int brightness = (int)(128 + 127 * (avg_z / sphere_radius));
356+
if (brightness < 0) brightness = 0;
357+
if (brightness > 255) brightness = 255;
358+
359+
for (int i = 0; i < 4; i++) {
360+
verts[i].color.r = brightness;
361+
verts[i].color.g = brightness;
362+
verts[i].color.b = brightness;
363+
verts[i].color.a = 255;
294364
}
365+
366+
/* Render quad as two triangles */
367+
int indices[6] = {0, 1, 2, 0, 2, 3};
368+
SDL_RenderGeometry(ctx->renderer, ctx->jack_texture, verts, 4, indices, 6);
295369
}
296370
}
297-
298-
/* Update texture */
299-
SDL_UpdateTexture(ctx->texture, NULL, ctx->pixels, WIDTH * sizeof(Uint32));
300-
SDL_RenderClear(ctx->renderer);
301-
SDL_RenderCopy(ctx->renderer, ctx->texture, NULL, NULL);
302371
}
303372

304373
/* Text scroller with SDL_ttf */

0 commit comments

Comments
 (0)