1. 程式人生 > >Directx11教程七之2D渲染

Directx11教程七之2D渲染

這個教程沿用了D3D11紋理那節教程的架構,再次貼出來看看


其中這次:ModelClass

   int mScrrenWidth, mScrrenHeight;
   int mBitmapWidth, mBitmapHeight;

增加了這四個私有屬性

先講一講WIN32的2D座標系,WIN32的2D座標系原點在視窗左上角

上圖 大概繪製了一下


而D3D11的3D左手座標系原點在視窗中心,

如圖:

此時ModelClass提供了一個函式在每幀呼叫更新頂點快取

bool ModelClass::UpdateBuffers(ID3D11DeviceContext* d3dDeviceContext, int positionX, int positionY)
{
	//在頂點快取最原始的資料被改變了,屬於動態頂點快取(以前教程那些原始頂點資料雖然後面誠意變換矩陣,但是未曾改變原始資料)

	//如何渲染圖片的位置未曾改變,就退出函式,這樣可以節省大量處理
	if ((positionX == mPreviousPosX)&&(positionY == mPreviousPosY))
	{
		return true;
	}

	//如果改變渲染圖片的位置改變了,就更新位置
	mPreviousPosX = positionX;
	mPreviousPosY = positionY;

	//求出win32座標下圖片的的left, right, top, bottom座標,由WIN32座標PosX和PosY變為D3D11座標系
	float left, right, top, bottom;

	left = (float)((mScrrenWidth / 2) *-1) + (float)positionX;
	right = left + (float)mBitmapWidth;
	top = (float)(mScrrenHeight / 2) - (float)positionY;
	bottom = top - (float)mBitmapHeight;

	//建立臨時的頂點陣列
	Vertex *vertexs;
	vertexs = new Vertex[mVertexCount];
	if (!vertexs)
	{
		return false;
	}

	//載入臨時頂點資料,這些是DX11座標,即螢幕中心為原點
	vertexs[0].pos = XMFLOAT3(left, top, 0.0f);
	vertexs[0].color = XMFLOAT2(0.0f, 0.0f);

	vertexs[1].pos = XMFLOAT3(right, bottom, 0.0f);
	vertexs[1].color = XMFLOAT2(1.0f, 1.0f);

	vertexs[2].pos = XMFLOAT3(left, bottom, 0.0f);
	vertexs[2].color = XMFLOAT2(0.0f, 1.0f);

	vertexs[3].pos = XMFLOAT3(left, top, 0.0f);
	vertexs[3].color = XMFLOAT2(0.0f, 0.0f);

	vertexs[4].pos = XMFLOAT3(right, top, 0.0f);
	vertexs[4].color = XMFLOAT2(1.0f, 0.0f);

	vertexs[5].pos = XMFLOAT3(right, bottom, 0.0f);
	vertexs[5].color = XMFLOAT2(1.0f, 1.0f);

	//鎖定頂點快取為了可以進行寫入(動態快取不能用UpdateSubResources寫入)
	D3D11_MAPPED_SUBRESOURCE mappedResource;
	HR(d3dDeviceContext->Map(md3dVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));

	//獲取指向頂點快取的指標
	Vertex* verticesPtr;
	verticesPtr = (Vertex*)mappedResource.pData;

	//把資料複製進頂點快取
	memcpy(verticesPtr, (void*)vertexs, (sizeof(Vertex) * mVertexCount));

	//解鎖頂點快取
	d3dDeviceContext->Unmap(md3dVertexBuffer, 0);

	//釋放頂點陣列
	delete vertexs;
	vertexs = NULL;
	return true;
}

函式的形參為2D圖片在WIN32座標下的X和Y座標,畢竟這樣提供引數的進行2D貼圖時候很直觀,這點用過GDI的同學都很清楚

在該函式中將圖片左上點的座標由WIN32的2D座標系空間轉化為D3D11的左手3D座標系空間的座標,(Z都設為0.0f),由於算出了圖片左上角的座標,然後由圖片的寬度,高度,螢幕寬度,螢幕高度,在算出圖片其它三個點(左下點,右上點,右下點)在D3D11的左手3D座標系的值,四個點剛好構成3D座標系的一個正方形,由兩個三角形構成,這樣轉化為6個頂點資料送入D3D11的頂點快取,進行繪製,則進行2D Rendering成功.

當然這裡有兩個問題就是:第一是,D3D11的ViewMatrix得是mCamera位置為(0.0,0.0,X),其中X<0.0f,這樣保證符合提供的形參和WIN32座標系下觀察的圖片渲染位置效果一樣

  第二是,透視投影矩陣換為正交投影矩陣 orthoMatrix

執行的程式結果如下:、

mModel->Render(mD3D->GetDeviceContext(),400,300); //視窗寬800,高600,由WIN32座標看就是在視窗中間


程式的源代連結如下: