improve lighting system

This commit is contained in:
asrael 2026-01-23 12:09:35 -06:00
parent 27c6fa628d
commit f18652dc97
15 changed files with 193 additions and 119 deletions

View file

@ -50,6 +50,7 @@
(var fps-sample-count 0) (var fps-sample-count 0)
(var fireball-mesh nil) (var fireball-mesh nil)
(var last-dt 0.016) (var last-dt 0.016)
(var lights nil)
(local cursor-look? true) (local cursor-look? true)
(local FIREBALL_COLOR 218) (local FIREBALL_COLOR 218)
@ -248,6 +249,7 @@
(pxl8.update_palette_deps) (pxl8.update_palette_deps)
(set camera (pxl8.create_camera_3d)) (set camera (pxl8.create_camera_3d))
(set world (pxl8.create_world)) (set world (pxl8.create_world))
(set lights (pxl8.create_lights))
(sky.generate-stars 12345) (sky.generate-stars 12345)
(create-fireball-mesh) (create-fireball-mesh)
@ -469,15 +471,13 @@
r1 (* 0.06 (math.sin (+ (* real-time 1.8) (* phase 0.5)))) r1 (* 0.06 (math.sin (+ (* real-time 1.8) (* phase 0.5))))
r2 (* 0.04 (math.sin (+ (* real-time 3.2) phase))) r2 (* 0.04 (math.sin (+ (* real-time 3.2) phase)))
light-radius (* 150 (+ 0.95 r1 r2))] light-radius (* 150 (+ 0.95 r1 r2))]
(pxl8.begin_frame_3d camera { (lights:clear)
(lights:add light-x light-y light-z 255 200 150 light-intensity light-radius)
(pxl8.begin_frame_3d camera lights {
:ambient 30 :ambient 30
:fog_density 0.0 :fog_density 0.0
:celestial_dir [0.5 -0.8 0.3] :celestial_dir [0.5 -0.8 0.3]
:celestial_intensity 0.5 :celestial_intensity 0.5})
:lights [{:x light-x :y light-y :z light-z
:r 255 :g 200 :b 150
:intensity light-intensity
:radius light-radius}]})
(pxl8.clear_depth) (pxl8.clear_depth)
(sky.update-gradient 1 2 6 6 10 18) (sky.update-gradient 1 2 6 6 10 18)

View file

@ -397,6 +397,7 @@ case "$COMMAND" in
src/gfx/pxl8_gfx.c src/gfx/pxl8_gfx.c
src/gfx/pxl8_glows.c src/gfx/pxl8_glows.c
src/gfx/pxl8_lightmap.c src/gfx/pxl8_lightmap.c
src/gfx/pxl8_lights.c
src/gfx/pxl8_mesh.c src/gfx/pxl8_mesh.c
src/gfx/pxl8_palette.c src/gfx/pxl8_palette.c
src/gfx/pxl8_particles.c src/gfx/pxl8_particles.c

View file

@ -71,8 +71,8 @@ static pxl8_light_result calc_vertex_light(
if (sky_factor < 0.0f) sky_factor = 0.0f; if (sky_factor < 0.0f) sky_factor = 0.0f;
intensity += sky_factor * frame->uniforms.celestial_intensity * 0.3f; intensity += sky_factor * frame->uniforms.celestial_intensity * 0.3f;
for (u32 i = 0; i < frame->uniforms.num_lights; i++) { for (u32 i = 0; i < frame->lights_count; i++) {
const pxl8_light* light = &frame->uniforms.lights[i]; const pxl8_light* light = &frame->lights[i];
f32 contrib = calc_light_intensity(light, world_pos, normal); f32 contrib = calc_light_intensity(light, world_pos, normal);
if (contrib > 0.0f) { if (contrib > 0.0f) {
intensity += contrib; intensity += contrib;
@ -1329,7 +1329,7 @@ u32* pxl8_cpu_get_output(pxl8_cpu_backend* cpu) {
void pxl8_cpu_render_glows( void pxl8_cpu_render_glows(
pxl8_cpu_backend* cpu, pxl8_cpu_backend* cpu,
const pxl8_glow_source* glows, const pxl8_glow* glows,
u32 glow_count u32 glow_count
) { ) {
if (!cpu || cpu->target_stack_depth == 0) return; if (!cpu || cpu->target_stack_depth == 0) return;
@ -1344,7 +1344,7 @@ void pxl8_cpu_render_glows(
u32* light_accum = target->light_accum; u32* light_accum = target->light_accum;
for (u32 gi = 0; gi < glow_count; gi++) { for (u32 gi = 0; gi < glow_count; gi++) {
const pxl8_glow_source* glow = &glows[gi]; const pxl8_glow* glow = &glows[gi];
i32 cx = glow->x; i32 cx = glow->x;
i32 cy = glow->y; i32 cy = glow->y;
i32 radius = glow->radius; i32 radius = glow->radius;

View file

@ -64,7 +64,7 @@ u32 pxl8_cpu_get_width(const pxl8_cpu_backend* cpu);
void pxl8_cpu_render_glows( void pxl8_cpu_render_glows(
pxl8_cpu_backend* cpu, pxl8_cpu_backend* cpu,
const pxl8_glow_source* glows, const pxl8_glow* glows,
u32 glow_count u32 glow_count
); );

View file

@ -607,10 +607,12 @@ pxl8_3d_frame pxl8_3d_frame_from_camera(const pxl8_3d_camera* camera, const pxl8
return frame; return frame;
} }
void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms) { 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; if (!gfx || !camera) return;
pxl8_3d_frame frame = pxl8_3d_frame_from_camera(camera, uniforms); pxl8_3d_frame frame = pxl8_3d_frame_from_camera(camera, uniforms);
frame.lights = lights ? pxl8_lights_data(lights) : NULL;
frame.lights_count = lights ? pxl8_lights_count(lights) : 0;
pxl8_mat4 vp = pxl8_mat4_multiply(frame.projection, frame.view); pxl8_mat4 vp = pxl8_mat4_multiply(frame.projection, frame.view);
@ -802,7 +804,7 @@ void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* pa
switch (effect) { switch (effect) {
case PXL8_GFX_EFFECT_GLOWS: { case PXL8_GFX_EFFECT_GLOWS: {
const pxl8_glow_source* glows = (const pxl8_glow_source*)params; const pxl8_glow* glows = (const pxl8_glow*)params;
switch (gfx->backend.type) { switch (gfx->backend.type) {
case PXL8_GFX_BACKEND_CPU: case PXL8_GFX_BACKEND_CPU:
pxl8_cpu_render_glows(gfx->backend.cpu, glows, count); pxl8_cpu_render_glows(gfx->backend.cpu, glows, count);

View file

@ -2,6 +2,7 @@
#include "pxl8_gfx2d.h" #include "pxl8_gfx2d.h"
#include "pxl8_gfx3d.h" #include "pxl8_gfx3d.h"
#include "pxl8_glows.h"
#include "pxl8_hal.h" #include "pxl8_hal.h"
#include "pxl8_colormap.h" #include "pxl8_colormap.h"
#include "pxl8_palette.h" #include "pxl8_palette.h"
@ -14,53 +15,6 @@ typedef enum pxl8_gfx_effect {
PXL8_GFX_EFFECT_GLOWS = 0, PXL8_GFX_EFFECT_GLOWS = 0,
} pxl8_gfx_effect; } pxl8_gfx_effect;
#define PXL8_MAX_GLOWS 256
typedef enum pxl8_glow_shape {
PXL8_GLOW_CIRCLE = 0,
PXL8_GLOW_DIAMOND = 1,
PXL8_GLOW_SHAFT = 2,
} pxl8_glow_shape;
typedef struct pxl8_glow_source {
u8 color;
u16 depth;
u8 height;
u16 intensity;
u8 radius;
pxl8_glow_shape shape;
i16 x;
i16 y;
} pxl8_glow_source;
static inline pxl8_glow_source pxl8_glow_create(i32 x, i32 y, u8 radius, u16 intensity, u8 color) {
return (pxl8_glow_source){
.color = color,
.depth = 0xFFFF,
.height = 0,
.intensity = intensity,
.radius = radius,
.shape = PXL8_GLOW_CIRCLE,
.x = (i16)x,
.y = (i16)y,
};
}
static inline pxl8_glow_source pxl8_glow_with_depth(pxl8_glow_source g, u16 depth) {
g.depth = depth;
return g;
}
static inline pxl8_glow_source pxl8_glow_with_shape(pxl8_glow_source g, pxl8_glow_shape shape) {
g.shape = shape;
return g;
}
static inline pxl8_glow_source pxl8_glow_with_height(pxl8_glow_source g, u8 height) {
g.height = height;
return g;
}
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View file

@ -1,53 +1,31 @@
#pragma once #pragma once
#include "pxl8_3d_camera.h" #include "pxl8_3d_camera.h"
#include "pxl8_lights.h"
#include "pxl8_math.h" #include "pxl8_math.h"
#include "pxl8_mesh.h" #include "pxl8_mesh.h"
#include "pxl8_types.h" #include "pxl8_types.h"
typedef struct pxl8_gfx pxl8_gfx; typedef struct pxl8_gfx pxl8_gfx;
#define PXL8_MAX_LIGHTS 16
typedef struct pxl8_light {
pxl8_vec3 position;
u8 r, g, b;
u8 intensity;
f32 radius;
f32 radius_sq;
f32 inv_radius_sq;
} pxl8_light;
static inline pxl8_light pxl8_light_create(pxl8_vec3 pos, u8 r, u8 g, u8 b, u8 intensity, f32 radius) {
f32 radius_sq = radius * radius;
return (pxl8_light){
.position = pos,
.r = r, .g = g, .b = b,
.intensity = intensity,
.radius = radius,
.radius_sq = radius_sq,
.inv_radius_sq = radius_sq > 0.0f ? 1.0f / radius_sq : 0.0f,
};
}
typedef struct pxl8_3d_uniforms { typedef struct pxl8_3d_uniforms {
u8 ambient; u8 ambient;
pxl8_vec3 celestial_dir; pxl8_vec3 celestial_dir;
f32 celestial_intensity; f32 celestial_intensity;
u8 fog_color; u8 fog_color;
f32 fog_density; f32 fog_density;
pxl8_light lights[PXL8_MAX_LIGHTS];
u32 num_lights;
f32 time; f32 time;
} pxl8_3d_uniforms; } pxl8_3d_uniforms;
typedef struct pxl8_3d_frame { typedef struct pxl8_3d_frame {
pxl8_3d_uniforms uniforms;
pxl8_vec3 camera_dir; pxl8_vec3 camera_dir;
pxl8_vec3 camera_pos; pxl8_vec3 camera_pos;
f32 far_clip; f32 far_clip;
const pxl8_light* lights;
u32 lights_count;
f32 near_clip; f32 near_clip;
pxl8_mat4 projection; pxl8_mat4 projection;
pxl8_3d_uniforms uniforms;
pxl8_mat4 view; pxl8_mat4 view;
} pxl8_3d_frame; } pxl8_3d_frame;
@ -55,7 +33,7 @@ typedef struct pxl8_3d_frame {
extern "C" { extern "C" {
#endif #endif
void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms); 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(pxl8_gfx* gfx, u8 color);
void pxl8_3d_clear_depth(pxl8_gfx* gfx); void pxl8_3d_clear_depth(pxl8_gfx* gfx);
void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color); void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 v0, pxl8_vec3 v1, u8 color);

View file

@ -1,9 +1,11 @@
#include "pxl8_glows.h" #include "pxl8_glows.h"
#include "pxl8_gfx.h"
#include <stdlib.h> #include <stdlib.h>
struct pxl8_glows { struct pxl8_glows {
pxl8_glow_source* data; pxl8_glow* data;
u32 capacity; u32 capacity;
u32 count; u32 count;
}; };
@ -12,7 +14,7 @@ pxl8_glows* pxl8_glows_create(u32 capacity) {
pxl8_glows* glows = calloc(1, sizeof(pxl8_glows)); pxl8_glows* glows = calloc(1, sizeof(pxl8_glows));
if (!glows) return NULL; if (!glows) return NULL;
glows->data = calloc(capacity, sizeof(pxl8_glow_source)); glows->data = calloc(capacity, sizeof(pxl8_glow));
if (!glows->data) { if (!glows->data) {
free(glows); free(glows);
return NULL; return NULL;
@ -33,7 +35,7 @@ void pxl8_glows_destroy(pxl8_glows* glows) {
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape) { void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape) {
if (!glows || glows->count >= glows->capacity) return; if (!glows || glows->count >= glows->capacity) return;
pxl8_glow_source* g = &glows->data[glows->count++]; pxl8_glow* g = &glows->data[glows->count++];
g->x = x; g->x = x;
g->y = y; g->y = y;
g->radius = radius; g->radius = radius;

View file

@ -1,8 +1,27 @@
#pragma once #pragma once
#include "pxl8_gfx.h"
#include "pxl8_types.h" #include "pxl8_types.h"
#define PXL8_GLOWS_MAX 16384
typedef enum pxl8_glow_shape {
PXL8_GLOW_CIRCLE = 0,
PXL8_GLOW_DIAMOND = 1,
PXL8_GLOW_SHAFT = 2,
} pxl8_glow_shape;
typedef struct pxl8_glow {
u8 color;
u16 depth;
u8 height;
u16 intensity;
u8 radius;
pxl8_glow_shape shape;
i16 x;
i16 y;
} pxl8_glow;
typedef struct pxl8_gfx pxl8_gfx;
typedef struct pxl8_glows pxl8_glows; typedef struct pxl8_glows pxl8_glows;
#ifdef __cplusplus #ifdef __cplusplus
@ -15,6 +34,7 @@ void pxl8_glows_destroy(pxl8_glows* glows);
void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape); void pxl8_glows_add(pxl8_glows* glows, i16 x, i16 y, u8 radius, u16 intensity, u8 color, u8 shape);
void pxl8_glows_clear(pxl8_glows* glows); void pxl8_glows_clear(pxl8_glows* glows);
u32 pxl8_glows_count(const pxl8_glows* glows); u32 pxl8_glows_count(const pxl8_glows* glows);
const pxl8_glow* pxl8_glows_data(const pxl8_glows* glows);
void pxl8_glows_render(pxl8_glows* glows, pxl8_gfx* gfx); void pxl8_glows_render(pxl8_glows* glows, pxl8_gfx* gfx);
#ifdef __cplusplus #ifdef __cplusplus

63
src/gfx/pxl8_lights.c Normal file
View file

@ -0,0 +1,63 @@
#include "pxl8_lights.h"
#include <stdlib.h>
struct pxl8_lights {
pxl8_light* data;
u32 capacity;
u32 count;
};
pxl8_lights* pxl8_lights_create(u32 capacity) {
if (capacity > PXL8_LIGHTS_MAX) capacity = PXL8_LIGHTS_MAX;
pxl8_lights* lights = calloc(1, sizeof(pxl8_lights));
if (!lights) return NULL;
lights->data = calloc(capacity, sizeof(pxl8_light));
if (!lights->data) {
free(lights);
return NULL;
}
lights->capacity = capacity;
lights->count = 0;
return lights;
}
void pxl8_lights_destroy(pxl8_lights* lights) {
if (!lights) return;
free(lights->data);
free(lights);
}
void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, u8 intensity, f32 radius) {
if (!lights || lights->count >= lights->capacity) return;
f32 radius_sq = radius * radius;
pxl8_light* l = &lights->data[lights->count++];
l->position.x = x;
l->position.y = y;
l->position.z = z;
l->r = r;
l->g = g;
l->b = b;
l->intensity = intensity;
l->radius = radius;
l->radius_sq = radius_sq;
l->inv_radius_sq = radius_sq > 0.0f ? 1.0f / radius_sq : 0.0f;
}
void pxl8_lights_clear(pxl8_lights* lights) {
if (!lights) return;
lights->count = 0;
}
u32 pxl8_lights_count(const pxl8_lights* lights) {
return lights ? lights->count : 0;
}
const pxl8_light* pxl8_lights_data(const pxl8_lights* lights) {
return lights ? lights->data : NULL;
}

33
src/gfx/pxl8_lights.h Normal file
View file

@ -0,0 +1,33 @@
#pragma once
#include "pxl8_math.h"
#include "pxl8_types.h"
#define PXL8_LIGHTS_MAX 256
typedef struct pxl8_light {
pxl8_vec3 position;
f32 inv_radius_sq;
u8 r, g, b;
u8 intensity;
f32 radius;
f32 radius_sq;
} pxl8_light;
typedef struct pxl8_lights pxl8_lights;
#ifdef __cplusplus
extern "C" {
#endif
pxl8_lights* pxl8_lights_create(u32 capacity);
void pxl8_lights_destroy(pxl8_lights* lights);
void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, u8 intensity, f32 radius);
void pxl8_lights_clear(pxl8_lights* lights);
u32 pxl8_lights_count(const pxl8_lights* lights);
const pxl8_light* pxl8_lights_data(const pxl8_lights* lights);
#ifdef __cplusplus
}
#endif

View file

@ -104,6 +104,8 @@ pxl8.GLOW_DIAMOND = effects.GLOW_DIAMOND
pxl8.GLOW_SHAFT = effects.GLOW_SHAFT pxl8.GLOW_SHAFT = effects.GLOW_SHAFT
pxl8.Glows = effects.Glows pxl8.Glows = effects.Glows
pxl8.create_glows = effects.Glows.new pxl8.create_glows = effects.Glows.new
pxl8.Lights = effects.Lights
pxl8.create_lights = effects.Lights.new
pxl8.Compressor = sfx.Compressor pxl8.Compressor = sfx.Compressor
pxl8.create_compressor = sfx.Compressor.new pxl8.create_compressor = sfx.Compressor.new

View file

@ -44,4 +44,36 @@ end
effects.Glows = Glows effects.Glows = Glows
local Lights = {}
Lights.__index = Lights
function Lights.new(capacity)
local ptr = C.pxl8_lights_create(capacity or 256)
if ptr == nil then
return nil
end
return setmetatable({ _ptr = ptr }, Lights)
end
function Lights:add(x, y, z, r, g, b, intensity, radius)
C.pxl8_lights_add(self._ptr, x, y, z, r or 255, g or 255, b or 255, intensity or 255, radius or 10)
end
function Lights:clear()
C.pxl8_lights_clear(self._ptr)
end
function Lights:count()
return C.pxl8_lights_count(self._ptr)
end
function Lights:destroy()
if self._ptr then
C.pxl8_lights_destroy(self._ptr)
self._ptr = nil
end
end
effects.Lights = Lights
return effects return effects

View file

@ -155,7 +155,7 @@ function gfx3d.draw_mesh(mesh, opts)
C.pxl8_3d_draw_mesh(core.gfx, mesh._ptr, model, material) C.pxl8_3d_draw_mesh(core.gfx, mesh._ptr, model, material)
end end
function gfx3d.begin_frame(camera, uniforms) function gfx3d.begin_frame(camera, lights, uniforms)
uniforms = uniforms or {} uniforms = uniforms or {}
local u = ffi.new("pxl8_3d_uniforms") local u = ffi.new("pxl8_3d_uniforms")
@ -175,27 +175,8 @@ function gfx3d.begin_frame(camera, uniforms)
end end
u.celestial_intensity = uniforms.celestial_intensity or 0.0 u.celestial_intensity = uniforms.celestial_intensity or 0.0
u.num_lights = 0 local lights_ptr = lights and lights._ptr or nil
if uniforms.lights then C.pxl8_3d_begin_frame(core.gfx, camera._ptr, lights_ptr, u)
for i, light in ipairs(uniforms.lights) do
if i > 16 then break end
local idx = i - 1
u.lights[idx].position.x = light.x or 0
u.lights[idx].position.y = light.y or 0
u.lights[idx].position.z = light.z or 0
u.lights[idx].r = light.r or 255
u.lights[idx].g = light.g or 255
u.lights[idx].b = light.b or 255
u.lights[idx].intensity = light.intensity or 255
u.lights[idx].radius = light.radius or 100
local radius_sq = u.lights[idx].radius * u.lights[idx].radius
u.lights[idx].radius_sq = radius_sq
u.lights[idx].inv_radius_sq = radius_sq > 0 and (1.0 / radius_sq) or 0
u.num_lights = i
end
end
C.pxl8_3d_begin_frame(core.gfx, camera._ptr, u)
end end
function gfx3d.clear(color) function gfx3d.clear(color)

View file

@ -197,21 +197,27 @@ static const char* pxl8_ffi_cdefs =
"\n" "\n"
"typedef struct pxl8_light {\n" "typedef struct pxl8_light {\n"
" pxl8_vec3 position;\n" " pxl8_vec3 position;\n"
" f32 inv_radius_sq;\n"
" u8 r, g, b;\n" " u8 r, g, b;\n"
" u8 intensity;\n" " u8 intensity;\n"
" f32 radius;\n" " f32 radius;\n"
" f32 radius_sq;\n" " f32 radius_sq;\n"
" f32 inv_radius_sq;\n"
"} pxl8_light;\n" "} pxl8_light;\n"
"\n" "\n"
"typedef struct pxl8_lights pxl8_lights;\n"
"pxl8_lights* pxl8_lights_create(u32 capacity);\n"
"void pxl8_lights_destroy(pxl8_lights* lights);\n"
"void pxl8_lights_add(pxl8_lights* lights, f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, u8 intensity, f32 radius);\n"
"void pxl8_lights_clear(pxl8_lights* lights);\n"
"u32 pxl8_lights_count(const pxl8_lights* lights);\n"
"const pxl8_light* pxl8_lights_data(const pxl8_lights* lights);\n"
"\n"
"typedef struct pxl8_3d_uniforms {\n" "typedef struct pxl8_3d_uniforms {\n"
" u8 ambient;\n" " u8 ambient;\n"
" pxl8_vec3 celestial_dir;\n" " pxl8_vec3 celestial_dir;\n"
" f32 celestial_intensity;\n" " f32 celestial_intensity;\n"
" u8 fog_color;\n" " u8 fog_color;\n"
" f32 fog_density;\n" " f32 fog_density;\n"
" pxl8_light lights[16];\n"
" u32 num_lights;\n"
" f32 time;\n" " f32 time;\n"
"} pxl8_3d_uniforms;\n" "} pxl8_3d_uniforms;\n"
"\n" "\n"
@ -236,7 +242,7 @@ static const char* pxl8_ffi_cdefs =
"\n" "\n"
"typedef enum pxl8_glow_shape { PXL8_GLOW_CIRCLE = 0, PXL8_GLOW_DIAMOND = 1, PXL8_GLOW_SHAFT = 2 } pxl8_glow_shape;\n" "typedef enum pxl8_glow_shape { PXL8_GLOW_CIRCLE = 0, PXL8_GLOW_DIAMOND = 1, PXL8_GLOW_SHAFT = 2 } pxl8_glow_shape;\n"
"\n" "\n"
"typedef struct pxl8_glow_source {\n" "typedef struct pxl8_glow {\n"
" u8 color;\n" " u8 color;\n"
" u16 depth;\n" " u16 depth;\n"
" u8 height;\n" " u8 height;\n"
@ -245,7 +251,7 @@ static const char* pxl8_ffi_cdefs =
" pxl8_glow_shape shape;\n" " pxl8_glow_shape shape;\n"
" i16 x;\n" " i16 x;\n"
" i16 y;\n" " i16 y;\n"
"} pxl8_glow_source;\n" "} pxl8_glow;\n"
"\n" "\n"
"void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count);\n" "void pxl8_gfx_apply_effect(pxl8_gfx* gfx, pxl8_gfx_effect effect, const void* params, u32 count);\n"
"void pxl8_gfx_blend_tables_update(pxl8_gfx* gfx);\n" "void pxl8_gfx_blend_tables_update(pxl8_gfx* gfx);\n"
@ -259,7 +265,7 @@ static const char* pxl8_ffi_cdefs =
"void pxl8_glows_render(pxl8_glows* glows, pxl8_gfx* gfx);\n" "void pxl8_glows_render(pxl8_glows* glows, pxl8_gfx* gfx);\n"
"void pxl8_gfx_colormap_update(pxl8_gfx* gfx);\n" "void pxl8_gfx_colormap_update(pxl8_gfx* gfx);\n"
"\n" "\n"
"void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_3d_uniforms* uniforms);\n" "void pxl8_3d_begin_frame(pxl8_gfx* gfx, const pxl8_3d_camera* camera, const pxl8_lights* lights, const pxl8_3d_uniforms* uniforms);\n"
"void pxl8_3d_clear(pxl8_gfx* gfx, u8 color);\n" "void pxl8_3d_clear(pxl8_gfx* gfx, u8 color);\n"
"void pxl8_3d_clear_depth(pxl8_gfx* gfx);\n" "void pxl8_3d_clear_depth(pxl8_gfx* gfx);\n"
"void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 p0, pxl8_vec3 p1, u8 color);\n" "void pxl8_3d_draw_line(pxl8_gfx* gfx, pxl8_vec3 p0, pxl8_vec3 p1, u8 color);\n"