better lighting

This commit is contained in:
asrael 2026-01-31 09:31:17 -06:00
parent 805a2713a3
commit 6ed4e17065
75 changed files with 6417 additions and 3667 deletions

View file

@ -6,45 +6,6 @@ static inline i32 pxl8_bytes_per_pixel(pxl8_pixel_mode mode) {
return (i32)mode;
}
static inline u16 pxl8_rgb565_pack(u8 r, u8 g, u8 b) {
return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
}
static inline void pxl8_rgb565_unpack(u16 color, u8* r, u8* g, u8* b) {
*r = (color >> 11) << 3;
*g = ((color >> 5) & 0x3F) << 2;
*b = (color & 0x1F) << 3;
}
static inline u16 pxl8_rgba32_to_rgb565(u32 rgba) {
return pxl8_rgb565_pack(rgba & 0xFF, (rgba >> 8) & 0xFF, (rgba >> 16) & 0xFF);
}
static inline u32 pxl8_rgb565_to_rgba32(u16 color) {
u8 r, g, b;
pxl8_rgb565_unpack(color, &r, &g, &b);
return r | ((u32)g << 8) | ((u32)b << 16) | 0xFF000000;
}
static inline void pxl8_rgba32_unpack(u32 color, u8* r, u8* g, u8* b, u8* a) {
*r = color & 0xFF;
*g = (color >> 8) & 0xFF;
*b = (color >> 16) & 0xFF;
*a = (color >> 24) & 0xFF;
}
static inline u32 pxl8_rgba32_pack(u8 r, u8 g, u8 b, u8 a) {
return r | ((u32)g << 8) | ((u32)b << 16) | ((u32)a << 24);
}
static inline u32 pxl8_color_to_rgba(u32 abgr) {
u8 r = abgr & 0xFF;
u8 g = (abgr >> 8) & 0xFF;
u8 b = (abgr >> 16) & 0xFF;
u8 a = (abgr >> 24) & 0xFF;
return ((u32)r << 24) | ((u32)g << 16) | ((u32)b << 8) | a;
}
static inline u32 pxl8_color_from_rgba(u32 rgba) {
u8 r = (rgba >> 24) & 0xFF;
u8 g = (rgba >> 16) & 0xFF;
@ -57,6 +18,51 @@ static inline u8 pxl8_color_lerp_channel(u8 c1, u8 c2, f32 t) {
return c1 + (i32)((c2 - c1) * t);
}
static inline f32 pxl8_color_hue(u32 color) {
u8 r = color & 0xFF;
u8 g = (color >> 8) & 0xFF;
u8 b = (color >> 16) & 0xFF;
u8 max = r > g ? (r > b ? r : b) : (g > b ? g : b);
u8 min = r < g ? (r < b ? r : b) : (g < b ? g : b);
if (max == min) return 0.0f;
f32 d = (f32)(max - min);
f32 h;
if (max == r) h = (f32)(g - b) / d + (g < b ? 6.0f : 0.0f);
else if (max == g) h = (f32)(b - r) / d + 2.0f;
else h = (f32)(r - g) / d + 4.0f;
return h / 6.0f;
}
static inline f32 pxl8_color_hue_diff(f32 h1, f32 h2) {
f32 d = h1 > h2 ? h1 - h2 : h2 - h1;
return d > 0.5f ? 1.0f - d : d;
}
static inline f32 pxl8_color_luminance(u32 color) {
u8 r = color & 0xFF;
u8 g = (color >> 8) & 0xFF;
u8 b = (color >> 16) & 0xFF;
return 0.299f * r + 0.587f * g + 0.114f * b;
}
static inline f32 pxl8_color_saturation(u32 color) {
u8 r = color & 0xFF;
u8 g = (color >> 8) & 0xFF;
u8 b = (color >> 16) & 0xFF;
u8 max = r > g ? (r > b ? r : b) : (g > b ? g : b);
u8 min = r < g ? (r < b ? r : b) : (g < b ? g : b);
if (max == 0) return 0.0f;
return (f32)(max - min) / (f32)max;
}
static inline u32 pxl8_color_to_rgba(u32 abgr) {
u8 r = abgr & 0xFF;
u8 g = (abgr >> 8) & 0xFF;
u8 b = (abgr >> 16) & 0xFF;
u8 a = (abgr >> 24) & 0xFF;
return ((u32)r << 24) | ((u32)g << 16) | ((u32)b << 8) | a;
}
static inline u8 pxl8_rgb332_pack(u8 r, u8 g, u8 b) {
return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
}
@ -69,3 +75,34 @@ static inline void pxl8_rgb332_unpack(u8 c, u8* r, u8* g, u8* b) {
*g = (gi << 5) | (gi << 2) | (gi >> 1);
*b = (bi << 6) | (bi << 4) | (bi << 2) | bi;
}
static inline u16 pxl8_rgb565_pack(u8 r, u8 g, u8 b) {
return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
}
static inline void pxl8_rgb565_unpack(u16 color, u8* r, u8* g, u8* b) {
*r = (color >> 11) << 3;
*g = ((color >> 5) & 0x3F) << 2;
*b = (color & 0x1F) << 3;
}
static inline u32 pxl8_rgb565_to_rgba32(u16 color) {
u8 r, g, b;
pxl8_rgb565_unpack(color, &r, &g, &b);
return r | ((u32)g << 8) | ((u32)b << 16) | 0xFF000000;
}
static inline u32 pxl8_rgba32_pack(u8 r, u8 g, u8 b, u8 a) {
return r | ((u32)g << 8) | ((u32)b << 16) | ((u32)a << 24);
}
static inline u16 pxl8_rgba32_to_rgb565(u32 rgba) {
return pxl8_rgb565_pack(rgba & 0xFF, (rgba >> 8) & 0xFF, (rgba >> 16) & 0xFF);
}
static inline void pxl8_rgba32_unpack(u32 color, u8* r, u8* g, u8* b, u8* a) {
*r = color & 0xFF;
*g = (color >> 8) & 0xFF;
*b = (color >> 16) & 0xFF;
*a = (color >> 24) & 0xFF;
}

File diff suppressed because it is too large Load diff

View file

@ -58,7 +58,9 @@ void pxl8_cpu_draw_mesh(
);
u8* pxl8_cpu_get_framebuffer(pxl8_cpu_backend* cpu);
u32* pxl8_cpu_get_light_accum(pxl8_cpu_backend* cpu);
u32* pxl8_cpu_get_output(pxl8_cpu_backend* cpu);
u16* pxl8_cpu_get_zbuffer(pxl8_cpu_backend* cpu);
u32 pxl8_cpu_get_height(const pxl8_cpu_backend* cpu);
u32 pxl8_cpu_get_width(const pxl8_cpu_backend* cpu);

View file

@ -27,6 +27,7 @@ typedef struct pxl8_sprite_cache_entry {
struct pxl8_gfx {
pxl8_atlas* atlas;
pxl8_gfx_backend backend;
const pxl8_bsp* bsp;
pxl8_colormap* colormap;
u8* framebuffer;
i32 framebuffer_height;
@ -38,6 +39,7 @@ struct pxl8_gfx {
pxl8_palette_cube* palette_cube;
pxl8_pixel_mode pixel_mode;
void* platform_data;
const pxl8_sdf* sdf;
pxl8_sprite_cache_entry* sprite_cache;
u32 sprite_cache_capacity;
u32 sprite_cache_count;
@ -61,6 +63,9 @@ pxl8_pixel_mode pxl8_gfx_get_pixel_mode(pxl8_gfx* gfx) {
u8* pxl8_gfx_get_framebuffer_indexed(pxl8_gfx* gfx) {
if (!gfx || gfx->pixel_mode == PXL8_PIXEL_HICOLOR) return NULL;
if (gfx->backend.type == PXL8_GFX_BACKEND_CPU) {
return pxl8_cpu_get_framebuffer(gfx->backend.cpu);
}
return gfx->framebuffer;
}
@ -73,6 +78,27 @@ i32 pxl8_gfx_get_height(const pxl8_gfx* gfx) {
return gfx ? gfx->framebuffer_height : 0;
}
u32* pxl8_gfx_get_light_accum(pxl8_gfx* gfx) {
if (!gfx) return NULL;
if (gfx->backend.type == PXL8_GFX_BACKEND_CPU) {
return pxl8_cpu_get_light_accum(gfx->backend.cpu);
}
return NULL;
}
const u32* pxl8_gfx_palette_colors(pxl8_gfx* gfx) {
if (!gfx || !gfx->palette) return NULL;
return pxl8_palette_colors(gfx->palette);
}
u16* pxl8_gfx_get_zbuffer(pxl8_gfx* gfx) {
if (!gfx) return NULL;
if (gfx->backend.type == PXL8_GFX_BACKEND_CPU) {
return pxl8_cpu_get_zbuffer(gfx->backend.cpu);
}
return NULL;
}
i32 pxl8_gfx_get_width(const pxl8_gfx* gfx) {
return gfx ? gfx->framebuffer_width : 0;
}
@ -608,12 +634,24 @@ pxl8_3d_frame pxl8_3d_frame_from_camera(const pxl8_3d_camera* camera, const pxl8
return frame;
}
void pxl8_3d_set_bsp(pxl8_gfx* gfx, const pxl8_bsp* bsp) {
if (!gfx) return;
gfx->bsp = bsp;
}
void pxl8_3d_set_sdf(pxl8_gfx* gfx, const pxl8_sdf* sdf) {
if (!gfx) return;
gfx->sdf = sdf;
}
void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_lights* lights, const pxl8_3d_uniforms* uniforms) {
if (!gfx || !camera) return;
pxl8_3d_frame frame = pxl8_3d_frame_from_camera(camera, uniforms);
frame.bsp = gfx->bsp;
frame.lights = lights ? pxl8_lights_data(lights) : NULL;
frame.lights_count = lights ? pxl8_lights_count(lights) : 0;
frame.sdf = gfx->sdf;
pxl8_mat4 vp = pxl8_mat4_multiply(frame.projection, frame.view);

View file

@ -32,6 +32,9 @@ pxl8_bounds pxl8_gfx_get_bounds(pxl8_gfx* gfx);
u8* pxl8_gfx_get_framebuffer_indexed(pxl8_gfx* gfx);
u16* pxl8_gfx_get_framebuffer_hicolor(pxl8_gfx* gfx);
i32 pxl8_gfx_get_height(const pxl8_gfx* gfx);
u32* pxl8_gfx_get_light_accum(pxl8_gfx* gfx);
const u32* pxl8_gfx_palette_colors(pxl8_gfx* gfx);
u16* pxl8_gfx_get_zbuffer(pxl8_gfx* gfx);
pxl8_palette* pxl8_gfx_palette(pxl8_gfx* gfx);
pxl8_colormap* pxl8_gfx_colormap(pxl8_gfx* gfx);
pxl8_pixel_mode pxl8_gfx_get_pixel_mode(pxl8_gfx* gfx);

View file

@ -6,6 +6,7 @@
#include "pxl8_mesh.h"
#include "pxl8_types.h"
typedef struct pxl8_bsp pxl8_bsp;
typedef struct pxl8_gfx pxl8_gfx;
typedef struct pxl8_3d_uniforms {
@ -17,7 +18,16 @@ typedef struct pxl8_3d_uniforms {
f32 time;
} pxl8_3d_uniforms;
typedef struct pxl8_3d_frame_desc {
const pxl8_bsp* bsp;
const pxl8_3d_camera* camera;
const pxl8_lights* lights;
const pxl8_sdf* sdf;
pxl8_3d_uniforms uniforms;
} pxl8_3d_frame_desc;
typedef struct pxl8_3d_frame {
const pxl8_bsp* bsp;
pxl8_vec3 camera_dir;
pxl8_vec3 camera_pos;
f32 far_clip;
@ -25,6 +35,7 @@ typedef struct pxl8_3d_frame {
u32 lights_count;
f32 near_clip;
pxl8_mat4 projection;
const pxl8_sdf* sdf;
pxl8_3d_uniforms uniforms;
pxl8_mat4 view;
} pxl8_3d_frame;
@ -33,6 +44,8 @@ typedef struct pxl8_3d_frame {
extern "C" {
#endif
void pxl8_3d_set_bsp(pxl8_gfx* gfx, const pxl8_bsp* bsp);
void pxl8_3d_set_sdf(pxl8_gfx* gfx, const pxl8_sdf* sdf);
void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_lights* lights, const pxl8_3d_uniforms* uniforms);
void pxl8_3d_clear(pxl8_gfx* gfx, u8 color);
void pxl8_3d_clear_depth(pxl8_gfx* gfx);