From d8bc07f945ebb5988b92afce34020b1e14c46b78 Mon Sep 17 00:00:00 2001 From: Richard Khoury Date: Thu, 14 Dec 2017 14:01:07 +1100 Subject: [PATCH] Added ability to save out overlay textures using the TextureSaveDialog. This is part of the work specified by github Issue 586, allowing the ability to save out the overlay in the TextureViewer. If no overlays are on then there is no option to save the overlay. Currently there is no option to remap the overlay to a grayscale or absolute value range before saving. This can be a future task. NOTE: the overlay texture resource that's saved out is not the blended texture that the user will see in the TextureViewer, it is just the overlay itself. The ability to save out the blended texture would be a future task. --- .../Windows/Dialogs/TextureSaveDialog.cpp | 32 +++++++++++++++---- .../Windows/Dialogs/TextureSaveDialog.h | 10 +++++- qrenderdoc/Windows/TextureViewer.cpp | 10 +++++- renderdoc/api/replay/renderdoc_replay.h | 3 ++ renderdoc/replay/replay_controller.h | 1 + 5 files changed, 48 insertions(+), 8 deletions(-) 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);