Directx11教程七之2D渲染

本文介绍如何使用Direct3D 11 (D3D11) 进行2D渲染,通过一个具体例子展示了如何将2D图片从WIN32坐标系转换到D3D11坐标系,并更新顶点缓存以实现图片位置的动态变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个教程沿用了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坐标看就是在窗口中间





程序的源代链接如下:

点击打开链接




     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值