如何使用 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 毫秒

其次,你问题多多:

  1. GetPerspectiveProjectionMatrixGetViewMatrix return 对局部变量的引用。它会导致网格渲染不正确。

  2. 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