@@ -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