Direct3D テクスチャ マッピング

テクスチャ マッピング テクノロジを使用すると、画像データを三角形のユニットにマッピングできます。この機能により、ペイントされたシーンのディテールとリアリズムが大幅に向上します。たとえば、立方体を作成し、各面に板のテクスチャをマッピングすると、立方体が木箱になります。 Direct3D では、テクスチャはインターフェイスIDirect3DTexture9によって表されます。テクスチャはサーフェスと同様のピクセル マトリックスです。サーフェスとは異なり、三角形ユニットにマッピングできます。

テクスチャ座標

Direct3D ロックで使用されるテクスチャ座標系は、水平方向の u 軸と垂直方向の v 軸から構成され、座標ペア (u, v) で識別されるテクスチャ要素をテクスチャ要素と呼びます。 v 軸は垂直です。

さまざまなスケールのテクスチャを処理できるようにするために、Direct3D はテクスチャ座標を正規化し、間隔 [0,1] に制限されます。各 3D 三角形ユニットについて、テクスチャ内の対応する三角形領域を定義し、マップします。三角形領域のテクスチャを 3D 三角形ユニットにマッピングするには、頂点構造を再度変更し、テクスチャ内の頂点を識別するためにテクスチャ座標ペアを追加する必要があります。

struct TextureVertex
{
	TextureVertex(){}
	TextureVertex()
	{

	}
	float _x, _y, _z;
	float _nx, _ny, _nz;
	float _u, _v;			//纹理坐标
	static const DWORD FVF;
};
const DWORD TextureVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1; //D3DFVF_TEX1表示顶点结构中包含了一对纹理坐标

3 つの頂点オブジェクトによって形成される各三角形には、そのテクスチャ座標系で定義された対応するテクスチャ三角形があります。指定されていても、テクスチャは、3D 三角形がスクリーン座標に変換されるラスタライズまで使用されません。マッピングが行われます

テクスチャを作成して有効にする

テクスチャ データは通常、ディスク上のイメージ ファイルから読み取られて、IDirect3DTexture9 オブジェクトにロードされます。これは、BMP、DDS、DIB、JPG、PNG、TGA 形式のイメージをロードできる D3DXCreateTextureFromFile 関数を使用して実現できます。

HRESULT D3DXCreateTextureFromFile(
	LPDIRECT3DDEVICE9         pDevice,
	LPCSTR                    pSrcFile,
	LPDIRECT3DTEXTURE9*       ppTexture
);
IDirect3DTexture9* _stonewall;
D3DXCreateTextureFromFile(Device, "stonewall.bmp", &_stonewall);

HRESULT IDirect3DDevice9::SetTexture(
	DWORD Stage,	//纹理层
	IDirect3DBaseTexture9* pTexture
);

//禁用某一纹理层,可将pTexture参数设为0,绘制物体时若不想使用纹理可以这样做
Device->SetTexture(0, 0);
renderObjectWithoutTexture();

//如果场景中的各个三角形所使用的纹理均不相同
Device->SetTexture(0, tex0);
drawTrisUsingTex0();

Device->SetTexture(0, tex1);
drawTrisUsingTex1();

Direct3D では、最大 8 つのテクスチャ レイヤーを設定でき、これらを組み合わせてより詳細な画像を作成できます。これをマルチ テクスチャリングと呼びます。

テクスチャフィルター

通常、テクスチャ三角形とスクリーン三角形のサイズは一致していませんが、テクスチャ三角形とスクリーン三角形のサイズが一致しない場合、後者に合わせるためにテクスチャ三角形を拡大または縮小する必要があります。このような歪みをある程度克服するために、Directではテクスチャフィルタリングと呼ばれる技術を使用しています。

Direct3D には 3 種類のテクスチャ フィルターが用意されており、フィルターの品質が高いほど計算のオーバーヘッドが大きくなり、処理速度が遅くなります。テクスチャ フィルタリング方法はSetSamplerStateメソッドを使用して設定できます。

最近点サンプリング: Direct3D がデフォルトで使用するフィルタリング方法です。この方法は処理速度が最も速いですが、効果は最も悪いです。次のコードは、それぞれ拡大フィルタと縮小フィルタに最近点サンプリング方法を設定することを示します。

リニア テクスチャ フィルター: このタイプのフィルター処理では、非常に良好な結果が得られ、現在のハードウェア構成では高速です。

異方性テクスチャ フィルタリング: このタイプのフィルタリングでは最良の結果が得られますが、処理速度も最も遅くなります。このフィルタリングを使用する場合は、異方性フィルタリングの品質を決定する D3DSAMP_MAXANISOTROPIC レベル値を設定する必要があります。値が大きいほど、画像効果が向上します。IDirect3DDevice::GetDeviceCaps 関数を呼び出して、返された D3DCAPS9 構造体パラメーターを確認し、ハードウェアでサポートされている値の正当な値の範囲を取得してください。

//设置最近点采样纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);

//设置线性纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

//设置各向异性纹理过滤
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);

//将各向异性过滤的质量水平设置为4
Device->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 4);

マルチレベルプログレッシブテクスチャ

画面上の三角形は、通常、テクスチャの三角形と同じサイズではありません。2 つのサイズの違いによる影響を最小限に抑えるために、段階的に一連のテクスチャを作成することで、テクスチャのマルチレベルのプログレッシブ テクスチャ チェーンを作成できます。特定のテクスチャから解像度を下げます。より重要な詳細を保持するには、各解像度のテクスチャに使用されるテクスチャ イメージとフィルタをカスタマイズする必要があります。Direct3D でマルチレベル プログレッシブ テクスチャを使用するのは非常に簡単です。ハードウェアがサポートしている場合は、マルチレベル プログレッシブ テクスチャの場合、D3DXCreateTextureFromFile 関数によってマルチレベル プログレッシブ テクスチャ チェーンが作成されます。さらに、Direct3D は、テクスチャ チェーンから画面の三角形に最も適合する第 1 レベルのテクスチャを自動的に選択します。 Direct3D によって処理され、処理中の時間とスペースのコストが比較的低いため、マルチレベルのプログレッシブ テクスチャが広く使用されています。

マルチレベルプログレッシブテクスチャフィルター

マルチレベル プログレッシブ テクスチャ フィルターは主に、Direct3D がマルチレベル プログレッシブ テクスチャを使用する方法を制御するために使用されます。マルチレベル プログレッシブ テクスチャ フィルターは次のように設定できます。

Device->SetSamplerState(0, D3DSAMP_MIPFILTER, Filter);

フィルターは次の値を取ることができます

D3DTEXF_NONE : マルチレベル プログレッシブ テクスチャ フィルターを無効にします
D3DTEXF_POINT : このフィルターを使用すると、Direct3D は画面の三角形に最も近いサイズのテクスチャ レベルを選択します。テクスチャ レベルが選択されると、Direct3D は指定された増幅フィルターと縮小フィルターはこのレベルのテクスチャをフィルターします
D3DTEXF_LINEAR : このフィルターを使用すると、Direct3D は画面の三角形のサイズに最も近い 2 つのテクスチャ レベルを取得し、指定された拡大フィルターと縮小フィルターを使用してテクスチャの各レベルをフィルターし、次にこれら 2 つのレベルのテクスチャをフィルターします。次に、テクスチャが線形に結合されて、最終的なカラー値が形成されます。

アドレッシングモード

前のセクションでは、テクスチャ座標は [0,1] の範囲に制限する必要があると述べました。技術的な観点から見ると、座標がこの範囲を超える場合があるため、これは問題です。Direct3D では、テクスチャ座標値を処理する 4 つのメソッドが定義されています。 [ 0,1] 間隔テクスチャ マッピング モードを超えています。繰り返しアドレッシングモード(ラップ)、ボーダーカラーアドレッシングモード(ボーダーカラー)、クランプアドレッシングモード(クランプ)、ミラーアドレッシングモード(ミラー)です。

//set wrap address mode
if (::GetAsyncKeyState('W') & 0x8000f)
{
	//表示对纹理的u方向或v方向设置纹理寻址模式
	Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
	Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); 
	//D3DTADDRESS_CLAMP、D3DTADDRESS_MIRROR
}

//set border color address mode
if (::GetAsyncKeyState('B') & 0x8000f)
{
	//表示对纹理的u方向或v方向设置纹理寻址模式
	Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
	Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
	Device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x000000ff);
}

テクスチャード クワッド ルーチン

1. オブジェクトを構成する頂点を構築し、それらのテクスチャ座標を指定します
2. 関数 D3DXCreateTextureFromFile を使用して、IDirect3DTexture9 インターフェイスのテクスチャをロードし
ます 3. 縮小/増幅フィルタとマルチレベル プログレッシブ テクスチャ フィルタを設定します
4オブジェクトを描画する前に、関数 IDirect3DDevice9::SetTexture を使用して、オブジェクトに関連付けられたテクスチャを設定します。

bool SetUpTextureQuad()
{
	Device->CreateVertexBuffer(6 * sizeof(TextureVertex), D3DUSAGE_WRITEONLY, TextureVertex::FVF, D3DPOOL_MANAGED, &Quad, 0);
	TextureVertex* v;
	Quad->Lock(0, 0, (void**)&v, 0);
	v[0] = TextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
	v[1] = TextureVertex(-1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
	v[2] = TextureVertex(1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);

	v[3] = TextureVertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 3.0f);
	v[4] = TextureVertex(1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 0.0f);
	v[5] = TextureVertex(1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 3.0f, 3.0f);
	Quad->Unlock();
	
	D3DXCreateTextureFromFile(Device, "dx5_logo.bmp", &Tex);
	//启用纹理
	Device->SetTexture(0, Tex);
	//设置放大/缩小过滤器
	Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	//设置渐进纹理过滤器
	Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

	//不使用光照
	Device->SetRenderState(D3DRS_LIGHTING, false);

	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)Width / (float)Height, 1.0f, 1000.0f);
	Device->SetTransform(D3DTS_PROJECTION, &proj);
	return true;
}

bool DisplayTextureQuad(float timeDelta)
{
	if (Device)
	{
		Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
		Device->BeginScene();
		Device->SetStreamSource(0, Quad, 0, sizeof(TextureVertex));
		Device->SetFVF(TextureVertex::FVF);
		Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
		Device->EndScene();
		Device->Present(0, 0, 0, 0);
	}
	return true;
}

おすすめ

転載: blog.csdn.net/SwordArcher/article/details/132803354