| 2690 | } |
| 2691 | |
| 2692 | void Scene::createDrawList() |
| 2693 | { |
| 2694 | if (!mpMeshVao) |
| 2695 | return; |
| 2696 | |
| 2697 | // This function creates argument buffers for draw indirect calls to rasterize the scene. |
| 2698 | // The updateGeometryInstances() function must have been called before so that the flags are accurate. |
| 2699 | // |
| 2700 | // Note that we create four draw buffers to handle all combinations of: |
| 2701 | // 1) mesh is using 16- or 32-bit indices, |
| 2702 | // 2) mesh triangle winding is CW or CCW after transformation. |
| 2703 | // |
| 2704 | // TODO: Update the draw args if a mesh undergoes animation that flips the winding. |
| 2705 | |
| 2706 | mDrawArgs.clear(); |
| 2707 | |
| 2708 | // Helper to create the draw-indirect buffer. |
| 2709 | auto createDrawBuffer = [this](const auto& drawMeshes, bool ccw, ResourceFormat ibFormat = ResourceFormat::Unknown) |
| 2710 | { |
| 2711 | if (drawMeshes.size() > 0) |
| 2712 | { |
| 2713 | DrawArgs draw; |
| 2714 | draw.pBuffer = mpDevice->createBuffer(sizeof(drawMeshes[0]) * drawMeshes.size(), ResourceBindFlags::IndirectArg, MemoryType::DeviceLocal, drawMeshes.data()); |
| 2715 | draw.pBuffer->setName("Scene draw buffer"); |
| 2716 | FALCOR_ASSERT(drawMeshes.size() <= std::numeric_limits<uint32_t>::max()); |
| 2717 | draw.count = (uint32_t)drawMeshes.size(); |
| 2718 | draw.ccw = ccw; |
| 2719 | draw.ibFormat = ibFormat; |
| 2720 | mDrawArgs.push_back(draw); |
| 2721 | } |
| 2722 | }; |
| 2723 | |
| 2724 | if (hasIndexBuffer()) |
| 2725 | { |
| 2726 | std::vector<DrawIndexedArguments> drawClockwiseMeshes[2], drawCounterClockwiseMeshes[2]; |
| 2727 | |
| 2728 | uint32_t instanceID = 0; |
| 2729 | for (const auto& instance : mGeometryInstanceData) |
| 2730 | { |
| 2731 | if (instance.getType() != GeometryType::TriangleMesh) continue; |
| 2732 | |
| 2733 | const auto& mesh = mMeshDesc[instance.geometryID]; |
| 2734 | bool use16Bit = mesh.use16BitIndices(); |
| 2735 | |
| 2736 | DrawIndexedArguments draw; |
| 2737 | draw.IndexCountPerInstance = mesh.indexCount; |
| 2738 | draw.InstanceCount = 1; |
| 2739 | draw.StartIndexLocation = mesh.ibOffset * (use16Bit ? 2 : 1); |
| 2740 | draw.BaseVertexLocation = mesh.vbOffset; |
| 2741 | draw.StartInstanceLocation = instanceID++; |
| 2742 | |
| 2743 | int i = use16Bit ? 0 : 1; |
| 2744 | (instance.isWorldFrontFaceCW()) ? drawClockwiseMeshes[i].push_back(draw) : drawCounterClockwiseMeshes[i].push_back(draw); |
| 2745 | } |
| 2746 | |
| 2747 | createDrawBuffer(drawClockwiseMeshes[0], false, ResourceFormat::R16Uint); |
| 2748 | createDrawBuffer(drawClockwiseMeshes[1], false, ResourceFormat::R32Uint); |
| 2749 | createDrawBuffer(drawCounterClockwiseMeshes[0], true, ResourceFormat::R16Uint); |
nothing calls this directly
no test coverage detected