diff --git a/projects/common/dx_renderer.cpp b/projects/common/dx_renderer.cpp index 6686c77..c755351 100644 --- a/projects/common/dx_renderer.cpp +++ b/projects/common/dx_renderer.cpp @@ -1,4 +1,5 @@ #include "dx_renderer.h" +#include "bitmap.h" bool IsCompressed(DXGI_FORMAT fmt); bool IsVideo(DXGI_FORMAT fmt); @@ -1077,6 +1078,111 @@ HRESULT CreateTexture( return S_OK; } +bool SaveDxTextureAsPNG(DxRenderer* pRenderer, ID3D12Resource* pTexture, const std::filesystem::path& absPath) +{ + D3D12_RESOURCE_DESC texDesc = pTexture->GetDesc(); + const uint32_t width = static_cast(texDesc.Width); + const uint32_t height = static_cast(texDesc.Height); + + // Get copyable footprint to determine the GPU-aligned row pitch + D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint = {}; + UINT64 totalBytes = 0; + pRenderer->Device->GetCopyableFootprints(&texDesc, 0, 1, 0, &footprint, nullptr, nullptr, &totalBytes); + + // Create CPU-readable readback buffer + ComPtr readbackBuffer; + HRESULT hr = CreateBuffer(pRenderer, static_cast(totalBytes), D3D12_HEAP_TYPE_READBACK, &readbackBuffer); + if (FAILED(hr)) + { + GREX_LOG_ERROR("SaveDxTextureAsPNG: failed to create readback buffer"); + return false; + } + + // Create a temporary command allocator and command list + ComPtr cmdAlloc; + ComPtr cmdList; + hr = pRenderer->Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc)); + if (FAILED(hr)) + { + GREX_LOG_ERROR("SaveDxTextureAsPNG: failed to create command allocator"); + return false; + } + hr = pRenderer->Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc.Get(), nullptr, IID_PPV_ARGS(&cmdList)); + if (FAILED(hr)) + { + GREX_LOG_ERROR("SaveDxTextureAsPNG: failed to create command list"); + return false; + } + + // Transition: PRESENT -> COPY_SOURCE + D3D12_RESOURCE_BARRIER barrierToCopy = {}; + barrierToCopy.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrierToCopy.Transition.pResource = pTexture; + barrierToCopy.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrierToCopy.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + barrierToCopy.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; + cmdList->ResourceBarrier(1, &barrierToCopy); + + // Copy texture to readback buffer + D3D12_TEXTURE_COPY_LOCATION dst = {}; + dst.pResource = readbackBuffer.Get(); + dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + dst.PlacedFootprint = footprint; + + D3D12_TEXTURE_COPY_LOCATION src = {}; + src.pResource = pTexture; + src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + src.SubresourceIndex = 0; + + cmdList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + + // Transition: COPY_SOURCE -> PRESENT + D3D12_RESOURCE_BARRIER barrierToPresent = {}; + barrierToPresent.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrierToPresent.Transition.pResource = pTexture; + barrierToPresent.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrierToPresent.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE; + barrierToPresent.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + cmdList->ResourceBarrier(1, &barrierToPresent); + + cmdList->Close(); + + ID3D12CommandList* pList = cmdList.Get(); + pRenderer->Queue->ExecuteCommandLists(1, &pList); + + if (!WaitForGpu(pRenderer)) + { + GREX_LOG_ERROR("SaveDxTextureAsPNG: WaitForGpu failed"); + return false; + } + + // Map and convert BGRA -> RGBA, force alpha = 255 + void* pMapped = nullptr; + readbackBuffer->Map(0, nullptr, &pMapped); + + BitmapRGBA8u bitmap(width, height); + uint8_t* pDst = reinterpret_cast(bitmap.GetPixels()); + const uint8_t* pSrc = static_cast(pMapped); + const uint32_t rowPitch = footprint.Footprint.RowPitch; + + for (uint32_t y = 0; y < height; ++y) + { + const uint8_t* pSrcRow = pSrc + y * rowPitch; + uint8_t* pDstRow = pDst + y * width * 4; + for (uint32_t x = 0; x < width; ++x) + { + pDstRow[x * 4 + 0] = pSrcRow[x * 4 + 2]; // R <- B + pDstRow[x * 4 + 1] = pSrcRow[x * 4 + 1]; // G <- G + pDstRow[x * 4 + 2] = pSrcRow[x * 4 + 0]; // B <- R + pDstRow[x * 4 + 3] = 255; // A <- 1 (swapchain alpha is meaningless) + } + } + + readbackBuffer->Unmap(0, nullptr); + + return BitmapRGBA8u::Save(absPath, &bitmap); +} + HRESULT CreateTexture( DxRenderer* pRenderer, uint32_t width, diff --git a/projects/common/dx_renderer.h b/projects/common/dx_renderer.h index 0cc7268..cf27e8e 100644 --- a/projects/common/dx_renderer.h +++ b/projects/common/dx_renderer.h @@ -221,4 +221,6 @@ HRESULT CompileHLSL( std::vector* pDXIL, std::string* pErrorMsg); -HRESULT CopyDataToBuffer(size_t dataSize, void* pData, ID3D12Resource* pBuffer); \ No newline at end of file +HRESULT CopyDataToBuffer(size_t dataSize, void* pData, ID3D12Resource* pBuffer); + +bool SaveDxTextureAsPNG(DxRenderer* pRenderer, ID3D12Resource* pTexture, const std::filesystem::path& absPath); \ No newline at end of file diff --git a/projects/geometry/101_color_cube_d3d12/101_color_cube_d3d12.cpp b/projects/geometry/101_color_cube_d3d12/101_color_cube_d3d12.cpp index dbdf0e8..853feef 100644 --- a/projects/geometry/101_color_cube_d3d12/101_color_cube_d3d12.cpp +++ b/projects/geometry/101_color_cube_d3d12/101_color_cube_d3d12.cpp @@ -188,9 +188,11 @@ int main(int argc, char** argv) // ************************************************************************* window->ResetTimer(); + uint32_t frameIndex = 0; + while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -266,12 +268,24 @@ int main(int argc, char** argv) break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } + // Present if (!SwapchainPresent(renderer.get())) { assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/101_color_cube_d3d12/CMakeLists.txt b/projects/geometry/101_color_cube_d3d12/CMakeLists.txt index 144ccc1..677e037 100644 --- a/projects/geometry/101_color_cube_d3d12/CMakeLists.txt +++ b/projects/geometry/101_color_cube_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 101_color_cube_d3d12 101_color_cube_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/102_cornell_box_d3d12/102_cornell_box_d3d12.cpp b/projects/geometry/102_cornell_box_d3d12/102_cornell_box_d3d12.cpp index 1e51364..61dff24 100644 --- a/projects/geometry/102_cornell_box_d3d12/102_cornell_box_d3d12.cpp +++ b/projects/geometry/102_cornell_box_d3d12/102_cornell_box_d3d12.cpp @@ -232,11 +232,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -330,6 +332,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -337,6 +348,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/102_cornell_box_d3d12/CMakeLists.txt b/projects/geometry/102_cornell_box_d3d12/CMakeLists.txt index 07bc211..de11249 100644 --- a/projects/geometry/102_cornell_box_d3d12/CMakeLists.txt +++ b/projects/geometry/102_cornell_box_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 102_cornell_box_d3d12 102_cornell_box_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/103_cone_d3d12/103_cone_d3d12.cpp b/projects/geometry/103_cone_d3d12/103_cone_d3d12.cpp index 4c4d24f..98a0930 100644 --- a/projects/geometry/103_cone_d3d12/103_cone_d3d12.cpp +++ b/projects/geometry/103_cone_d3d12/103_cone_d3d12.cpp @@ -212,11 +212,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -304,6 +306,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -311,6 +322,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/103_cone_d3d12/CMakeLists.txt b/projects/geometry/103_cone_d3d12/CMakeLists.txt index 7704083..76d9bca 100644 --- a/projects/geometry/103_cone_d3d12/CMakeLists.txt +++ b/projects/geometry/103_cone_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 103_cone_d3d12 103_cone_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/104_debug_tbn_d3d12/104_debug_tbn_d3d12.cpp b/projects/geometry/104_debug_tbn_d3d12/104_debug_tbn_d3d12.cpp index 6ee222d..cc470e9 100644 --- a/projects/geometry/104_debug_tbn_d3d12/104_debug_tbn_d3d12.cpp +++ b/projects/geometry/104_debug_tbn_d3d12/104_debug_tbn_d3d12.cpp @@ -265,11 +265,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -392,6 +394,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -399,6 +410,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/104_debug_tbn_d3d12/CMakeLists.txt b/projects/geometry/104_debug_tbn_d3d12/CMakeLists.txt index 2169526..1e8c278 100644 --- a/projects/geometry/104_debug_tbn_d3d12/CMakeLists.txt +++ b/projects/geometry/104_debug_tbn_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 104_debug_tbn_d3d12 104_debug_tbn_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/110_mesh_shader_triangle_d3d12/110_mesh_shader_triangle_d3d12.cpp b/projects/geometry/110_mesh_shader_triangle_d3d12/110_mesh_shader_triangle_d3d12.cpp index 751662e..a1656b9 100644 --- a/projects/geometry/110_mesh_shader_triangle_d3d12/110_mesh_shader_triangle_d3d12.cpp +++ b/projects/geometry/110_mesh_shader_triangle_d3d12/110_mesh_shader_triangle_d3d12.cpp @@ -240,11 +240,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -292,6 +294,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -299,6 +310,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/110_mesh_shader_triangle_d3d12/CMakeLists.txt b/projects/geometry/110_mesh_shader_triangle_d3d12/CMakeLists.txt index 327659f..c8955e3 100644 --- a/projects/geometry/110_mesh_shader_triangle_d3d12/CMakeLists.txt +++ b/projects/geometry/110_mesh_shader_triangle_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 110_mesh_shader_triangle_d3d12 110_mesh_shader_triangle_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/111_mesh_shader_meshlets_d3d12/111_mesh_shader_meshlets_d3d12.cpp b/projects/geometry/111_mesh_shader_meshlets_d3d12/111_mesh_shader_meshlets_d3d12.cpp index 4441c62..e52bbb1 100644 --- a/projects/geometry/111_mesh_shader_meshlets_d3d12/111_mesh_shader_meshlets_d3d12.cpp +++ b/projects/geometry/111_mesh_shader_meshlets_d3d12/111_mesh_shader_meshlets_d3d12.cpp @@ -300,11 +300,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -365,6 +367,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -372,6 +383,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/111_mesh_shader_meshlets_d3d12/CMakeLists.txt b/projects/geometry/111_mesh_shader_meshlets_d3d12/CMakeLists.txt index 8065586..dc7b582 100644 --- a/projects/geometry/111_mesh_shader_meshlets_d3d12/CMakeLists.txt +++ b/projects/geometry/111_mesh_shader_meshlets_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 111_mesh_shader_meshlets_d3d12 111_mesh_shader_meshlets_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/112_mesh_shader_amplification_d3d12/112_mesh_shader_amplification_d3d12.cpp b/projects/geometry/112_mesh_shader_amplification_d3d12/112_mesh_shader_amplification_d3d12.cpp index a27c4b1..f9abe23 100644 --- a/projects/geometry/112_mesh_shader_amplification_d3d12/112_mesh_shader_amplification_d3d12.cpp +++ b/projects/geometry/112_mesh_shader_amplification_d3d12/112_mesh_shader_amplification_d3d12.cpp @@ -313,11 +313,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -380,6 +382,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -387,6 +398,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/112_mesh_shader_amplification_d3d12/CMakeLists.txt b/projects/geometry/112_mesh_shader_amplification_d3d12/CMakeLists.txt index 2de4631..f240f45 100644 --- a/projects/geometry/112_mesh_shader_amplification_d3d12/CMakeLists.txt +++ b/projects/geometry/112_mesh_shader_amplification_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 112_mesh_shader_amplification_d3d12 112_mesh_shader_amplification_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/113_mesh_shader_instancing_d3d12/113_mesh_shader_instancing_d3d12.cpp b/projects/geometry/113_mesh_shader_instancing_d3d12/113_mesh_shader_instancing_d3d12.cpp index 47c30c5..b5fbd13 100644 --- a/projects/geometry/113_mesh_shader_instancing_d3d12/113_mesh_shader_instancing_d3d12.cpp +++ b/projects/geometry/113_mesh_shader_instancing_d3d12/113_mesh_shader_instancing_d3d12.cpp @@ -355,11 +355,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -515,6 +517,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Command list execution is done we can read the pipeline stats hasPiplineStats = true; @@ -525,6 +536,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/113_mesh_shader_instancing_d3d12/CMakeLists.txt b/projects/geometry/113_mesh_shader_instancing_d3d12/CMakeLists.txt index df0db2d..8c8b2da 100644 --- a/projects/geometry/113_mesh_shader_instancing_d3d12/CMakeLists.txt +++ b/projects/geometry/113_mesh_shader_instancing_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 113_mesh_shader_instancing_d3d12 113_mesh_shader_instancing_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/114_mesh_shader_culling_d3d12/114_mesh_shader_culling_d3d12.cpp b/projects/geometry/114_mesh_shader_culling_d3d12/114_mesh_shader_culling_d3d12.cpp index 614fb0a..8a960aa 100644 --- a/projects/geometry/114_mesh_shader_culling_d3d12/114_mesh_shader_culling_d3d12.cpp +++ b/projects/geometry/114_mesh_shader_culling_d3d12/114_mesh_shader_culling_d3d12.cpp @@ -424,11 +424,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -666,6 +668,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Command list execution is done we can read the pipeline stats hasPiplineStats = true; @@ -676,6 +687,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/114_mesh_shader_culling_d3d12/CMakeLists.txt b/projects/geometry/114_mesh_shader_culling_d3d12/CMakeLists.txt index ba03c8a..abea79d 100644 --- a/projects/geometry/114_mesh_shader_culling_d3d12/CMakeLists.txt +++ b/projects/geometry/114_mesh_shader_culling_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 114_mesh_shader_culling_d3d12 114_mesh_shader_culling_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/115_mesh_shader_lod_d3d12/115_mesh_shader_lod_d3d12.cpp b/projects/geometry/115_mesh_shader_lod_d3d12/115_mesh_shader_lod_d3d12.cpp index 09f1e97..8200f6f 100644 --- a/projects/geometry/115_mesh_shader_lod_d3d12/115_mesh_shader_lod_d3d12.cpp +++ b/projects/geometry/115_mesh_shader_lod_d3d12/115_mesh_shader_lod_d3d12.cpp @@ -448,11 +448,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -672,6 +674,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Command list execution is done we can read the pipeline stats hasPiplineStats = true; @@ -682,6 +693,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/115_mesh_shader_lod_d3d12/CMakeLists.txt b/projects/geometry/115_mesh_shader_lod_d3d12/CMakeLists.txt index d6b83ed..59b0287 100644 --- a/projects/geometry/115_mesh_shader_lod_d3d12/CMakeLists.txt +++ b/projects/geometry/115_mesh_shader_lod_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 115_mesh_shader_lod_d3d12 115_mesh_shader_lod_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/116_mesh_shader_calc_lod_d3d12/116_mesh_shader_calc_lod_d3d12.cpp b/projects/geometry/116_mesh_shader_calc_lod_d3d12/116_mesh_shader_calc_lod_d3d12.cpp index 9a55bd3..c54cd3c 100644 --- a/projects/geometry/116_mesh_shader_calc_lod_d3d12/116_mesh_shader_calc_lod_d3d12.cpp +++ b/projects/geometry/116_mesh_shader_calc_lod_d3d12/116_mesh_shader_calc_lod_d3d12.cpp @@ -457,11 +457,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -689,6 +691,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Command list execution is done we can read the pipeline stats hasPiplineStats = true; @@ -699,6 +710,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/116_mesh_shader_calc_lod_d3d12/CMakeLists.txt b/projects/geometry/116_mesh_shader_calc_lod_d3d12/CMakeLists.txt index a54edb5..5e6d4e4 100644 --- a/projects/geometry/116_mesh_shader_calc_lod_d3d12/CMakeLists.txt +++ b/projects/geometry/116_mesh_shader_calc_lod_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 116_mesh_shader_calc_lod_d3d12 116_mesh_shader_calc_lod_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/117_mesh_shader_cull_lod_d3d12/117_mesh_shader_cull_lod_d3d12.cpp b/projects/geometry/117_mesh_shader_cull_lod_d3d12/117_mesh_shader_cull_lod_d3d12.cpp index d951f6b..b29bdff 100644 --- a/projects/geometry/117_mesh_shader_cull_lod_d3d12/117_mesh_shader_cull_lod_d3d12.cpp +++ b/projects/geometry/117_mesh_shader_cull_lod_d3d12/117_mesh_shader_cull_lod_d3d12.cpp @@ -543,11 +543,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -813,6 +815,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Command list execution is done we can read the pipeline stats if (queryBuffer) @@ -826,6 +837,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/117_mesh_shader_cull_lod_d3d12/CMakeLists.txt b/projects/geometry/117_mesh_shader_cull_lod_d3d12/CMakeLists.txt index 33dcb38..4b873f7 100644 --- a/projects/geometry/117_mesh_shader_cull_lod_d3d12/CMakeLists.txt +++ b/projects/geometry/117_mesh_shader_cull_lod_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( ${PROJECT_NAME} ${PROJECT_NAME}.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/118_mesh_shader_vertex_attrs_d3d12/118_mesh_shader_vertex_attrs_d3d12.cpp b/projects/geometry/118_mesh_shader_vertex_attrs_d3d12/118_mesh_shader_vertex_attrs_d3d12.cpp index df2a76f..dac6ebe 100644 --- a/projects/geometry/118_mesh_shader_vertex_attrs_d3d12/118_mesh_shader_vertex_attrs_d3d12.cpp +++ b/projects/geometry/118_mesh_shader_vertex_attrs_d3d12/118_mesh_shader_vertex_attrs_d3d12.cpp @@ -375,11 +375,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -491,6 +493,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -498,6 +509,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/118_mesh_shader_vertex_attrs_d3d12/CMakeLists.txt b/projects/geometry/118_mesh_shader_vertex_attrs_d3d12/CMakeLists.txt index dd75ce7..716f242 100644 --- a/projects/geometry/118_mesh_shader_vertex_attrs_d3d12/CMakeLists.txt +++ b/projects/geometry/118_mesh_shader_vertex_attrs_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( ${PROJECT_NAME} ${PROJECT_NAME}.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/geometry/119_mesh_shader_vertex_bary_d3d12/119_mesh_shader_vertex_bary_d3d12.cpp b/projects/geometry/119_mesh_shader_vertex_bary_d3d12/119_mesh_shader_vertex_bary_d3d12.cpp index 2b438dc..89e6ac1 100644 --- a/projects/geometry/119_mesh_shader_vertex_bary_d3d12/119_mesh_shader_vertex_bary_d3d12.cpp +++ b/projects/geometry/119_mesh_shader_vertex_bary_d3d12/119_mesh_shader_vertex_bary_d3d12.cpp @@ -375,11 +375,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -491,6 +493,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -498,6 +509,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/geometry/119_mesh_shader_vertex_bary_d3d12/CMakeLists.txt b/projects/geometry/119_mesh_shader_vertex_bary_d3d12/CMakeLists.txt index 86e3b7a..e6b8097 100644 --- a/projects/geometry/119_mesh_shader_vertex_bary_d3d12/CMakeLists.txt +++ b/projects/geometry/119_mesh_shader_vertex_bary_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( ${PROJECT_NAME} ${PROJECT_NAME}.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h diff --git a/projects/io/401_gltf_basic_geo_d3d12/401_gltf_basic_geo_d3d12.cpp b/projects/io/401_gltf_basic_geo_d3d12/401_gltf_basic_geo_d3d12.cpp index 4b840d5..b20b6b3 100644 --- a/projects/io/401_gltf_basic_geo_d3d12/401_gltf_basic_geo_d3d12.cpp +++ b/projects/io/401_gltf_basic_geo_d3d12/401_gltf_basic_geo_d3d12.cpp @@ -279,11 +279,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -357,6 +359,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -364,6 +375,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/io/402_gltf_basic_texture_d3d12/402_gltf_basic_texture_d3d12.cpp b/projects/io/402_gltf_basic_texture_d3d12/402_gltf_basic_texture_d3d12.cpp index 395cd3f..9335384 100644 --- a/projects/io/402_gltf_basic_texture_d3d12/402_gltf_basic_texture_d3d12.cpp +++ b/projects/io/402_gltf_basic_texture_d3d12/402_gltf_basic_texture_d3d12.cpp @@ -279,11 +279,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -357,6 +359,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -364,6 +375,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/io/403_gltf_basic_material_d3d12/403_gltf_basic_material_d3d12.cpp b/projects/io/403_gltf_basic_material_d3d12/403_gltf_basic_material_d3d12.cpp index b8a30eb..4b9d483 100644 --- a/projects/io/403_gltf_basic_material_d3d12/403_gltf_basic_material_d3d12.cpp +++ b/projects/io/403_gltf_basic_material_d3d12/403_gltf_basic_material_d3d12.cpp @@ -279,11 +279,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -357,6 +359,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -364,6 +375,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/io/404_gltf_basic_material_texture_d3d12/404_gltf_basic_material_texture_d3d12.cpp b/projects/io/404_gltf_basic_material_texture_d3d12/404_gltf_basic_material_texture_d3d12.cpp index 0807fb4..68d0174 100644 --- a/projects/io/404_gltf_basic_material_texture_d3d12/404_gltf_basic_material_texture_d3d12.cpp +++ b/projects/io/404_gltf_basic_material_texture_d3d12/404_gltf_basic_material_texture_d3d12.cpp @@ -279,11 +279,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -357,6 +359,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -364,6 +375,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/io/405_gltf_full_material_test_d3d12/405_gltf_full_material_test_d3d12.cpp b/projects/io/405_gltf_full_material_test_d3d12/405_gltf_full_material_test_d3d12.cpp index d54a167..d3cce62 100644 --- a/projects/io/405_gltf_full_material_test_d3d12/405_gltf_full_material_test_d3d12.cpp +++ b/projects/io/405_gltf_full_material_test_d3d12/405_gltf_full_material_test_d3d12.cpp @@ -365,11 +365,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -484,6 +486,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -491,6 +502,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/misc/gltf_d3d12/gltf_d3d12.cpp b/projects/misc/gltf_d3d12/gltf_d3d12.cpp index 61b1e42..f84939b 100644 --- a/projects/misc/gltf_d3d12/gltf_d3d12.cpp +++ b/projects/misc/gltf_d3d12/gltf_d3d12.cpp @@ -365,11 +365,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -484,6 +486,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -491,6 +502,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/misc/imgui_d3d12/CMakeLists.txt b/projects/misc/imgui_d3d12/CMakeLists.txt index 50a5121..a70f1cd 100644 --- a/projects/misc/imgui_d3d12/CMakeLists.txt +++ b/projects/misc/imgui_d3d12/CMakeLists.txt @@ -10,6 +10,8 @@ add_executable( ${GREX_PROJECTS_COMMON_DIR}/window.cpp ${GREX_PROJECTS_COMMON_DIR}/Timer.h ${GREX_PROJECTS_COMMON_DIR}/Timer.cpp + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${IMGUI_D3D12_FILES} @@ -26,6 +28,7 @@ target_include_directories( test_app_imgui_d3d12 PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${IMGUI_INC_DIR} + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/misc/imgui_d3d12/test_app_imgui_d3d12.cpp b/projects/misc/imgui_d3d12/test_app_imgui_d3d12.cpp index cad214e..1cea791 100644 --- a/projects/misc/imgui_d3d12/test_app_imgui_d3d12.cpp +++ b/projects/misc/imgui_d3d12/test_app_imgui_d3d12.cpp @@ -169,11 +169,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -244,6 +246,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -251,6 +262,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/pbr/201_pbr_spheres_d3d12/201_pbr_spheres_d3d12.cpp b/projects/pbr/201_pbr_spheres_d3d12/201_pbr_spheres_d3d12.cpp index 63c42d5..b244293 100644 --- a/projects/pbr/201_pbr_spheres_d3d12/201_pbr_spheres_d3d12.cpp +++ b/projects/pbr/201_pbr_spheres_d3d12/201_pbr_spheres_d3d12.cpp @@ -357,11 +357,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -563,6 +565,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -570,6 +581,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/pbr/202_pbr_camera_d3d12/202_pbr_camera_d3d12.cpp b/projects/pbr/202_pbr_camera_d3d12/202_pbr_camera_d3d12.cpp index 913915d..e6bc689 100644 --- a/projects/pbr/202_pbr_camera_d3d12/202_pbr_camera_d3d12.cpp +++ b/projects/pbr/202_pbr_camera_d3d12/202_pbr_camera_d3d12.cpp @@ -450,11 +450,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -642,6 +644,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -649,6 +660,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/pbr/203_pbr_align_d3d12/203_pbr_align_d3d12.cpp b/projects/pbr/203_pbr_align_d3d12/203_pbr_align_d3d12.cpp index ea9b8c0..bd7fb1f 100644 --- a/projects/pbr/203_pbr_align_d3d12/203_pbr_align_d3d12.cpp +++ b/projects/pbr/203_pbr_align_d3d12/203_pbr_align_d3d12.cpp @@ -357,11 +357,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -603,6 +605,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -610,6 +621,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/pbr/251_pbr_explorer_d3d12/251_pbr_explorer_d3d12.cpp b/projects/pbr/251_pbr_explorer_d3d12/251_pbr_explorer_d3d12.cpp index 71aee55..1a43fd9 100644 --- a/projects/pbr/251_pbr_explorer_d3d12/251_pbr_explorer_d3d12.cpp +++ b/projects/pbr/251_pbr_explorer_d3d12/251_pbr_explorer_d3d12.cpp @@ -505,11 +505,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -992,6 +994,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -999,6 +1010,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/pbr/252_pbr_material_properties_d3d12/252_pbr_material_properties_d3d12.cpp b/projects/pbr/252_pbr_material_properties_d3d12/252_pbr_material_properties_d3d12.cpp index 47de7ea..85fb543 100644 --- a/projects/pbr/252_pbr_material_properties_d3d12/252_pbr_material_properties_d3d12.cpp +++ b/projects/pbr/252_pbr_material_properties_d3d12/252_pbr_material_properties_d3d12.cpp @@ -421,11 +421,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -719,6 +721,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -726,6 +737,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/pbr/253_pbr_material_textures_d3d12/253_pbr_material_textures_d3d12.cpp b/projects/pbr/253_pbr_material_textures_d3d12/253_pbr_material_textures_d3d12.cpp index df9dbcb..3d69d9f 100644 --- a/projects/pbr/253_pbr_material_textures_d3d12/253_pbr_material_textures_d3d12.cpp +++ b/projects/pbr/253_pbr_material_textures_d3d12/253_pbr_material_textures_d3d12.cpp @@ -483,11 +483,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -991,6 +993,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -998,6 +1009,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/000_raygen_uv_d3d12/000_raygen_uv_d3d12.cpp b/projects/raytracing/000_raygen_uv_d3d12/000_raygen_uv_d3d12.cpp index a4e7286..485054e 100644 --- a/projects/raytracing/000_raygen_uv_d3d12/000_raygen_uv_d3d12.cpp +++ b/projects/raytracing/000_raygen_uv_d3d12/000_raygen_uv_d3d12.cpp @@ -237,11 +237,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -315,6 +317,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -322,6 +333,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/000_raygen_uv_d3d12/CMakeLists.txt b/projects/raytracing/000_raygen_uv_d3d12/CMakeLists.txt index ad25aac..e02392c 100644 --- a/projects/raytracing/000_raygen_uv_d3d12/CMakeLists.txt +++ b/projects/raytracing/000_raygen_uv_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 000_raygen_uv_d3d12 000_raygen_uv_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -20,6 +22,7 @@ target_include_directories( 000_raygen_uv_d3d12 PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/001_raytracing_basic_d3d12/001_raytracing_basic_d3d12.cpp b/projects/raytracing/001_raytracing_basic_d3d12/001_raytracing_basic_d3d12.cpp index b8bac7a..f0032f3 100644 --- a/projects/raytracing/001_raytracing_basic_d3d12/001_raytracing_basic_d3d12.cpp +++ b/projects/raytracing/001_raytracing_basic_d3d12/001_raytracing_basic_d3d12.cpp @@ -304,11 +304,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -390,6 +392,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -397,6 +408,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/001_raytracing_basic_d3d12/CMakeLists.txt b/projects/raytracing/001_raytracing_basic_d3d12/CMakeLists.txt index acc0179..8d8e85d 100644 --- a/projects/raytracing/001_raytracing_basic_d3d12/CMakeLists.txt +++ b/projects/raytracing/001_raytracing_basic_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 001_raytracing_basic_d3d12 001_raytracing_basic_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -20,6 +22,7 @@ target_include_directories( 001_raytracing_basic_d3d12 PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/002_basic_procedural_d3d12/002_basic_procedural_d3d12.cpp b/projects/raytracing/002_basic_procedural_d3d12/002_basic_procedural_d3d12.cpp index 35026da..fd672ac 100644 --- a/projects/raytracing/002_basic_procedural_d3d12/002_basic_procedural_d3d12.cpp +++ b/projects/raytracing/002_basic_procedural_d3d12/002_basic_procedural_d3d12.cpp @@ -359,11 +359,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -445,6 +447,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -452,6 +463,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/002_basic_procedural_d3d12/CMakeLists.txt b/projects/raytracing/002_basic_procedural_d3d12/CMakeLists.txt index 90ae677..4756aec 100644 --- a/projects/raytracing/002_basic_procedural_d3d12/CMakeLists.txt +++ b/projects/raytracing/002_basic_procedural_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 002_basic_procedural_d3d12 002_basic_procedural_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -20,6 +22,7 @@ target_include_directories( 002_basic_procedural_d3d12 PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/003_sphereflake_d3d12/003_sphereflake_d3d12.cpp b/projects/raytracing/003_sphereflake_d3d12/003_sphereflake_d3d12.cpp index 8869887..52dd9fa 100644 --- a/projects/raytracing/003_sphereflake_d3d12/003_sphereflake_d3d12.cpp +++ b/projects/raytracing/003_sphereflake_d3d12/003_sphereflake_d3d12.cpp @@ -427,11 +427,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -513,6 +515,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -520,6 +531,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/003_sphereflake_d3d12/CMakeLists.txt b/projects/raytracing/003_sphereflake_d3d12/CMakeLists.txt index 41da793..4db482f 100644 --- a/projects/raytracing/003_sphereflake_d3d12/CMakeLists.txt +++ b/projects/raytracing/003_sphereflake_d3d12/CMakeLists.txt @@ -8,6 +8,8 @@ add_executable( ${GREX_PROJECTS_COMMON_DIR}/config.h ${GREX_PROJECTS_COMMON_DIR}/sphereflake.h ${GREX_PROJECTS_COMMON_DIR}/sphereflake.cpp + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -22,6 +24,7 @@ target_include_directories( 003_sphereflake_d3d12 PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/004_basic_reflection_d3d12/004_basic_reflection_d3d12.cpp b/projects/raytracing/004_basic_reflection_d3d12/004_basic_reflection_d3d12.cpp index 88d030f..5680f66 100644 --- a/projects/raytracing/004_basic_reflection_d3d12/004_basic_reflection_d3d12.cpp +++ b/projects/raytracing/004_basic_reflection_d3d12/004_basic_reflection_d3d12.cpp @@ -506,11 +506,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -592,6 +594,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -599,6 +610,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/004_basic_reflection_d3d12/CMakeLists.txt b/projects/raytracing/004_basic_reflection_d3d12/CMakeLists.txt index a053586..84f8782 100644 --- a/projects/raytracing/004_basic_reflection_d3d12/CMakeLists.txt +++ b/projects/raytracing/004_basic_reflection_d3d12/CMakeLists.txt @@ -8,6 +8,8 @@ add_executable( ${GREX_PROJECTS_COMMON_DIR}/config.h ${GREX_PROJECTS_COMMON_DIR}/sphereflake.h ${GREX_PROJECTS_COMMON_DIR}/sphereflake.cpp + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -22,6 +24,7 @@ target_include_directories( 004_basic_reflection_d3d12 PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/005_basic_shadow_d3d12/005_basic_shadow_d3d12.cpp b/projects/raytracing/005_basic_shadow_d3d12/005_basic_shadow_d3d12.cpp index 4836903..1890930 100644 --- a/projects/raytracing/005_basic_shadow_d3d12/005_basic_shadow_d3d12.cpp +++ b/projects/raytracing/005_basic_shadow_d3d12/005_basic_shadow_d3d12.cpp @@ -552,11 +552,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -638,6 +640,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -645,6 +656,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/005_basic_shadow_d3d12/CMakeLists.txt b/projects/raytracing/005_basic_shadow_d3d12/CMakeLists.txt index 8202beb..472eff7 100644 --- a/projects/raytracing/005_basic_shadow_d3d12/CMakeLists.txt +++ b/projects/raytracing/005_basic_shadow_d3d12/CMakeLists.txt @@ -8,6 +8,8 @@ add_executable( ${GREX_PROJECTS_COMMON_DIR}/config.h ${GREX_PROJECTS_COMMON_DIR}/sphereflake.h ${GREX_PROJECTS_COMMON_DIR}/sphereflake.cpp + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -22,6 +24,7 @@ target_include_directories( 005_basic_shadow_d3d12 PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/006_basic_shadow_dynamic_d3d12/006_basic_shadow_dynamic_d3d12.cpp b/projects/raytracing/006_basic_shadow_dynamic_d3d12/006_basic_shadow_dynamic_d3d12.cpp index 21affab..d6cdfeb 100644 --- a/projects/raytracing/006_basic_shadow_dynamic_d3d12/006_basic_shadow_dynamic_d3d12.cpp +++ b/projects/raytracing/006_basic_shadow_dynamic_d3d12/006_basic_shadow_dynamic_d3d12.cpp @@ -556,11 +556,13 @@ int main(int argc, char** argv) char* pConstantBufferAddr = nullptr; CHECK_CALL(constantBuffer->Map(0, nullptr, reinterpret_cast(&pConstantBufferAddr))); + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -656,6 +658,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -663,6 +674,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } constantBuffer->Unmap(0, nullptr); diff --git a/projects/raytracing/006_basic_shadow_dynamic_d3d12/CMakeLists.txt b/projects/raytracing/006_basic_shadow_dynamic_d3d12/CMakeLists.txt index a7f8062..3ca4b96 100644 --- a/projects/raytracing/006_basic_shadow_dynamic_d3d12/CMakeLists.txt +++ b/projects/raytracing/006_basic_shadow_dynamic_d3d12/CMakeLists.txt @@ -8,6 +8,8 @@ add_executable( ${GREX_PROJECTS_COMMON_DIR}/config.h ${GREX_PROJECTS_COMMON_DIR}/sphereflake.h ${GREX_PROJECTS_COMMON_DIR}/sphereflake.cpp + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -22,6 +24,7 @@ target_include_directories( 006_basic_shadow_dynamic_d3d12 PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/021_raytracing_triangles_d3d12/021_raytracing_triangles_d3d12.cpp b/projects/raytracing/021_raytracing_triangles_d3d12/021_raytracing_triangles_d3d12.cpp index 6fae04b..9cdff30 100644 --- a/projects/raytracing/021_raytracing_triangles_d3d12/021_raytracing_triangles_d3d12.cpp +++ b/projects/raytracing/021_raytracing_triangles_d3d12/021_raytracing_triangles_d3d12.cpp @@ -253,11 +253,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -345,6 +347,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -352,6 +363,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/021_raytracing_triangles_d3d12/CMakeLists.txt b/projects/raytracing/021_raytracing_triangles_d3d12/CMakeLists.txt index 6999b6a..5a7f9bf 100644 --- a/projects/raytracing/021_raytracing_triangles_d3d12/CMakeLists.txt +++ b/projects/raytracing/021_raytracing_triangles_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 021_raytracing_triangles_d3d12 021_raytracing_triangles_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -23,6 +25,7 @@ target_include_directories( PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm ${GREX_THIRD_PARTY_DIR}/tinyobjloader + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/022_raytracing_multi_geo_d3d12/022_raytracing_multi_geo_d3d12.cpp b/projects/raytracing/022_raytracing_multi_geo_d3d12/022_raytracing_multi_geo_d3d12.cpp index e1d1d51..eb60189 100644 --- a/projects/raytracing/022_raytracing_multi_geo_d3d12/022_raytracing_multi_geo_d3d12.cpp +++ b/projects/raytracing/022_raytracing_multi_geo_d3d12/022_raytracing_multi_geo_d3d12.cpp @@ -277,11 +277,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -371,6 +373,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -378,6 +389,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/022_raytracing_multi_geo_d3d12/CMakeLists.txt b/projects/raytracing/022_raytracing_multi_geo_d3d12/CMakeLists.txt index 98aa20a..41d8caf 100644 --- a/projects/raytracing/022_raytracing_multi_geo_d3d12/CMakeLists.txt +++ b/projects/raytracing/022_raytracing_multi_geo_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 022_raytracing_multi_geo_d3d12 022_raytracing_multi_geo_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -23,6 +25,7 @@ target_include_directories( PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm ${GREX_THIRD_PARTY_DIR}/tinyobjloader + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/023_raytracing_multi_instance_d3d12/023_raytracing_multi_instance_d3d12.cpp b/projects/raytracing/023_raytracing_multi_instance_d3d12/023_raytracing_multi_instance_d3d12.cpp index 46b28f5..5a97fbb 100644 --- a/projects/raytracing/023_raytracing_multi_instance_d3d12/023_raytracing_multi_instance_d3d12.cpp +++ b/projects/raytracing/023_raytracing_multi_instance_d3d12/023_raytracing_multi_instance_d3d12.cpp @@ -280,11 +280,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -374,6 +376,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -381,6 +392,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/023_raytracing_multi_instance_d3d12/CMakeLists.txt b/projects/raytracing/023_raytracing_multi_instance_d3d12/CMakeLists.txt index eefa8a5..6edb259 100644 --- a/projects/raytracing/023_raytracing_multi_instance_d3d12/CMakeLists.txt +++ b/projects/raytracing/023_raytracing_multi_instance_d3d12/CMakeLists.txt @@ -6,6 +6,8 @@ add_executable( 023_raytracing_multi_instance_d3d12 023_raytracing_multi_instance_d3d12.cpp ${GREX_PROJECTS_COMMON_DIR}/config.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.h + ${GREX_PROJECTS_COMMON_DIR}/bitmap.cpp ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.h ${GREX_PROJECTS_COMMON_DIR}/dx_renderer.cpp ${GREX_PROJECTS_COMMON_DIR}/window.h @@ -23,6 +25,7 @@ target_include_directories( PUBLIC ${GREX_PROJECTS_COMMON_DIR} ${GREX_THIRD_PARTY_DIR}/glm ${GREX_THIRD_PARTY_DIR}/tinyobjloader + ${GREX_THIRD_PARTY_DIR}/stb ) target_link_libraries( diff --git a/projects/raytracing/024_raytracing_pbr_spheres_d3d12/024_raytracing_pbr_spheres_d3d12.cpp b/projects/raytracing/024_raytracing_pbr_spheres_d3d12/024_raytracing_pbr_spheres_d3d12.cpp index 666ed51..5bbed45 100644 --- a/projects/raytracing/024_raytracing_pbr_spheres_d3d12/024_raytracing_pbr_spheres_d3d12.cpp +++ b/projects/raytracing/024_raytracing_pbr_spheres_d3d12/024_raytracing_pbr_spheres_d3d12.cpp @@ -358,11 +358,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -476,6 +478,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -483,6 +494,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/025_raytracing_refract_d3d12/025_raytracing_refract_d3d12.cpp b/projects/raytracing/025_raytracing_refract_d3d12/025_raytracing_refract_d3d12.cpp index 964e1ce..5f0392b 100644 --- a/projects/raytracing/025_raytracing_refract_d3d12/025_raytracing_refract_d3d12.cpp +++ b/projects/raytracing/025_raytracing_refract_d3d12/025_raytracing_refract_d3d12.cpp @@ -376,11 +376,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -489,6 +491,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } if (!SwapchainPresent(renderer.get())) @@ -496,6 +507,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/030_raytracing_path_trace_d3d12/030_raytracing_path_trace_d3d12.cpp b/projects/raytracing/030_raytracing_path_trace_d3d12/030_raytracing_path_trace_d3d12.cpp index ccc32c1..6ac53ee 100644 --- a/projects/raytracing/030_raytracing_path_trace_d3d12/030_raytracing_path_trace_d3d12.cpp +++ b/projects/raytracing/030_raytracing_path_trace_d3d12/030_raytracing_path_trace_d3d12.cpp @@ -486,11 +486,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -704,6 +706,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } } @@ -718,6 +729,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/raytracing/031_raytracing_path_trace_pbr_d3d12/031_raytracing_path_trace_pbr_d3d12.cpp b/projects/raytracing/031_raytracing_path_trace_pbr_d3d12/031_raytracing_path_trace_pbr_d3d12.cpp index 8d638a6..56e9517 100644 --- a/projects/raytracing/031_raytracing_path_trace_pbr_d3d12/031_raytracing_path_trace_pbr_d3d12.cpp +++ b/projects/raytracing/031_raytracing_path_trace_pbr_d3d12/031_raytracing_path_trace_pbr_d3d12.cpp @@ -526,11 +526,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -770,6 +772,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } } } @@ -784,6 +795,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/texture/301_textured_cube_d3d12/301_textured_cube_d3d12.cpp b/projects/texture/301_textured_cube_d3d12/301_textured_cube_d3d12.cpp index 3751d00..272c19b 100644 --- a/projects/texture/301_textured_cube_d3d12/301_textured_cube_d3d12.cpp +++ b/projects/texture/301_textured_cube_d3d12/301_textured_cube_d3d12.cpp @@ -234,11 +234,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -319,6 +321,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -326,6 +337,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/texture/302_lambert_textured_cube_d3d12/302_lambert_textured_cube_d3d12.cpp b/projects/texture/302_lambert_textured_cube_d3d12/302_lambert_textured_cube_d3d12.cpp index 9df220d..8bfac4d 100644 --- a/projects/texture/302_lambert_textured_cube_d3d12/302_lambert_textured_cube_d3d12.cpp +++ b/projects/texture/302_lambert_textured_cube_d3d12/302_lambert_textured_cube_d3d12.cpp @@ -248,11 +248,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -340,6 +342,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -347,6 +358,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/texture/303_phong_textured_cube_d3d12/303_phong_textured_cube_d3d12.cpp b/projects/texture/303_phong_textured_cube_d3d12/303_phong_textured_cube_d3d12.cpp index 829eadb..32a6333 100644 --- a/projects/texture/303_phong_textured_cube_d3d12/303_phong_textured_cube_d3d12.cpp +++ b/projects/texture/303_phong_textured_cube_d3d12/303_phong_textured_cube_d3d12.cpp @@ -253,11 +253,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -348,6 +350,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -355,6 +366,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/texture/304_normal_map_d3d12/304_normal_map_d3d12.cpp b/projects/texture/304_normal_map_d3d12/304_normal_map_d3d12.cpp index 041a1db..b299fec 100644 --- a/projects/texture/304_normal_map_d3d12/304_normal_map_d3d12.cpp +++ b/projects/texture/304_normal_map_d3d12/304_normal_map_d3d12.cpp @@ -262,11 +262,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -367,6 +369,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -374,6 +385,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/texture/305_normal_map_explorer_d3d12/305_normal_map_explorer_d3d12.cpp b/projects/texture/305_normal_map_explorer_d3d12/305_normal_map_explorer_d3d12.cpp index b09386c..0627542 100644 --- a/projects/texture/305_normal_map_explorer_d3d12/305_normal_map_explorer_d3d12.cpp +++ b/projects/texture/305_normal_map_explorer_d3d12/305_normal_map_explorer_d3d12.cpp @@ -255,11 +255,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -421,6 +423,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -428,6 +439,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/texture/306_parallax_occlusion_map_d3d12/306_parallax_occlusion_map_d3d12.cpp b/projects/texture/306_parallax_occlusion_map_d3d12/306_parallax_occlusion_map_d3d12.cpp index 81fe604..05cccf6 100644 --- a/projects/texture/306_parallax_occlusion_map_d3d12/306_parallax_occlusion_map_d3d12.cpp +++ b/projects/texture/306_parallax_occlusion_map_d3d12/306_parallax_occlusion_map_d3d12.cpp @@ -270,11 +270,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -375,6 +377,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -382,6 +393,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/texture/307_parallax_occlusion_map_explorer_d3d12/307_parallax_occlusion_map_explorer_d3d12.cpp b/projects/texture/307_parallax_occlusion_map_explorer_d3d12/307_parallax_occlusion_map_explorer_d3d12.cpp index 30b139c..fb34424 100644 --- a/projects/texture/307_parallax_occlusion_map_explorer_d3d12/307_parallax_occlusion_map_explorer_d3d12.cpp +++ b/projects/texture/307_parallax_occlusion_map_explorer_d3d12/307_parallax_occlusion_map_explorer_d3d12.cpp @@ -256,11 +256,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -422,6 +424,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -429,6 +440,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0; diff --git a/projects/texture/308_normal_map_vs_pom_d3d12/308_normal_map_vs_pom_d3d12.cpp b/projects/texture/308_normal_map_vs_pom_d3d12/308_normal_map_vs_pom_d3d12.cpp index 07f31a3..010be92 100644 --- a/projects/texture/308_normal_map_vs_pom_d3d12/308_normal_map_vs_pom_d3d12.cpp +++ b/projects/texture/308_normal_map_vs_pom_d3d12/308_normal_map_vs_pom_d3d12.cpp @@ -323,11 +323,13 @@ int main(int argc, char** argv) // ************************************************************************* // Main loop // ************************************************************************* + uint32_t frameIndex = 0; + window->ResetTimer(); while (window->PollEvents()) { - if (args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) + if (args.screenshotFrame < 0 && args.autoExitSeconds >= 0 && window->GetElapsedSeconds() >= args.autoExitSeconds) { break; } @@ -523,6 +525,15 @@ int main(int argc, char** argv) assert(false && "WaitForGpu failed"); break; } + if (!args.screenshotPath.empty() && (args.screenshotFrame < 0 || (int)frameIndex == args.screenshotFrame)) + { + SaveDxTextureAsPNG(renderer.get(), swapchainBuffer.Get(), args.screenshotPath); + args.screenshotPath.clear(); + if (args.screenshotFrame >= 0) + { + break; + } + } // Present if (!SwapchainPresent(renderer.get())) @@ -530,6 +541,8 @@ int main(int argc, char** argv) assert(false && "SwapchainPresent failed"); break; } + + ++frameIndex; } return 0;