9-2加上光照计算的GOURAUD shader多边形)
对于光照计算的颜色,就是考虑了法线和初始颜色。
对于固定着色的多边形,将多边形的颜色复制到lit_color[0]中;对于恒定着色的多边形,计算面法线,存储在lit_color[0]; GOURAUD着色计算顶点法线,存储在lit_color{0,1,2}中。
光照计算步骤
1只计算光照强度,并对顶点进行标记,以防重复计算
2使用多边形的初始颜色对顶点的光照强度调制。
另外, 提到了一个物体转换为多边形时,顶点结合性将丧失,说白了,就是重复计算,因此,在物体级进行Gouraud计算较为合适。
原理仍然如此简单,代码仍然如此多。绝知此事要躬行。
intDDRAW_LIUSHUIXIAN_TEXTURE::Light_OBJECT4DV2_World16(ddraw_math math,int rgb_format,OBJECT4DV2_PTR obj,CAM4DV1_PTR cam,LIGHTV1_PTR lights,int max_lights )
{
unsigned int r_base, g_base, b_base, //原来的颜色值
r_sum, g_sum,b_sum, //全部光源的总体光照效果
r_sum0, g_sum0,b_sum0,
r_sum1, g_sum1,b_sum1,
r_sum2, g_sum2,b_sum2,
ri, gi,bi,
shaded_color; //最后的颜色
float dp, //点积
dist, //表面和光源之间的距离
dists,
i, //强度
nl, //法线长度
atten; //衰减计算结果
VECTOR4D u, v,n, l, d, s;
if ( ! ( obj->state &OBJECT4DV2_STATE_ACTIVE ) ||
( obj-> state &OBJECT4DV2_STATE_CULLED ) ||
! ( obj->state &OBJECT4DV2_STATE_VISIBLE))
{
return ( 0 );
}
for ( int poly = 0; poly < obj->num_polys; poly++)
{
POLY4DV2_PTR curr_poly = &obj->plist[poly];
if ( ! ( curr_poly->state &POLY4DV2_STATE_ACTIVE) ||
( curr_poly->state &POLY4DV2_STATE_CLIPPED) ||
( curr_poly->state &POLY4DV2_STATE_BACKFACE ))
{
continue;
}
SET_BIT( curr_poly->state,POLY4DV2_STATE_LIT );
//提取指向主列表的顶点索引
int vindex_0 = curr_poly->vert[0];
int vindex_1 = curr_poly->vert[1];
int vindex_2 = curr_poly->vert[2];
//检查多边形的着色模式
if ( curr_poly->attr &POLY4DV2_ATTR_SHADE_MODE_FLAT )
{
//提取多边形颜色的RGB值
_RGB565FROM16BIT( curr_poly->color, & r_base, & g_base, & b_base );
//转换成.8.8格式
r_base <<= 3;
g_base <<= 2;
b_base <<= 3;
//初始化总体光照颜色
r_sum = 0;
g_sum = 0;
b_sum = 0;
n.z = FLT_MAX;
//遍历光照
for ( int curr_light = 0; curr_light < max_lights; curr_light ++)
{
//光源是否被打开
if ( lights[curr_light].state==LIGHTV1_STATE_OFF)
{
continue;
}
//判断光源类型
if ( lights[curr_light].attr &LIGHTV1_ATTR_AMBIENT )
{
r_sum += ( ( lights[curr_light].c_ambient.r *r_base) / 256 );
g_sum += ( ( lights[curr_light].c_ambient.g *g_base) / 256 );
b_sum += ( ( lights[curr_light].c_ambient.b *b_base) / 256 );
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_INFINITE )
{
if( n.z ==FLT_MAX)
{
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_1].v, &u );
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_2].v, &v );
math.VECTOR4D_CROSS( &u, &v, &n );
}
nl = curr_poly->nlength;
dp = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );
if ( dp > 0 )
{
i = 128 * dp / nl;
r_sum += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_POINT )
{
if ( n.z ==FLT_MAX)
{
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_1].v, &u );
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_2].v, &v );
math.VECTOR4D_CROSS( &u, &v, &n );
}
nl = curr_poly->nlength;
//计算从表面到光源的向量
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &lights[curr_light].pos, &l );
//计算距离和衰减
dist = math.VECTOR4D_length( &l);
dp = math.VECTOR4D_DOT( &n, &l);
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( nl * dist * atten );
r_sum += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT1 )
{
if (n.z ==FLT_MAX)
{
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_1].v, &u );
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_2].v, &v );
math.VECTOR4D_CROSS( &v, &u, &n );
}
nl = curr_poly->nlength;
//计算从表面到光源的向量333
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &lights[curr_light].pos, &l );
//计算距离和衰减
dist = math.VECTOR4D_length( &l);
dp = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( nl * atten );
r_sum += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT2 )
{
if (n.z ==FLT_MAX )
{
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_1].v, &u );
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_2].v, &v );
math.VECTOR4D_CROSS( &v, &u, &n );
}
nl = curr_poly->nlength;
dp = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );
if ( dp > 0 )
{
//计算从表面到光源的向量
math.VECTOR4D_Build( &lights[curr_light].pos, &obj->vlist_trans[vindex_0].v, &s );
dists = math.VECTOR4D_length( &s);
float dpsl = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;
if ( dpsl > 0)
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );
float dpsl_exp = dpsl;
for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index++ )
{
dpsl *= dpsl;
}
i = 128 * dp * dpsl_exp / ( nl * atten );
r_sum += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
}
}
//确保颜色分量不溢出
if ( r_sum > 255 )
{
r_sum = 255;
}
if ( g_sum > 255 )
{
g_sum = 255;
}
if ( b_sum > 255 )
{
b_sum = 255;
}
//写入颜色
curr_poly->lit_color[0] = _RGB16BIT565( r_sum, g_sum, b_sum );
}
else
if ( curr_poly->attr &POLY4DV2_ATTR_SHADE_MODE_GOURAUD )
{
//提取多边形颜色的RGB值
_RGB565FROM16BIT( curr_poly->color, & r_base, & g_base, & b_base );
//转换成.8.8格式
r_base <<= 3;
g_base <<= 2;
b_base <<= 3;
//初始化顶点的累积RGB值
r_sum0 = 0;
g_sum0 = 0;
b_sum0 = 0;
r_sum1 = 0;
g_sum1 = 0;
b_sum1 = 0;
r_sum2 = 0;
g_sum2 = 0;
b_sum2 = 0;
//遍历光照
for ( int curr_light = 0; curr_light < max_lights; curr_light ++)
{
//光源是否被打开
if ( lights[curr_light].state==LIGHTV1_STATE_OFF)
{
continue;
}
//判断光源类型
if ( lights[curr_light].attr &LIGHTV1_ATTR_AMBIENT )
{
ri += ( ( lights[curr_light].c_ambient.r *r_base) / 256 );
gi += ( ( lights[curr_light].c_ambient.g *g_base) / 256 );
bi += ( ( lights[curr_light].c_ambient.b *b_base) / 256 );
//环境光源对每个顶点的影响相同
r_sum0 += ri;
g_sum0 += gi;
b_sum0 += bi;
r_sum1 += ri;
g_sum1 += gi;
b_sum1 += bi;
r_sum2 += ri;
g_sum2 += gi;
b_sum2 += bi;
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_INFINITE )
{
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_0].n, &lights[curr_light].dir );
if ( dp > 0 )
{
i = 128 * dp / nl;
r_sum0 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum0 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum0 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_1].n, &lights[curr_light].dir );
if ( dp > 0 )
{
i = 128 * dp / nl;
r_sum1 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum1 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum1 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_2].n, &lights[curr_light].dir );
if ( dp > 0 )
{
i = 128 * dp / nl;
r_sum2 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum2 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum2 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_POINT )
{
//计算从表面到光源的向量
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &lights[curr_light].pos, &l );
//计算距离和衰减
dist = math.VECTOR4D_length( &l);
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_0].n, & l);
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( dist * atten );
r_sum0 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum0 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum0 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_1].n, & l);
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( dist * atten );
r_sum1 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum1 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum1 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_2].n, & l);
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( dist * atten );
r_sum2 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum2 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum2 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT1 )
{
//计算从表面到光源的向量
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &lights[curr_light].pos, &l );
//计算距离和衰减
dist = math.VECTOR4D_length( &l);
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_0].n, & lights[curr_light].dir );
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( atten );
r_sum0 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum0 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum0 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_1].n, & lights[curr_light].dir );
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( atten );
r_sum1 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum1 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum1 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_2].n, & lights[curr_light].dir );
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( atten );
r_sum2 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum2 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum2 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT2 )
{
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_0].n, & lights[curr_light].dir );
if ( dp > 0 )
{
math.VECTOR4D_Build( &lights[curr_light].pos, &obj->vlist_trans[vindex_0].v, &s );
dists = math.VECTOR4D_length( &s );
float dpsl = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;
if ( dpsl > 0)
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );
float dpsl_exp = dpsl;
for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )
{
dpsl_exp *= dpsl;
}
i = 128 * dp * dpsl_exp / ( atten );
r_sum0 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum0 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum0 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_1].n, & lights[curr_light].dir );
if ( dp > 0 )
{
math.VECTOR4D_Build( &lights[curr_light].pos, &obj->vlist_trans[vindex_1].v, &s );
dists = math.VECTOR4D_length( &s );
float dpsl = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;
if ( dpsl > 0)
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );
float dpsl_exp = dpsl;
for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )
{
dpsl_exp *= dpsl;
}
i = 128 * dp * dpsl_exp / ( atten );
r_sum1 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum1 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum1 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
//顶点
dp = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_2].n, & lights[curr_light].dir );
if ( dp > 0 )
{
math.VECTOR4D_Build( &lights[curr_light].pos, &obj->vlist_trans[vindex_2].v, &s );
dists = math.VECTOR4D_length( &s );
float dpsl = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;
if ( dpsl > 0)
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );
float dpsl_exp = dpsl;
for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )
{
dpsl_exp *= dpsl;
}
i = 128 * dp * dpsl_exp / ( atten );
r_sum2 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum2 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum2 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
}
}
//确保颜色分量不溢出
if ( r_sum0 > 255 )
{
r_sum0 = 255;
}
if ( g_sum0 > 255 )
{
g_sum0 = 255;
}
if ( b_sum0 > 255 )
{
b_sum0 = 255;
}
if ( r_sum1 > 255 )
{
r_sum1 = 255;
}
if ( g_sum1 > 255 )
{
g_sum1 = 255;
}
if ( b_sum1 > 255 )
{
b_sum1 = 255;
}
if ( r_sum2 > 255 )
{
r_sum2 = 255;
}
if ( g_sum2 > 255 )
{
g_sum2 = 255;
}
if ( b_sum2 > 255 )
{
b_sum2 = 255;
}
//写入颜色
curr_poly->lit_color[0] = _RGB16BIT565( r_sum0, g_sum0, b_sum0 );
curr_poly->lit_color[1] = _RGB16BIT565( r_sum1, g_sum1, b_sum1 );
curr_poly->lit_color[2] = _RGB16BIT565( r_sum2, g_sum2, b_sum2 );
}
else
{
curr_poly->lit_color[0] = curr_poly->color;
}
}
return ( 1 );
}
现在,看下渲染列表的。
先加个渲染列表版本2结构
typedefstruct RENDERLIST4DV2_TYP
{
int state; //渲染列表的状态
int attr; //渲染列表的属性
POLYF4DV2_PTR poly_ptrs[RENDERLIST4DV2_MAX_POLYS];//索引缓存数组(多边形面)
POLYF4DV2 poly_data[RENDERLIST4DV2_MAX_POLYS];//顶点数组
int num_polys; //渲染列表中包含的多边形数目
}RENDERLIST4DV2, *RENDERLIST4DV2_PTR;
intDDRAW_LIUSHUIXIAN_TEXTURE::Light_RENDERLIST4DV2_World16(ddraw_math math,int rgb_format,RENDERLIST4DV2_PTR rend_list, CAM4DV1_PTR cam, LIGHTV1_PTR lights, int max_lights )
{
unsigned int r_base, g_base,b_base, //原来的颜色值
r_sum, g_sum,b_sum, //全部光源的总体光照效果
r_sum0, g_sum0,b_sum0,
r_sum1, g_sum1,b_sum1,
r_sum2, g_sum2,b_sum2,
ri, gi,bi,
shaded_color; //最后的颜色
float dp, //点积
dist, //表面和光源之间的距离
dists,
i, //强度
nl, //法线长度
atten; //衰减计算结果
VECTOR4D u, v,n, l, d, s;
for ( int poly = 0; poly < rend_list->num_polys; poly++)
{
POLYF4DV2_PTR curr_poly = &rend_list->poly_ptrs[poly];
if ( ! ( curr_poly->state &POLY4DV2_STATE_ACTIVE) ||
( curr_poly->state &POLY4DV2_STATE_CLIPPED) ||
( curr_poly->state &POLY4DV2_STATE_BACKFACE) ||
( curr_poly->state &POLY4DV2_STATE_LIT ))
{
continue;
}
SET_BIT( curr_poly->state,POLY4DV2_STATE_LIT );
//检查多边形的着色模式
if ( curr_poly->attr &POLY4DV2_ATTR_SHADE_MODE_FLAT )
{
//提取多边形颜色的RGB值
_RGB565FROM16BIT( curr_poly->color, & r_base, & g_base, & b_base );
//转换成.8.8格式
r_base <<= 3;
g_base <<= 2;
b_base <<= 3;
//初始化总体光照颜色
r_sum = 0;
g_sum = 0;
b_sum = 0;
n.z = FLT_MAX;
//遍历光照
for ( int curr_light = 0; curr_light < max_lights; curr_light ++)
{
//光源是否被打开
if ( lights[curr_light].state==LIGHTV1_STATE_OFF)
{
continue;
}
//判断光源类型
if ( lights[curr_light].attr &LIGHTV1_ATTR_AMBIENT )
{
r_sum += ( ( lights[curr_light].c_ambient.r *r_base) / 256 );
g_sum += ( ( lights[curr_light].c_ambient.g *g_base) / 256 );
b_sum += ( ( lights[curr_light].c_ambient.b *b_base) / 256 );
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_INFINITE )
{
if( n.z ==FLT_MAX)
{
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[1].v, &u );
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[2].v, &v );
math.VECTOR4D_CROSS( &u, &v, &n );
}
nl = curr_poly->nlength;
dp = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );
if ( dp > 0 )
{
i = 128 * dp / nl;
r_sum += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_POINT )
{
if ( n.z ==FLT_MAX)
{
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[1].v, &u );
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[2].v, &v );
math.VECTOR4D_CROSS( &u, &v, &n );
}
nl = curr_poly->nlength;
//计算从表面到光源的向量
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &lights[curr_light].pos, &l );
//计算距离和衰减
dist = math.VECTOR4D_length( &l);
dp = math.VECTOR4D_DOT( &n, &l);
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( nl * dist * atten );
r_sum += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT1 )
{
if (n.z ==FLT_MAX)
{
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[1].v, &u );
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[2].v, &v );
math.VECTOR4D_CROSS( &u, &v, &n );
}
nl = curr_poly->nlength;
//计算从表面到光源的向量
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &lights[curr_light].pos, &l );
//计算距离和衰减
dist = math.VECTOR4D_length( &l);
dp = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( nl * atten );
r_sum += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT2 )
{
if (n.z ==FLT_MAX )
{
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[1].v, &u );
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[2].v, &v );
math.VECTOR4D_CROSS( &u, &v, &n );
}
nl = curr_poly->nlength;
dp = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );
if ( dp > 0 )
{
//计算从表面到光源的向量
math.VECTOR4D_Build( &lights[curr_light].pos, &curr_poly->tvlist[0].v, &s );
dists = math.VECTOR4D_length( &s);
float dpsl = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;
if ( dpsl > 0)
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );
float dpsl_exp = dpsl;
for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index++ )
{
dpsl *= dpsl;
}
i = 128 * dp * dpsl_exp / ( nl * atten );
r_sum += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
}
}
//确保颜色分量不溢出
if ( r_sum > 255 )
{
r_sum = 255;
}
if ( g_sum > 255 )
{
g_sum = 255;
}
if ( b_sum > 255 )
{
b_sum = 255;
}
//写入颜色
curr_poly->lit_color[0] = _RGB16BIT565( r_sum, g_sum, b_sum );
}
else
if ( curr_poly->attr &POLY4DV2_ATTR_SHADE_MODE_GOURAUD )
{
//提取多边形颜色的RGB值
_RGB565FROM16BIT( curr_poly->color, & r_base, & g_base, & b_base );
//转换成.8.8格式
r_base <<= 3;
g_base <<= 2;
b_base <<= 3;
//初始化顶点的累积RGB值
r_sum0 = 0;
g_sum0 = 0;
b_sum0 = 0;
r_sum1 = 0;
g_sum1 = 0;
b_sum1 = 0;
r_sum2 = 0;
g_sum2 = 0;
b_sum2 = 0;
//遍历光照
for ( int curr_light = 0; curr_light < max_lights; curr_light ++)
{
//光源是否被打开
if ( lights[curr_light].state==LIGHTV1_STATE_OFF)
{
continue;
}
//判断光源类型
if ( lights[curr_light].attr &LIGHTV1_ATTR_AMBIENT )
{
ri += ( ( lights[curr_light].c_ambient.r *r_base) / 256 );
gi += ( ( lights[curr_light].c_ambient.g *g_base) / 256 );
bi += ( ( lights[curr_light].c_ambient.b *b_base) / 256 );
//环境光源对每个顶点的影响相同
r_sum0 += ri;
g_sum0 += gi;
b_sum0 += bi;
r_sum1 += ri;
g_sum1 += gi;
b_sum1 += bi;
r_sum2 += ri;
g_sum2 += gi;
b_sum2 += bi;
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_INFINITE )
{
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[0].n, &lights[curr_light].dir );
if ( dp > 0 )
{
i = 128 * dp;
r_sum0 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum0 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum0 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[1].n, &lights[curr_light].dir );
if ( dp > 0 )
{
i = 128 * dp;
r_sum1 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum1 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum1 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[2].n, &lights[curr_light].dir );
if ( dp > 0 )
{
i = 128 * dp ;
r_sum2 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum2 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum2 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_POINT )
{
//计算从表面到光源的向量
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &lights[curr_light].pos, &l );
//计算距离和衰减
dist = math.VECTOR4D_length( &l);
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[0].n, &l);
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( dist * atten );
r_sum0 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum0 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum0 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[1].n, &l);
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( dist * atten );
r_sum1 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum1 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum1 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[2].n, &l);
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( dist * atten );
r_sum2 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum2 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum2 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT1 )
{
//计算从表面到光源的向量
math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &lights[curr_light].pos, &l );
//计算距离和衰减
dist = math.VECTOR4D_length( &l);
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[0].n, &lights[curr_light].dir );
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( atten );
r_sum0 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum0 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum0 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[1].n, &lights[curr_light].dir );
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( atten );
r_sum1 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum1 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum1 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[2].n, &lights[curr_light].dir );
if ( dp > 0 )
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );
i = 128 * dp / ( atten );
r_sum2 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum2 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum2 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
else
if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT2 )
{
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[0].n, &lights[curr_light].dir );
if ( dp > 0 )
{
math.VECTOR4D_Build( &lights[curr_light].pos, &curr_poly->tvlist[0].v, &s );
dists = math.VECTOR4D_length( &s );
float dpsl = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;
if ( dpsl > 0)
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );
float dpsl_exp = dpsl;
for (int e_index = 1;e_index < ( int )lights[curr_light].pf;e_index ++ )
{
dpsl_exp *= dpsl;
}
i = 128 * dp * dpsl_exp / ( atten );
r_sum0 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum0 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum0 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[1].n, &lights[curr_light].dir );
if ( dp > 0 )
{
math.VECTOR4D_Build( &lights[curr_light].pos, &curr_poly->tvlist[1].v, &s );
dists = math.VECTOR4D_length( &s );
float dpsl = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;
if ( dpsl > 0)
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );
float dpsl_exp = dpsl;
for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )
{
dpsl_exp *= dpsl;
}
i = 128 * dp * dpsl_exp / ( atten );
r_sum1 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum1 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum1 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
//顶点
dp = math.VECTOR4D_DOT( &curr_poly->tvlist[2].n, &lights[curr_light].dir );
if ( dp > 0 )
{
math.VECTOR4D_Build( &lights[curr_light].pos, &curr_poly->tvlist[2].v, &s );
dists = math.VECTOR4D_length( &s );
float dpsl = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;
if ( dpsl > 0)
{
atten = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );
float dpsl_exp = dpsl;
for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )
{
dpsl_exp *= dpsl;
}
i = 128 * dp * dpsl_exp / ( atten );
r_sum2 += ( lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);
g_sum2 += ( lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);
b_sum2 += ( lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);
}
}
}
}
//确保颜色分量不溢出
if ( r_sum0 > 255 )
{
r_sum0 = 255;
}
if ( g_sum0 > 255 )
{
g_sum0 = 255;
}
if ( b_sum0 > 255 )
{
b_sum0 = 255;
}
if ( r_sum1 > 255 )
{
r_sum1 = 255;
}
if ( g_sum1 > 255 )
{
g_sum1 = 255;
}
if ( b_sum1 > 255 )
{
b_sum1 = 255;
}
if ( r_sum2 > 255 )
{
r_sum2 = 255;
}
if ( g_sum2 > 255 )
{
g_sum2 = 255;
}
if ( b_sum2 > 255 )
{
b_sum2 = 255;
}
//写入颜色
curr_poly->lit_color[0] = _RGB16BIT565( r_sum0, g_sum0, b_sum0 );
curr_poly->lit_color[1] = _RGB16BIT565( r_sum1, g_sum1, b_sum1 );
curr_poly->lit_color[2] = _RGB16BIT565( r_sum2, g_sum2, b_sum2 );
}
else
{
curr_poly->lit_color[0] = curr_poly->color;
}
}
return ( 1 );
}
现在从头到尾弄下吧,遇到啥算啥。
#define SPOT_LIGHT1_INDEX 4
#define SPOT_LIGHT2_INDEX 3
摄像机位置改变下
POINT4D cam_pos = {0,0,0,1};
在GAME_INIT()初始化中,
liushuixian.Init_CAM4DV1( &cam, CAM_MODEL_EULER, &cam_pos, & cam_dir, &cam_target, 200.0, 12000.0, 120.0, SCREEN_WIDTH, SCREEN_HEIGHT );
math->VECTOR4D_INITXYZ( &vscale, 10.00, 10.00, 10.00 );
接下来加载新版本的.COB模型,可以看到,多了个mipmap的生成(可选)。新增了加载和识别纹理的功能,目前只支持1个纹理。
首先加上个提取文件名函数
char *DDRAW_LIUSHUIXIAN_TEXTURE::Extract_Filename_From_Path(char * filepath,char * filename )
{
if( !filepath || strlen(filepath ) == 0 )
return (NULL );
intindex_end = strlen( filepath ) - 1;
//查找文件名
while( (filepath[index_end] !='\\' ) && ( filepath[index_end] !='/' ) && ( filepath[index_end] > 0 ) )
index_end --;
//将文件名复制到变量filename中
memcpy(filename, & filepath[index_end + 1 ],strlen( filepath ) -index_end );
returnfilename;
}
重置列表
voidDDRAW_LIUSHUIXIAN_TEXTURE::Reset_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list)
{
rend_list->num_polys = 0; // 渲染的多边形数,默认为0
}
重置物体
voidDDRAW_LIUSHUIXIAN_TEXTURE::Reset_OBJECT4DV2(OBJECT4DV2_PTR obj )
{
RESET_BIT( obj->state, OBJECT4DV2_STATE_CULLED);
for( int poly = 0; poly < obj->num_polys; poly ++ )
{
POLY4DV2_PTR curr_poly = &obj->plist[poly];
if ( ! curr_poly->state &POLY4DV2_STATE_ACTIVE)
{
continue;
}
RESET_BIT( curr_poly->state, POLY4DV2_STATE_CLIPPED );
RESET_BIT( curr_poly->state, POLY4DV2_STATE_BACKFACE );
RESET_BIT( curr_poly->state, POLY4DV2_STATE_LIT );
}
}
转换
voidDDRAW_LIUSHUIXIAN_TEXTURE::Transform_OBJECT4DV2(OBJECT4DV2_PTRobj,
MATRIX4X4_PTR mt, //变换矩阵
int coord_select,
int transform_basis,
int all_frames,
ddraw_math math2 ) //指定要变换的坐标
{
if( ! all_frames )
{
switch( coord_select )
{
case TRANSFORM_LOCAL_ONLY:
{
//对物体的每个局部/模型顶点坐标进行变换
for( int vertex = 0; vertex < obj->num_vertices; vertex++ )
{
POINT4D presult; //用于暂时存储变换结果
math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].v,mt, & presult );
math2.VECTOR4D_COPY( &obj->vlist_local[vertex].v, &presult );
if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )
{
math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].n,mt, & presult );
math2.VECTOR4D_COPY( &obj->vlist_local[vertex].n, &presult );
}
}
}
break;
case TRANSFORM_TRANS_ONLY:
{
for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )
{
//使用矩阵mt对顶点进行变换
POINT4D presult; //用于暂时存储变换结果
math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_trans[vertex].v,mt, & presult );
math2.VECTOR4D_COPY( &obj->vlist_trans[vertex].v, &presult );
if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )
{
math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].n,mt, & presult );
math2.VECTOR4D_COPY( &obj->vlist_local[vertex].n, &presult );
}
}
}
break;
case TRANSFORM_LOCAL_TO_TRANS:
{
for( int vertex = 0; vertex < obj->num_vertices; vertex++ )
{
POINT4D presult; //用于暂时存储变换结果
//使用矩阵mt对顶点进行变换
math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].v,mt, & obj->vlist_trans[vertex].v );
if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )
{
math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].n,mt, & presult );
math2.VECTOR4D_COPY( &obj->vlist_local[vertex].n, &presult );
}
}
}
break;
default:
break;
}
}
else
{
switch( coord_select )
{
case TRANSFORM_LOCAL_ONLY:
{
//对物体的每个局部/模型顶点坐标进行变换
for( int vertex = 0; vertex < obj->num_vertices; vertex++ )
{
POINT4D presult; //用于暂时存储变换结果
math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].v,mt, & presult );
math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].v, &presult );
if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )
{
math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].n,mt, & presult );
math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].n, &presult );
}
}
}
break;
case TRANSFORM_TRANS_ONLY:
{
for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )
{
//使用矩阵mt对顶点进行变换
POINT4D presult; //用于暂时存储变换结果
math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].v,mt, & presult );
math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].v, &presult );
if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )
{
math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].n,mt, & presult );
math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].n, &presult );
}
}
}
break;
case TRANSFORM_LOCAL_TO_TRANS:
{
for( int vertex = 0; vertex < obj->num_vertices; vertex++ )
{
POINT4D presult; //用于暂时存储变换结果
//使用矩阵mt对顶点进行变换
math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].v,mt, & obj->vlist_trans[vertex].v );
if( obj->head_vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )
{
math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].n,mt, & presult );
math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].n, &presult );
}
}
}
break;
default:
break;
}
}
//最后检查是否对朝向向量进行变换
if ( transform_basis)
{
//旋转物体的朝向向量
VECTOR4D vresult; //用于存储旋转结果
//旋转ux
math2.Mat_Mul_VECTOR4D_4X4( &obj->ux, mt, & vresult );
math2.VECTOR4D_COPY( &obj->ux, & vresult );
//旋转uy
math2.Mat_Mul_VECTOR4D_4X4( &obj->uy, mt, & vresult );
math2.VECTOR4D_COPY( &obj->uy, & vresult );
//旋转uz
math2.Mat_Mul_VECTOR4D_4X4( &obj->uz, mt, & vresult );
math2.VECTOR4D_COPY( &obj->uz, & vresult );
}
}
模型坐标系转换到世界坐标系
voidDDRAW_LIUSHUIXIAN_TEXTURE::Model_To_World_OBJECT4DV2(OBJECT4DV2_PTR obj, ddraw_math math2,int coord_select,int all_frames )
{
if( ! all_frames )
{
if( coord_select ==TRANSFORM_LOCAL_TO_TRANS )
{
//满足条件,对其进行变换
for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )
{
//平移顶点
math2.VECTOR4D_ADD( &obj->vlist_local[vertex].v, &obj->world_pos, &obj->vlist_trans[vertex].v );
math2.VECTOR4D_COPY( &obj->vlist_trans[vertex].n, &obj->vlist_local[vertex].n );
}
}
else
{
for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )
{
//平移顶点
math2.VECTOR4D_ADD( &obj->vlist_trans[vertex].v, &obj->world_pos, &obj->vlist_trans[vertex].v );
}
}
}
else
{
if( coord_select ==TRANSFORM_LOCAL_TO_TRANS )
{
//满足条件,对其进行变换
for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )
{
//平移顶点
math2.VECTOR4D_ADD( &obj->head_vlist_local[vertex].v, &obj->world_pos, &obj->head_vlist_local[vertex].v );
math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].n, &obj->head_vlist_local[vertex].n );
}
}
else
{
for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )
{
//平移顶点
math2.VECTOR4D_ADD( &obj->head_vlist_local[vertex].v, &obj->world_pos, &obj->head_vlist_local[vertex].v );
}
}
}
}
intDDRAW_LIUSHUIXIAN_TEXTURE::Insert_OBJECT4DV2_RENDERLIST4DV2(ddraw_mathmath, RENDERLIST4DV2_PTRrend_list, OBJECT4DV2_PTRobj, int insert_local = 0 )
{
unsigned intbase_color;
if ( ! ( obj->state &OBJECT4DV2_STATE_ACTIVE ) ||
( obj-> state &OBJECT4DV2_STATE_CULLED ) ||
! ( obj->state &OBJECT4DV2_STATE_VISIBLE))
{
return ( 0 );
}
for ( int poly = 0; poly < obj->num_polys; poly++)
{
POLY4DV2_PTR curr_poly = &obj->plist[poly];
if ( ! ( curr_poly->state &POLY4DV2_STATE_ACTIVE) ||
( curr_poly->state &POLY4DV2_STATE_CLIPPED) ||
( curr_poly->state &POLY4DV2_STATE_BACKFACE ))
{
continue;
}
VERTEX4DTV1_PTR vlist_old = curr_poly->vlist;
if ( insert_local )
{
curr_poly->vlist = obj->vlist_local;
}
else
{
curr_poly->vlist = obj->vlist_trans;
}
if ( ! Insert_POLY4DV2_RENDERLIST4DV2(rend_list, curr_poly,math))
{
curr_poly->vlist = vlist_old;
return ( 0 );
}
curr_poly->vlist = vlist_old;
}
return ( 1 );
}
向列表插入顶点
intDDRAW_LIUSHUIXIAN_TEXTURE::Insert_POLY4DV2_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list, POLY4DV2_PTRpoly, ddraw_mathmath)
{
if( rend_list->num_polys >=RENDERLIST4DV2_MAX_POLYS )
return ( 0 );
rend_list->poly_ptrs[rend_list->num_polys] = &rend_list->poly_data[rend_list->num_polys];
rend_list->poly_data[rend_list->num_polys].state = poly->state;
rend_list->poly_data[rend_list->num_polys].attr = poly->attr;
rend_list->poly_data[rend_list->num_polys].color = poly->color;
rend_list->poly_data[rend_list->num_polys].nlength = poly->nlength;
rend_list->poly_data[rend_list->num_polys].texture = poly->texture;
rend_list->poly_data[rend_list->num_polys].lit_color[0]= poly->lit_color[0];
rend_list->poly_data[rend_list->num_polys].lit_color[1]= poly->lit_color[1];
rend_list->poly_data[rend_list->num_polys].lit_color[2]= poly->lit_color[2];
VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].tvlist[0], &poly->vlist[poly->vert[0]] );
VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].tvlist[1], &poly->vlist[poly->vert[1]] );
VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].tvlist[2], &poly->vlist[poly->vert[2]] );
VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].vlist[0], &poly->vlist[poly->vert[0]] );
VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].vlist[1], &poly->vlist[poly->vert[1]] );
VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].vlist[2], &poly->vlist[poly->vert[2]] );
rend_list->poly_data[rend_list->num_polys].tvlist[0].t = poly->tlist[poly->text[0]];
rend_list->poly_data[rend_list->num_polys].tvlist[1].t = poly->tlist[poly->text[1]];
rend_list->poly_data[rend_list->num_polys].tvlist[2].t = poly->tlist[poly->text[2]];
rend_list->poly_data[rend_list->num_polys].vlist[0].t = poly->tlist[poly->text[0]];
rend_list->poly_data[rend_list->num_polys].vlist[1].t = poly->tlist[poly->text[1]];
rend_list->poly_data[rend_list->num_polys].vlist[2].t = poly->tlist[poly->text[2]];
if( rend_list->num_polys == 0 )
{
rend_list->poly_data[0].next = NULL;
rend_list->poly_data[0].prev = NULL;
}
else
{
rend_list->poly_data[rend_list->num_polys].next = NULL;
rend_list->poly_data[rend_list->num_polys].prev = & rend_list->poly_data[rend_list->num_polys-1];
rend_list->poly_data[rend_list->num_polys-1].next = & rend_list->poly_data[rend_list->num_polys];
}
rend_list->num_polys++;
return ( 1 );
}
去除背面
voidDDRAW_LIUSHUIXIAN_TEXTURE::Remove_Backfaces_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list, CAM4DV1_PTRcam, ddraw_mathmath )
{
// process each poly in mesh
for (int poly=0; poly < rend_list->num_polys; poly++)
{
// acquire polygon
POLYF4DV2_PTR curr_poly = rend_list->poly_ptrs[poly];
// is this polygon valid?
// test this polygon if and only if it's not clipped, not culled,
// active, and visible and not 2 sided. Note we test for backface in the event that
// a previous call might have already determined this, so why work
// harder!
if ( ( curr_poly ==NULL) ||
!(curr_poly->state &POLY4DV2_STATE_ACTIVE) ||
(curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||
(curr_poly->attr & POLY4DV2_ATTR_2SIDED) ||
(curr_poly->state &POLY4DV2_STATE_BACKFACE) )
{
continue;
}
VECTOR4D u,v, n;
// build u, v
math.VECTOR4D_Build(&curr_poly->tvlist[0].v,&curr_poly->tvlist[1].v, &u);
math.VECTOR4D_Build(&curr_poly->tvlist[0].v,&curr_poly->tvlist[2].v, &v);
// compute cross product
math.VECTOR4D_CROSS(&u, &v, &n);
// now create eye vector to viewpoint
VECTOR4D view;
math.VECTOR4D_Build(&curr_poly->tvlist[0].v, &cam->pos, &view);
// and finally, compute the dot product
float dp =math.VECTOR4D_DOT(&n, &view);
// if the sign is > 0 then visible, 0 = scathing, < 0 invisible
if (dp <= 0.0 )
SET_BIT(curr_poly->state,POLY4DV2_STATE_BACKFACE);
} // end for poly
}// end Remove_Backfaces_OBJECT4DV1
//世界坐标系到摄像机坐标系
voidDDRAW_LIUSHUIXIAN_TEXTURE::World_To_Camera_RENDERLIST4DV2(ddraw_math math2,RENDERLIST4DV2_PTRrend_list, CAM4DV1_PTRcam)
{
for( int poly = 0; poly < rend_list->num_polys; poly++ )
{
//获得当前多边形
POLYF4DV2_PTR curr_poly =rend_list->poly_ptrs[poly];
//当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)
if( ( curr_poly ==NULL ) ||
!( curr_poly->state &POLY4DV2_STATE_ACTIVE ) ||
( curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||
( curr_poly->state &POLY4DV2_STATE_BACKFACE ) )
continue; //进入下一个多边形
//满足条件,对其进行变换
for( int vertex = 0; vertex < 3; vertex ++ )
{
//使用相机对象中的矩阵mcma对顶点进行变换
POINT4D presult; //用于存储每次变换的结果
//对顶点进行变换
math2.Mat_Mul_VECTOR4D_4X4( &curr_poly->tvlist[vertex].v, &cam->mcam, &presult );
//将结果存回去
math2.VECTOR4D_COPY( &curr_poly->tvlist[vertex].v, &presult );
}
}
}
同样,更改Z排序
voidSort_RENDERLIST4DV2( RENDERLIST4DV2_PTR rend_list, int sort_method = SORT_POLYLIST_AVGZ )
{
switch( sort_method )
{
case SORT_POLYLIST_AVGZ:
{
qsort( ( void *)rend_list->poly_ptrs,rend_list->num_polys,sizeof( POLYF4DV2_PTR ),Compare_AvgZ_PolyF4DV2 );
}
break;
case SORT_POLYLIST_NEARZ:
{
qsort( ( void *)rend_list->poly_ptrs,rend_list->num_polys,sizeof( POLYF4DV2_PTR ),Compare_NearZ_PolyF4DV2);
}
break;
case SORT_POLYLIST_FARZ:
{
qsort( ( void *)rend_list->poly_ptrs,rend_list->num_polys,sizeof( POLYF4DV2_PTR ),Compare_FarZ_PolyF4DV2 );
}
break;
default:
break;
}
}
intCompare_AvgZ_PolyF4DV2( const void * arg1,const void * arg2 )
{
float z1, z2;
POLYF4DV2_PTR poly_1, poly_2;
poly_1 = * ( ( POLYF4DV2_PTR * ) ( arg1 ));
poly_2 = * ( ( POLYF4DV2_PTR * ) ( arg2 ));
z1 = ( float ) 0.33333 * ( poly_1->tvlist[0].z +poly_1->tvlist[1].z +poly_1->tvlist[2].z );
z2 = ( float ) 0.33333 * ( poly_2->tvlist[0].z +poly_2->tvlist[1].z +poly_2->tvlist[2].z );
if ( z1 >z2 )
{
return -1;
}
else
if ( z1 <z2)
{
return 1;
}
else
{
return 0;
}
}
intCompare_NearZ_PolyF4DV2( const void * arg1,const void * arg2 )
{
float z1, z2;
POLYF4DV2_PTR poly_1, poly_2;
poly_1 = * ( ( POLYF4DV2_PTR * ) ( arg1 ));
poly_2 = * ( ( POLYF4DV2_PTR * ) ( arg2 ));
z1 = MIN( poly_1->tvlist[0].z,poly_1->tvlist[1].z );
z1 = MIN( z1,poly_1->tvlist[2].z );
z2 = MIN( poly_2->tvlist[0].z,poly_2->tvlist[1].z );
z2 = MIN( z2,poly_2->tvlist[2].z );
if ( z1 >z2 )
{
return -1;
}
else
if ( z1 <z2)
{
return 1;
}
else
{
return 0;
}
}
intCompare_FarZ_PolyF4DV2( const void * arg1,const void * arg2 )
{
float z1, z2;
POLYF4DV2_PTR poly_1, poly_2;
poly_1 = * ( ( POLYF4DV2_PTR * ) ( arg1 ));
poly_2 = * ( ( POLYF4DV2_PTR * ) ( arg2 ));
z1 = MAX( poly_1->tvlist[0].z,poly_1->tvlist[1].z );
z1 = MAX( z1,poly_1->tvlist[2].z );
z2 = MAX( poly_2->tvlist[0].z,poly_2->tvlist[1].z );
z2 = MAX( z2,poly_2->tvlist[2].z );
if ( z1 >z2 )
{
return -1;
}
else
if ( z1 <z2)
{
return 1;
}
else
{
return 0;
}
}
相应的摄像机坐标系到投影坐标系
voidDDRAW_LIUSHUIXIAN_TEXTURE::Camera_To_Perspective_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list, CAM4DV1_PTRcam)
{
for( int poly = 0; poly < rend_list->num_polys; poly++ )
{
//获得当前多边形
POLYF4DV2_PTR curr_poly =rend_list->poly_ptrs[poly];
//当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)
if( ( curr_poly ==NULL ) ||
!( curr_poly->state &POLY4DV2_STATE_ACTIVE ) ||
( curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||
( curr_poly->state &POLY4DV2_STATE_BACKFACE ) )
continue; //进入下一个多边形
//满足条件,对其进行变换
for( int vertex = 0; vertex < 3; vertex ++ )
{
float z = curr_poly->tvlist[vertex].z;
//根据相机的观察参数对顶点进行变换
curr_poly->tvlist[vertex].x = cam->view_dist *curr_poly->tvlist[vertex].x /z;
curr_poly->tvlist[vertex].y = cam->view_dist *curr_poly->tvlist[vertex].y *cam->aspect_ratio /z;
}
}
}
投影坐标系到屏幕坐标系
voidDDRAW_LIUSHUIXIAN_TEXTURE::Perspective_To_Screen_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list, CAM4DV1_PTRcam)
{
for( int poly = 0; poly < rend_list->num_polys; poly++ )
{
//获得当前多边形
POLYF4DV2_PTR curr_poly =rend_list->poly_ptrs[poly];
//当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)
if( ( curr_poly ==NULL ) ||
!( curr_poly->state &POLY4DV2_STATE_ACTIVE ) ||
( curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||
( curr_poly->state &POLY4DV2_STATE_BACKFACE ) )
continue; //进入下一个多边形
float alpha = ( 0.5 * cam->viewport_width - 0.5 );
float beta = ( 0.5 *cam->viewport_height - 0.5 );
//满足条件,对其进行变换
for( int vertex = 0; vertex < 3; vertex ++ )
{
//顶点的透视坐标是归一化的,取值范围为-1到,对坐标进行缩放,并反转Y轴
curr_poly->tvlist[vertex].x = alpha + alpha *curr_poly->tvlist[vertex].x;
curr_poly->tvlist[vertex].y = beta - beta *curr_poly->tvlist[vertex].y;
}
}
}
与GOURAUD类似,用纹理代替颜色值
voidddraw_math::Draw_Textured_Triangle16(POLYF4DV2_PTR face,UCHAR * _dest_buffer,int mem_pitch )
{
int v0 = 0, v1 = 1,v2 = 2, temp = 0,tri_type = TRI_TYPE_NONE,irestart = INTERP_LHS;
int dx, dy, dyl, dyr, //存储差值
u, v, //UV值
du, dv,
xi, yi, //当前的x和y坐标
ui,vi, //当前的UV值
index_x, index_y, //循环变量
x, y, //存储一般性X和Y坐标
xstart, xend,ystart,yrestart, yend,xl,
dxdyl, xr,dxdyr, dudyl,ul, dvdyl, vl,
dudyr, ur,dvdyr, vr;
int x0, y0, tu0, tv0, //顶点的初始颜色
x1, y1,tu1, tv1,
x2, y2,tu2, tv2;
USHORT * screen_ptr = NULL,
* screen_line = NULL,
* textmap = NULL,
* dest_buffer = (USHORT * )_dest_buffer;
UCHAR logbase2ofx[513] =
{
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};
//提取纹理图
textmap = ( USHORT * ) face->texture->buffer;
int texture_shift2 =logbase2ofx[face->texture->width];
//将内存跨距的单位调整为字
mem_pitch >>= 1;
//判断三角形是否在屏幕内
if ( ( ( face->tvlist[0].y <m_min_clip_y) &&
( face->tvlist[1].y <m_min_clip_y) &&
( face->tvlist[2].y <m_min_clip_y) ) ||
( ( face->tvlist[0].y >m_max_clip_y) &&
( face->tvlist[1].y >m_max_clip_y) &&
( face->tvlist[2].y >m_max_clip_y) ) ||
( ( face->tvlist[0].x <m_min_clip_x) &&
( face->tvlist[1].x <m_min_clip_x) &&
( face->tvlist[2].x <m_min_clip_x) ) ||
( ( face->tvlist[0].x >m_max_clip_x) &&
( face->tvlist[1].x >m_max_clip_x) &&
( face->tvlist[2].x >m_max_clip_x) ) )
{
return;
}
//判断三角形是否退化为直线
if ( ( ( face->tvlist[0].x ==face->tvlist[1].x ) &&
( face->tvlist[1].x ==face->tvlist[2].x ) ) ||
( ( face->tvlist[0].y ==face->tvlist[1].y ) &&
( face->tvlist[1].y ==face->tvlist[2].y ) ) )
{
return;
}
//对顶点进行排序
if ( face->tvlist[v1].y <face->tvlist[v0].y )
{
SWAP( v0,v1, temp );
}
if ( face->tvlist[v2].y <face->tvlist[v0].y )
{
SWAP( v0,v2, temp );
}
if ( face->tvlist[v2].y <face->tvlist[v1].y )
{
SWAP( v1,v2, temp );
}
//判断三角形是否平顶
if ( face->tvlist[v0].y ==face->tvlist[v1].y )
{
//设置三角形类型
tri_type = TRI_TYPE_FLAT_TOP;
//将顶点从左到右的顺序排列
if ( face->tvlist[v1].x <face->tvlist[v0].x )
{
SWAP( v0,v1, temp );
}
}
else
//判断三角形是否平底
if ( face->tvlist[v1].y ==face->tvlist[v2].y )
{
//设置三角形类型
tri_type = TRI_TYPE_FLAT_BOTTOM;
//将顶点从左到右的顺序排列
if ( face->tvlist[v2].x <face->tvlist[v1].x )
{
SWAP( v1,v2, temp );
}
}
else
//肯定是常规三角形
{
tri_type = TRI_TYPE_GENERAL;
}
//提取各个顶点的坐标值和RGB值
x0 = ( int ) ( face->tvlist[v0].x + 0.5 );
y0 = ( int ) ( face->tvlist[v0].y + 0.5 );
tu0 = ( int ) ( face->tvlist[v0].u0 );
tv0 = ( int ) ( face->tvlist[v0].v0 );
x1 = ( int ) ( face->tvlist[v1].x + 0.5 );
y1 = ( int ) ( face->tvlist[v1].y + 0.5 );
tu1 = ( int ) ( face->tvlist[v1].u0 );
tv1 = ( int ) ( face->tvlist[v1].v0 );
x2 = ( int ) ( face->tvlist[v2].x + 0.5 );
y2 = ( int ) ( face->tvlist[v2].y + 0.5 );
tu2 = ( int ) ( face->tvlist[v2].u0 );
tv2 = ( int ) ( face->tvlist[v2].v0 );
//设置斜率转折点
yrestart = y1;
//判断三角形类型
if ( tri_type &TRI_TYPE_FLAT_MASK )
{
if ( tri_type ==TRI_TYPE_FLAT_TOP )
{
//计算各种差值
dy = y2 - y0;
dxdyl = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dy;
dudyl = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dy;
dvdyl = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dy;
dxdyr = ( ( x2 - x1 ) << FIXP16_SHIFT ) / dy;
dudyr = ( ( tu2 - tu1 ) << FIXP16_SHIFT ) / dy;
dvdyr = ( ( tv2 - tv1 ) << FIXP16_SHIFT ) / dy;
//垂直裁剪测试
if ( y0 <m_min_clip_y )
{
//垂直计算Y坐标差值
dy = ( m_min_clip_y - y0 );
//计算第一条扫描线起点的各种值
xl = dxdyl * dy + (x0 << FIXP16_SHIFT );
ul = dudyl * dy + (tu0 << FIXP16_SHIFT );
vl = dvdyl * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线终点的各种值
xr = dxdyr * dy + (x1 << FIXP16_SHIFT );
ur = dudyr * dy + (tu1 << FIXP16_SHIFT );
vr = dvdyr * dy + (tv1 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = m_min_clip_y;
}
else
{
//不用裁剪
//设置第一条扫描线起点和终点的各种值
xl = ( x0 << FIXP16_SHIFT );
ul = ( tu0 << FIXP16_SHIFT );
vl = ( tv0 << FIXP16_SHIFT );
xr = ( x1 << FIXP16_SHIFT );
ur = ( tu1 << FIXP16_SHIFT );
vr = ( tv1 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = y0;
}
}
else //肯定是平底三角形
{
//计算各种差值
dy = y1 - y0;
dxdyl = ( ( x1 - x0 ) << FIXP16_SHIFT ) / dy;
dudyl = ( ( tu1 - tu0 ) << FIXP16_SHIFT ) / dy;
dvdyl = ( ( tv1 - tv0 ) << FIXP16_SHIFT ) / dy;
dxdyr = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dy;
dudyr = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dy;
dvdyr = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dy;
//垂直裁剪测试
if ( y0 <m_min_clip_y )
{
//垂直计算Y坐标差值
dy = ( m_min_clip_y - y0 );
//计算第一条扫描线起点的各种值
xl = dxdyl * dy + (x0 << FIXP16_SHIFT );
ul = dudyl * dy + (tu0 << FIXP16_SHIFT );
vl = dvdyl * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线终点的各种值
xr = dxdyr * dy + (x0 << FIXP16_SHIFT );
ur = dudyr * dy + (tu0 << FIXP16_SHIFT );
vr = dvdyr * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = m_min_clip_y;
}
else
{
//不用裁剪
//设置第一条扫描线起点和终点的各种值
xl = ( x0 << FIXP16_SHIFT );
ul = ( tu0 << FIXP16_SHIFT );
vl = ( tv0 << FIXP16_SHIFT );
xr = ( x0 << FIXP16_SHIFT );
ur = ( tu0 << FIXP16_SHIFT );
vr = ( tv0 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = y0;
}
}
//总是检测三角形最下面的部分是否会被裁剪掉
if (( yend =y2 ) > m_max_clip_y )
{
yend = m_max_clip_y;
}
//水平裁剪测试
if ( ( x0 <m_min_clip_x ) || ( x0 > m_max_clip_x ) ||
( x1 < m_min_clip_x ) || (x1 > m_max_clip_x ) ||
( x2 < m_min_clip_x ) || (x2 > m_max_clip_x ) )
{
//裁剪版本
//让指screen_ptr指向第一条扫描线起点在缓存的位置
screen_ptr = dest_buffer + ( ystart * mem_pitch );
for ( yi =ystart; yi <=yend; yi++ )
{
//计算扫描线起点和终点的X坐标
xstart = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );
xend = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );
//计算扫描线起点和终点的坐标
ui = ul + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
//计算扫描线上的RGB梯度
if ( ( dx = (xend - xstart )) > 0 )
{
du = ( ur - ul ) /dx;
dv = ( vr - vl ) /dx;
}
else
{
du = ( ur - ul );
dv = ( vr - vl );
}
//扫描线起点水平裁剪测试
if ( xstart <m_min_clip_x )
{
//计算起点移动距离
dx = m_min_clip_x - xstart;
//重新计算扫描线起点的RGB值
ui += dx * du;
vi += dx * dv;
//重新设置循环起始条件
xstart = m_min_clip_x;
}
//终点水平测试
if ( xend >m_max_clip_x )
{
xend = m_max_clip_x;
}
//绘制扫描线
for( xi =xstart; xi <=xend; xi ++ )
{
//绘制像素,假设格式为.6.5
screen_ptr[xi] = textmap[ ( ui >> FIXP16_SHIFT ) + ( ( vi >> FIXP16_SHIFT ) << texture_shift2 )];
//计算下一个像素的UV值
ui += du;
vi += dv;
}
//计算下一条扫描线起点和终点的x坐标和RGB值
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
//让指针screen_ptr指向视频缓存的下一行
screen_ptr += mem_pitch;
}
}
//三角形没有被裁剪时的绘制代码
else
{
screen_ptr = dest_buffer + ( ystart * mem_pitch );
for ( yi =ystart; yi <=yend; yi++ )
{
//计算扫描线起点和终点的X坐标
xstart = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );
xend = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );
//计算扫描线起点和终点的坐标
ui = ul + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
//计算扫描线上的RGB梯度
if ( ( dx = (xend - xstart )) > 0 )
{
du = ( ur - ul ) /dx;
dv = ( vr - vl ) /dx;
}
else
{
du = ( ur - ul );
dv = ( vr - vl );
}
//绘制扫描线
for( xi =xstart; xi <=xend; xi ++ )
{
//绘制像素,
screen_ptr[xi] = textmap[( ui >> FIXP16_SHIFT ) + ( ( vi >> FIXP16_SHIFT ) << texture_shift2 )];
//计算下一个像素的RGB值
ui += du;
vi += dv;
}
//计算下一条扫描线起点和终点的x坐标和RGB值
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
//让指针screen_ptr指向视频缓存的下一行
screen_ptr += mem_pitch;
}
}
}
else
//绘制常规三角形
if ( tri_type ==TRI_TYPE_GENERAL )
{
if (( yend =y2 ) > m_max_clip_y )
{
yend = m_max_clip_y;
}
if ( y1 <m_min_clip_y )
{
//垂直计算Y坐标差值
//左侧
dyl = ( y2 - y1 );
dxdyl = ( ( x2 - x1 ) << FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu2 - tu1 ) << FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv2 - tv1 ) << FIXP16_SHIFT ) / dyl;
//右侧
dyr = ( y2 - y0 );
dxdyr = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dyr;
//垂直计算Y坐标差值
dyr = ( m_min_clip_y - y0 );
dyl = ( m_min_clip_y - y1 ) ;
//计算第一条扫描线起点的各种值
xl = dxdyl * dyl + (xl << FIXP16_SHIFT );
ul = dudyl * dyl + (tu1 << FIXP16_SHIFT );
vl = dvdyl * dyl + (tv1 << FIXP16_SHIFT );
//计算第一条扫描线终点的各种值
xr = dxdyr * dyr + (x0 << FIXP16_SHIFT );
ur = dudyr * dyr + (tu0 << FIXP16_SHIFT );
vr = dvdyr * dyr + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = m_min_clip_y;
if ( dxdyr >dxdyl )
{
SWAP( dxdyl,dxdyr, temp );
SWAP( dudyl,dudyr, temp );
SWAP( dvdyl,dvdyr, temp );
SWAP(xl, xr, temp );
SWAP( ul,ur, temp );
SWAP( vl,vr, temp );
SWAP( x1,x2, temp );
SWAP( y1,y2, temp );
SWAP( tu1,tu2, temp );
SWAP( tv1,tv2, temp );
irestart = INTERP_RHS;
}
}
else
if ( y0 < m_min_clip_y )
{
//垂直计算Y坐标差值
//左侧
dyl = ( y1 - y0 );
dxdyl = ( ( x1 - x0 ) << FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu1 - tu0 ) << FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv1 - tv0 ) << FIXP16_SHIFT ) / dyl;
//右侧
dyr = ( y2 - y0 );
dxdyr = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dyr;
//垂直计算Y坐标差值
dy = ( m_min_clip_y - y0 );
//计算第一条扫描线起点的各种值
xl = dxdyl * dy + (x0 << FIXP16_SHIFT );
ul = dudyl * dy + (tu0 << FIXP16_SHIFT );
vl = dvdyl * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线终点的各种值
xr = dxdyr * dy + (x0 << FIXP16_SHIFT );
ur = dudyr * dy + (tu0 << FIXP16_SHIFT );
vr = dvdyr * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = m_min_clip_y;
if ( dxdyr <dxdyl )
{
SWAP( dxdyl,dxdyr, temp );
SWAP( dudyl,dudyr, temp );
SWAP( dvdyl,dvdyr, temp );
SWAP( xl,xr, temp );
SWAP( ul,ur, temp );
SWAP( vl,vr, temp );
SWAP( x1,x2, temp );
SWAP( y1,y2, temp );
SWAP(tu1, tu2, temp );
SWAP( tv1,tv2, temp );
irestart = INTERP_RHS;
}
}
else
{
dyl = ( y1 - y0 );
dxdyl = ( ( x1 - x0 ) << FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu1 - tu0 ) << FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv1 - tv0 ) << FIXP16_SHIFT ) / dyl;
//右侧
dyr = ( y2 - y0 );
dxdyr = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv2 -tv0 ) << FIXP16_SHIFT ) /dyr;
xl = ( x0 << FIXP16_SHIFT );
ul = ( tu0 << FIXP16_SHIFT );
vl = ( tv0 << FIXP16_SHIFT );
xr = ( x0 << FIXP16_SHIFT );
ur = ( tu0 << FIXP16_SHIFT );
vr = ( tv0 << FIXP16_SHIFT );
ystart = y0;
if ( dxdyr <dxdyl )
{
SWAP( dxdyl,dxdyr, temp );
SWAP( dudyl,dudyr, temp );
SWAP( dvdyl,dvdyr, temp );
SWAP( xl,xr, temp );
SWAP( ul,ur, temp );
SWAP( vl,vr, temp );
SWAP( x1,x2, temp );
SWAP( y1,y2, temp );
SWAP( tu1,tu2, temp );
SWAP( tv1,tv2, temp );
irestart = INTERP_RHS;
}
}
//水平裁剪测试
if ( ( x0 <m_min_clip_x ) || ( x0 > m_max_clip_x ) ||
( x1 < m_min_clip_x ) || (x1 > m_max_clip_x ) ||
( x2 < m_min_clip_x ) || (x2 > m_max_clip_x ) )
{
//裁剪版本
//让指screen_ptr指向第一条扫描线起点在缓存的位置
screen_ptr = dest_buffer + ( ystart * mem_pitch );
for ( yi =ystart; yi <=yend; yi++ )
{
//计算扫描线起点和终点的X坐标
xstart = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );
xend = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );
//计算扫描线起点和终点的坐标
ui = ul + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
//计算扫描线上的RGB梯度
if ( ( dx = (xend - xstart )) > 0 )
{
du = ( ur - ul ) /dx;
dv = ( vr - vl ) /dx;
}
else
{
du = ( ur - ul );
dv = ( vr - vl );
}
//扫描线起点水平裁剪测试
if ( xstart <m_min_clip_x )
{
//计算起点移动距离
dx = m_min_clip_x - xstart;
//重新计算扫描线起点的RGB值
ui += dx * du;
vi += dx * dv;
//重新设置循环起始条件
xstart = m_min_clip_x;
}
//终点水平测试
if ( xend >m_max_clip_x )
{
xend = m_max_clip_x;
}
//绘制扫描线
for( xi =xstart; xi <=xend; xi ++ )
{
//绘制像素,假设格式为.6.5
screen_ptr[xi] = textmap[( ui >> FIXP16_SHIFT ) + ( ( vi >> FIXP16_SHIFT ) << texture_shift2 )];
//计算下一个像素的uv值
ui += du;
vi += dv;
}
//计算下一条扫描线起点和终点的x坐标和RGB值
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
//让指针screen_ptr指向视频缓存的下一行
screen_ptr += mem_pitch;
if ( yi ==yrestart )
{
if ( irestart ==INTERP_LHS )
{
dyl = ( y2 - y1 );
dxdyl = ( ( x2 - x1 ) <<FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu2 - tu1 ) <<FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv2 - tv1 ) <<FIXP16_SHIFT ) / dyl;
xl = ( xl << FIXP16_SHIFT );
ul = ( tu1 << FIXP16_SHIFT );
vl = ( tv1 << FIXP16_SHIFT );
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
}
else
{
dyr = ( y1 - y2 );
dxdyr = ( ( x1 - x2 ) <<FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu1 - tu2 ) <<FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv1 - tv2 ) <<FIXP16_SHIFT ) / dyr;
xr = ( x2 << FIXP16_SHIFT );
ur = ( tu2 << FIXP16_SHIFT );
vr = ( tv2 << FIXP16_SHIFT );
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
}
}
}
}
else
{
//裁剪版本
//让指screen_ptr指向第一条扫描线起点在缓存的位置
screen_ptr = dest_buffer + ( ystart * mem_pitch );
for ( yi =ystart; yi <=yend; yi++ )
{
//计算扫描线起点和终点的X坐标
xstart = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );
xend = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );
//计算扫描线起点和终点的坐标
ui = ul + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
//计算扫描线上的RGB梯度
if ( ( dx = (xend - xstart )) > 0 )
{
du = ( ur - ul ) /dx;
dv = ( vr - vl ) /dx;
}
else
{
du = ( ur - ul );
dv = ( vr - vl );
}
//绘制扫描线
for( xi =xstart; xi <=xend; xi ++ )
{
//绘制像素,
screen_ptr[xi] = textmap[( ui >> FIXP16_SHIFT ) + ( ( vi >> FIXP16_SHIFT ) << texture_shift2 )];
//计算下一个像素的RGB值
ui += du;
vi += dv;
}
//计算下一条扫描线起点和终点的x坐标和RGB值
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
//让指针screen_ptr指向视频缓存的下一行
screen_ptr += mem_pitch;
if ( yi ==yrestart )
{
if ( irestart ==INTERP_LHS )
{
dyl = ( y2 - y1 );
dxdyl = ( ( x2 - x1 ) <<FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu2 - tu1 ) <<FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv2 - tv1 ) <<FIXP16_SHIFT ) / dyl;
xl = ( xl << FIXP16_SHIFT );
ul = ( tu1 << FIXP16_SHIFT );
vl = ( tv1 << FIXP16_SHIFT );
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
}
else
{
dyr = ( y1 - y2 );
dxdyr = ( ( x1 - x2 ) <<FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu1 - tu2 ) <<FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv1 - tv2 ) <<FIXP16_SHIFT ) / dyr;
xr = ( x2 << FIXP16_SHIFT );
ur = ( tu2 << FIXP16_SHIFT );
vr = ( tv2 << FIXP16_SHIFT );
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
}
}
}
}
}
}
一个类似的函数
voidddraw_math::Draw_Textured_TriangleFS16(POLYF4DV2_PTR face,UCHAR * _dest_buffer,int mem_pitch )
{
int v0 = 0, v1 = 1,v2 = 2, temp = 0,tri_type = TRI_TYPE_NONE,irestart = INTERP_LHS;
int dx, dy, dyl, dyr, //存储差值
u, v, //UV值
du, dv,
xi, yi, //当前的x和y坐标
ui,vi, //当前的UV值
index_x, index_y, //循环变量
x, y, //存储一般性X和Y坐标
xstart, xend,ystart,yrestart, yend,xl,
dxdyl, xr,dxdyr, dudyl,ul, dvdyl, vl,
dudyr, ur,dvdyr, vr;
USHORT r_base,g_base, b_base,
r_textel, g_textel,b_textel, textel;
int x0, y0, tu0, tv0, //顶点的初始颜色
x1, y1,tu1, tv1,
x2, y2,tu2, tv2;
USHORT * screen_ptr = NULL,
* screen_line = NULL,
* textmap = NULL,
* dest_buffer = (USHORT * )_dest_buffer;
UCHAR logbase2ofx[513] =
{
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};
//提取纹理图
textmap = ( USHORT * ) face->texture->buffer;
int texture_shift2 =logbase2ofx[face->texture->width];
//将内存跨距的单位调整为字
mem_pitch >>= 1;
//判断三角形是否在屏幕内
if ( ( ( face->tvlist[0].y <m_min_clip_y) &&
( face->tvlist[1].y <m_min_clip_y) &&
( face->tvlist[2].y <m_min_clip_y) ) ||
( ( face->tvlist[0].y >m_max_clip_y) &&
( face->tvlist[1].y >m_max_clip_y) &&
( face->tvlist[2].y >m_max_clip_y) ) ||
( ( face->tvlist[0].x <m_min_clip_x) &&
( face->tvlist[1].x <m_min_clip_x) &&
( face->tvlist[2].x <m_min_clip_x) ) ||
( ( face->tvlist[0].x >m_max_clip_x) &&
( face->tvlist[1].x >m_max_clip_x) &&
( face->tvlist[2].x >m_max_clip_x) ) )
{
return;
}
//判断三角形是否退化为直线
if ( ( ( face->tvlist[0].x ==face->tvlist[1].x ) &&
( face->tvlist[1].x ==face->tvlist[2].x ) ) ||
( ( face->tvlist[0].y ==face->tvlist[1].y ) &&
( face->tvlist[1].y ==face->tvlist[2].y ) ) )
{
return;
}
//对顶点进行排序
if ( face->tvlist[v1].y <face->tvlist[v0].y )
{
SWAP( v0,v1, temp );
}
if ( face->tvlist[v2].y <face->tvlist[v0].y )
{
SWAP( v0,v2, temp );
}
if ( face->tvlist[v2].y <face->tvlist[v1].y )
{
SWAP( v1,v2, temp );
}
//判断三角形是否平顶
if ( face->tvlist[v0].y ==face->tvlist[v1].y )
{
//设置三角形类型
tri_type = TRI_TYPE_FLAT_TOP;
//将顶点从左到右的顺序排列
if ( face->tvlist[v1].x <face->tvlist[v0].x )
{
SWAP( v0,v1, temp );
}
}
else
//判断三角形是否平底
if ( face->tvlist[v1].y ==face->tvlist[v2].y )
{
//设置三角形类型
tri_type = TRI_TYPE_FLAT_BOTTOM;
//将顶点从左到右的顺序排列
if ( face->tvlist[v2].x <face->tvlist[v1].x )
{
SWAP( v1,v2, temp );
}
}
else
//肯定是常规三角形
{
tri_type = TRI_TYPE_GENERAL;
}
_RGB565FROM16BIT( face->lit_color[0], & r_base, & g_base, & b_base );
//提取各个顶点的坐标值和RGB值
x0 = ( int ) ( face->tvlist[v0].x + 0.5 );
y0 = ( int ) ( face->tvlist[v0].y + 0.5 );
tu0 = ( int ) ( face->tvlist[v0].u0 );
tv0 = ( int ) ( face->tvlist[v0].v0 );
x1 = ( int ) ( face->tvlist[v1].x + 0.5 );
y1 = ( int ) ( face->tvlist[v1].y + 0.5 );
tu1 = ( int ) ( face->tvlist[v1].u0 );
tv1 = ( int ) ( face->tvlist[v1].v0 );
x2 = ( int ) ( face->tvlist[v2].x + 0.5 );
y2 = ( int ) ( face->tvlist[v2].y + 0.5 );
tu2 = ( int ) ( face->tvlist[v2].u0 );
tv2 = ( int ) ( face->tvlist[v2].v0 );
//设置斜率转折点
yrestart = y1;
//判断三角形类型
if ( tri_type &TRI_TYPE_FLAT_MASK )
{
if ( tri_type ==TRI_TYPE_FLAT_TOP )
{
//计算各种差值
dy = y2 - y0;
dxdyl = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dy;
dudyl = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dy;
dvdyl = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dy;
dxdyr = ( ( x2 - x1 ) << FIXP16_SHIFT ) / dy;
dudyr = ( ( tu2 - tu1 ) << FIXP16_SHIFT ) / dy;
dvdyr = ( ( tv2 - tv1 ) << FIXP16_SHIFT ) / dy;
//垂直裁剪测试
if ( y0 <m_min_clip_y )
{
//垂直计算Y坐标差值
dy = ( m_min_clip_y - y0 );
//计算第一条扫描线起点的各种值
xl = dxdyl * dy + (x0 << FIXP16_SHIFT );
ul = dudyl * dy + (tu0 << FIXP16_SHIFT );
vl = dvdyl * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线终点的各种值
xr = dxdyr * dy + (x1 << FIXP16_SHIFT );
ur = dudyr * dy + (tu1 << FIXP16_SHIFT );
vr = dvdyr * dy + (tv1 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = m_min_clip_y;
}
else
{
//不用裁剪
//设置第一条扫描线起点和终点的各种值
xl = ( x0 << FIXP16_SHIFT );
ul = ( tu0 << FIXP16_SHIFT );
vl = ( tv0 << FIXP16_SHIFT );
xr = ( x1 << FIXP16_SHIFT );
ur = ( tu1 << FIXP16_SHIFT );
vr = ( tv1 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = y0;
}
}
else //肯定是平底三角形
{
//计算各种差值
dy = y1 - y0;
dxdyl = ( ( x1 - x0 ) << FIXP16_SHIFT ) / dy;
dudyl = ( ( tu1 - tu0 ) << FIXP16_SHIFT ) / dy;
dvdyl = ( ( tv1 - tv0 ) << FIXP16_SHIFT ) / dy;
dxdyr = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dy;
dudyr = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dy;
dvdyr = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dy;
//垂直裁剪测试
if ( y0 <m_min_clip_y )
{
//垂直计算Y坐标差值
dy = ( m_min_clip_y - y0 );
//计算第一条扫描线起点的各种值
xl = dxdyl * dy + (x0 << FIXP16_SHIFT );
ul = dudyl * dy + (tu0 << FIXP16_SHIFT );
vl = dvdyl * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线终点的各种值
xr = dxdyr * dy + (x0 << FIXP16_SHIFT );
ur = dudyr * dy + (tu0 << FIXP16_SHIFT );
vr = dvdyr * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = m_min_clip_y;
}
else
{
//不用裁剪
//设置第一条扫描线起点和终点的各种值
xl = ( x0 << FIXP16_SHIFT );
ul = ( tu0 << FIXP16_SHIFT );
vl = ( tv0 << FIXP16_SHIFT );
xr = ( x0 << FIXP16_SHIFT );
ur = ( tu0 << FIXP16_SHIFT );
vr = ( tv0 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = y0;
}
}
//总是检测三角形最下面的部分是否会被裁剪掉
if (( yend =y2 ) > m_max_clip_y )
{
yend = m_max_clip_y;
}
//水平裁剪测试
if ( ( x0 <m_min_clip_x ) || ( x0 > m_max_clip_x ) ||
( x1 < m_min_clip_x ) || (x1 > m_max_clip_x ) ||
( x2 < m_min_clip_x ) || (x2 > m_max_clip_x ) )
{
//裁剪版本
//让指screen_ptr指向第一条扫描线起点在缓存的位置
screen_ptr = dest_buffer + ( ystart * mem_pitch );
for ( yi =ystart; yi <=yend; yi++ )
{
//计算扫描线起点和终点的X坐标
xstart = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );
xend = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );
//计算扫描线起点和终点的坐标
ui = ul + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
//计算扫描线上的RGB梯度
if ( ( dx = (xend - xstart )) > 0 )
{
du = ( ur - ul ) /dx;
dv = ( vr - vl ) /dx;
}
else
{
du = ( ur - ul );
dv = ( vr - vl );
}
//扫描线起点水平裁剪测试
if ( xstart <m_min_clip_x )
{
//计算起点移动距离
dx = m_min_clip_x - xstart;
//重新计算扫描线起点的RGB值
ui += dx * du;
vi += dx * dv;
//重新设置循环起始条件
xstart = m_min_clip_x;
}
//终点水平测试
if ( xend >m_max_clip_x )
{
xend = m_max_clip_x;
}
//绘制扫描线
for( xi =xstart; xi <=xend; xi ++ )
{
//绘制像素,假设格式为.6.5
textel = textmap[ ( ui >>FIXP16_SHIFT ) + ( ( vi >> FIXP16_SHIFT ) << texture_shift2 )];
r_textel = ( ( textel >> 11 );
g_textel = ( ( textel >> 5 ) & 0x3f );
b_textel = ( textel & 0x1f );
r_textel *= r_base;
g_textel *= g_base;
b_textel *= b_base;
screen_ptr[xi] = ( ( b_textel >> 5 ) + ( ( g_textel >> 6 ) << 5 ) + ( ( r_texte >> 5 ) << 11 ) );
//计算下一个像素的UV值
ui += du;
vi += dv;
}
//计算下一条扫描线起点和终点的x坐标和RGB值
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
//让指针screen_ptr指向视频缓存的下一行
screen_ptr += mem_pitch;
}
}
//三角形没有被裁剪时的绘制代码
else
{
screen_ptr = dest_buffer + ( ystart * mem_pitch );
for ( yi =ystart; yi <=yend; yi++ )
{
//计算扫描线起点和终点的X坐标
xstart = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );
xend = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );
//计算扫描线起点和终点的坐标
ui = ul + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
//计算扫描线上的RGB梯度
if ( ( dx = (xend - xstart )) > 0 )
{
du = ( ur - ul ) /dx;
dv = ( vr - vl ) /dx;
}
else
{
du = ( ur - ul );
dv = ( vr - vl );
}
//绘制扫描线
for( xi = xstart; xi <= xend; xi ++ )
{
//绘制像素,
textel = textmap[ ( ui >>FIXP16_SHIFT ) + ( ( vi >> FIXP16_SHIFT ) << texture_shift2 )];
r_textel = ( ( textel >> 11 ) );
g_textel = ( ( textel >> 5 ) & 0x3f );
b_textel = ( textel & 0x1f );
r_textel *= r_base;
g_textel *= g_base;
b_textel *= b_base;
screen_ptr[xi] = ( ( b_textel >> 5 ) + ( ( g_textel >> 6 ) << 5 ) + ( ( r_texte >> 5 ) << 11 ) );
//计算下一个像素的RGB值
ui += du;
vi += dv;
}
//计算下一条扫描线起点和终点的x坐标和RGB值
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
//让指针screen_ptr指向视频缓存的下一行
screen_ptr += mem_pitch;
}
}
}
else
//绘制常规三角形
if ( tri_type ==TRI_TYPE_GENERAL )
{
if (( yend =y2 ) > m_max_clip_y )
{
yend = m_max_clip_y;
}
if ( y1 <m_min_clip_y )
{
//垂直计算Y坐标差值
//左侧
dyl = ( y2 - y1 );
dxdyl = ( ( x2 - x1 ) << FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu2 - tu1 ) << FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv2 - tv1 ) << FIXP16_SHIFT ) / dyl;
//右侧
dyr = ( y2 - y0 );
dxdyr = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dyr;
//垂直计算Y坐标差值
dyr = ( m_min_clip_y - y0 );
dyl = ( m_min_clip_y - y1 ) ;
//计算第一条扫描线起点的各种值
xl = dxdyl * dyl + (xl << FIXP16_SHIFT );
ul = dudyl * dyl + (tu1 << FIXP16_SHIFT );
vl = dvdyl * dyl + (tv1 << FIXP16_SHIFT );
//计算第一条扫描线终点的各种值
xr = dxdyr * dyr + (x0 << FIXP16_SHIFT );
ur = dudyr * dyr + (tu0 << FIXP16_SHIFT );
vr = dvdyr * dyr + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = m_min_clip_y;
if ( dxdyr >dxdyl )
{
SWAP( dxdyl,dxdyr, temp );
SWAP( dudyl,dudyr, temp );
SWAP( dvdyl,dvdyr, temp );
SWAP( xl,xr, temp );
SWAP( ul,ur, temp );
SWAP( vl,vr, temp );
SWAP( x1,x2, temp );
SWAP( y1,y2, temp );
SWAP( tu1,tu2, temp );
SWAP( tv1,tv2, temp );
irestart = INTERP_RHS;
}
}
else
if ( y0 <m_min_clip_y )
{
//垂直计算Y坐标差值
//左侧
dyl = ( y1 - y0 );
dxdyl = ( ( x1 - x0 ) << FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu1 - tu0 ) << FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv1 - tv0 ) << FIXP16_SHIFT ) / dyl;
//右侧
dyr = ( y2 - y0 );
dxdyr = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dyr;
//垂直计算Y坐标差值
dy = ( m_min_clip_y - y0 );
//计算第一条扫描线起点的各种值
xl = dxdyl * dy + (x0 << FIXP16_SHIFT );
ul = dudyl * dy + (tu0 << FIXP16_SHIFT );
vl = dvdyl * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线终点的各种值
xr = dxdyr * dy + (x0 << FIXP16_SHIFT );
ur = dudyr * dy + (tu0 << FIXP16_SHIFT );
vr = dvdyr * dy + (tv0 << FIXP16_SHIFT );
//计算第一条扫描线的Y坐标
ystart = m_min_clip_y;
if ( dxdyr <dxdyl )
{
SWAP( dxdyl,dxdyr, temp );
SWAP( dudyl,dudyr, temp );
SWAP( dvdyl,dvdyr, temp );
SWAP( xl,xr, temp );
SWAP( ul,ur, temp );
SWAP( vl,vr, temp );
SWAP( x1,x2, temp );
SWAP( y1,y2, temp );
SWAP( tu1,tu2, temp );
SWAP( tv1,tv2, temp );
irestart = INTERP_RHS;
}
}
else
{
dyl = ( y1 - y0 );
dxdyl = ( ( x1 - x0 ) << FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu1 - tu0 ) << FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv1 - tv0 ) << FIXP16_SHIFT ) / dyl;
//右侧
dyr = ( y2 - y0 );
dxdyr = ( ( x2 - x0 ) << FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu2 - tu0 ) << FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv2 - tv0 ) << FIXP16_SHIFT ) / dyr;
xl = ( x0 << FIXP16_SHIFT );
ul = ( tu0 << FIXP16_SHIFT );
vl = ( tv0 << FIXP16_SHIFT );
xr = ( x0 << FIXP16_SHIFT );
ur = ( tu0 << FIXP16_SHIFT );
vr = ( tv0 << FIXP16_SHIFT );
ystart = y0;
if ( dxdyr <dxdyl )
{
SWAP( dxdyl,dxdyr, temp );
SWAP( dudyl,dudyr, temp );
SWAP( dvdyl,dvdyr, temp );
SWAP(xl, xr, temp );
SWAP( ul,ur, temp );
SWAP( vl,vr, temp );
SWAP( x1,x2, temp );
SWAP( y1,y2, temp );
SWAP( tu1,tu2, temp );
SWAP( tv1,tv2, temp );
irestart = INTERP_RHS;
}
}
//水平裁剪测试
if ( ( x0 <m_min_clip_x ) || ( x0 > m_max_clip_x ) ||
( x1 < m_min_clip_x ) || (x1 > m_max_clip_x ) ||
( x2 < m_min_clip_x ) || (x2 > m_max_clip_x ) )
{
//裁剪版本
//让指screen_ptr指向第一条扫描线起点在缓存的位置
screen_ptr = dest_buffer + ( ystart * mem_pitch );
for ( yi =ystart; yi <=yend; yi++ )
{
//计算扫描线起点和终点的X坐标
xstart = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );
xend = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );
//计算扫描线起点和终点的坐标
ui = ul + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
//计算扫描线上的RGB梯度
if ( ( dx = (xend - xstart )) > 0 )
{
du = ( ur - ul ) /dx;
dv = ( vr - vl ) /dx;
}
else
{
du = ( ur - ul );
dv = ( vr - vl );
}
//扫描线起点水平裁剪测试
if ( xstart <m_min_clip_x )
{
//计算起点移动距离
dx = m_min_clip_x - xstart;
//重新计算扫描线起点的RGB值
ui += dx * du;
vi += dx * dv;
//重新设置循环起始条件
xstart = m_min_clip_x;
}
//终点水平测试
if ( xend >m_max_clip_x )
{
xend = m_max_clip_x;
}
//绘制扫描线
for( xi =xstart; xi <=xend; xi ++ )
{
//绘制像素,假设格式为.6.5
textel = textmap[ ( ui >>FIXP16_SHIFT ) + ( ( vi >> FIXP16_SHIFT ) << texture_shift2 )];
r_textel = ( ( textel >> 11 );
g_textel = ( ( textel >> 5 ) & 0x3f );
b_textel = ( textel & 0x1f );
r_textel *= r_base;
g_textel *= g_base;
b_textel *= b_base;
screen_ptr[xi] = ( ( b_textel >> 5 ) + ( ( g_textel >> 6 ) << 5 ) + ( ( r_texte >> 5 ) << 11 ) );
//计算下一个像素的uv值
ui += du;
vi += dv;
}
//计算下一条扫描线起点和终点的x坐标和RGB值
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
//让指针screen_ptr指向视频缓存的下一行
screen_ptr += mem_pitch;
if ( yi ==yrestart )
{
if ( irestart ==INTERP_LHS )
{
dyl = ( y2 - y1 );
dxdyl = ( ( x2 - x1 ) <<FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu2 - tu1 ) <<FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv2 - tv1 ) <<FIXP16_SHIFT ) / dyl;
xl = ( xl << FIXP16_SHIFT );
ul = ( tu1 << FIXP16_SHIFT );
vl = ( tv1 << FIXP16_SHIFT );
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
}
else
{
dyr = ( y1 - y2 );
dxdyr = ( ( x1 - x2 ) <<FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu1 - tu2 ) <<FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv1 - tv2 ) <<FIXP16_SHIFT ) / dyr;
xr = ( x2 << FIXP16_SHIFT );
ur = ( tu2 << FIXP16_SHIFT );
vr = ( tv2 << FIXP16_SHIFT );
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
}
}
}
}
else
{
//裁剪版本
//让指screen_ptr指向第一条扫描线起点在缓存的位置
screen_ptr = dest_buffer + ( ystart * mem_pitch );
for ( yi =ystart; yi <=yend; yi++ )
{
//计算扫描线起点和终点的X坐标
xstart = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );
xend = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );
//计算扫描线起点和终点的坐标
ui = ul + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
//计算扫描线上的RGB梯度
if ( ( dx = (xend - xstart )) > 0 )
{
du = ( ur - ul ) /dx;
dv = ( vr - vl ) /dx;
}
else
{
du = ( ur - ul );
dv = ( vr - vl );
}
//绘制扫描线
for( xi =xstart; xi <=xend; xi ++ )
{
//绘制像素,
textel = textmap[ ( ui >>FIXP16_SHIFT ) + ( ( vi >> FIXP16_SHIFT ) << texture_shift2 )];
r_textel = ( ( textel >> 11 );
g_textel = ( ( textel >> 5 ) & 0x3f );
b_textel = ( textel & 0x1f );
r_textel *= r_base;
g_textel *= g_base;
b_textel *= b_base;
screen_ptr[xi] = ( ( b_textel >> 5 ) + ( ( g_textel >> 6 ) << 5 ) + ( ( r_texte >> 5 ) << 11 ) );
//计算下一个像素的RGB值
ui += du;
vi += dv;
}
//计算下一条扫描线起点和终点的x坐标和RGB值
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
//让指针screen_ptr指向视频缓存的下一行
screen_ptr += mem_pitch;
if ( yi ==yrestart )
{
if ( irestart ==INTERP_LHS )
{
dyl = ( y2 - y1 );
dxdyl = ( ( x2 - x1 ) <<FIXP16_SHIFT ) / dyl;
dudyl = ( ( tu2 - tu1 ) <<FIXP16_SHIFT ) / dyl;
dvdyl = ( ( tv2 - tv1 ) <<FIXP16_SHIFT ) / dyl;
xl = ( xl << FIXP16_SHIFT );
ul = ( tu1 << FIXP16_SHIFT );
vl = ( tv1 << FIXP16_SHIFT );
xl += dxdyl;
ul += dudyl;
vl += dvdyl;
}
else
{
dyr = ( y1 - y2 );
dxdyr = ( ( x1 - x2 ) <<FIXP16_SHIFT ) / dyr;
dudyr = ( ( tu1 - tu2 ) <<FIXP16_SHIFT ) / dyr;
dvdyr = ( ( tv1 - tv2 ) <<FIXP16_SHIFT ) / dyr;
xr = ( x2 << FIXP16_SHIFT );
ur = ( tu2 << FIXP16_SHIFT );
vr = ( tv2 << FIXP16_SHIFT );
xr += dxdyr;
ur += dudyr;
vr += dvdyr;
}
}
}
}
}
}
总的绘制列表
voidDDRAW_LIUSHUIXIAN_TEXTURE::Draw_RENDERLIST4DV2_Solid16(ddraw_mathmath2, RENDERLIST4DV2_PTRrend_list, UCHAR *video_buffer,int lpitch)
{
POLYF4DV2 face;
for( int poly = 0; poly < rend_list->num_polys; poly++ )
{
//获得当前多边形
POLYF4DV2_PTR curr_poly =rend_list->poly_ptrs[poly];
//当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)
if( !( curr_poly->state &POLY4DV2_STATE_ACTIVE ) ||
( curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||
( curr_poly->state &POLY4DV2_STATE_BACKFACE ) )
continue; //进入下一个多边形
//先测试纹理,
if( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_TEXTURE )
{
face.tvlist[0].x = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].x;
face.tvlist[0].y = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].y;
face.tvlist[0].u0 = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].u0;
face.tvlist[0].v0 = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].v0;
face.tvlist[1].x = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].x;
face.tvlist[1].y = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].y;
face.tvlist[1].u0 = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].u0;
face.tvlist[1].v0 = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].v0;
face.tvlist[2].x = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].x;
face.tvlist[2].y = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].y;
face.tvlist[2].u0 = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].u0;
face.tvlist[2].v0 = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].v0;
face.texture = rend_list->poly_ptrs[poly]->texture;
if( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_CONSTANT )
{
math2.Draw_Textured_Triangle16( &face, video_buffer,lpitch );
}
else
{
face.lit_color[0] = rend_list->poly_ptrs[poly]->lit_color[0];
math2.Draw_Textured_TriangleFS16( &face, video_buffer,lpitch );
}
}
else
if( ( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_FLAT )
|| ( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_CONSTANT ) )
{
math2.Draw_Triangle_2D2_16(rend_list->poly_ptrs[poly]->tvlist[0].x,
rend_list->poly_ptrs[poly]->tvlist[0].y,
rend_list->poly_ptrs[poly]->tvlist[1].x,
rend_list->poly_ptrs[poly]->tvlist[1].y,
rend_list->poly_ptrs[poly]->tvlist[2].x,
rend_list->poly_ptrs[poly]->tvlist[2].y,
rend_list->poly_ptrs[poly]->lit_color[0],
video_buffer, lpitch );
}
else
if( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_GOURAUD )
{
face.tvlist[0].x = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].x;
face.tvlist[0].y = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].y;
face.lit_color[0] = rend_list->poly_ptrs[poly]->lit_color[0];
face.tvlist[1].x = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].x;
face.tvlist[1].y = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].y;
face.lit_color[1] = rend_list->poly_ptrs[poly]->lit_color[1];
face.tvlist[2].x = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].x;
face.tvlist[2].y = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].y;
face.lit_color[2] = rend_list->poly_ptrs[poly]->lit_color[2];
math2.Draw_Gouraud_Triangle16( &face, video_buffer,lpitch );
}
}
}
进行一些修正后,