Directx11教程七之2D渲染

这个教程沿用了D3D11纹理那节教程的架构,再次贴出来看看

Directx11教程七之2D渲染_第1张图片


其中这次:ModelClass

   int mScrrenWidth, mScrrenHeight;
   int mBitmapWidth, mBitmapHeight;

增加了这四个私有属性

先讲一讲WIN32的2D坐标系,WIN32的2D坐标系原点在窗口左上角

上图 大概绘制了一下

Directx11教程七之2D渲染_第2张图片

而D3D11的3D左手坐标系原点在窗口中心,

如图:Directx11教程七之2D渲染_第3张图片


此时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坐标看就是在窗口中间


Directx11教程七之2D渲染_第4张图片



程序的源代链接如下:

点击打开链接




     

你可能感兴趣的:(directx11入门)