Jo Engine 2026.11.1
Jo Sega Saturn Engine
Loading...
Searching...
No Matches
light.h File Reference

Jo Engine point lights: light sources (a position, a color, a radius, a strength; all around like a bulb or in a cone like a torch) that light the static meshes (in world coordinates: the rooms of the cells, the buildings...) through their gouraud tables (no sprite: the colors of the corners of the polygons). More...

Go to the source code of this file.

Macros

#define JO_MAX_POINT_LIGHTS
 Point lights at most.
#define JO_MAX_POINT_LIGHT_MESHES
 Meshes lit by the point lights at most.
#define JO_POINT_LIGHT_STRENGTH_DEFAULT
 Strength of a light that doubles the color of a polygon in front of it (gouraud: 16 is the color of the texture, a light of this strength adds 16).

Functions

int jo_3d_point_light_add (const jo_pos3D_fixed *const position, const unsigned char r, const unsigned char g, const unsigned char b, const int radius, const int strength)
 Add a point light.
void jo_3d_point_light_set_intensity (const int id, const int intensity)
 Intensity of a light (a flicker, a pulse: cheap).
void jo_3d_point_light_set_color (const int id, const unsigned char r, const unsigned char g, const unsigned char b)
 Color of a light (cheap).
void jo_3d_point_light_set_position (const int id, const jo_pos3D_fixed *const position)
 Move a light (its light is computed again on all the meshes: costly).
void jo_3d_point_light_set_spot (const int id, const jo_pos3D_fixed *const direction, const int angle)
 A spot light (a torch, a lamp with a shade): the light goes in a cone; or all around (a bulb, the default).
void jo_3d_point_light_set_shadows (const int id, const bool shadows)
 Shadows of a light (on by default when jo_3d_point_lights_set_occlusion() is set): off for a light that moves at each frame (a muzzle flash, an explosion): its light is computed again faster (no ray).
void jo_3d_point_light_set_sampled (const int id, const bool sampled)
 Light of a light seen by jo_3d_point_lights_sample() (the objects, the weapon of the player): on by default; off for a light that is only a sheen on the walls (a torch on the camera would light the weapon in front of it).
void jo_3d_point_light_enable (const int id, const bool enabled)
 Switch a light on or off (cheap).
void jo_3d_point_lights_enable (const bool enabled)
 The point lights on or off (off: the meshes get their colors back).
bool jo_3d_point_lights_add_mesh (jo_3d_mesh *const mesh)
 Add a mesh lit by the point lights: its points in world coordinates (a mesh drawn without a matrix of its own), its polygons with gouraud tables (JO_VDP1_COLOR_CALC_GOURAUD). Its gouraud tables are read now: their colors are kept.
void jo_3d_point_lights_set_mesh_seen (const jo_3d_mesh *const mesh, const bool seen)
 A mesh is seen or not in this frame (for instance the cells drawn, see jo_cells_prepare()): the light changes of the meshes not seen are applied when they are seen again (a light that pulses costs nothing in the rooms not seen).
void jo_3d_point_lights_set_occlusion (bool(*hit)(const jo_pos3D_fixed *const origin, const jo_pos3D_fixed *const dir, const jo_fixed max_t))
 Shadows: a function that tells if a ray hits a wall (for instance the walls of the cells, see jo_cells_add_point_light_meshes()), JO_NULL: no shadow.
void jo_3d_point_lights_update (void)
 Write the gouraud tables changed by the lights (computes the light of the lights added or moved first): once per frame, before the meshes are drawn.
void jo_3d_point_lights_sample (const jo_pos3D_fixed *const position, int *const r, int *const g, int *const b)
 The light of the lights at a point (for an object that moves: a character, a weapon, see jo_3d_set_tint()).
void jo_3d_point_lights_clear (void)
 Remove the lights and the meshes (the gouraud tables get their colors back): before the meshes are freed.

Detailed Description

Jo Engine point lights: light sources (a position, a color, a radius, a strength; all around like a bulb or in a cone like a torch) that light the static meshes (in world coordinates: the rooms of the cells, the buildings...) through their gouraud tables (no sprite: the colors of the corners of the polygons).

Author
Johannes Fetz
  • The light of a source on a corner of a polygon: strength x facing x radius^2 / (radius^2 + distance^2) (facing: the face turned toward the light, both sides), up to 4 x radius. With shadows (jo_3d_point_lights_set_occlusion()), a ray from the light to the corner: a wall between them stops it (the light goes through the doors)
  • The light is computed once for each corner (when a light or a mesh is added, or a light moves); a change of the intensity, of the color or a light switched on or off only writes the gouraud tables of the polygons it lights: a light can flicker or pulse at each frame for little CPU time
  • The gouraud tables of the meshes keep their colors (the light baked in them): the lights are added to them
  • Only the changes are computed (the difference of the light of a light on its polygons), only on the meshes seen; the tables are written in a copy in the work RAM, copied into the VRAM by the DMA controller (the CPU waits a long time for the VRAM of the VDP1 while it draws)
  • Usage: jo_3d_point_lights_add_mesh() for each mesh (or jo_cells_add_point_light_meshes()), jo_3d_point_light_add() for each light, then jo_3d_point_lights_update() at each frame. jo_3d_point_lights_clear() before the meshes are freed
  • Option: jo_3d_point_lights_enable(false) gives the meshes their colors back (no point light)

Macro Definition Documentation

◆ JO_MAX_POINT_LIGHT_MESHES

#define JO_MAX_POINT_LIGHT_MESHES

Meshes lit by the point lights at most.

◆ JO_MAX_POINT_LIGHTS

#define JO_MAX_POINT_LIGHTS

Point lights at most.

◆ JO_POINT_LIGHT_STRENGTH_DEFAULT

#define JO_POINT_LIGHT_STRENGTH_DEFAULT

Strength of a light that doubles the color of a polygon in front of it (gouraud: 16 is the color of the texture, a light of this strength adds 16).

Function Documentation

◆ jo_3d_point_light_add()

int jo_3d_point_light_add ( const jo_pos3D_fixed *const position,
const unsigned char r,
const unsigned char g,
const unsigned char b,
const int radius,
const int strength )

Add a point light.

Parameters
positionPosition (world, Q16.16)
rRed (0 to 255)
gGreen (0 to 255)
bBlue (0 to 255)
radiusDistance where the light is half of its strength (world units); it stops at 4 x radius
strengthLight in front of it (JO_POINT_LIGHT_STRENGTH_DEFAULT: the color doubled)
Returns
Id of the light, -1 if there are too many lights

◆ jo_3d_point_light_enable()

void jo_3d_point_light_enable ( const int id,
const bool enabled )

Switch a light on or off (cheap).

Parameters
idId of the light
enabledtrue: on

◆ jo_3d_point_light_set_color()

void jo_3d_point_light_set_color ( const int id,
const unsigned char r,
const unsigned char g,
const unsigned char b )

Color of a light (cheap).

Parameters
idId of the light
rRed (0 to 255)
gGreen (0 to 255)
bBlue (0 to 255)

◆ jo_3d_point_light_set_intensity()

void jo_3d_point_light_set_intensity ( const int id,
const int intensity )

Intensity of a light (a flicker, a pulse: cheap).

Parameters
idId of the light
intensity0 (off) to 256 (its strength)

◆ jo_3d_point_light_set_position()

void jo_3d_point_light_set_position ( const int id,
const jo_pos3D_fixed *const position )

Move a light (its light is computed again on all the meshes: costly).

Parameters
idId of the light
positionPosition (world, Q16.16)

◆ jo_3d_point_light_set_sampled()

void jo_3d_point_light_set_sampled ( const int id,
const bool sampled )

Light of a light seen by jo_3d_point_lights_sample() (the objects, the weapon of the player): on by default; off for a light that is only a sheen on the walls (a torch on the camera would light the weapon in front of it).

Parameters
idId of the light
sampledtrue: jo_3d_point_lights_sample() adds its light

◆ jo_3d_point_light_set_shadows()

void jo_3d_point_light_set_shadows ( const int id,
const bool shadows )

Shadows of a light (on by default when jo_3d_point_lights_set_occlusion() is set): off for a light that moves at each frame (a muzzle flash, an explosion): its light is computed again faster (no ray).

Parameters
idId of the light
shadowstrue: the walls stop its light

◆ jo_3d_point_light_set_spot()

void jo_3d_point_light_set_spot ( const int id,
const jo_pos3D_fixed *const direction,
const int angle )

A spot light (a torch, a lamp with a shade): the light goes in a cone; or all around (a bulb, the default).

Parameters
idId of the light
directionDirection of the cone (world, unit vector Q16.16), JO_NULL: all around (a bulb)
angleAngle of the cone (degrees, 1 to 179): full light in its inner 3/4, none outside of it
Remarks
The light is computed again on all the meshes (costly, like jo_3d_point_light_set_position())

◆ jo_3d_point_lights_add_mesh()

bool jo_3d_point_lights_add_mesh ( jo_3d_mesh *const mesh)

Add a mesh lit by the point lights: its points in world coordinates (a mesh drawn without a matrix of its own), its polygons with gouraud tables (JO_VDP1_COLOR_CALC_GOURAUD). Its gouraud tables are read now: their colors are kept.

Parameters
meshMesh
Returns
true if added
Remarks
Each polygon needs its own table (the light of each polygon is written in it): the polygons of a mesh that share a table (a model loaded by jo_3d_load_model(): the same colors, one table) get a table each here, in a new block of the VRAM (the models of the cells: loaded with a table per polygon)

◆ jo_3d_point_lights_clear()

void jo_3d_point_lights_clear ( void )

Remove the lights and the meshes (the gouraud tables get their colors back): before the meshes are freed.

◆ jo_3d_point_lights_enable()

void jo_3d_point_lights_enable ( const bool enabled)

The point lights on or off (off: the meshes get their colors back).

Parameters
enabledtrue: on (the default)

◆ jo_3d_point_lights_sample()

void jo_3d_point_lights_sample ( const jo_pos3D_fixed *const position,
int *const r,
int *const g,
int *const b )

The light of the lights at a point (for an object that moves: a character, a weapon, see jo_3d_set_tint()).

Parameters
positionPoint (world)
rRed added (gouraud units: 16 doubles a color)
gGreen added
bBlue added
Remarks
The walls between a light with shadows and the point stop its light (a ray for each light in reach)

◆ jo_3d_point_lights_set_mesh_seen()

void jo_3d_point_lights_set_mesh_seen ( const jo_3d_mesh *const mesh,
const bool seen )

A mesh is seen or not in this frame (for instance the cells drawn, see jo_cells_prepare()): the light changes of the meshes not seen are applied when they are seen again (a light that pulses costs nothing in the rooms not seen).

Parameters
meshMesh (added by jo_3d_point_lights_add_mesh())
seentrue: seen (the default)

◆ jo_3d_point_lights_set_occlusion()

void jo_3d_point_lights_set_occlusion ( bool(* hit )(const jo_pos3D_fixed *const origin, const jo_pos3D_fixed *const dir, const jo_fixed max_t))

Shadows: a function that tells if a ray hits a wall (for instance the walls of the cells, see jo_cells_add_point_light_meshes()), JO_NULL: no shadow.

Parameters
hitThe ray from origin along dir (unit vector) hits something before max_t (Q16.16)

◆ jo_3d_point_lights_update()

void jo_3d_point_lights_update ( void )

Write the gouraud tables changed by the lights (computes the light of the lights added or moved first): once per frame, before the meshes are drawn.