如何使用 DirectX 11 渲染多个网格
How to render multiple meshes using DirectX 11
我正在使用 C++ 和 DirectX 11 开发图形引擎。在导入场景(使用 Assimp)时,我必须使用单独的着色器渲染多个网格。我通过以下方法做到这一点
我有一个 std::vector 来存储着色器,另一个用于存储网格。打开文件后,我将所有网格添加到该矢量。接下来,我使用 for 循环遍历向量的元素并分别绘制它们中的每一个。绘制完所有网格后,我交换缓冲区。这工作得很好,除了 framerate/performance 很糟糕。
我不知道如何才能更有效地完成这项工作,或者这种事情应该如何完成。
void CRenderer::RenderFrame(void(*r)(void), void(*gui)(void),std::vector<CMesh>& meshStr, std::vector<CShader>& shaderStr)
{
const float BackColor[4] = { 0.03f, 0.03f, 0.03f, 1.f };
DeviceContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
DeviceContext->ClearRenderTargetView(backbuffer, BackColor);
for (int i = 0; i < shaderStr.size(); i++)
{
UseShader(&shaderStr[i], sizeof(Vertex), 0);
r();
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
DeviceContext->VSSetConstantBuffers(0, 1, &CurrentShader->GetConstantBuffer());
DeviceContext->PSSetConstantBuffers(0, 1, &CurrentShader->GetConstantBuffer());
DeviceContext->VSSetConstantBuffers(1, 1, &CurrentShader->GetLightConstantBuffer());
DeviceContext->PSSetConstantBuffers(1, 1, &CurrentShader->GetLightConstantBuffer());
DeviceContext->DrawIndexed(meshStr[i].GetIndicesCount(), 0, 0);
}
gui();
SwapChain->Present(0, 0);
}
首先,您不应该在 WindowProc
中渲染。
正确的方法是在每个滴答开始时处理所有消息,然后渲染帧。
像这样:
void CWindow::BeginTick(void(*ETick)())
{
GetCursorPos(&LastMousePosition);
LastTime = std::chrono::system_clock::now();
while (true)
{
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetCursorPos(&CurrentMousePosition);
CurrentTime = std::chrono::system_clock::now();
UpdateDeltaTime();
ETick();
}
}
对于这个帧循环,我每帧大约有 0.8 毫秒
其次,你问题多多:
GetPerspectiveProjectionMatrix
和 GetViewMatrix
return 对局部变量的引用。它会导致网格渲染不正确。
OpenCdlg
中的错误 - 您分配了 len - 4
个字符,但您阅读了 len
。
txt_path = new char[len - 4];
f.seekg(0);
f.read(txt_path, sizeof(char) * len);
应该是
txt_path = new char[len + 1]; // allocate len + 1 for terminator
f.seekg(0);
f.read(txt_path, sizeof(char) * len);
txt_path[len] = 0; // add zero terminator
我正在使用 C++ 和 DirectX 11 开发图形引擎。在导入场景(使用 Assimp)时,我必须使用单独的着色器渲染多个网格。我通过以下方法做到这一点 我有一个 std::vector 来存储着色器,另一个用于存储网格。打开文件后,我将所有网格添加到该矢量。接下来,我使用 for 循环遍历向量的元素并分别绘制它们中的每一个。绘制完所有网格后,我交换缓冲区。这工作得很好,除了 framerate/performance 很糟糕。
我不知道如何才能更有效地完成这项工作,或者这种事情应该如何完成。
void CRenderer::RenderFrame(void(*r)(void), void(*gui)(void),std::vector<CMesh>& meshStr, std::vector<CShader>& shaderStr)
{
const float BackColor[4] = { 0.03f, 0.03f, 0.03f, 1.f };
DeviceContext->ClearDepthStencilView(DepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
DeviceContext->ClearRenderTargetView(backbuffer, BackColor);
for (int i = 0; i < shaderStr.size(); i++)
{
UseShader(&shaderStr[i], sizeof(Vertex), 0);
r();
DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
DeviceContext->VSSetConstantBuffers(0, 1, &CurrentShader->GetConstantBuffer());
DeviceContext->PSSetConstantBuffers(0, 1, &CurrentShader->GetConstantBuffer());
DeviceContext->VSSetConstantBuffers(1, 1, &CurrentShader->GetLightConstantBuffer());
DeviceContext->PSSetConstantBuffers(1, 1, &CurrentShader->GetLightConstantBuffer());
DeviceContext->DrawIndexed(meshStr[i].GetIndicesCount(), 0, 0);
}
gui();
SwapChain->Present(0, 0);
}
首先,您不应该在 WindowProc
中渲染。
正确的方法是在每个滴答开始时处理所有消息,然后渲染帧。
像这样:
void CWindow::BeginTick(void(*ETick)())
{
GetCursorPos(&LastMousePosition);
LastTime = std::chrono::system_clock::now();
while (true)
{
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetCursorPos(&CurrentMousePosition);
CurrentTime = std::chrono::system_clock::now();
UpdateDeltaTime();
ETick();
}
}
对于这个帧循环,我每帧大约有 0.8 毫秒
其次,你问题多多:
GetPerspectiveProjectionMatrix
和GetViewMatrix
return 对局部变量的引用。它会导致网格渲染不正确。OpenCdlg
中的错误 - 您分配了len - 4
个字符,但您阅读了len
。txt_path = new char[len - 4]; f.seekg(0); f.read(txt_path, sizeof(char) * len);
应该是
txt_path = new char[len + 1]; // allocate len + 1 for terminator f.seekg(0); f.read(txt_path, sizeof(char) * len); txt_path[len] = 0; // add zero terminator