|
テクスチャーマッピングというのは、ポリゴンの面に画像を貼りつける技術のことです。 今回、貼りつける画像は ![]() これを使います。 ポリゴンにテクスチャを貼るにはどうしたら良いのか? まず、ポリゴンの頂点にUV座標というのを設定します。 同じようにテクスチャの画像にもUV値を設定します。 これは要するにテクスチャを貼るためのXY座標と思ってかまいません。 このUV値の対応がテクスチャの画像をポリゴンのどこに貼るのかという基準になります。 UV値は浮動小数点型で0〜1の値をとります。 つまり(0,0)は左上隅、(1,0)は右上隅、(0,1)は左下隅、(1,1)は右下隅の テクスチャ画像のピクセルを指します。 さて、ポリゴンの頂点にUV値を設定したのなら、それぞれの頂点を結ぶときに 線形補間しながら、その値をポリゴンバッファに書きこんでおきましょう。 さらに、そのポリゴンバッファの値を元に水平ラインで線形補間しながらポリゴンの面を塗れば テクスチャマッピングの完成です。
//-----------------------------------------------------------------------------
// テクスチャマッピング
//-----------------------------------------------------------------------------
void draw_shape(shape_type shape,LPDIRECTDRAWSURFACE3 Surface)
{
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd,sizeof(DDSURFACEDESC));
ddsd.dwSize = sizeof(ddsd);
//サーフェイスをロックして、ビデオメモリへのポインタを得る。
Surface->Lock(NULL,&ddsd,DDLOCK_WAIT, NULL );
LPWORD lpVideoMemory = (LPWORD)ddsd.lpSurface;
int video_pitch = ddsd.lPitch/2;
//↓TEXTUREを置いたサーフェイスをロックしてポインタを得る
DDSURFACEDESC ddsd2;
memset( &ddsd2, 0, sizeof( ddsd2 ) );
ddsd2.dwSize = sizeof( ddsd2 );
g_pDDSOff[0]->Lock( NULL, &ddsd2, DDLOCK_WAIT, NULL );
LPWORD tex_ram = (LPWORD)ddsd2.lpSurface;
int tex_pitch = ddsd2.lPitch/2;
for(int i = 0; i < shape.number_of_tryangel; i++)
{
//裏を向いているポリゴンは描かない
if( backface(shape.men[i],cube_vertices) == 1)
{
//ポリゴンバッファをクリア
resetpolyBuf();
//三角形を描きながらポリゴンバッファに値を書きこむ
Line((int)shape.vertex[shape.men[i].index[0]].sx + XORIGIN,
(int)shape.vertex[shape.men[i].index[0]].sy + YORIGIN,
(int)shape.vertex[shape.men[i].index[1]].sx + XORIGIN,
(int)shape.vertex[shape.men[i].index[1]].sy + YORIGIN,
ddsd,
lpVideoMemory,
shape.men[i].index[0],
shape.men[i].index[1]
);
Line((int)shape.vertex[shape.men[i].index[1]].sx + XORIGIN,
(int)shape.vertex[shape.men[i].index[1]].sy + YORIGIN,
(int)shape.vertex[shape.men[i].index[2]].sx + XORIGIN,
(int)shape.vertex[shape.men[i].index[2]].sy + YORIGIN,
ddsd,
lpVideoMemory,
shape.men[i].index[1],
shape.men[i].index[2]
);
Line((int)shape.vertex[shape.men[i].index[2]].sx + XORIGIN,
(int)shape.vertex[shape.men[i].index[2]].sy + YORIGIN,
(int)shape.vertex[shape.men[i].index[0]].sx + XORIGIN,
(int)shape.vertex[shape.men[i].index[0]].sy + YORIGIN,
ddsd,
lpVideoMemory,
shape.men[i].index[2],
shape.men[i].index[0]
);
//UV値を比較しながらポリゴンバッファの値を元にテクスチャのピクセルを求め、ポリゴンを塗る
for(int y=0; y<480; y++){
if((polyBuf[y].min != 32767) && (polyBuf[y].max != -32768)){
int u = polyBuf[y].minu;
int v = polyBuf[y].minv;
int addv = 0;
int addu = 0;
if( (polyBuf[y].max - polyBuf[y].min) != 0){
addu = (polyBuf[y].maxu - polyBuf[y].minu) / (polyBuf[y].max - polyBuf[y].min);
addv = (polyBuf[y].maxv - polyBuf[y].minv) / (polyBuf[y].max - polyBuf[y].min);
}
for(int x=polyBuf[y].min; x<polyBuf[y].max; x++,u+=addu,v+=addv){
lpVideoMemory[video_pitch * y + x] = tex_ram[tex_pitch * (v>>16) + (u>>16)] ;
}
}
}
}
}
// ロックを解除
g_pDDSOff[0]->Unlock( NULL );
Surface->Unlock( NULL );
}
|