mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Add simple OpenEXR save/load support using tinyexr
* Thanks to https://github.com/syoyo/tinyexr for the load and save code!
This commit is contained in:
@@ -33,6 +33,7 @@ os/os_specific.o \
|
||||
3rdparty/jpeg-compressor/jpge.o \
|
||||
3rdparty/lz4/lz4.o \
|
||||
3rdparty/stb/stb_impl.o \
|
||||
3rdparty/tinyexr/tinyexr.o \
|
||||
driver/gl/gl_common.o \
|
||||
driver/gl/gl_driver.o \
|
||||
driver/gl/gl_manager.o \
|
||||
|
||||
@@ -136,6 +136,7 @@ enum FileType
|
||||
eFileType_BMP,
|
||||
eFileType_TGA,
|
||||
eFileType_HDR,
|
||||
eFileType_EXR,
|
||||
};
|
||||
|
||||
enum AlphaMapping
|
||||
|
||||
@@ -36,6 +36,21 @@
|
||||
#include "stb/stb_image.h"
|
||||
#include "common/dds_readwrite.h"
|
||||
|
||||
// not provided by tinyexr, just do by hand
|
||||
bool is_exr_file(FILE *f)
|
||||
{
|
||||
FileIO::fseek64(f, 0, SEEK_SET);
|
||||
|
||||
const uint32_t openexr_magic = MAKE_FOURCC(0x76, 0x2f, 0x31, 0x01);
|
||||
|
||||
uint32_t magic = 0;
|
||||
FileIO::fread(&magic, sizeof(magic), 1, f);
|
||||
|
||||
FileIO::fseek64(f, 0, SEEK_SET);
|
||||
|
||||
return magic == openexr_magic;
|
||||
}
|
||||
|
||||
template<>
|
||||
string ToStrHelper<false, RDCDriver>::Get(const RDCDriver &el)
|
||||
{
|
||||
@@ -480,6 +495,9 @@ ReplayCreateStatus RenderDoc::FillInitParams(const char *logFile, RDCDriver &dri
|
||||
if(is_dds_file(f))
|
||||
ret = x = y = comp = 1;
|
||||
|
||||
if(is_exr_file(f))
|
||||
ret = x = y = comp = 1;
|
||||
|
||||
FileIO::fclose(f);
|
||||
|
||||
if(ret == 1 && x > 0 && y > 0 && comp > 0)
|
||||
|
||||
@@ -46,6 +46,9 @@ class Chunk;
|
||||
#include "os/os_specific.h"
|
||||
#include "common/threading.h"
|
||||
|
||||
// not provided by tinyexr, just do by hand
|
||||
bool is_exr_file(FILE *f);
|
||||
|
||||
struct ICrashHandler
|
||||
{
|
||||
virtual ~ICrashHandler() {}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "replay/type_helpers.h"
|
||||
|
||||
#include "stb/stb_image.h"
|
||||
#include "tinyexr/tinyexr.h"
|
||||
#include "common/dds_readwrite.h"
|
||||
|
||||
class ImageViewer : public IReplayDriver
|
||||
@@ -194,7 +195,26 @@ ReplayCreateStatus IMG_CreateReplayDevice(const char *logfile, IReplayDriver **d
|
||||
|
||||
bool dds = false;
|
||||
|
||||
if(stbi_is_hdr_from_file(f))
|
||||
if(is_exr_file(f))
|
||||
{
|
||||
texDetails.format = rgba32_float;
|
||||
|
||||
FileIO::fseek64(f, 0, SEEK_SET);
|
||||
|
||||
const char *err = NULL;
|
||||
|
||||
int ret = LoadEXRFP((float **)&data, (int *)&texDetails.width, (int *)&texDetails.height, f, &err);
|
||||
datasize = texDetails.width*texDetails.height*4*sizeof(float);
|
||||
|
||||
// could be an unsupported form of EXR, like deep image or other
|
||||
if(ret != 0)
|
||||
{
|
||||
if(data) free(data);
|
||||
RDCERR("EXR file detected, but couldn't load with LoadEXR %d: '%s'", ret, err);
|
||||
return eReplayCreate_APIUnsupported;
|
||||
}
|
||||
}
|
||||
else if(stbi_is_hdr_from_file(f))
|
||||
{
|
||||
texDetails.format = rgba32_float;
|
||||
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
<ClInclude Include="3rdparty\stb\stb_image.h" />
|
||||
<ClInclude Include="3rdparty\stb\stb_image_write.h" />
|
||||
<ClInclude Include="3rdparty\stb\stb_truetype.h" />
|
||||
<ClInclude Include="3rdparty\tinyexr\tinyexr.h" />
|
||||
<ClInclude Include="api\app\renderdoc_app.h" />
|
||||
<ClInclude Include="api\replay\basic_types.h" />
|
||||
<ClInclude Include="api\replay\control_types.h" />
|
||||
@@ -286,6 +287,7 @@
|
||||
<ClCompile Include="3rdparty\jpeg-compressor\jpge.cpp" />
|
||||
<ClCompile Include="3rdparty\lz4\lz4.c" />
|
||||
<ClCompile Include="3rdparty\stb\stb_impl.c" />
|
||||
<ClCompile Include="3rdparty\tinyexr\tinyexr.cpp" />
|
||||
<ClCompile Include="common\common.cpp" />
|
||||
<ClCompile Include="common\dds_readwrite.cpp" />
|
||||
<ClCompile Include="core\core.cpp" />
|
||||
@@ -382,4 +384,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -88,6 +88,9 @@
|
||||
<Filter Include="Common\Strings">
|
||||
<UniqueIdentifier>{ce0b860f-38b7-48af-b49d-7dcb23378f82}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="3rdparty\tinyexr">
|
||||
<UniqueIdentifier>{aadadb32-abbc-45b3-8f86-026eed994ba9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="maths\camera.h">
|
||||
@@ -309,6 +312,9 @@
|
||||
<ClInclude Include="serialise\string_utils.h">
|
||||
<Filter>Common\Strings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="3rdparty\tinyexr\tinyexr.h">
|
||||
<Filter>3rdparty\tinyexr</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="maths\camera.cpp">
|
||||
@@ -536,6 +542,9 @@
|
||||
<ClCompile Include="serialise\string_utils.cpp">
|
||||
<Filter>Common\Strings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="3rdparty\tinyexr\tinyexr.cpp">
|
||||
<Filter>3rdparty\tinyexr</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="os\win32\comexport.def">
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "jpeg-compressor/jpge.h"
|
||||
#include "stb/stb_image.h"
|
||||
#include "stb/stb_image_write.h"
|
||||
#include "tinyexr/tinyexr.h"
|
||||
#include "common/dds_readwrite.h"
|
||||
|
||||
float ConvertComponent(ResourceFormat fmt, byte *data)
|
||||
@@ -561,8 +562,8 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
downcast = true;
|
||||
|
||||
// for DDS don't downcast, for non-HDR always downcast if we're not already RGBA8 unorm
|
||||
// for HDR we can convert from most regular types as well as 10.10.10.2 and 11.11.10
|
||||
if((sd.destType != eFileType_DDS && sd.destType != eFileType_HDR &&
|
||||
// for HDR&EXR we can convert from most regular types as well as 10.10.10.2 and 11.11.10
|
||||
if((sd.destType != eFileType_DDS && sd.destType != eFileType_HDR && sd.destType != eFileType_EXR &&
|
||||
(td.format.compByteWidth != 1 || td.format.compType != eCompType_UNorm)
|
||||
) ||
|
||||
downcast ||
|
||||
@@ -945,9 +946,9 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
|
||||
delete[] jpgdst;
|
||||
}
|
||||
else if(sd.destType == eFileType_HDR)
|
||||
else if(sd.destType == eFileType_HDR || sd.destType == eFileType_EXR)
|
||||
{
|
||||
float *fldata = new float[td.width*td.height*3];
|
||||
float *fldata = new float[td.width*td.height*4];
|
||||
|
||||
byte *srcData = subdata[0];
|
||||
|
||||
@@ -958,6 +959,7 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
float r = 0.0f;
|
||||
float g = 0.0f;
|
||||
float b = 0.0f;
|
||||
float a = 1.0f;
|
||||
|
||||
if(td.format.special && td.format.specialFormat == eSpecial_R10G10B10A2)
|
||||
{
|
||||
@@ -968,6 +970,7 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
r = vec.x;
|
||||
g = vec.y;
|
||||
b = vec.z;
|
||||
a = vec.w;
|
||||
|
||||
srcData += 4;
|
||||
}
|
||||
@@ -980,6 +983,7 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
r = vec.x;
|
||||
g = vec.y;
|
||||
b = vec.z;
|
||||
a = 1.0f;
|
||||
|
||||
srcData += 4;
|
||||
}
|
||||
@@ -991,18 +995,32 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path)
|
||||
g = ConvertComponent(td.format, srcData + td.format.compByteWidth*1);
|
||||
if(td.format.compCount >= 3)
|
||||
b = ConvertComponent(td.format, srcData + td.format.compByteWidth*2);
|
||||
if(td.format.compCount >= 4)
|
||||
a = ConvertComponent(td.format, srcData + td.format.compByteWidth*3);
|
||||
|
||||
srcData += td.format.compCount * td.format.compByteWidth;
|
||||
}
|
||||
|
||||
fldata[(y*td.width + x) * 3 + 0] = r;
|
||||
fldata[(y*td.width + x) * 3 + 1] = g;
|
||||
fldata[(y*td.width + x) * 3 + 2] = b;
|
||||
fldata[(y*td.width + x) * 4 + 0] = r;
|
||||
fldata[(y*td.width + x) * 4 + 1] = g;
|
||||
fldata[(y*td.width + x) * 4 + 2] = b;
|
||||
fldata[(y*td.width + x) * 4 + 3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = stbi_write_hdr_to_file(f, td.width, td.height, 3, fldata);
|
||||
success = (ret != 0);
|
||||
if(sd.destType == eFileType_HDR)
|
||||
{
|
||||
int ret = stbi_write_hdr_to_file(f, td.width, td.height, 4, fldata);
|
||||
success = (ret != 0);
|
||||
}
|
||||
else if(sd.destType == eFileType_EXR)
|
||||
{
|
||||
const char *err = NULL;
|
||||
int ret = SaveEXRFP(fldata, (int)td.width, (int)td.height, f, &err);
|
||||
success = (ret == 0);
|
||||
if(!success)
|
||||
RDCERR("Error saving EXR file %d: '%s'", ret, err);
|
||||
}
|
||||
|
||||
delete[] fldata;
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@ namespace renderdoc
|
||||
BMP,
|
||||
TGA,
|
||||
HDR,
|
||||
EXR,
|
||||
};
|
||||
|
||||
public enum AlphaMapping
|
||||
|
||||
@@ -150,7 +150,9 @@ namespace renderdocui.Windows.Dialogs
|
||||
|
||||
jpegCompression.Enabled = (saveData.destType == FileType.JPG);
|
||||
|
||||
alphaLDRGroup.Visible = (saveData.destType != FileType.HDR && saveData.destType != FileType.DDS);
|
||||
alphaLDRGroup.Visible = (saveData.destType != FileType.HDR &&
|
||||
saveData.destType != FileType.EXR &&
|
||||
saveData.destType != FileType.DDS);
|
||||
|
||||
bool noAlphaFormat = (saveData.destType == FileType.BMP || saveData.destType == FileType.JPG);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user