API Design
/* A material pass maps directly to one PVR2 polygon header configuration. */
typedef struct {
uint32_t list_type; /* PVR_LIST_OP_POLY, PVR_LIST_TR_POLY, PVR_LIST_PT_POLY */
/* Texturing */
sh_texture_t *texture; /* NULL = untextured */
uint32_t tex_filter; /* PVR_FILTER_NONE, PVR_FILTER_BILINEAR, PVR_FILTER_TRILINEAR */
uint32_t tex_env; /* PVR_TXRENV_REPLACE, PVR_TXRENV_MODULATE, etc. */
uint32_t uv_clamp; /* PVR_UVCLAMP_NONE, PVR_UVCLAMP_U, PVR_UVCLAMP_V, PVR_UVCLAMP_UV */
/* Blending */
uint32_t blend_src; /* PVR_BLEND_ONE, PVR_BLEND_SRCALPHA, etc. */
uint32_t blend_dst; /* PVR_BLEND_ZERO, PVR_BLEND_INVSRCALPHA, etc. */
/* Depth */
uint32_t depth_compare; /* PVR_DEPTHCMP_GEQUAL, PVR_DEPTHCMP_GREATER, etc. */
int depth_write; /* 1 = write, 0 = no write */
/* Culling */
uint32_t cull_mode; /* PVR_CULLING_NONE, PVR_CULLING_CW, PVR_CULLING_CCW */
/* Color */
uint32_t base_color; /* Default vertex base color (ARGB) */
uint32_t offset_color; /* For bump mapping: K1/K2/K3/Q packed into oargb */
/* Shading */
uint32_t shade_mode; /* PVR_SHADE_FLAT or PVR_SHADE_GOURAUD */
/* Fog */
uint32_t fog_mode; /* PVR_FOG_TABLE, PVR_FOG_VERTEX, PVR_FOG_DISABLE */
} sh_material_pass_t;
/* A material is 1-4 passes over the same geometry. */
typedef struct {
int pass_count; /* 1-4 */
sh_material_pass_t passes[4]; /* Max 4 passes (base + lightmap + bump + env) */
char name[32]; /* Debug name */
} sh_material_t;
/* --- Predefined Materials (common patterns) --- */
/* Opaque textured (one pass, PVR_LIST_OP_POLY). */
void sh_material_opaque(sh_material_t *mat, sh_texture_t *tex);
/* Transparent textured (one pass, PVR_LIST_TR_POLY, src alpha blend). */
void sh_material_transparent(sh_material_t *mat, sh_texture_t *tex);
/* Punch-through (one pass, PVR_LIST_PT_POLY, alpha test). */
void sh_material_punchthrough(sh_material_t *mat, sh_texture_t *tex);
/* Lightmapped (two passes: opaque base + translucent multiply lightmap).
From SPECTRE Q-003: depth compare GEQUAL on pass 2, no depth bias needed
on PVR2 if geometry is identical. */
void sh_material_lightmapped(sh_material_t *mat, sh_texture_t *diffuse, sh_texture_t *lightmap);
/* Bump mapped (from SPECTRE Q-004/Q-005: offset color K1/K2/K3/Q,
FLAT shading required, bump texture is S/T angle pairs 16-bit twiddled). */
void sh_material_bumpmapped(sh_material_t *mat, sh_texture_t *diffuse, sh_texture_t *bumpmap);
/* Environment mapped (second pass with env texture, additive blend). */
void sh_material_envmapped(sh_material_t *mat, sh_texture_t *diffuse, sh_texture_t *envmap);
/* --- Submission --- */
/* Compile a material pass into a PVR polygon header. Call once, reuse. */
void sh_material_compile(const sh_material_pass_t *pass, pvr_poly_hdr_t *hdr);
/* Compile all passes. headers must have room for mat->pass_count entries. */
void sh_material_compile_all(const sh_material_t *mat, pvr_poly_hdr_t *headers);