When saving textures if only one channel is visible, save as greyscale

This commit is contained in:
baldurk
2015-11-14 19:27:57 +01:00
parent f29d3aceb2
commit 73ad61d38e
4 changed files with 55 additions and 0 deletions
+2
View File
@@ -178,6 +178,8 @@ struct TextureSave
// and file format doesn't support saving all slices, only
// slice 0 is saved
} slice;
int channelExtract;
// for formats without an alpha channel, define how it should be
// mapped. Only available for uncompressed simple formats, done
+40
View File
@@ -490,6 +490,10 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
sd.slice.slicesAsGrid = false;
}
// can't extract a channel that's not in the source texture
if(sd.channelExtract >= 0 && (uint32_t)sd.channelExtract >= td.format.compCount)
sd.channelExtract = -1;
sd.slice.sliceGridWidth = RDCMAX(sd.slice.sliceGridWidth, 1);
// store sample count so we know how many 'slices' is one real slice
@@ -876,6 +880,25 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
}
int numComps = td.format.compCount;
// if we want a grayscale image of one channel, splat it across all channels
// and set alpha to full
if(sd.channelExtract >= 0 && td.format.compByteWidth == 1 && (uint32_t)sd.channelExtract < td.format.compCount)
{
for(uint32_t y=0; y < td.height; y++)
{
for(uint32_t x=0; x < td.width; x++)
{
subdata[0][ ( y * td.width + x ) * 4 + 0 ] = subdata[0][ ( y * td.width + x ) * 4 + sd.channelExtract ];
if(td.format.compCount >= 2)
subdata[0][ ( y * td.width + x ) * 4 + 1 ] = subdata[0][ ( y * td.width + x ) * 4 + sd.channelExtract ];
if(td.format.compCount >= 3)
subdata[0][ ( y * td.width + x ) * 4 + 2 ] = subdata[0][ ( y * td.width + x ) * 4 + sd.channelExtract ];
if(td.format.compCount >= 4)
subdata[0][ ( y * td.width + x ) * 4 + 3 ] = 255;
}
}
}
// handle formats that don't support alpha
if(numComps == 4 && (sd.destType == eFileType_BMP || sd.destType == eFileType_JPG) )
@@ -1074,6 +1097,23 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
a = RDCMAX(a, 0.0f);
}
if(sd.channelExtract == 0)
{
g = b = r; a = 1.0f;
}
if(sd.channelExtract == 1)
{
r = b = g; a = 1.0f;
}
if(sd.channelExtract == 2)
{
r = g = b; a = 1.0f;
}
if(sd.channelExtract == 3)
{
r = g = b = a; a = 1.0f;
}
fldata[(y*td.width + x) * 4 + 0] = r;
fldata[(y*td.width + x) * 4 + 1] = g;
fldata[(y*td.width + x) * 4 + 2] = b;
+2
View File
@@ -487,6 +487,8 @@ namespace renderdoc
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
public SliceMapping slice = new SliceMapping();
public int channelExtract = -1;
public AlphaMapping alpha = AlphaMapping.Discard;
public FloatVector alphaCol = new FloatVector(0.666f, 0.666f, 0.666f);
public FloatVector alphaColSecondary = new FloatVector(0.333f, 0.333f, 0.333f);
+11
View File
@@ -3399,6 +3399,17 @@ namespace renderdocui.Windows
m_SaveDialog.saveData.id = m_TexDisplay.texid;
m_SaveDialog.saveData.slice.sliceIndex = (int)m_TexDisplay.sliceFace;
m_SaveDialog.saveData.mip = (int)m_TexDisplay.mip;
m_SaveDialog.saveData.channelExtract = -1;
if (m_TexDisplay.Red && !m_TexDisplay.Green && !m_TexDisplay.Blue && !m_TexDisplay.Alpha)
m_SaveDialog.saveData.channelExtract = 0;
if (!m_TexDisplay.Red && m_TexDisplay.Green && !m_TexDisplay.Blue && !m_TexDisplay.Alpha)
m_SaveDialog.saveData.channelExtract = 1;
if (!m_TexDisplay.Red && !m_TexDisplay.Green && m_TexDisplay.Blue && !m_TexDisplay.Alpha)
m_SaveDialog.saveData.channelExtract = 2;
if (!m_TexDisplay.Red && !m_TexDisplay.Green && !m_TexDisplay.Blue && m_TexDisplay.Alpha)
m_SaveDialog.saveData.channelExtract = 3;
m_SaveDialog.saveData.comp.blackPoint = m_TexDisplay.rangemin;
m_SaveDialog.saveData.comp.whitePoint = m_TexDisplay.rangemax;
m_SaveDialog.saveData.alphaCol = m_TexDisplay.lightBackgroundColour;