完成模型定义后就可以进行显示处理。CreateWindowSizeDependentResources方法首先根据窗口状态初始化显示比例,并设置可视角度为70度(DirectX只支持弧度,度转为弧度可通过常量XM_PI实现);0.01f和100.0f则用来设置可见距离。这些参数之间的详细介绍见directx10游戏编程入门 5.6。
void CubeRenderer::CreateWindowSizeDependentResources()
{
Direct3DBase::CreateWindowSizeDependentResources();
float aspectRatio = m_windowBounds.Width / m_windowBounds.Height;
float fovAngleY = 70.0f * XM_PI / 180.0f;
XMStoreFloat4x4(
&m_constantBufferData.projection,
XMMatrixTranspose(
XMMatrixMultiply(
XMMatrixPerspectiveFovRH(
fovAngleY,
aspectRatio,
0.01f,
100.0f
),
XMLoadFloat4x4(&m_orientationTransform3D)
)
)
);
}
至此,各项准备工作就绪,场景中的正方体和摄像机的位置已经定好,可以开拍了!
应用展示的是一个旋转正方体,那么必然有一个方法负责更新不同时刻正方体的旋转角度。下面的Update方法用timeTotal * XM_PIDIV4来实现这个功能。XMMatrixRotationY方法说明正方体沿Y轴旋转。其他部分则是设置观察的位置。eye说明眼睛所在的位置;at则是眼睛观察的方向;up用来表示坐标系中的“上”,一般不做更改。而眼睛的可视角和视力已经在CreateWindowSizeDependentResources方法中定义过。这一步更新模型状态,确定哪些内容会显示在屏幕上,但并没有真正显示结果。
void CubeRenderer::Update(float timeTotal, float timeDelta)
{
(void) timeDelta; // 未使用的参数。
XMVECTOR eye = XMVectorSet(0.0f, 0.7f, 1.5f, 0.0f);
XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f);
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));
XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(timeTotal * XM_PIDIV4)));
}
Render方法实现最终图像的绘制,其主要就是设置各个功能的缓冲区地址。
void CubeRenderer::Render()
{
const float midnightBlue[] = { 0.098f, 0.098f, 0.439f, 1.000f };
m_d3dContext->ClearRenderTargetView(
m_renderTargetView.Get(),
midnightBlue
);
m_d3dContext->ClearDepthStencilView(
m_depthStencilView.Get(),
D3D11_CLEAR_DEPTH,
1.0f,
0
);
// 仅在加载时绘制多维数据集(加载为异步过程)。
if (!m_loadingComplete)
{
return;
}
m_d3dContext->OMSetRenderTargets(
1,
m_renderTargetView.GetAddressOf(),
m_depthStencilView.Get()
);
m_d3dContext->UpdateSubresource(
m_constantBuffer.Get(),
0,
NULL,
&m_constantBufferData,
0,
0
);
UINT stride = sizeof(VertexPositionColor);
UINT offset = 0;
m_d3dContext->IASetVertexBuffers(
0,
1,
m_vertexBuffer.GetAddressOf(),
&stride,
&offset
);
m_d3dContext->IASetIndexBuffer(
m_indexBuffer.Get(),
DXGI_FORMAT_R16_UINT,
0
);
m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_d3dContext->IASetInputLayout(m_inputLayout.Get());
m_d3dContext->VSSetShader(
m_vertexShader.Get(),
nullptr,
0
);
m_d3dContext->VSSetConstantBuffers(
0,
1,
m_constantBuffer.GetAddressOf()
);
m_d3dContext->PSSetShader(
m_pixelShader.Get(),
nullptr,
0
);
m_d3dContext->DrawIndexed(
m_indexCount,
0,
0
);
}
至此,整个CubeRenderer.cpp文件结束,完成旋转正方体的实现。通过这个示例程序了解DirectX的工作原理,结合DirectX 10 3D游戏编程入门,对其中涉及的数学知识和渲染过程有更深的体会。3D编程真是有点复杂,还要好好研究下。