diff --git a/qrenderdoc/Windows/Dialogs/TextureSaveDialog.cpp b/qrenderdoc/Windows/Dialogs/TextureSaveDialog.cpp index 67eaba307..db3ce4c68 100644 --- a/qrenderdoc/Windows/Dialogs/TextureSaveDialog.cpp +++ b/qrenderdoc/Windows/Dialogs/TextureSaveDialog.cpp @@ -28,8 +28,8 @@ #include "Code/QRDUtils.h" #include "ui_TextureSaveDialog.h" -TextureSaveDialog::TextureSaveDialog(const TextureDescription &t, const TextureSave &s, - QWidget *parent) +TextureSaveDialog::TextureSaveDialog(const TextureDescription &t, bool enableOverlaySelection, + const TextureSave &s, QWidget *parent) : QDialog(parent), ui(new Ui::TextureSaveDialog) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); @@ -46,6 +46,9 @@ TextureSaveDialog::TextureSaveDialog(const TextureDescription &t, const TextureS ui->blackPoint->setFont(Formatter::PreferredFont()); ui->whitePoint->setFont(Formatter::PreferredFont()); + if(!enableOverlaySelection) + ui->texSelectionGroup->hide(); + QObject::connect(&typingTimer, &QTimer::timeout, [this] { SetFiletypeFromFilename(); }); ui->fileFormat->clear(); @@ -126,15 +129,20 @@ TextureSaveDialog::TextureSaveDialog(const TextureDescription &t, const TextureS ui->gridWidth->setMaximum(tex.depth * tex.arraysize * tex.msSamp); - ui->mipGroup->setVisible(tex.mips > 1); + SetOptionsVisible(true); +} - ui->sampleGroup->setVisible(tex.msSamp > 1); +void TextureSaveDialog::SetOptionsVisible(bool visible) +{ + ui->mipGroup->setVisible(visible && tex.mips > 1); - ui->sliceGroup->setVisible(tex.depth > 1 || tex.arraysize > 1 || tex.msSamp > 1); + ui->sampleGroup->setVisible(visible && tex.msSamp > 1); + + ui->sliceGroup->setVisible(visible && (tex.depth > 1 || tex.arraysize > 1 || tex.msSamp > 1)); if(saveData.destType != FileType::DDS) { - ui->cubeCruciform->setEnabled(tex.cubemap && tex.arraysize == 6); + ui->cubeCruciform->setEnabled(visible && tex.cubemap && tex.arraysize == 6); if(!ui->oneSlice->isChecked() && !ui->cubeCruciform->isEnabled()) ui->mapSlicesToGrid->setChecked(true); @@ -188,6 +196,18 @@ void TextureSaveDialog::SetFilenameFromFiletype() } } +void TextureSaveDialog::on_mainTex_clicked() +{ + SetOptionsVisible(true); + m_saveOverlayInsteadOfSelectedTexture = false; +} + +void TextureSaveDialog::on_overlayTex_clicked() +{ + SetOptionsVisible(false); + m_saveOverlayInsteadOfSelectedTexture = true; +} + void TextureSaveDialog::on_fileFormat_currentIndexChanged(int index) { saveData.destType = (FileType)qMax(0, ui->fileFormat->currentIndex()); diff --git a/qrenderdoc/Windows/Dialogs/TextureSaveDialog.h b/qrenderdoc/Windows/Dialogs/TextureSaveDialog.h index 5dad109e0..e8dfe3c9a 100644 --- a/qrenderdoc/Windows/Dialogs/TextureSaveDialog.h +++ b/qrenderdoc/Windows/Dialogs/TextureSaveDialog.h @@ -38,13 +38,17 @@ class TextureSaveDialog : public QDialog Q_OBJECT public: - explicit TextureSaveDialog(const TextureDescription &t, const TextureSave &s, QWidget *parent = 0); + explicit TextureSaveDialog(const TextureDescription &t, bool enableOverlaySelection, + const TextureSave &s, QWidget *parent = 0); ~TextureSaveDialog(); QString filename(); TextureSave config() { return saveData; } + bool saveOverlayInstead() { return m_saveOverlayInsteadOfSelectedTexture; } private slots: + void on_mainTex_clicked(); + void on_overlayTex_clicked(); void on_fileFormat_currentIndexChanged(int index); void on_jpegCompression_valueChanged(double arg1); void on_exportAllMips_toggled(bool checked); @@ -74,6 +78,8 @@ private slots: private: Ui::TextureSaveDialog *ui; + void SetOptionsVisible(bool visible); + void SetFilenameFromFiletype(); void SetFiletypeFromFilename(); @@ -82,5 +88,7 @@ private: TextureDescription tex; TextureSave saveData; + bool m_saveOverlayInsteadOfSelectedTexture = false; + bool m_Recurse = false; }; diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index 65e2f4a40..9b7770baa 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -3377,11 +3377,19 @@ void TextureViewer::on_saveTex_clicked() config.id = id; } - TextureSaveDialog saveDialog(*texptr, config, this); + const auto overlayTexID = m_Output->GetDebugOverlayTexID(); + const bool hasSelectedOverlay = (m_Output->GetTextureDisplay().overlay != DebugOverlay::NoOverlay); + const bool hasOverlay = (hasSelectedOverlay && overlayTexID != ResourceId()); + TextureSaveDialog saveDialog(*texptr, hasOverlay, config, this); int res = RDDialog::show(&saveDialog); config = saveDialog.config(); + if(saveDialog.saveOverlayInstead()) + { + config.id = overlayTexID; + } + if(res) { ANALYTIC_SET(UIFeatures.Export.TextureSave, true); diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 67d667b99..007d9eebd 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -529,6 +529,9 @@ Should only be called for texture outputs. )"); virtual ResourceId GetDebugOverlayTexID() = 0; + DOCUMENT(R"(Retrieves the :class:`TextureDisplay` associated with this output)"); + virtual const TextureDisplay &GetTextureDisplay() = 0; + DOCUMENT(R"(Retrieve the contents of a particular pixel in a texture. Should only be called for texture outputs. diff --git a/renderdoc/replay/replay_controller.h b/renderdoc/replay/replay_controller.h index 11a888143..f33996686 100644 --- a/renderdoc/replay/replay_controller.h +++ b/renderdoc/replay/replay_controller.h @@ -56,6 +56,7 @@ public: ResourceId GetCustomShaderTexID() { return m_CustomShaderResourceId; } ResourceId GetDebugOverlayTexID() { return m_OverlayResourceId; } + const TextureDisplay &GetTextureDisplay() { return m_RenderData.texDisplay; } PixelValue PickPixel(ResourceId texID, bool customShader, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample); rdcpair PickVertex(uint32_t eventID, uint32_t x, uint32_t y);