9-2加上光照计算的GOURAUD shader多边形)
来源:互联网 发布:淘宝买家具哪个品牌好 编辑:程序博客网 时间:2024/06/18 03:54
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_mathmath,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结构
typedefstructRENDERLIST4DV2_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_mathmath,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_PTRobj )
{
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_PTRmt, //变换矩阵
intcoord_select,
inttransform_basis,
intall_frames,
ddraw_mathmath2 ) //指定要变换的坐标
{
if( !all_frames )
{
switch( coord_select )
{
caseTRANSFORM_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;
caseTRANSFORM_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;
caseTRANSFORM_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 )
{
caseTRANSFORM_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;
caseTRANSFORM_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;
caseTRANSFORM_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_PTRobj, ddraw_mathmath2,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 )
{
unsignedintbase_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 (intpoly=0; poly <rend_list->num_polys;poly++)
{
// acquire polygon
POLYF4DV2_PTRcurr_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;
}
VECTOR4Du,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
VECTOR4Dview;
math.VECTOR4D_Build(&curr_poly->tvlist[0].v, &cam->pos, &view);
// and finally, compute the dot product
floatdp =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_mathmath2,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 )
{
caseSORT_POLYLIST_AVGZ:
{
qsort( (void *)rend_list->poly_ptrs,rend_list->num_polys,sizeof(POLYF4DV2_PTR ),Compare_AvgZ_PolyF4DV2 );
}
break;
caseSORT_POLYLIST_NEARZ:
{
qsort( (void *)rend_list->poly_ptrs,rend_list->num_polys,sizeof(POLYF4DV2_PTR ),Compare_NearZ_PolyF4DV2);
}
break;
caseSORT_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_PTRface,UCHAR *_dest_buffer,intmem_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;
UCHARlogbase2ofx[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_PTRface,UCHAR *_dest_buffer,intmem_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;
UCHARlogbase2ofx[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,intlpitch)
{
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 );
}
}
}
进行一些修正后,
- 9-2加上光照计算的GOURAUD shader多边形)
- GLSL shader中光照的计算
- 光照计算Shader
- 2014年3月24日星期一(9-1GOURAUD SHADER)
- Unity3D shader(9)——vertex shader(phong光照和BlinnPhong光照)
- <Shader>LightMap光照Shader的实现
- OpenGL-- Shader 颜色 光照 2
- unity shader学习笔记(二)——在Unity中计算漫反射光照
- unity shader学习笔记(三)——在Unity中计算高光反射光照
- 任意多边形的面积计算(包括凹多边形的)
- 简单的光照checkerboard球体shader实现
- 4.边缘光照的描边shader
- 常用的光照模型Shader Models
- shader中常见的光照基础-漫反射
- 一步步学shader系列(2):环境光照diffuse漫反射光照
- Flex计算多边形(Geometry)的中心点
- 计算多边形的面积
- 计算多边形的面积
- poj3253 Fence Repair(哈弗曼)
- win7下VC++6.0打开多个工作区间
- 2014年8月26日星期二(DEMO8-9加载COB模型)
- 机器视觉专题
- [LeetCode] Balanced Binary Tree 平衡二叉树
- 9-2加上光照计算的GOURAUD shader多边形)
- 去学隐身术吧
- 前端开发神器 Emmet 介绍
- 使用 Emmet 生成 HTML 的语法详解
- 使用 Emmet 提高编写 CSS 的效率
- Emmet 常用的高级功能
- 一切成功源于积累——20141205 长达10小时 100点内盘整 美日120.200
- What does a double question mark do in C#?
- Trigger a button click with JavaScript on the Enter key in a text box