| 584 | } |
| 585 | |
| 586 | void Texture::captureToFile( |
| 587 | uint32_t mipLevel, |
| 588 | uint32_t arraySlice, |
| 589 | const std::filesystem::path& path, |
| 590 | Bitmap::FileFormat format, |
| 591 | Bitmap::ExportFlags exportFlags, |
| 592 | bool async |
| 593 | ) |
| 594 | { |
| 595 | if (format == Bitmap::FileFormat::DdsFile) |
| 596 | { |
| 597 | FALCOR_THROW("Texture::captureToFile does not yet support saving to DDS."); |
| 598 | } |
| 599 | |
| 600 | if (mType != Type::Texture2D) |
| 601 | FALCOR_THROW("Texture::captureToFile only supported for 2D textures."); |
| 602 | |
| 603 | RenderContext* pContext = mpDevice->getRenderContext(); |
| 604 | |
| 605 | // Handle the special case where we have an HDR texture with less then 3 channels. |
| 606 | FormatType type = getFormatType(mFormat); |
| 607 | uint32_t channels = getFormatChannelCount(mFormat); |
| 608 | std::vector<uint8_t> textureData; |
| 609 | ResourceFormat resourceFormat = mFormat; |
| 610 | |
| 611 | if (type == FormatType::Float && channels < 3) |
| 612 | { |
| 613 | ref<Texture> pOther = mpDevice->createTexture2D( |
| 614 | getWidth(mipLevel), |
| 615 | getHeight(mipLevel), |
| 616 | ResourceFormat::RGBA32Float, |
| 617 | 1, |
| 618 | 1, |
| 619 | nullptr, |
| 620 | ResourceBindFlags::RenderTarget | ResourceBindFlags::ShaderResource |
| 621 | ); |
| 622 | pContext->blit(getSRV(mipLevel, 1, arraySlice, 1), pOther->getRTV(0, 0, 1)); |
| 623 | textureData = pContext->readTextureSubresource(pOther.get(), 0); |
| 624 | resourceFormat = ResourceFormat::RGBA32Float; |
| 625 | } |
| 626 | else |
| 627 | { |
| 628 | uint32_t subresource = getSubresourceIndex(arraySlice, mipLevel); |
| 629 | textureData = pContext->readTextureSubresource(this, subresource); |
| 630 | } |
| 631 | |
| 632 | uint32_t width = getWidth(mipLevel); |
| 633 | uint32_t height = getHeight(mipLevel); |
| 634 | |
| 635 | auto func = [=]() { Bitmap::saveImage(path, width, height, format, exportFlags, resourceFormat, true, (void*)textureData.data()); }; |
| 636 | |
| 637 | if (async) |
| 638 | Threading::dispatchTask(func); |
| 639 | else |
| 640 | func(); |
| 641 | } |
| 642 | |
| 643 | void Texture::uploadInitData(RenderContext* pRenderContext, const void* pData, bool autoGenMips) |