【问题标题】:How to render multiple meshes using DirectX 11如何使用 DirectX 11 渲染多个网格
【发布时间】:2019-07-01 19:51:52
【问题描述】:

我正在使用 c++ 和 DirectX 11 开发图形引擎。在导入场景(使用 Assimp)时,我必须使用单独的着色器渲染多个网格。我通过以下方法做到这一点 我有一个 std::vector 来存储着色器和另一个用于网格。打开文件后,我将所有网格添加到该向量中。接下来,我使用 for 循环遍历向量的元素并分别绘制它们中的每一个。绘制完所有网格后,我交换缓冲区。除了帧率/性能很糟糕之外,这一切都很好。

我不知道如何才能更有效地完成这项工作,或者这种事情应该如何完成。

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);
}

【问题讨论】:

  • 速度慢是因为 CPU 还是 GPU?你有多少个网格?有多少个顶点/三角形?你如何设置顶点/索引缓冲区? r 函数有什么作用?
  • 我不确定是 CPU 导致了减速还是 GPU,但据我所知应该是 CPU。这取决于,我的意思是它滞后于我尝试加载的任何文件,但是对于这个特定的测试,它是 7 个网格,但没有什么是我的 gpu 不能轻松处理的。顶点和索引缓冲区绑定在 UseShader() 中。 (对不起;忘记提供源代码)功能。 r() 只是一个函数指针,用于更新矩阵和照明向量、颜色等的常量缓冲区。
  • 嗯,奇怪。它看起来不错,应该可以正常工作。因此,必须对其进行分析以找出实际原因。我可以尝试为您提供帮助,但您必须共享您的项目,或者至少共享带有调试符号的可运行二进制文件。
  • 或者你可以尝试自己做。首先,我会通过在 Intel GPA 中进行帧捕获来检查 GPU。它将向您展示 GPU 部分的速度。如果帧时间小于你在程序中看到的帧时间,那么你的 CPU 受限,你应该分析 CPU 部分(如果你有 vTune,VerySleepy 或手动检测)
  • 首先感谢您的快速响应,我使用了 Intel GPA,看来我的 CPU 很好,GPU 是导致瓶颈的原因。它是 1050 ti 4 GB,我认为它应该能够轻松处理更复杂的场景。帧时间大约是 4000 帧,时不时地跃升至甚至超过 10000 帧。 GPU 持续时间始终保持较小。在意识到 GPU 造成了瓶颈后,我更加困惑......

标签: c++ directx-11


【解决方案1】:

首先,您不应该在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 返回对局部变量的引用。它会导致网格渲染不正确。

  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
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 2017-11-26
    • 2016-09-08
    • 1970-01-01
    • 2018-03-18
    • 2019-04-16
    相关资源
    最近更新 更多