Un-ignored: the dev drive is the ground truth the restoration and emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio content). Kept in-repo for the pod-owner community. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
242 lines
5.7 KiB
C++
242 lines
5.7 KiB
C++
static void xform_light_project ( VERTEX *v1,
|
|
int n_verts,
|
|
int strip_shade,
|
|
int front_face,
|
|
VIEW *eye,
|
|
LIGHTSOURCE *blondie,
|
|
MATRIX quad_aligned_m,
|
|
MTLSURFACE *surf )
|
|
{
|
|
--{{{ floating point registers
|
|
--{{{ 12 matrix registers total 12
|
|
register float m00, m01, m02,
|
|
m10, m11, m12,
|
|
m20, m21, m22,
|
|
tx, ty, tz;
|
|
|
|
--}}}
|
|
--{{{ 7 viewport scaling 18
|
|
register float wx, wy, wz,
|
|
eye_d,
|
|
zmax,
|
|
shx, shy;
|
|
|
|
--}}}
|
|
--{{{ 2 lighting registers 20
|
|
|
|
/*
|
|
NB - kd is intrinsic colour, held in frame buffer. ks is now also
|
|
held in frame buffer as a 4-bit number, so we 6% control over specular
|
|
stuff.
|
|
*/
|
|
|
|
register float normfactor;
|
|
--}}}
|
|
|
|
--{{{ 10 temporary registers 31 all used up and more ! ! !
|
|
|
|
register float fdot;
|
|
register float invz;
|
|
|
|
/* temporary registers, re-loaded per vertex */
|
|
register float px, py, pz;
|
|
#define nx px
|
|
#define ny py
|
|
#define nz pz
|
|
|
|
register float cdiff, cspec;
|
|
|
|
register float lx, ly, lz;
|
|
#define rx lx
|
|
#define ry ly
|
|
#define rz lz
|
|
|
|
|
|
--}}}
|
|
--}}}
|
|
--{{{ integer registers
|
|
/* 8 register parameters in use */
|
|
|
|
/* if cooked, dolighting=0, lightbump = 0 */
|
|
/* if smooth, dolighting=1, lightbump = 1 */
|
|
/* if flat, dolighting=nv-2, lightbump = -1 */
|
|
/* per vertex, dolighting+=lightbump */
|
|
|
|
VERTEX *light_v;
|
|
LIGHTSOURCE *bulb;
|
|
int dolighting;
|
|
int lightbump;
|
|
float *light;
|
|
float *half;
|
|
float *norm;
|
|
float *phong_table;
|
|
int dot;
|
|
|
|
--}}}
|
|
|
|
--{{{ initialize
|
|
--{{{ cache matrix ...use fld.q if possible
|
|
m00=quad_aligned_m[0][0];
|
|
m01=quad_aligned_m[0][1];
|
|
m02=quad_aligned_m[0][2];
|
|
|
|
m10=quad_aligned_m[1][0];
|
|
m11=quad_aligned_m[1][1];
|
|
m12=quad_aligned_m[1][2];
|
|
|
|
m20=quad_aligned_m[2][0];
|
|
m21=quad_aligned_m[2][1];
|
|
m22=quad_aligned_m[2][2];
|
|
|
|
tx =quad_aligned_m[3][0];
|
|
ty =quad_aligned_m[3][1];
|
|
tz =quad_aligned_m[3][2];
|
|
--}}}
|
|
|
|
phong_table=surf->specular_table;
|
|
|
|
wx =eye->screen_half_width;
|
|
wy =eye->screen_half_height;
|
|
wz =eye->zscale;
|
|
|
|
eye_d=eye->d;
|
|
zmax =1.0f;
|
|
|
|
shx=wx*(eye->shift_x + 1.0f);
|
|
shy=wy*(eye->shift_y + 1.0f);
|
|
|
|
if (strip_shade & strip_shade_coloured) {
|
|
dolighting = 0;
|
|
lightbump = 0;
|
|
}
|
|
else if (strip_shade & strip_shade_smooth) {
|
|
dolighting = 1;
|
|
lightbump = 0;
|
|
light_v = v1;
|
|
}
|
|
else {
|
|
dolighting = n_verts-2;
|
|
lightbump = -1;
|
|
light_v = v1+1;
|
|
}
|
|
--}}}
|
|
--{{{ which surface ?
|
|
if (front_face)
|
|
normfactor = 1.0f;
|
|
else
|
|
normfactor =-1.0f;
|
|
--}}}
|
|
|
|
while (n_verts) {
|
|
--{{{ transform 18 flops
|
|
/* ****************
|
|
transform this point
|
|
*/
|
|
px=v1->position[0];
|
|
py=v1->position[1];
|
|
pz=v1->position[2];
|
|
|
|
rx=(px*m00)+(py*m10)+(pz*m20)+tx;
|
|
ry=(px*m01)+(py*m11)+(pz*m21)+ty;
|
|
rz=(px*m02)+(py*m12)+(pz*m22)+tz;
|
|
|
|
--}}}
|
|
--{{{ project 18 flops
|
|
/* **************
|
|
project it to screen-space
|
|
*/
|
|
invz=eye_d/rz;
|
|
|
|
px=(rx*wx*invz)+shx;
|
|
py=(ry*wy*invz)+shy;
|
|
pz=zmax-(wz*invz);
|
|
|
|
#if 0
|
|
--{{{ vertex check
|
|
{
|
|
float x, y;
|
|
int code=0;
|
|
|
|
x=px;
|
|
y=py;
|
|
|
|
if (x < 0.0) code |= 1;
|
|
if (x > 639.99) code |= 2;
|
|
if (y < 0.0) code |= 4;
|
|
if (y > 479.99) code |= 8;
|
|
|
|
if (code) {
|
|
printf ("Vertex (i=%i n_pts=%d) fail in project_points, \ncode=%d x=%f y=%f z=%f shift_x=%f shift_y=%f\n",
|
|
i, n_verts, code, x, y, pz, eye->shift_x, eye->shift_y );
|
|
exit(0);
|
|
}
|
|
}
|
|
--}}}
|
|
#endif
|
|
|
|
v1->position[0] = px;
|
|
v1->position[1] = py;
|
|
v1->position[2] = pz;
|
|
--}}}
|
|
--{{{ light 16 flops
|
|
if (dolighting) {
|
|
norm=light_v->normcol;
|
|
/* ********************
|
|
light this point
|
|
*/
|
|
/* NOTE - force into adjacent registers for f0 and fst.d */
|
|
cdiff=0.0f;
|
|
cspec=0.0f;
|
|
|
|
nx=normfactor*norm[0];
|
|
ny=normfactor*norm[1];
|
|
nz=normfactor*norm[2];
|
|
|
|
for (bulb=blondie; bulb; bulb=bulb->next ) {
|
|
--{{{ light up this vertex according to bulb type
|
|
light=&bulb->xformpos[0];
|
|
|
|
/* do diffuse shading */
|
|
lx=light[0];
|
|
ly=light[1];
|
|
lz=light[2];
|
|
|
|
fdot=(nx*lx) + (ny*ly) + (nz*lz);
|
|
|
|
/* the multiply by light colour happens at end-of-frame */
|
|
if (fdot > 0.0f)
|
|
cdiff+=fdot;
|
|
|
|
/* do specular shading - NOTE power factor has gone */
|
|
half=(float *) *(int *) &(bulb->xformpos[3]);
|
|
|
|
lx=half[0];
|
|
ly=half[1];
|
|
lz=half[2];
|
|
|
|
dot=(int) ((nx*lx) + (ny*ly) + (nz*lz));
|
|
|
|
if (dot > 0) {
|
|
if (dot > (phong_precision - 1))
|
|
dot = phong_precision-1;
|
|
|
|
/* the multiply by light colour happens at end-of-frame */
|
|
/* ditto ks */
|
|
cspec +=phong_table[dot];
|
|
}
|
|
--}}}
|
|
}
|
|
/* fst.d .. */
|
|
norm[0]=cdiff*230.0;
|
|
norm[1]=cspec*255.0;
|
|
}
|
|
--}}}
|
|
|
|
v1++;
|
|
light_v++;
|
|
|
|
dolighting+=lightbump;
|
|
n_verts--;
|
|
}
|
|
}
|