diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index 54b06d22b..35225c4a4 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -188,6 +188,7 @@ enum AlphaMapping eAlphaMap_Discard, eAlphaMap_BlendToColour, eAlphaMap_BlendToCheckerboard, + eAlphaMap_Preserve, }; enum SpecialFormat diff --git a/renderdoc/replay/replay_renderer.cpp b/renderdoc/replay/replay_renderer.cpp index de1c4d562..a7ad1ae19 100644 --- a/renderdoc/replay/replay_renderer.cpp +++ b/renderdoc/replay/replay_renderer.cpp @@ -1013,12 +1013,20 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path) } else if(sd.destType == eFileType_PNG) { + // discard alpha if requested + for(uint32_t p = 0; sd.alpha == eAlphaMap_Discard && p < td.width * td.height; p++) + subdata[0][p * 4 + 3] = 255; + int ret = stbi_write_png_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps, subdata[0], rowPitch); success = (ret != 0); } else if(sd.destType == eFileType_TGA) { + // discard alpha if requested + for(uint32_t p = 0; sd.alpha == eAlphaMap_Discard && p < td.width * td.height; p++) + subdata[0][p * 4 + 3] = 255; + int ret = stbi_write_tga_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps, subdata[0]); success = (ret != 0); diff --git a/renderdocui/Interop/Enums.cs b/renderdocui/Interop/Enums.cs index a9a9198e1..c72dbf27e 100644 --- a/renderdocui/Interop/Enums.cs +++ b/renderdocui/Interop/Enums.cs @@ -191,6 +191,7 @@ namespace renderdoc Discard, BlendToColour, BlendToCheckerboard, + Preserve, }; public enum SpecialFormat diff --git a/renderdocui/Windows/Dialogs/TextureSaveDialog.Designer.cs b/renderdocui/Windows/Dialogs/TextureSaveDialog.Designer.cs index 78cba84ee..f53cf6e3f 100644 --- a/renderdocui/Windows/Dialogs/TextureSaveDialog.Designer.cs +++ b/renderdocui/Windows/Dialogs/TextureSaveDialog.Designer.cs @@ -275,10 +275,6 @@ // this.alphaMap.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.alphaMap.FormattingEnabled = true; - this.alphaMap.Items.AddRange(new object[] { - "Discard", - "Blend to Colour", - "Blend to Checkerboard"}); this.alphaMap.Location = new System.Drawing.Point(89, 3); this.alphaMap.Name = "alphaMap"; this.alphaMap.Size = new System.Drawing.Size(148, 21); diff --git a/renderdocui/Windows/Dialogs/TextureSaveDialog.cs b/renderdocui/Windows/Dialogs/TextureSaveDialog.cs index 49b3174e5..bf8cb6d5b 100644 --- a/renderdocui/Windows/Dialogs/TextureSaveDialog.cs +++ b/renderdocui/Windows/Dialogs/TextureSaveDialog.cs @@ -14,6 +14,33 @@ namespace renderdocui.Windows.Dialogs { public partial class TextureSaveDialog : Form { + struct AlphaMappingString + { + public AlphaMappingString(AlphaMapping v) + { + val = v; + } + + public AlphaMapping val; + + public override string ToString() + { + switch (val) + { + case AlphaMapping.Discard: + return "Discard"; + case AlphaMapping.BlendToColour: + return "Blend to Colour"; + case AlphaMapping.BlendToCheckerboard: + return "Blend To Checkerboard"; + case AlphaMapping.Preserve: + return "Preserve"; + } + + return ""; + } + } + public TextureSaveDialog(Core core) { InitializeComponent(); @@ -86,8 +113,6 @@ namespace renderdocui.Windows.Dialogs { jpegCompression.Value = saveData.jpegQuality; - alphaMap.SelectedIndex = (int)saveData.alpha; - blackPoint.Text = Formatter.Format(saveData.comp.blackPoint); whitePoint.Text = Formatter.Format(saveData.comp.whitePoint); @@ -151,7 +176,14 @@ namespace renderdocui.Windows.Dialogs mapSlicesToGrid.Checked = true; } + fileFormat.SelectedIndex = 0; + fileFormat.SelectedIndex = 1; fileFormat.SelectedIndex = (int)saveData.destType; + + if(saveData.alpha == AlphaMapping.Discard) + alphaMap.SelectedIndex = 0; + else + alphaMap.SelectedIndex = alphaMap.Items.Count - 1; } private void fileFormat_SelectedIndexChanged(object sender, EventArgs e) @@ -166,7 +198,51 @@ namespace renderdocui.Windows.Dialogs bool noAlphaFormat = (saveData.destType == FileType.BMP || saveData.destType == FileType.JPG); - alphaMap.Enabled = (tex.format.compCount == 4 && noAlphaFormat); + // any filetype, PNG supporting or not, can choose to preserve or discard the alpha + alphaMap.Enabled = tex.format.compCount == 4; + + if (alphaMap.Enabled) + { + if (noAlphaFormat && alphaMap.Items.Count != 3) + { + int idx = (int)alphaMap.SelectedIndex; + + alphaMap.Items.Clear(); + alphaMap.Items.AddRange(new object[] { + new AlphaMappingString(AlphaMapping.Discard), + new AlphaMappingString(AlphaMapping.BlendToColour), + new AlphaMappingString(AlphaMapping.BlendToCheckerboard) + }); + + // if we were discard before, still discard, otherwise blend to checkerboard + if (idx <= 0) + alphaMap.SelectedIndex = 0; + else + alphaMap.SelectedIndex = alphaMap.Items.Count - 1; + } + else if (alphaMap.Items.Count != 2) + { + int idx = (int)alphaMap.SelectedIndex; + + alphaMap.Items.Clear(); + alphaMap.Items.AddRange(new object[] { + new AlphaMappingString(AlphaMapping.Discard), + new AlphaMappingString(AlphaMapping.Preserve) + }); + + // allow the previous selection to clamp, to either discard or preserve + alphaMap.SelectedIndex = Helpers.Clamp(idx, 0, alphaMap.Items.Count-1); + } + } + + if (alphaMap.Items.Count == 0) + { + alphaMap.Items.Clear(); + alphaMap.Items.AddRange(new object[] { + new AlphaMappingString(AlphaMapping.Discard), + new AlphaMappingString(AlphaMapping.Preserve) + }); + } alphaCol.Enabled = (saveData.alpha == AlphaMapping.BlendToColour && tex.format.compCount == 4 && noAlphaFormat); @@ -198,7 +274,7 @@ namespace renderdocui.Windows.Dialogs private void alphaMap_SelectedIndexChanged(object sender, EventArgs e) { - saveData.alpha = (AlphaMapping)alphaMap.SelectedIndex; + saveData.alpha = ((AlphaMappingString)alphaMap.SelectedItem).val; alphaCol.Enabled = (saveData.alpha == AlphaMapping.BlendToColour); } @@ -287,7 +363,7 @@ namespace renderdocui.Windows.Dialogs private void ok_Click(object sender, EventArgs e) { - saveData.alpha = (AlphaMapping)alphaMap.SelectedIndex; + saveData.alpha = ((AlphaMappingString)alphaMap.SelectedItem).val; if (saveData.alpha == AlphaMapping.BlendToCheckerboard) { diff --git a/renderdocui/Windows/TextureViewer.cs b/renderdocui/Windows/TextureViewer.cs index 538b8b95e..54c49de65 100644 --- a/renderdocui/Windows/TextureViewer.cs +++ b/renderdocui/Windows/TextureViewer.cs @@ -3670,7 +3670,7 @@ namespace renderdocui.Windows m_SaveDialog.saveData.comp.blackPoint = m_TexDisplay.rangemin; m_SaveDialog.saveData.comp.whitePoint = m_TexDisplay.rangemax; m_SaveDialog.saveData.alphaCol = m_TexDisplay.lightBackgroundColour; - m_SaveDialog.saveData.alpha = m_TexDisplay.Alpha ? AlphaMapping.BlendToCheckerboard : AlphaMapping.Discard; + m_SaveDialog.saveData.alpha = m_TexDisplay.Alpha ? AlphaMapping.Preserve : AlphaMapping.Discard; if (m_TexDisplay.Alpha && !checkerBack.Checked) m_SaveDialog.saveData.alpha = AlphaMapping.BlendToColour; m_SaveDialog.tex = CurrentTexture;