« 範囲外のデータの取り扱い | メイン | データ構造、実装よりの話 »

2007年09月01日

グラフィックライブラリ:: DirectX とか

    

いろいろと追加していっていると、だんだんソフトウェアで処理するのが面倒になってきた。
と、少し DirectX で描いてみる。 ( テクスチャは別のところで設定 )
射影変換行列には、左手座標系正射影行列を上下反転した形で設定している。

struct SpriteVertex
{
    float x, y, z;
    float tu, tv;
};
SpriteVertex vtx[4];
vtx[0].z = vtx[1].z = vtx[2].z = vtx[3].z = 0.0f;

vtx[0].x = -0.5f; // TL
vtx[0].y = -0.5f;
vtx[0].tu = (p.tx + 0.5f) / p.img_width;
vtx[0].tv = (p.ty + 0.5f) / p.img_height;

vtx[1].x = 0.5f; // TR
vtx[1].y = -0.5f;
vtx[1].tu = (p.tx + p.tw + 0.5f) / p.img_width;
vtx[1].tv = (p.ty + 0.5f) / p.img_height;

vtx[2].x = 0.5f; // BR
vtx[2].y = 0.5f;
vtx[2].tu = (p.tx + p.tw + 0.5f) / p.img_width;
vtx[2].tv = (p.ty + p.th + 0.5f) / p.img_height;

vtx[3].x = -0.5f; // BL
vtx[3].y = 0.5f;
vtx[3].tu = (p.tx + 0.5f) / p.img_width;
vtx[3].tv = (p.ty + p.th + 0.5f) / p.img_height;

g_MatStack->Push();

D3DXVECTOR3 center( 0.0f, 0.0f, 0.0f );
g_MatStack->LoadIdentity();
g_MatStack->Scale( p.w, p.h, 1.0f );
if( p.angle != 0.0f )
    g_MatStack->RotateAxis( &center, p.angle );
g_MatStack->Translate( p.x+p.w/2, p.y+p.h/2, p.z );
g_pd3dDevice->SetTransform( D3DTS_WORLD, g_MatStack->GetTop() );

g_pd3dDevice->SetFVF( D3DFVF_XYZ|D3DFVF_TEX1 );
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, reinterpret_cast<void*>(vtx), sizeof(vtx[0]) );

g_MatStack->Pop();

やっぱり楽だなぁ。
同じようにして線を引いてみる。

struct LineVertex
{
    float x, y, z;
};
LineVertex vtx[4];
vtx[0].z = vtx[1].z = vtx[2].z = vtx[3].z = z;

float w2 = width / 2.0f;
float w = (float)(ex - sx);
float h = (float)(ey - sy);
float length = sqrt( (float)(w*w + h*h) );
float dy = w * w2 / length;
float dx = h * w2 / length;

vtx[0].x = sx - dx; // TL
vtx[0].y = sy + dy;
vtx[1].x = ex - dx; // TR
vtx[1].y = ey + dy;
vtx[2].x = ex + dx; // BR
vtx[2].y = ey - dy;
vtx[3].x = sx + dx; // BL
vtx[3].y = sy - dy;

g_MatStack->Push();
g_MatStack->LoadIdentity();
g_pd3dDevice->SetTransform( D3DTS_WORLD, g_MatStack->GetTop() );

g_pd3dDevice->SetRenderState( D3DRS_TEXTUREFACTOR, col );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TFACTOR );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR );
g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

g_pd3dDevice->SetFVF( D3DFVF_XYZ );
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, reinterpret_cast<void*>(vtx), sizeof(vtx[0]) );
g_MatStack->Pop();

最初計算ミスってて出なくて少し悩んだがやはり楽。
自前で線引かなくても ID3DXLine があるのか。

上位で DirectX とソフトウェアが簡単に切り替えられるようにするかな。



投稿者 Takenori : 2007年09月01日 21:47




comments powered by Disqus
Total : Today : Yesterday : なかのひと