--User changes

-Allow for saving EXR as full 31-bit float per component per pixel.
 -Allow for saving the output from the final render dialog as a different image format without starting the rendering process over.

--Code changes:
 -Make StripsRender() handle memsetting the final output image so calling code no longer has to.
 -Make FinalRenderEmberController<T>::SaveCurrentRender() return the path that the image was actually saved to.
This commit is contained in:
Person
2019-11-29 23:52:17 -08:00
parent 59605f10a8
commit 35d4eb3464
12 changed files with 352 additions and 64 deletions

View File

@ -326,10 +326,12 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
auto size = w * h;
bool doBmp = Find(opt.Format(), "bmp");
bool doJpg = Find(opt.Format(), "jpg");
bool doExr = Find(opt.Format(), "exr");
bool doExr16 = Find(opt.Format(), "exr");
bool doExr32 = Find(opt.Format(), "exr32");
bool doPng8 = Find(opt.Format(), "png");
bool doPng16 = Find(opt.Format(), "png16");
bool doOnlyPng8 = doPng8 && !doPng16;
bool doOnlyExr16 = doExr16 && !doExr32;
vector<byte> rgb8Image;
vector<std::thread> writeFileThreads;
writeFileThreads.reserve(5);
@ -370,7 +372,7 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
{
bool doBothPng = doPng16 && (opt.Format().find("png") != opt.Format().rfind("png"));
if (doBothPng || doOnlyPng8)//8-bit PNG
if (doBothPng || doOnlyPng8)//8-bit PNG.
{
writeFileThreads.push_back(std::thread([&]()
{
@ -385,7 +387,7 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
}));
}
if (doPng16)
if (doPng16)//16-bit PNG.
{
writeFileThreads.push_back(std::thread([&]()
{
@ -410,19 +412,56 @@ bool EmberAnimate(int argc, _TCHAR* argv[], EmberOptions& opt)
}
}
if (doExr)
if (doExr16)
{
writeFileThreads.push_back(std::thread([&]()
{
auto fn = baseFilename + ".exr";
VerbosePrint("Writing " + fn);
vector<Rgba> rgba32Image(size);
Rgba32ToRgbaExr(finalImagep, rgba32Image.data(), w, h, opt.Transparency());
auto writeSuccess = WriteExr(fn.c_str(), rgba32Image.data(), w, h, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
bool doBothExr = doExr32 && (opt.Format().find("exr") != opt.Format().rfind("exr"));
if (!writeSuccess)
cout << "Error writing " << fn << "\n";
}));
if (doBothExr || doOnlyExr16)//16-bit EXR
{
writeFileThreads.push_back(std::thread([&]()
{
auto fn = baseFilename + ".exr";
VerbosePrint("Writing " + fn);
vector<Rgba> rgba32Image(size);
Rgba32ToRgbaExr(finalImagep, rgba32Image.data(), w, h, opt.Transparency());
auto writeSuccess = WriteExr16(fn.c_str(), rgba32Image.data(), w, h, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
if (!writeSuccess)
cout << "Error writing " << fn << "\n";
}));
}
if (doExr32)//32-bit EXR.
{
writeFileThreads.push_back(std::thread([&]()
{
auto suffix = opt.Suffix();
auto fn = baseFilename;
if (doBothExr)//Add suffix if they specified both EXR.
{
VerbosePrint("Doing both EXR formats, so adding suffix _exr32 to avoid overwriting the same file.");
fn += "_exr32";
}
fn += ".exr";
VerbosePrint("Writing " + fn);
vector<float> r(size);
vector<float> g(size);
vector<float> b(size);
vector<float> a(size);
Rgba32ToRgba32Exr(finalImagep, r.data(), g.data(), b.data(), a.data(), w, h, opt.Transparency());
auto writeSuccess = WriteExr32(fn.c_str(),
r.data(),
g.data(),
b.data(),
a.data(),
w, h, opt.EnableComments(), comments, opt.Id(), opt.Url(), opt.Nick());
if (!writeSuccess)
cout << "Error writing " << fn << "\n";
}));
}
}
Join(writeFileThreads);