这个教程沿用了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;
}
在该函数中将图片左上点的坐标由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坐标看就是在窗口中间
程序的源代链接如下:
点击打开链接