単純な一時変換だと画像が歪んで見えてしまいます。
[album]489[/album]
そこで、「透視補正」をかけます。
前のプログラムのように画像の上/下を選択するのではなく、テクスチャ内の座標で指定するプログラムにしました。
テクスチャ内の画像の左下が(0,0)で、右上が(1,1)です。
void draw3dHenkan(
double x1,double y1,double z1,
double x2,double y2,double z2,
double x3,double y3,double z3,
double tx1,double ty1,
double tx2,double ty2,
double tx3,double ty3,
const bmp_t* bmp,
const camera_t* camera) {
int xx1,yy1,xx2,yy2,xx3,yy3;
double zz1,zz2,zz3;
double tx,ty;
int ux,uy,mx,my,dx,dy,temp;
double uz,mz,dz,dtemp;
double uiz,miz,diz;
double utx,uty,mtx,mty,dtx,dty;
int lx,rx;
double lz,rz,nz,iz;
double liz,riz,niz;
double ltx,rtx,lty,rty;
int i,j;
int x,y;
double ntx,nty;
if(bmp==NULL || camera==NULL)return;
henkan3dzahyou(&tx,&ty,&zz1,x1,y1,z1,camera);
xx1=(int)tx;yy1=(int)ty;
henkan3dzahyou(&tx,&ty,&zz2,x2,y2,z2,camera);
xx2=(int)tx;yy2=(int)ty;
henkan3dzahyou(&tx,&ty,&zz3,x3,y3,z3,camera);
xx3=(int)tx;yy3=(int)ty;
if(zz1my) {
temp=ux;ux=mx;mx=temp;
temp=uy;uy=my;my=temp;
dtemp=uz;uz=mz;mz=dtemp;
dtemp=uiz;uiz=miz;miz=dtemp;
dtemp=utx;utx=mtx;mtx=dtemp;
dtemp=uty;uty=mty;mty=dtemp;
}
if(my>dy) {
temp=mx;mx=dx;dx=temp;
temp=my;my=dy;dy=temp;
dtemp=mz;mz=dz;dz=dtemp;
dtemp=miz;miz=diz;diz=dtemp;
dtemp=mtx;mtx=dtx;dtx=dtemp;
dtemp=mty;mty=dty;dty=dtemp;
}
if(uy>my) {
temp=ux;ux=mx;mx=temp;
temp=uy;uy=my;my=temp;
dtemp=uz;uz=mz;mz=dtemp;
dtemp=uiz;uiz=miz;miz=dtemp;
dtemp=utx;utx=mtx;mtx=dtemp;
dtemp=uty;uty=mty;mty=dtemp;
}
for(i=uy;irx) {
temp=lx;lx=rx;rx=temp;
dtemp=lz;lz=rz;rz=dtemp;
dtemp=liz;liz=riz;riz=dtemp;
dtemp=ltx;ltx=rtx;rtx=dtemp;
dtemp=lty;lty=rty;rty=dtemp;
}
for(j=lx;jrx) {
temp=lx;lx=rx;rx=temp;
dtemp=lz;lz=rz;rz=dtemp;
dtemp=liz;liz=riz;riz=dtemp;
dtemp=ltx;ltx=rtx;rtx=dtemp;
dtemp=lty;lty=rty;rty=dtemp;
}
for(j=lx;j<=rx;j++) {
nz=lz+(rx==lx?0:(rz-lz)*(j-lx)/(rx-lx));
niz=liz+(rx==lx?0:(riz-liz)*(j-lx)/(rx-lx));
ntx=ltx+(rx==lx?0:(rtx-ltx)*(j-lx)/(rx-lx));
nty=lty+(rx==lx?0:(rty-lty)*(j-lx)/(rx-lx));
x=(int)(ntx/niz*bmpGetWidth(bmp))%bmpGetWidth(bmp);
y=(int)(nty/niz*bmpGetHeight(bmp))%bmpGetHeight(bmp);
if(x<0)x+=bmpGetWidth(bmp);
if(y<0)y+=bmpGetHeight(bmp);
y=bmpGetHeight(bmp)-1-y;
setRGB(j,i,bmpGetXY(bmp,x,y).r,bmpGetXY(bmp,x,y).g,bmpGetXY(bmp,x,y).b,nz);
}
}
}
[album]490[/album]
ただし、旧エンジンでは37fps程度なのに対し、新エンジンが同じシーンで26fpsと、
若干fpsが下がってしまいました。
ついでに、同じような動作のプログラムをDXライブラリに移植し、比較してみました。
こちらが自作プログラムです。17fps程度です。
[album]491[/album]
そして、こちらがDXライブラリを使用したプログラムです。当たり前のように60fps程度出ます。
[album]492[/album]
この技術を応用して、PMDモデルを描画してみました。
しかし、28fpsと低いfpsで、しかも本家のように綺麗には描画されず、ベタ塗りになっています。
それでもある程度の精度は得られています。
なお、テクスチャとしてはBMPファイルしか読み込めないので、モデルによってはおかしくなります。
[album]493[/album]
この3種類のプログラムを添付しておきます。