📄 gui3d2.cpp
字号:
#include <stdlib.h>
#include <fstream.h>
#include <float.h>
#include "gui16.h"
#define INDEX_FORWORD(index) index = (index + 1) % num;
#define INDEX_BACKWORD(index) index = (index - 1 + num) % num;
inline void fillTriangle3d(DDSURFACEDESC* ddsd,CPointList* ppl,TRIANGLE3D* t,WORD color)
{ long lx1,ly1,lx2,ly2,rx1,ry1,rx2,ry2,ldx,ldy,rdx,rdy;
long minY,maxY,lindex,rindex,lxinc,rxinc,lxadd,rxadd,lxsgn,rxsgn,lxsum,rxsum;
long i,x11,x22,num = 3;
POINT3D_INT1 points[3];
POINT3D* p3d;
long width=ddsd->dwWidth-1,height=ddsd->dwHeight-1;
long pitch = ddsd->lPitch>>1;
WORD* p=(WORD*)ddsd->lpSurface,*pt;
p3d = &ppl->points[t->p1];
points[0].x = (long)p3d->x, points[0].y = (long)p3d->y, points[0].z = (long)p3d->z;
p3d = &ppl->points[t->p2];
points[1].x = (long)p3d->x, points[1].y = (long)p3d->y, points[1].z = (long)p3d->z;
p3d = &ppl->points[t->p3];
points[2].x = (long)p3d->x, points[2].y = (long)p3d->y, points[2].z = (long)p3d->z;
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;
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;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
lx2 = points[lindex].x;
ly2 = points[lindex].y;
ldx = lx2 - lx1;
ldy = ly2 - ly1;
lxsgn = (ldx >= 0)?1:-1;
if(ldy>0)
{ lxadd = ldx/ldy;
lxinc = (ldx%ldy)*lxsgn;
}
rx1 = points[rindex].x;
ry1 = points[rindex].y;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
rx2 = points[rindex].x;
ry2 = points[rindex].y;
rdx = rx2 - rx1;
rdy = ry2 - ry1;
rxsgn = (rdx >= 0)?1:-1;
if(rdy>0)
{ rxadd = rdx/rdy;
rxinc = (rdx%rdy)*rxsgn;
}
lxsum = 0;
rxsum = 0;
minY++;
p += pitch*minY;
while(1)
{ lxsum+=lxinc;
lx1+=lxadd;
if(lxsum >= ldy)
{ lx1+=lxsgn;
lxsum -= ldy;
}
rxsum+=rxinc;
rx1+=rxadd;
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;
pt = p + x11;
*pt = color;
while(x11<x22)
{ pt++;
*pt = color;
x11++;
}
}
if(minY >= maxY)
break;
if(minY == ly2)
{ do{
lx1 = points[lindex].x;
ly1 = points[lindex].y;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
lx2 = points[lindex].x;
ly2 = points[lindex].y;
}while(ly2 == ly1);
ldx = lx2 - lx1;
ldy = ly2 - ly1;
lxsgn = (ldx >= 0)?1:-1;
if(ldy>0)
{ lxadd = ldx/ldy;
lxinc = (ldx%ldy)*lxsgn;
}
}
if(minY == ry2)
{ do{
rx1 = points[rindex].x;
ry1 = points[rindex].y;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
rx2 = points[rindex].x;
ry2 = points[rindex].y;
}while(ry2 == ry1);
rdx = rx2 - rx1;
rdy = ry2 - ry1;
rxsgn = (rdx >= 0)?1:-1;
if(rdy>0);
{ rxadd = rdx/rdy;
rxinc = (rdx%rdy)*rxsgn;
}
}
minY++;
p += pitch;
}
}
/*
typedef struct { long x1,z1,x2,z2,y;}HLINE3D;
#define FLOAT_TO_FIXED(f) ((long)(f*0x00010000))
#define FIXED_TO_SHORT(f) ((short)(f>>16))
#define ROUND_FIXED_TO_SHORT(f) ((short)((f+FLOAT_TO_FIXED(0.5))>>16))
inline void fillTriangle3dWithZ(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,lxinc,rxinc,lxadd,lzadd,rxadd,rzadd;
long lxsgn,rxsgn,lxsum,rxsum;
long i,x11,x22,num = 3,lineNum = 0;
POINT3D_INT1 points[3];
POINT3D* p3d;
HLINE3D* lines;
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;
p3d = &ppl->points[t->p1];
points[0].x = (long)p3d->x, points[0].y = (long)p3d->y, points[0].z = FLOAT_TO_FIXED(p3d->z);
p3d = &ppl->points[t->p2];
points[1].x = (long)p3d->x, points[1].y = (long)p3d->y, points[1].z = FLOAT_TO_FIXED(p3d->z);
p3d = &ppl->points[t->p3];
points[2].x = (long)p3d->x, points[2].y = (long)p3d->y, points[2].z = FLOAT_TO_FIXED(p3d->z);
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;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
lx2 = points[lindex].x;
ly2 = points[lindex].y;
lz2 = points[lindex].z;
ldx = lx2 - lx1;
ldy = ly2 - ly1;
ldz = lz2 - lz1;
lxsgn = (ldx >= 0)?1:-1;
lxadd = ldx/ldy;
lxinc = (ldx%ldy)*lxsgn;
lzadd = ldz/ldy;
rx1 = points[rindex].x;
ry1 = points[rindex].y;
rz1 = points[rindex].z;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
rx2 = points[rindex].x;
ry2 = points[rindex].y;
rz2 = points[rindex].z;
rdx = rx2 - rx1;
rdy = ry2 - ry1;
rdz = rz2 - rz1;
rxsgn = (rdx >= 0)?1:-1;
rxadd = rdx/rdy;
rxinc = (rdx%rdy)*rxsgn;
rzadd = rdz/rdy;
lxsum = 0;
rxsum = 0;
minY++;
while(1)
{ lxsum+=lxinc;
lx1+=lxadd;
lz1+=lzadd;
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;
lines[lineNum].x1 = x11;
lines[lineNum].z1 = lz1;
lines[lineNum].x2 = x22;
lines[lineNum].z2 = rz1;
lines[lineNum++].y = minY;
}
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);
lx2 = points[lindex].x;
ly2 = points[lindex].y;
lz2 = points[lindex].z;
}while(ly2 == ly1);
ldx = lx2 - lx1;
ldy = ly2 - ly1;
ldz = lz2 - 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);
rx2 = points[rindex].x;
ry2 = points[rindex].y;
rz2 = points[rindex].z;
}while(ry2 == ry1);
rdx = rx2 - rx1;
rdy = ry2 - ry1;
rdz = rz2 - rz1;
rxsgn = (rdx >= 0)?1:-1;
rxadd = rdx/rdy;
rxinc = (rdx%rdy)*rxsgn;
rzadd = rdz/rdy;
rxsum = 0;
}
minY++;
}
WORD* p11;
short* p22;
int dx,dz,x,z,y,x2,z2,zadd;
for(i = 0;i < lineNum;i++)
{ x = lines[i].x1;
z = lines[i].z1;
x2 = lines[i].x2;
z2 = lines[i].z2;
y = lines[i].y;
dx = x2 - x;
dz = z2 - z;
p22 = p2 + pitch2*y + x;
p11 = p1 + pitch1*y + x;
if(FIXED_TO_SHORT(z) < *p22)
{ *p11 = color;
*p22 = FIXED_TO_SHORT(z);
}
if(dx <= 0)
{ continue;
}
zadd = dz/dx;
while(x < x2)
{ x++;
p11++;
p22++;
z += zadd;
if(FIXED_TO_SHORT(z) < *p22)
{ *p11 = color;
*p22 = FIXED_TO_SHORT(z);
}
}
}
delete[] lines;
}*/
#define ROUND_FIXED_TO_SHORT(f) ((short)((f+FLOAT_TO_FIXED(0.5))>>16))
inline void fillTriangle3dWithZ(DDSURFACEDESC* ddsd,DDSURFACEDESC* ddsdZBuf,CPointList* ppl,TRIANGLE3D* t,WORD color)
{ long lx1,ly1,lz1,ly2,rx1,ry1,rz1,ry2,ldx,ldy,ldz,rdx,rdy,rdz;
long minY,maxY,lindex,rindex,lxinc,rxinc,lxadd,lzadd,rxadd,rzadd;
long lxsgn,rxsgn,lxsum,rxsum;
long i,x11,x22,num = 3,lineNum = 0;
POINT3D_INT1 points[3];
POINT3D* p3d;
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;
WORD* p11;
short* p22;
long z,zadd,lps;
p3d = &ppl->points[t->p1];
points[0].x = (long)p3d->x, points[0].y = (long)p3d->y, points[0].z = FLOAT_TO_FIXED(p3d->z);
p3d = &ppl->points[t->p2];
points[1].x = (long)p3d->x, points[1].y = (long)p3d->y, points[1].z = FLOAT_TO_FIXED(p3d->z);
p3d = &ppl->points[t->p3];
points[2].x = (long)p3d->x, points[2].y = (long)p3d->y, points[2].z = FLOAT_TO_FIXED(p3d->z);
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;
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;
INDEX_FORWORD(lindex);
//INDEX_BACKWORD(lindex);
ly2 = points[lindex].y;
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;
rx1 = points[rindex].x;
ry1 = points[rindex].y;
rz1 = points[rindex].z;
INDEX_BACKWORD(rindex);
//INDEX_FORWORD(rindex);
ry2 = points[rindex].y;
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;
lxsum = 0;
rxsum = 0;
minY++;
p2 += pitch2*minY;
p1 += pitch1*minY;
while(1)
{/* __asm
{ push edi
push esi
mov eax,lxsum
mov esi,lxinc
mov ebx,lx1
mov edi,lxadd
mov ecx,lzadd
mov edx,ldy
add eax,esi
mov esi,lxsgn
add ebx,edi
add lz1,ecx
cmp eax,edx
jl SHORT __rr
add ebx,esi
sub eax,edx
__rr:
mov lx1,ebx
mov lxsum,eax
mov eax,rxsum
mov esi,rxinc
mov ebx,rx1
mov edi,rxadd
mov ecx,rzadd
mov edx,rdy
add eax,esi
mov esi,rxsgn
add ebx,edi
add rz1,ecx
cmp eax,edx
jl SHORT __clp
add ebx,esi
sub eax,edx
__clp:
mov esi,width
mov rx1,ebx
mov rxsum,eax
mov ecx,minY
dec ebx
mov eax,lx1
cmp ecx,0
jl SHORT __goon
cmp ecx,height
jg SHORT __goon
cmp eax,esi
jg SHORT __goon
cmp ebx,0
jl SHORT __goon
cmp ebx,eax
jl SHORT __goon
cmp eax,0
jge SHORT __clp2
mov eax,0
__clp2:
cmp ebx,esi
jle SHORT __fill
mov ebx,esi
__fill:
mov si,color
mov ecx,lz1
mov x11,eax
mov x22,ebx
mov ebx,p2
mov z,ecx
mov edx,p1
sar ecx,16
lea ebx,[ebx+eax*2]
lea edx,[edx+eax*2]
mov edi,eax
cmp cx,WORD PTR[ebx]
jge SHORT __fill2
mov WORD PTR[edx],si
mov WORD PTR[ebx],cx
__fill2:
mov ecx,x22
cmp ecx,edi
jle SHORT __goon
mov eax,rz1
sub eax,z
mov esi,edx
sub ecx,edi
cdq
idiv ecx
mov edx,esi
mov lps,ecx
mov edi,eax
mov eax,z
add eax,edi
__looptop:
add ebx,2
add edx,2
mov ecx,eax
sar ecx,16
mov si,WORD PTR [ebx]
add eax,edi
cmp cx,si
mov si,color
jge SHORT __loop
mov WORD PTR[ebx],cx
mov WORD PTR[edx],si
__loop:
dec lps
jnz SHORT __looptop
__goon:
pop esi
pop edi
}*/
lxsum+=lxinc;
lx1+=lxadd;
lz1+=lzadd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -