📄 gui3d2.cpp
字号:
if(lxsum >= ldy)
{ lx1+=lxsgn;
lxsum -= ldy;
}
rxsum+=rxinc;
rx1+=rxadd;
rz1+=rzadd;
if(rxsum >= rdy)
{ rx1+=rxsgn;
rxsum -= rdy;
}
x11 = lx1,x22 = rx1 - 1;
if(minY>=0&&minY<=height&&x11<=width&&x22>=0&&x22>=x11)
{ if(x11<0)
x11=0;
if(x22>width)
x22=width;
z = lz1;
p22 = p2 + x11;
p11 = p1 + x11;
if(FIXED_TO_SHORT(z) < *p22)
{ *p11 = color;
*p22 = FIXED_TO_SHORT(z);
}
if(x22 > x11)
{ zadd = (rz1 - z)/(x22 - x11);
while(x11++ < x22)
{ z += zadd;
p11++;
p22++;
if(FIXED_TO_SHORT(z) < *p22)
{ *p11 = color;
*p22 = FIXED_TO_SHORT(z);
}
}
}
}
if(minY >= maxY)
break;
if(minY == ly2)
{ do{
lx1 = points[lindex].x;
ly1 = points[lindex].y;
lz1 = points[lindex].z;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
ly2 = points[lindex].y;
}while(ly2 == ly1);
ldx = points[lindex].x - lx1;
ldy = ly2 - ly1;
ldz = points[lindex].z - lz1;
lxsgn = (ldx >= 0)?1:-1;
lxadd = ldx/ldy;
lxinc = (ldx%ldy)*lxsgn;
lzadd = ldz/ldy;
lxsum = 0;
}
if(minY == ry2)
{ do{
rx1 = points[rindex].x;
ry1 = points[rindex].y;
rz1 = points[rindex].z;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
ry2 = points[rindex].y;
}while(ry2 == ry1);
rdx = points[rindex].x - rx1;
rdy = ry2 - ry1;
rdz = points[rindex].z - rz1;
rxsgn = (rdx >= 0)?1:-1;
rxadd = rdx/rdy;
rxinc = (rdx%rdy)*rxsgn;
rzadd = rdz/rdy;
rxsum = 0;
}
minY++;
p2 += pitch2;
p1 += pitch1;
}
}
typedef struct { long x1,x2,y,z1,u1,v1,z2,u2,v2;}HLINE3D;
typedef struct { long x1,x2,y;
float z1,u1,v1,z2,u2,v2;}HLINE3D1;
inline void fillTriangle3dWithZT(DDSURFACEDESC* ddsd,DDSURFACEDESC* ddsdZBuf,CPointList* ppl,TRIANGLE3D* t,WORD color)
{ long lx1,ly1,lz1,lx2,ly2,lz2,rx1,ry1,rz1,rx2,ry2,rz2,ldx,ldy,ldz,rdx,rdy,rdz;
long minY,maxY,lindex,rindex,lxadd,lzadd,rxadd,rzadd;
long luadd,ruadd,lvadd,rvadd;
long lu1,lv1,lu2,lv2,ru1,rv1,ru2,rv2,ldu,ldv,rdu,rdv;
long i,x11,x22,num = 3,lineNum = 0;
long mapWidth,mapHeight;
POINT3D_INT2 points[3];
POINT3D* p3d;
HLINE3D* lines;
if(t->maped == FALSE)
{ fillTriangle3dWithZ(ddsd,ddsdZBuf,ppl,t,color);
return;
}
long width=ddsd->dwWidth-1,width1=ddsd->dwWidth,height=ddsd->dwHeight-1;
long pitch1 = ddsd->lPitch>>1;
long pitch2 = ddsdZBuf->lPitch>>1;
WORD* p1=(WORD*)ddsd->lpSurface;
short* p2=(short*)ddsdZBuf->lpSurface;
mapWidth = tex.textures[t->map]->width-1;
mapHeight = tex.textures[t->map]->height-1;
p3d = &ppl->points[t->p1];
points[0].x = FLOAT_TO_FIXED(p3d->x), points[0].y = (long)p3d->y, points[0].z = FLOAT_TO_FIXED(p3d->z);
points[0].u = FLOAT_TO_FIXED(t->u1*mapWidth), points[0].v = FLOAT_TO_FIXED(t->v1*mapHeight);
p3d = &ppl->points[t->p2];
points[1].x = FLOAT_TO_FIXED(p3d->x), points[1].y = (long)p3d->y, points[1].z = FLOAT_TO_FIXED(p3d->z);
points[1].u = FLOAT_TO_FIXED(t->u2*mapWidth), points[1].v = FLOAT_TO_FIXED(t->v2*mapHeight);
p3d = &ppl->points[t->p3];
points[2].x = FLOAT_TO_FIXED(p3d->x), points[2].y = (long)p3d->y, points[2].z = FLOAT_TO_FIXED(p3d->z);
points[2].u = FLOAT_TO_FIXED(t->u3*mapWidth), points[2].v = FLOAT_TO_FIXED(t->v3*mapHeight);
rindex = lindex = 0;
maxY=minY=points[0].y;
for(i=0;i<num;i++)
{ if(points[i].y<minY)
minY = points[lindex = i].y;
else if(points[i].y > maxY)
maxY = points[i].y;
}
if(minY == maxY)
return;
if((lines = new HLINE3D[maxY - minY]) == NULL)
return;
rindex = lindex;
while(points[lindex].y == minY)
//INDEX_BACKWORD(lindex);
INDEX_FORWORD(lindex);
INDEX_BACKWORD(lindex);
//INDEX_FORWORD(lindex);
while(points[rindex].y == minY)
//INDEX_FORWORD(rindex);
INDEX_BACKWORD(rindex);
//INDEX_BACKWORD(rindex);
INDEX_FORWORD(rindex);
lx1 = points[lindex].x;
ly1 = points[lindex].y;
lz1 = points[lindex].z;
lu1 = points[lindex].u;
lv1 = points[lindex].v;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
lx2 = points[lindex].x;
ly2 = points[lindex].y;
lz2 = points[lindex].z;
lu2 = points[lindex].u;
lv2 = points[lindex].v;
ldx = lx2 - lx1;
ldy = ly2 - ly1;
ldz = lz2 - lz1;
ldu = lu2 - lu1;
ldv = lv2 - lv1;
lxadd = ldx/ldy;
lzadd = ldz/ldy;
luadd = ldu/ldy;
lvadd = ldv/ldy;
rx1 = points[rindex].x;
ry1 = points[rindex].y;
rz1 = points[rindex].z;
ru1 = points[rindex].u;
rv1 = points[rindex].v;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
rx2 = points[rindex].x;
ry2 = points[rindex].y;
rz2 = points[rindex].z;
ru2 = points[rindex].u;
rv2 = points[rindex].v;
rdx = rx2 - rx1;
rdy = ry2 - ry1;
rdz = rz2 - rz1;
rdu = ru2 - ru1;
rdv = rv2 - rv1;
rxadd = rdx/rdy;
rzadd = rdz/rdy;
ruadd = rdu/rdy;
rvadd = rdv/rdy;
minY++;
while(1)
{ lx1+=lxadd;
lz1+=lzadd;
lu1+=luadd;
lv1+=lvadd;
rx1+=rxadd;
rz1+=rzadd;
ru1+=ruadd;
rv1+=rvadd;
x11 = FIXED_TO_LONG(lx1),x22 = FIXED_TO_LONG(rx1) - 1;
if(minY>=0&&minY<=height&&x11<=width&&x22>=0&&x22>=x11)
{ if(x11<0)
x11=0;
if(x22>width)
x22=width;
lines[lineNum].x1 = x11;
lines[lineNum].z1 = lz1;
lines[lineNum].u1 = lu1;
lines[lineNum].v1 = lv1;
lines[lineNum].x2 = x22;
lines[lineNum].z2 = rz1;
lines[lineNum].u2 = ru1;
lines[lineNum].v2 = rv1;
lines[lineNum++].y = minY;
}
if(minY >= maxY)
break;
if(minY == ly2)
{ do{
lx1 = points[lindex].x;
ly1 = points[lindex].y;
lz1 = points[lindex].z;
lu1 = points[lindex].u;
lv1 = points[lindex].v;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
lx2 = points[lindex].x;
ly2 = points[lindex].y;
lz2 = points[lindex].z;
lu2 = points[lindex].u;
lv2 = points[lindex].v;
}while(ly2 == ly1);
ldx = lx2 - lx1;
ldy = ly2 - ly1;
ldz = lz2 - lz1;
ldu = lu2 - lu1;
ldv = lv2 - lv1;
lxadd = ldx/ldy;
lzadd = ldz/ldy;
luadd = ldu/ldy;
lvadd = ldv/ldy;
}
if(minY == ry2)
{ do{
rx1 = points[rindex].x;
ry1 = points[rindex].y;
rz1 = points[rindex].z;
ru1 = points[rindex].u;
rv1 = points[rindex].v;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
rx2 = points[rindex].x;
ry2 = points[rindex].y;
rz2 = points[rindex].z;
ru2 = points[rindex].u;
rv2 = points[rindex].v;
}while(ry2 == ry1);
rdx = rx2 - rx1;
rdy = ry2 - ry1;
rdz = rz2 - rz1;
rdu = ru2 - ru1;
rdv = rv2 - rv1;
rxadd = rdx/rdy;
rzadd = rdz/rdy;
ruadd = rdu/rdy;
rvadd = rdv/rdy;
}
minY++;
}
WORD* p11,*pm;
short* p22;
pm = tex.textures[t->map]->image;
UINT wh = tex.textures[t->map]->width;
int dx,dz,du,dv,x,z,u,v,y,x2,z2,u2,v2,zadd,uadd,vadd;
for(i = 0;i < lineNum;i++)
{ x = lines[i].x1;
z = lines[i].z1;
u = lines[i].u1;
v = lines[i].v1;
x2 = lines[i].x2;
z2 = lines[i].z2;
u2 = lines[i].u2;
v2 = lines[i].v2;
y = lines[i].y;
dx = x2 - x;
dz = z2 - z;
du = u2 - u;
dv = v2 - v;
p22 = p2 + pitch2*y + x;
p11 = p1 + pitch1*y + x;
if(FIXED_TO_SHORT(z) < *p22)
{ *p11 = *(pm+FIXED_TO_SHORT(v)*wh + FIXED_TO_SHORT(u));
*p22 = FIXED_TO_SHORT(z);
}
if(dx <= 0)
{ continue;
}
zadd = dz/dx;
uadd = du/dx;
vadd = dv/dx;
while(x < x2)
{ x++;
p11++;
p22++;
z += zadd;
u += uadd;
v += vadd;
if(FIXED_TO_SHORT(z) < *p22)
{ *p11 = *(pm+FIXED_TO_SHORT(v)*wh + FIXED_TO_SHORT(u));
*p22 = FIXED_TO_SHORT(z);
}
}
}
delete[] lines;
}
inline void fillTriangle3dWithZT1(DDSURFACEDESC* ddsd,DDSURFACEDESC* ddsdZBuf,CPointList* ppl,TRIANGLE3D* t,WORD color)
{ long lx1,ly1,lx2,ly2,rx1,ry1,rx2,ry2,ldx,ldy,rdx,rdy;
float lz1,lz2,rz1,rz2,ldz,rdz,lzadd,rzadd,luadd,lvadd,ruadd,rvadd;
long minY,maxY,lindex,rindex,lxadd,rxadd;
float lu1,lv1,lu2,lv2,ru1,rv1,ru2,rv2,ldu,ldv,rdu,rdv;
long i,x11,x22,num = 3,lineNum = 0;
POINT3D_INT2 points[3];
POINT3D* p3d;
HLINE3D1* lines;
if(t->maped == FALSE)
{ fillTriangle3dWithZ(ddsd,ddsdZBuf,ppl,t,color);
return;
}
long width=ddsd->dwWidth-1,width1=ddsd->dwWidth,height=ddsd->dwHeight-1;
long pitch1 = ddsd->lPitch>>1;
long pitch2 = ddsdZBuf->lPitch>>1;
long mapWidth,mapHeight;
WORD* p1=(WORD*)ddsd->lpSurface;
short* p2=(short*)ddsdZBuf->lpSurface;
mapWidth = tex.textures[t->map]->width-1;
mapHeight = tex.textures[t->map]->height-1;
p3d = &ppl->points[t->p1];
points[0].x = FLOAT_TO_FIXED(p3d->x), points[0].y = (long)p3d->y, points[0].z = p3d->z;
points[0].u = t->u1*mapWidth, points[0].v = t->v1*mapHeight;
p3d = &ppl->points[t->p2];
points[1].x = FLOAT_TO_FIXED(p3d->x), points[1].y = (long)p3d->y, points[1].z = p3d->z;
points[1].u = t->u2*mapWidth, points[1].v = t->v2*mapHeight;
p3d = &ppl->points[t->p3];
points[2].x = FLOAT_TO_FIXED(p3d->x), points[2].y = (long)p3d->y, points[2].z = p3d->z;
points[2].u = t->u3*mapWidth, points[2].v = t->v3*mapHeight;
rindex = lindex = 0;
maxY=minY=points[0].y;
for(i=0;i<num;i++)
{ if(points[i].y<minY)
minY = points[lindex = i].y;
else if(points[i].y > maxY)
maxY = points[i].y;
}
if(minY == maxY)
return;
if((lines = new HLINE3D1[maxY - minY]) == NULL)
return;
rindex = lindex;
while(points[lindex].y == minY)
//INDEX_BACKWORD(lindex);
INDEX_FORWORD(lindex);
INDEX_BACKWORD(lindex);
//INDEX_FORWORD(lindex);
while(points[rindex].y == minY)
//INDEX_FORWORD(rindex);
INDEX_BACKWORD(rindex);
//INDEX_BACKWORD(rindex);
INDEX_FORWORD(rindex);
lx1 = points[lindex].x;
ly1 = points[lindex].y;
lz1 = 1.0/points[lindex].z;
lu1 = points[lindex].u*lz1;
lv1 = points[lindex].v*lz1;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
lx2 = points[lindex].x;
ly2 = points[lindex].y;
lz2 = 1.0/points[lindex].z;
lu2 = points[lindex].u*lz2;
lv2 = points[lindex].v*lz2;
ldx = lx2 - lx1;
ldy = ly2 - ly1;
ldz = lz2 - lz1;
ldu = lu2 - lu1;
ldv = lv2 - lv1;
lxadd = ldx/ldy;
lzadd = ldz/ldy;
luadd = ldu/ldy;
lvadd = ldv/ldy;
rx1 = points[rindex].x;
ry1 = points[rindex].y;
rz1 = 1.0/points[rindex].z;
ru1 = points[rindex].u*rz1;
rv1 = points[rindex].v*rz1;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
rx2 = points[rindex].x;
ry2 = points[rindex].y;
rz2 = 1.0/points[rindex].z;
ru2 = points[rindex].u*rz2;
rv2 = points[rindex].v*rz2;
rdx = rx2 - rx1;
rdy = ry2 - ry1;
rdz = rz2 - rz1;
rdu = ru2 - ru1;
rdv = rv2 - rv1;
rxadd = rdx/rdy;
rzadd = rdz/rdy;
ruadd = rdu/rdy;
rvadd = rdv/rdy;
minY++;
while(1)
{ lx1+=lxadd;
lz1+=lzadd;
lu1+=luadd;
lv1+=lvadd;
rx1+=rxadd;
rz1+=rzadd;
ru1+=ruadd;
rv1+=rvadd;
x11 = FIXED_TO_LONG(lx1),x22 = FIXED_TO_LONG(rx1) - 1;
if(minY>=0&&minY<=height&&x11<=width&&x22>=0&&x22>=x11)
{ lines[lineNum].x1 = x11;
lines[lineNum].z1 = lz1;
lines[lineNum].u1 = lu1;
lines[lineNum].v1 = lv1;
lines[lineNum].x2 = x22;
lines[lineNum].z2 = rz1;
lines[lineNum].u2 = ru1;
lines[lineNum].v2 = rv1;
lines[lineNum++].y = minY;
}
if(minY >= maxY)
break;
if(minY == ly2)
{ do{
lx1 = points[lindex].x;
ly1 = points[lindex].y;
lz1 = 1.0/points[lindex].z;
lu1 = points[lindex].u*lz1;
lv1 = points[lindex].v*lz1;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
lx2 = points[lindex].x;
ly2 = points[lindex].y;
lz2 = 1.0/points[lindex].z;
lu2 = points[lindex].u*lz2;
lv2 = points[lindex].v*lz2;
}while(ly2 == ly1);
ldx = lx2 - lx1;
ldy = ly2 - ly1;
ldz = lz2 - lz1;
ldu = lu2 - lu1;
ldv = lv2 - lv1;
lxadd = ldx/ldy;
lzadd = ldz/ldy;
luadd = ldu/ldy;
lvadd = ldv/ldy;
}
if(minY == ry2)
{ do{
rx1 = points[rindex].x;
ry1 = points[rindex].y;
rz1 = 1.0/points[rindex].z;
ru1 = points[rindex].u*rz1;
rv1 = points[rindex].v*rz1;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
rx2 = points[rindex].x;
ry2 = points[rindex].y;
rz2 = 1.0/points[rindex].z;
ru2 = points[rindex].u*rz2;
rv2 = points[rindex].v*rz2;
}while(ry2 == ry1);
rdx = rx2 - rx1;
rdy = ry2 - ry1;
rdz = rz2 - rz1;
rdu = ru2 - ru1;
rdv = rv2 - rv1;
rxadd = rdx/rdy;
rzadd = rdz/rdy;
ruadd = rdu/rdy;
rvadd = rdv/rdy;
}
minY++;
}
WORD* p11,*pm;
short* p22;
pm = tex.textures[t->map]->image;
UINT wh = tex.textures[t->map]->width;
long dx,x,y,x2,lps;
// long zz,uu,vv;
// float z,u,v;
float zadd,uadd,vadd;
float uf,ub,vf,vb,zf,zb;
long uf1,ub1,vf1,vb1,zf1,zb1,zadd1,uadd1,vadd1;
float zzz;
for(i = 0;i < lineNum;i++)
{ x = lines[i].x1;
zf = lines[i].z1;
zzz = ((float)0x00010000)/zf;
zf1 = long(zzz);
uf = lines[i].u1;
uf1 = long(uf*zzz);
vf = lines[i].v1;
vf1 = long(vf*zzz);
x2 = lines[i].x2;
y = lines[i].y;
if(x2<0 || x>width || y<0 || y>height)
continue;
dx = x2 - x;
zadd = (lines[i].z2 - zf)/dx;
uadd = (lines[i].u2 - uf)/dx;
vadd = (lines[i].v2 - vf)/dx;
long tp;
if(x<0)
{ tp = 0 - x;
zf += zadd*tp;
zzz = ((float)0x00010000)/zf;
zf1 = long(zzz);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -