glow rendering fixes to bring stars back

This commit is contained in:
asrael 2026-02-10 11:10:37 -06:00
parent 657b590b6f
commit c538641ec8
26 changed files with 773 additions and 1491 deletions

View file

@ -9,6 +9,7 @@
#include "pxl8_color.h"
#include "pxl8_colormap.h"
#include "pxl8_font.h"
#include "pxl8_glows.h"
#include "pxl8_hal.h"
#include "pxl8_log.h"
#include "pxl8_macros.h"
@ -694,6 +695,7 @@ void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8
pxl8_3d_frame frame = pxl8_3d_frame_from_camera(camera, uniforms);
frame.bsp = gfx->bsp;
frame.uniforms.camera_pos = frame.camera_pos;
frame.uniforms.lights = lights ? pxl8_lights_data(lights) : NULL;
frame.uniforms.lights_count = lights ? pxl8_lights_count(lights) : 0;
@ -765,7 +767,7 @@ void pxl8_3d_clear(pxl8_gfx* gfx, u8 color) {
void pxl8_3d_clear_depth(pxl8_gfx* gfx) {
if (!gfx) return;
pxl8_clear_depth(gfx->renderer, gfx_current_depth(gfx));
pxl8_cmdbuf_clear_depth(gfx->cmdbuf, gfx_current_depth(gfx));
}
void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color) {
@ -1043,6 +1045,107 @@ bool pxl8_gfx_get_wireframe(const pxl8_gfx* gfx) {
return gfx ? gfx->wireframe : false;
}
void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count) {
if (!gfx || !params || count == 0) return;
if (effect == PXL8_GFX_EFFECT_GLOWS) {
u8* fb = (u8*)pxl8_texture_get_data(gfx->renderer, gfx_current_color(gfx));
if (!fb || !gfx->colormap) return;
u16* zb = (u16*)pxl8_texture_get_data(gfx->renderer, gfx_current_depth(gfx));
i32 w = gfx->framebuffer_width;
i32 h = gfx->framebuffer_height;
const pxl8_glow* glows = (const pxl8_glow*)params;
for (u32 i = 0; i < count; i++) {
const pxl8_glow* g = &glows[i];
i32 cx = g->x;
i32 cy = g->y;
i32 r = (i32)g->radius;
if (r <= 0) continue;
bool depth_test = g->depth > 0 && zb;
f32 base_intensity = (f32)g->intensity / 255.0f;
f32 inv_r = 1.0f / (f32)r;
i32 x0 = cx - r;
i32 y0 = cy - r;
i32 x1 = cx + r;
i32 y1 = cy + r;
if (g->shape == PXL8_GLOW_SHAFT) {
i32 sh = (i32)g->height;
if (sh <= 0) sh = 1;
y0 = cy - sh;
y1 = cy + sh;
}
if (x0 < 0) x0 = 0;
if (y0 < 0) y0 = 0;
if (x1 >= w) x1 = w - 1;
if (y1 >= h) y1 = h - 1;
for (i32 py = y0; py <= y1; py++) {
i32 dy = py - cy;
for (i32 px = x0; px <= x1; px++) {
i32 idx = py * w + px;
if (depth_test && zb[idx] < g->depth) continue;
u8 src = fb[idx];
if (src == PXL8_TRANSPARENT) continue;
i32 dx = px - cx;
f32 falloff;
switch (g->shape) {
case PXL8_GLOW_CIRCLE: {
f32 dist_sq = (f32)(dx * dx + dy * dy);
f32 norm = dist_sq * inv_r * inv_r;
if (norm >= 1.0f) continue;
falloff = 1.0f - norm;
falloff *= falloff;
break;
}
case PXL8_GLOW_DIAMOND: {
f32 manhattan = (f32)(abs(dx) + abs(dy));
f32 norm = manhattan * inv_r;
if (norm >= 1.0f) continue;
falloff = 1.0f - norm;
falloff *= falloff;
break;
}
case PXL8_GLOW_SHAFT: {
f32 abs_dx = (f32)abs(dx);
if (abs_dx >= (f32)r) continue;
f32 x_falloff = 1.0f - abs_dx * inv_r;
i32 sh = (i32)g->height;
if (sh <= 0) sh = 1;
f32 abs_dy = (f32)abs(dy);
f32 y_falloff = 1.0f - abs_dy / (f32)sh;
falloff = x_falloff * y_falloff;
falloff *= falloff;
break;
}
default: continue;
}
f32 brightness = falloff * base_intensity;
f32 raw = brightness * 255.0f;
if (raw > 255.0f) raw = 255.0f;
u8 light_u8 = (u8)raw;
if (light_u8 < 4) continue;
fb[idx] = pxl8_colormap_additive_dithered(
gfx->colormap, src, g->color,
light_u8, (u32)px, (u32)py
);
}
}
}
}
}
u8 pxl8_gfx_get_ambient(const pxl8_gfx* gfx) {
return gfx ? gfx->frame.uniforms.ambient : 0;
}