Allow TGA and PNG to discard/flatten alpha as desired. Refs #407

* DDS will always save the format entirely literally, and the float
  formats do not support alpha processing currently.
* TGA and PNG will either discard the alpha and write entirely opaque,
  or they'll include it in the file. Blending to colour or checkerboard
  is not supported.
This commit is contained in:
baldurk
2016-11-02 23:39:35 +01:00
parent dc96853b39
commit 5a5c576a33
6 changed files with 92 additions and 10 deletions
+1
View File
@@ -188,6 +188,7 @@ enum AlphaMapping
eAlphaMap_Discard,
eAlphaMap_BlendToColour,
eAlphaMap_BlendToCheckerboard,
eAlphaMap_Preserve,
};
enum SpecialFormat
+8
View File
@@ -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);
+1
View File
@@ -191,6 +191,7 @@ namespace renderdoc
Discard,
BlendToColour,
BlendToCheckerboard,
Preserve,
};
public enum SpecialFormat
@@ -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);
@@ -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)
{
+1 -1
View File
@@ -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;