diff --git a/Source/Ember/Renderer.cpp b/Source/Ember/Renderer.cpp index d780bd4..3c615a3 100644 --- a/Source/Ember/Renderer.cpp +++ b/Source/Ember/Renderer.cpp @@ -421,7 +421,7 @@ eRenderStatus Renderer::Run(vector& finalImage, double time, s //it.Toc("Interp 1"); //Save only for palette insertion. - if (m_InsertPalette && BytesPerChannel() == 1) + if (m_InsertPalette) m_TempEmber = m_Ember; if (!resume)//Only need to create this when starting a new render. @@ -1232,22 +1232,38 @@ eRenderStatus Renderer::AccumulatorToFinalImage(byte* pixels, size_t } }); - //Insert the palette into the image for debugging purposes. Only works with 8bpc and is not implemented on the GPU. - if (m_InsertPalette && BytesPerChannel() == 1) + //Insert the palette into the image for debugging purposes. Not implemented on the GPU. + if (m_InsertPalette) { size_t i, j, ph = 100; if (ph >= FinalRasH()) ph = FinalRasH(); - for (j = 0; j < ph; j++) + if (BytesPerChannel() == 1) { - for (i = 0; i < FinalRasW(); i++) + for (j = 0; j < ph; j++) { - byte* p = pixels + (NumChannels() * (i + j * FinalRasW())); - p[0] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][0] * WHITE);//The palette is [0..1], output image is [0..255]. - p[1] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][1] * WHITE); - p[2] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][2] * WHITE); + for (i = 0; i < FinalRasW(); i++) + { + auto p = pixels + (NumChannels() * (i + j * FinalRasW())); + p[0] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][0] * WHITE);//The palette is [0..1], output image is [0..255]. + p[1] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][1] * WHITE); + p[2] = byte(m_TempEmber.m_Palette[i * 256 / FinalRasW()][2] * WHITE); + } + } + } + else//BPC == 2. + { + for (j = 0; j < ph; j++) + { + for (i = 0; i < FinalRasW(); i++) + { + auto p16 = reinterpret_cast(pixels + (PixelSize() * (i + j * FinalRasW()))); + p16[0] = glm::uint16(m_TempEmber.m_Palette[i * 256 / FinalRasW()][0] * WHITE * bucketT(256)); //The palette is [0..1], output image is [0..65535]. + p16[1] = glm::uint16(m_TempEmber.m_Palette[i * 256 / FinalRasW()][1] * WHITE * bucketT(256)); + p16[2] = glm::uint16(m_TempEmber.m_Palette[i * 256 / FinalRasW()][2] * WHITE * bucketT(256)); + } } } } diff --git a/Source/EmberAnimate/EmberAnimate.cpp b/Source/EmberAnimate/EmberAnimate.cpp index 77c5f90..8be3278 100644 --- a/Source/EmberAnimate/EmberAnimate.cpp +++ b/Source/EmberAnimate/EmberAnimate.cpp @@ -153,12 +153,6 @@ bool EmberAnimate(EmberOptions& opt) opt.BitsPerChannel(8); } - if (opt.InsertPalette() && opt.BitsPerChannel() != 8) - { - cout << "Inserting palette only supported with 8 bits per channel, insertion will not take place.\n"; - opt.InsertPalette(false); - } - if (opt.AspectRatio() < 0) { cout << "Invalid pixel aspect ratio " << opt.AspectRatio() << "\n. Must be positive, setting to 1.\n"; @@ -235,9 +229,6 @@ bool EmberAnimate(EmberOptions& opt) if (opt.DeMax() > -1) embers[i].m_MaxRadDE = T(opt.DeMax()); - if (opt.SubBatchSize() != DEFAULT_SBS) - embers[i].m_SubBatchSize = opt.SubBatchSize(); - embers[i].m_Quality *= T(opt.QualityScale()); embers[i].m_FinalRasW = size_t(T(embers[i].m_FinalRasW) * opt.SizeScale()); embers[i].m_FinalRasH = size_t(T(embers[i].m_FinalRasH) * opt.SizeScale()); @@ -302,7 +293,6 @@ bool EmberAnimate(EmberOptions& opt) r->EarlyClip(opt.EarlyClip()); r->YAxisUp(opt.YAxisUp()); r->LockAccum(opt.LockAccum()); - r->InsertPalette(opt.InsertPalette()); r->PixelAspectRatio(T(opt.AspectRatio())); r->Transparency(opt.Transparency()); r->NumChannels(channels); @@ -389,7 +379,7 @@ bool EmberAnimate(EmberOptions& opt) } stats = renderer->Stats(); - comments = renderer->ImageComments(stats, opt.PrintEditDepth(), opt.HexPalette()); + comments = renderer->ImageComments(stats, opt.PrintEditDepth(), true); os.str(""); size_t iterCount = renderer->TotalIterCount(1); os << comments.m_NumIters << " / " << iterCount << " (" << std::fixed << std::setprecision(2) << ((double(stats.m_Iters) / double(iterCount)) * 100) << "%)"; @@ -466,21 +456,11 @@ int _tmain(int argc, _TCHAR* argv[]) { #ifdef DO_DOUBLE - if (opt.Bits() == 64) - { + if (!opt.Sp()) b = EmberAnimate(opt); - } else #endif - if (opt.Bits() == 33) - { - b = EmberAnimate(opt); - } - else if (opt.Bits() == 32) - { - cout << "Bits 32/int histogram no longer supported. Using bits == 33 (float).\n"; - b = EmberAnimate(opt); - } + b = EmberAnimate(opt); } return b ? 0 : 1; diff --git a/Source/EmberCommon/EmberOptions.h b/Source/EmberCommon/EmberOptions.h index 9ca0a2b..9badfd8 100644 --- a/Source/EmberCommon/EmberOptions.h +++ b/Source/EmberCommon/EmberOptions.h @@ -42,6 +42,7 @@ enum class eOptionIDs : et //Boolean args. OPT_OPENCL, + OPT_SP, OPT_EARLYCLIP, OPT_POS_Y_UP, OPT_TRANSPARENCY, @@ -60,13 +61,10 @@ enum class eOptionIDs : et OPT_DUMP_KERNEL, //Value args. - OPT_SEED,//Int value args. - OPT_NTHREADS, + OPT_NTHREADS,//Int value args. OPT_STRIPS, OPT_SUPERSAMPLE, - OPT_BITS, OPT_BPC, - OPT_SBS, OPT_PRINT_EDIT_DEPTH, OPT_JPEG, OPT_BEGIN, @@ -297,35 +295,38 @@ public: /// EmberOptions() { - m_BoolArgs.reserve(25); - m_IntArgs.reserve(25); - m_UintArgs.reserve(25); - m_DoubleArgs.reserve(25); - m_StringArgs.reserve(35); + const size_t size = 30; + m_BoolArgs.reserve(size); + m_IntArgs.reserve(size); + m_UintArgs.reserve(size); + m_DoubleArgs.reserve(size); + m_StringArgs.reserve(size); + //Informational bools. + INITBOOLOPTION(Help, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_HELP, _T("--help"), false, SO_NONE, "\t--help Show this screen and exit.\n")); + INITBOOLOPTION(Version, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_VERSION, _T("--version"), false, SO_NONE, "\t--version Show version and exit.\n")); + INITBOOLOPTION(OpenCLInfo, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_DUMP_OPENCL_INFO, _T("--openclinfo"), false, SO_NONE, "\t--openclinfo Display platforms and devices for OpenCL and exit.\n")); + INITBOOLOPTION(AllVars, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_ALL_VARS, _T("--allvars"), false, SO_NONE, "\t--allvars Display the names of all supported variations and exit.\n")); + INITBOOLOPTION(RegVars, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_REG_VARS, _T("--regvars"), false, SO_NONE, "\t--regvars Display the names of all supported regular variations and exit.\n")); + INITBOOLOPTION(PreVars, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_PRE_VARS, _T("--prevars"), false, SO_NONE, "\t--prevars Display the names of all supported pre variations and exit.\n")); + INITBOOLOPTION(PostVars, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_POST_VARS, _T("--postvars"), false, SO_NONE, "\t--postvars Display the names of all supported post variations and exit.\n")); //Diagnostic bools. - INITBOOLOPTION(Help, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_HELP, _T("--help"), false, SO_NONE, "\t--help Show this screen.\n")); - INITBOOLOPTION(Version, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_VERSION, _T("--version"), false, SO_NONE, "\t--version Show version.\n")); - INITBOOLOPTION(Verbose, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_VERBOSE, _T("--verbose"), false, SO_NONE, "\t--verbose Verbose output.\n")); - INITBOOLOPTION(Debug, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_DEBUG, _T("--debug"), false, SO_NONE, "\t--debug Debug output.\n")); - INITBOOLOPTION(DumpArgs, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_DUMP_ARGS, _T("--dumpargs"), false, SO_NONE, "\t--dumpargs Print all arguments entered from either the command line or environment variables.\n")); - INITBOOLOPTION(DoProgress, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_PROGRESS, _T("--progress"), false, SO_NONE, "\t--progress Display progress. This will slow down processing by about 10%.\n")); - INITBOOLOPTION(OpenCLInfo, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_DUMP_OPENCL_INFO, _T("--openclinfo"), false, SO_NONE, "\t--openclinfo Display platforms and devices for OpenCL.\n")); - INITBOOLOPTION(AllVars, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_ALL_VARS, _T("--allvars"), false, SO_NONE, "\t--allvars Display the names of all supported variations.\n")); - INITBOOLOPTION(RegVars, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_REG_VARS, _T("--regvars"), false, SO_NONE, "\t--regvars Display the names of all supported regular variations.\n")); - INITBOOLOPTION(PreVars, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_PRE_VARS, _T("--prevars"), false, SO_NONE, "\t--prevars Display the names of all supported pre variations.\n")); - INITBOOLOPTION(PostVars, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_POST_VARS, _T("--postvars"), false, SO_NONE, "\t--postvars Display the names of all supported post variations.\n")); + INITBOOLOPTION(Verbose, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_VERBOSE, _T("--verbose"), false, SO_NONE, "\t--verbose Verbose output [default: false].\n")); + INITBOOLOPTION(Debug, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_DEBUG, _T("--debug"), false, SO_NONE, "\t--debug Debug output [default: false].\n")); + INITBOOLOPTION(DumpArgs, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_DUMP_ARGS, _T("--dumpargs"), false, SO_NONE, "\t--dumpargs Print all arguments entered from either the command line or environment variables [default: false].\n")); + INITBOOLOPTION(DoProgress, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_PROGRESS, _T("--progress"), false, SO_NONE, "\t--progress Display progress. This will slow down processing by about 10% [default: false].\n")); //Execution bools. INITBOOLOPTION(EmberCL, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_OPENCL, _T("--opencl"), false, SO_NONE, "\t--opencl Use OpenCL renderer (EmberCL) for rendering [default: false].\n")); + INITBOOLOPTION(Sp, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_SP, _T("--sp"), false, SO_NONE, "\t--sp Use single precision for rendering instead of double precision [default: false].\n")); INITBOOLOPTION(EarlyClip, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_EARLYCLIP, _T("--earlyclip"), false, SO_NONE, "\t--earlyclip Perform clipping of RGB values before spatial filtering for better antialiasing and resizing [default: false].\n")); INITBOOLOPTION(YAxisUp, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_POS_Y_UP, _T("--yaxisup"), false, SO_NONE, "\t--yaxisup Orient the image with the positive y axis pointing up [default: false].\n")); INITBOOLOPTION(Transparency, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_TRANSPARENCY, _T("--transparency"), false, SO_NONE, "\t--transparency Include alpha channel in final output [default: false except for PNG].\n")); INITBOOLOPTION(NameEnable, Eob(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_NAME_ENABLE, _T("--name_enable"), false, SO_NONE, "\t--name_enable Use the name attribute contained in the Xml as the output filename [default: false].\n")); - INITBOOLOPTION(HexPalette, Eob(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_HEX_PALETTE, _T("--hex_palette"), true, SO_OPT, "\t--hex_palette Force palette RGB values to be hex [default: true].\n")); - INITBOOLOPTION(InsertPalette, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_INSERT_PALETTE, _T("--insert_palette"), false, SO_NONE, "\t--insert_palette Insert the palette into the image for debugging purposes [default: false].\n")); - INITBOOLOPTION(JpegComments, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_JPEG_COMMENTS, _T("--enable_jpeg_comments"), true, SO_OPT, "\t--enable_jpeg_comments Enables comments in the jpeg header [default: true].\n")); - INITBOOLOPTION(PngComments, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_PNG_COMMENTS, _T("--enable_png_comments"), true, SO_OPT, "\t--enable_png_comments Enables comments in the png header [default: true].\n")); + INITBOOLOPTION(HexPalette, Eob(eOptionUse::OPT_ANIM_GENOME, eOptionIDs::OPT_HEX_PALETTE, _T("--hex_palette"), true, SO_OPT, "\t--hex_palette Force palette RGB values to be hex when saving to Xml [default: true].\n")); + INITBOOLOPTION(InsertPalette, Eob(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_INSERT_PALETTE, _T("--insert_palette"), false, SO_NONE, "\t--insert_palette Insert the palette into the image for debugging purposes. Disabled when running with OpenCL [default: false].\n")); + INITBOOLOPTION(JpegComments, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_JPEG_COMMENTS, _T("--enable_jpeg_comments"), false, SO_OPT, "\t--enable_jpeg_comments Enables embedding the flame parameters and user identifying information in the jpeg header [default: false].\n")); + INITBOOLOPTION(PngComments, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_PNG_COMMENTS, _T("--enable_png_comments"), false, SO_OPT, "\t--enable_png_comments Enables embedding the flame parameters and user identifying information png header [default: false].\n")); INITBOOLOPTION(WriteGenome, Eob(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_WRITE_GENOME, _T("--write_genome"), false, SO_NONE, "\t--write_genome Write out flame associated with center of motion blur window [default: false].\n")); - INITBOOLOPTION(ThreadedWrite, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_THREADED_WRITE, _T("--threaded_write"), true, SO_OPT, "\t--threaded_write Use a separate thread to write images to disk. This gives better performance, but doubles the memory required for the final output buffer. [default: true].\n")); + INITBOOLOPTION(ThreadedWrite, Eob(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_THREADED_WRITE, _T("--threaded_write"), true, SO_OPT, "\t--threaded_write Use a separate thread to write images to disk. This gives better performance, but doubles the memory required for the final output buffer. [default: true].\n")); INITBOOLOPTION(Enclosed, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_ENCLOSED, _T("--enclosed"), true, SO_OPT, "\t--enclosed Use enclosing Xml tags [default: true].\n")); INITBOOLOPTION(NoEdits, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_NO_EDITS, _T("--noedits"), false, SO_NONE, "\t--noedits Exclude edit tags when writing Xml [default: false].\n")); INITBOOLOPTION(UnsmoothEdge, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_UNSMOOTH_EDGE, _T("--unsmoother"), false, SO_NONE, "\t--unsmoother Do not use smooth blending for sheep edges [default: false].\n")); @@ -341,16 +342,10 @@ public: INITINTOPTION(Priority, Eoi(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_PRIORITY, _T("--priority"), int(eThreadPriority::NORMAL), SO_REQ_SEP, "\t--priority= The priority of the CPU rendering threads, 1, 25, 50, 75, 99. This does not apply to OpenCL rendering.\n")); #endif //Uint. - INITUINTOPTION(Seed, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_SEED, _T("--seed"), 0, SO_REQ_SEP, "\t--seed= Integer seed to use for the random number generator [default: random].\n")); INITUINTOPTION(ThreadCount, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_NTHREADS, _T("--nthreads"), 0, SO_REQ_SEP, "\t--nthreads= The number of threads to use [default: use all available cores].\n")); INITUINTOPTION(Strips, Eou(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_STRIPS, _T("--nstrips"), 1, SO_REQ_SEP, "\t--nstrips= The number of fractions to split a single render frame into. Useful for print size renders or low memory systems [default: 1].\n")); - INITUINTOPTION(Supersample, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_SUPERSAMPLE, _T("--supersample"), 0, SO_REQ_SEP, "\t--supersample= The supersample value used to override the one specified in the file [default: 0 (use value from file)].\n")); + INITUINTOPTION(Supersample, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_SUPERSAMPLE, _T("--supersample"), 0, SO_REQ_SEP, "\t--supersample= The supersample value used to override the one specified in the file [default: 0 (use value from file), Range: 0 - 4].\n")); INITUINTOPTION(BitsPerChannel, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_BPC, _T("--bpc"), 8, SO_REQ_SEP, "\t--bpc= Bits per channel. 8 or 16 for PNG, 8 for all others, always 8 with OpenCL [default: 8].\n")); - INITUINTOPTION(SubBatchSize, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_SBS, _T("--sub_batch_size"), DEFAULT_SBS, SO_REQ_SEP, "\t--sub_batch_size= The chunk size that iterating will be broken into [default: 10k].\n")); - INITUINTOPTION(Bits, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_BITS, _T("--bits"), 33, SO_REQ_SEP, "\t--bits= Determines the types used for the calculations [default: 33].\n" - "\t\t\t\t\t32: float.\n" - "\t\t\t\t\t33: float.\n"//This differs from the original which used an int hist for bits 33. - "\t\t\t\t\t64: double.\n")); INITUINTOPTION(PrintEditDepth, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_PRINT_EDIT_DEPTH, _T("--print_edit_depth"), 0, SO_REQ_SEP, "\t--print_edit_depth= Depth to truncate tag structure when converting a flame to Xml. 0 prints all tags [default: 0].\n")); INITUINTOPTION(JpegQuality, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_JPEG, _T("--jpeg"), 95, SO_REQ_SEP, "\t--jpeg= Jpeg quality 0-100 for compression [default: 95].\n")); INITUINTOPTION(FirstFrame, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_BEGIN, _T("--begin"), UINT_MAX, SO_REQ_SEP, "\t--begin= Time of first frame to render [default: first time specified in file].\n")); @@ -459,6 +454,7 @@ public: PARSEBOOLOPTION(eOptionIDs::OPT_PRE_VARS, PreVars); PARSEBOOLOPTION(eOptionIDs::OPT_POST_VARS, PostVars); PARSEBOOLOPTION(eOptionIDs::OPT_OPENCL, EmberCL); + PARSEBOOLOPTION(eOptionIDs::OPT_SP, Sp); PARSEBOOLOPTION(eOptionIDs::OPT_EARLYCLIP, EarlyClip); PARSEBOOLOPTION(eOptionIDs::OPT_POS_Y_UP, YAxisUp); PARSEBOOLOPTION(eOptionIDs::OPT_TRANSPARENCY, Transparency); @@ -478,13 +474,10 @@ public: PARSEINTOPTION(eOptionIDs::OPT_SHEEP_GEN, SheepGen); PARSEINTOPTION(eOptionIDs::OPT_SHEEP_ID, SheepId); PARSEINTOPTION(eOptionIDs::OPT_PRIORITY, Priority); - PARSEUINTOPTION(eOptionIDs::OPT_SEED, Seed);//uint args. - PARSEUINTOPTION(eOptionIDs::OPT_NTHREADS, ThreadCount); + PARSEUINTOPTION(eOptionIDs::OPT_NTHREADS, ThreadCount);//uint args. PARSEUINTOPTION(eOptionIDs::OPT_STRIPS, Strips); PARSEUINTOPTION(eOptionIDs::OPT_SUPERSAMPLE, Supersample); - PARSEUINTOPTION(eOptionIDs::OPT_BITS, Bits); PARSEUINTOPTION(eOptionIDs::OPT_BPC, BitsPerChannel); - PARSEUINTOPTION(eOptionIDs::OPT_SBS, SubBatchSize); PARSEUINTOPTION(eOptionIDs::OPT_PRINT_EDIT_DEPTH, PrintEditDepth); PARSEUINTOPTION(eOptionIDs::OPT_JPEG, JpegQuality); PARSEUINTOPTION(eOptionIDs::OPT_BEGIN, FirstFrame); @@ -735,6 +728,7 @@ public: Eob PostVars; Eob EmberCL;//Value bool. + Eob Sp; Eob EarlyClip; Eob YAxisUp; Eob Transparency; @@ -755,12 +749,10 @@ public: Eoi SheepGen; Eoi SheepId; Eoi Priority; - Eou Seed;//Value uint. - Eou ThreadCount; + Eou ThreadCount;//Value uint. Eou Strips; Eou Supersample; Eou BitsPerChannel; - Eou SubBatchSize; Eou Bits; Eou PrintEditDepth; Eou JpegQuality; diff --git a/Source/EmberGenome/EmberGenome.cpp b/Source/EmberGenome/EmberGenome.cpp index 2391f80..479a2bb 100644 --- a/Source/EmberGenome/EmberGenome.cpp +++ b/Source/EmberGenome/EmberGenome.cpp @@ -306,24 +306,12 @@ bool EmberGenome(EmberOptions& opt) else if (opt.Clone() != "") filename = opt.Clone(); else if (opt.Mutate() != "") filename = opt.Mutate(); - if (ParseEmberFile(parser, filename, embers)) - { - if (opt.SubBatchSize() != DEFAULT_SBS) - for (i = 0; i < embers.size(); i++) - embers[i].m_SubBatchSize = opt.SubBatchSize(); - } - else + if (!ParseEmberFile(parser, filename, embers)) return false; if (doCross1) { - if (ParseEmberFile(parser, opt.Cross1(), embers2)) - { - if (opt.SubBatchSize() != DEFAULT_SBS) - for (i = 0; i < embers2.size(); i++) - embers2[i].m_SubBatchSize = opt.SubBatchSize(); - } - else + if (!ParseEmberFile(parser, opt.Cross1(), embers2)) return false; } @@ -826,21 +814,11 @@ int _tmain(int argc, _TCHAR* argv[]) { #ifdef DO_DOUBLE - if (opt.Bits() == 64) - { + if (!opt.Sp()) b = EmberGenome(opt); - } else #endif - if (opt.Bits() == 33) - { - b = EmberGenome(opt); - } - else if (opt.Bits() == 32) - { - cerr << "Bits 32/int histogram no longer supported. Using bits == 33 (float).\n"; - b = EmberGenome(opt); - } + b = EmberGenome(opt); } return b ? 0 : 1; diff --git a/Source/EmberRender/EmberRender.cpp b/Source/EmberRender/EmberRender.cpp index 3eb730b..9d0601e 100644 --- a/Source/EmberRender/EmberRender.cpp +++ b/Source/EmberRender/EmberRender.cpp @@ -106,6 +106,12 @@ bool EmberRender(EmberOptions& opt) cout << "Bits per channel cannot be anything other than 8 with OpenCL, setting to 8.\n"; opt.BitsPerChannel(8); } + + if (opt.InsertPalette()) + { + cout << "Inserting palette not supported with OpenCL, insertion will not take place.\n"; + opt.InsertPalette(false); + } } if (opt.Format() != "jpg" && @@ -129,12 +135,6 @@ bool EmberRender(EmberOptions& opt) opt.BitsPerChannel(8); } - if (opt.InsertPalette() && opt.BitsPerChannel() != 8) - { - cout << "Inserting palette only supported with 8 bits per channel, insertion will not take place.\n"; - opt.InsertPalette(false); - } - if (opt.AspectRatio() < 0) { cout << "Invalid pixel aspect ratio " << opt.AspectRatio() << "\n. Must be positive, setting to 1.\n"; @@ -181,9 +181,6 @@ bool EmberRender(EmberOptions& opt) if (opt.DeMax() > -1) embers[i].m_MaxRadDE = T(opt.DeMax()); - if (opt.SubBatchSize() != DEFAULT_SBS) - embers[i].m_SubBatchSize = opt.SubBatchSize(); - embers[i].m_TemporalSamples = 1;//Force temporal samples to 1 for render. embers[i].m_Quality *= T(opt.QualityScale()); embers[i].m_FinalRasW = size_t(T(embers[i].m_FinalRasW) * opt.SizeScale()); @@ -282,7 +279,7 @@ bool EmberRender(EmberOptions& opt) //TotalIterCount() is actually using ScaledQuality() which does not get reset upon ember assignment, //so it ends up using the correct value for quality * strips. iterCount = renderer->TotalIterCount(1); - comments = renderer->ImageComments(stats, opt.PrintEditDepth(), opt.HexPalette()); + comments = renderer->ImageComments(stats, opt.PrintEditDepth(), true); os.str(""); os << comments.m_NumIters << " / " << iterCount << " (" << std::fixed << std::setprecision(2) << ((double(stats.m_Iters) / double(iterCount)) * 100) << "%)"; VerbosePrint("\nIters ran/requested: " + os.str()); @@ -356,21 +353,11 @@ int _tmain(int argc, _TCHAR* argv[]) { #ifdef DO_DOUBLE - if (opt.Bits() == 64) - { + if (!opt.Sp()) b = EmberRender(opt); - } else #endif - if (opt.Bits() == 33) - { - b = EmberRender(opt); - } - else if (opt.Bits() == 32) - { - cout << "Bits 32/int histogram no longer supported. Using bits == 33 (float).\n"; - b = EmberRender(opt); - } + b = EmberRender(opt); } return b ? 0 : 1; diff --git a/Source/Fractorium/Fractorium.h b/Source/Fractorium/Fractorium.h index 2eeba3c..db361b4 100644 --- a/Source/Fractorium/Fractorium.h +++ b/Source/Fractorium/Fractorium.h @@ -115,7 +115,6 @@ public slots: void OnActionSaveCurrentAsXml(bool checked); void OnActionSaveEntireFileAsXml(bool checked); void OnActionSaveCurrentScreen(bool checked); - void OnActionSaveCurrentToOpenedFile(bool checked); void OnActionExit(bool checked); void OnActionUndo(bool checked);//Edit. diff --git a/Source/Fractorium/Fractorium.qrc b/Source/Fractorium/Fractorium.qrc index 2f3fffc..cd946fb 100644 --- a/Source/Fractorium/Fractorium.qrc +++ b/Source/Fractorium/Fractorium.qrc @@ -13,7 +13,6 @@ Icons/layers-stack.png Icons/monitor.png Icons/016938-3d-transparent-glass-icon-symbols-shapes-shape-square-clear-16.png - Icons/document-hf-insert.png Icons/010425-3d-transparent-glass-icon-animals-spiderweb2.png Icons/database-medium.png Icons/databases.png diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui index 71c3659..e6bd161 100644 --- a/Source/Fractorium/Fractorium.ui +++ b/Source/Fractorium/Fractorium.ui @@ -3473,8 +3473,8 @@ 0 0 - 263 - 700 + 118 + 618 @@ -5491,8 +5491,8 @@ 0 0 - 259 - 652 + 133 + 52 @@ -6517,7 +6517,6 @@ - @@ -6759,7 +6758,6 @@ - @@ -6820,21 +6818,6 @@ E&xit - - - - :/Fractorium/Icons/document-hf-insert.png:/Fractorium/Icons/document-hf-insert.png - - - &Save Current to Opened File - - - <html><body><p>Save the currently displayed flame back to the opened file in memory.</p><p>This overwrites the original flame but does not store the file back to disk.</p></body></html> - - - Ctrl+B - - diff --git a/Source/Fractorium/FractoriumMenus.cpp b/Source/Fractorium/FractoriumMenus.cpp index 0611b7d..b16eca6 100644 --- a/Source/Fractorium/FractoriumMenus.cpp +++ b/Source/Fractorium/FractoriumMenus.cpp @@ -14,7 +14,6 @@ void Fractorium::InitMenusUI() connect(ui.ActionOpen, SIGNAL(triggered(bool)), this, SLOT(OnActionOpen(bool)), Qt::QueuedConnection); connect(ui.ActionSaveCurrentAsXml, SIGNAL(triggered(bool)), this, SLOT(OnActionSaveCurrentAsXml(bool)), Qt::QueuedConnection); connect(ui.ActionSaveEntireFileAsXml, SIGNAL(triggered(bool)), this, SLOT(OnActionSaveEntireFileAsXml(bool)), Qt::QueuedConnection); - connect(ui.ActionSaveCurrentToOpenedFile, SIGNAL(triggered(bool)), this, SLOT(OnActionSaveCurrentToOpenedFile(bool)), Qt::QueuedConnection); connect(ui.ActionSaveCurrentScreen, SIGNAL(triggered(bool)), this, SLOT(OnActionSaveCurrentScreen(bool)), Qt::QueuedConnection); connect(ui.ActionExit, SIGNAL(triggered(bool)), this, SLOT(OnActionExit(bool)), Qt::QueuedConnection); //Edit menu. @@ -399,8 +398,6 @@ void FractoriumEmberController::SaveCurrentToOpenedFile() } } -void Fractorium::OnActionSaveCurrentToOpenedFile(bool checked) { m_Controller->SaveCurrentToOpenedFile(); } - /// /// Exit the application. /// @@ -422,7 +419,9 @@ void FractoriumEmberController::Undo() int index = m_Ember.GetTotalXformIndex(CurrentXform()); m_LastEditWasUndoRedo = true; m_UndoIndex = std::max(0u, m_UndoIndex - 1u); + auto temp = m_EmberFilePointer;//m_EmberFilePointer will be set to point to whatever is passed in, which we don't want since it's coming from the undo list... SetEmber(m_UndoList[m_UndoIndex], true); + m_EmberFilePointer = temp;//...keep it pointing to the original one in the file. m_EditState = eEditUndoState::UNDO_REDO; if (index >= 0) @@ -446,7 +445,9 @@ void FractoriumEmberController::Redo() int index = m_Ember.GetTotalXformIndex(CurrentXform()); m_LastEditWasUndoRedo = true; m_UndoIndex = std::min(m_UndoIndex + 1, m_UndoList.size() - 1); + auto temp = m_EmberFilePointer; SetEmber(m_UndoList[m_UndoIndex], true); + m_EmberFilePointer = temp;//...keep it pointing to the original one in the file. m_EditState = eEditUndoState::UNDO_REDO; if (index >= 0) @@ -813,7 +814,7 @@ void Fractorium::OnActionFinalRender(bool checked) //First completely stop what the current rendering process is doing. m_Controller->DeleteRenderer();//Delete the renderer, but not the controller. m_Controller->StopPreviewRender(); - OnActionSaveCurrentToOpenedFile(true);//Save whatever was edited back to the current open file. + m_Controller->SaveCurrentToOpenedFile();//Save whatever was edited back to the current open file. m_RenderStatusLabel->setText("Renderer stopped."); m_FinalRenderDialog->show(); } diff --git a/Source/Fractorium/FractoriumRender.cpp b/Source/Fractorium/FractoriumRender.cpp index fdd0fc8..c3a4822 100644 --- a/Source/Fractorium/FractoriumRender.cpp +++ b/Source/Fractorium/FractoriumRender.cpp @@ -371,7 +371,9 @@ bool FractoriumEmberController::Render() if (ProcessState() != eProcessState::ACCUM_DONE) { //if (m_Renderer->Run(m_FinalImage, 0) == RENDER_OK)//Full, non-incremental render for debugging. - if (m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, (iterBegin || m_Fractorium->m_Settings->ContinuousUpdate())) == eRenderStatus::RENDER_OK)//Force output on iterBegin or if the settings specify to always do it. + bool update = iterBegin || m_Fractorium->m_Settings->ContinuousUpdate(); + + if (m_Renderer->Run(m_FinalImage, 0, m_SubBatchCount, update) == eRenderStatus::RENDER_OK)//Force output on iterBegin or if the settings specify to always do it. { //The amount to increment sub batch while rendering proceeds is purely empirical. //Change later if better values can be derived/observed. @@ -445,13 +447,16 @@ bool FractoriumEmberController::Render() FillSummary();//Only update summary on render completion since it's not the type of thing the user needs real-time updates on. } - //Update the GL window on start because the output will be forced. + //Update the GL window on start or continuous rendering because the output will be forced. //Update it on finish because the rendering process is completely done. - if (iterBegin || ProcessState() == eProcessState::ACCUM_DONE) + if (update || ProcessState() == eProcessState::ACCUM_DONE) { if (m_FinalImage.size() == m_Renderer->FinalBufferSize())//Make absolutely sure the correct amount of data is passed. gl->update(); + if (ProcessState() == eProcessState::ACCUM_DONE) + SaveCurrentToOpenedFile(); + //Uncomment for debugging kernel build and execution errors. //m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo())); //if (rendererCL) diff --git a/Source/Fractorium/FractoriumXforms.cpp b/Source/Fractorium/FractoriumXforms.cpp index c7fbee4..6800ab8 100644 --- a/Source/Fractorium/FractoriumXforms.cpp +++ b/Source/Fractorium/FractoriumXforms.cpp @@ -447,6 +447,8 @@ void FractoriumEmberController::FillXforms(int index) { auto cb1 = new QCheckBox(MakeXformCaption(i), m_Fractorium); auto cb2 = new QCheckBox(MakeXformCaption(i + 1), m_Fractorium); + QObject::connect(cb1, &QCheckBox::stateChanged, [&](int state) { m_Fractorium->ui.GLDisplay->update(); });//Ensure circles are drawn immediately after toggle. + QObject::connect(cb2, &QCheckBox::stateChanged, [&](int state) { m_Fractorium->ui.GLDisplay->update(); }); m_Fractorium->m_XformSelections.push_back(cb1); m_Fractorium->m_XformSelections.push_back(cb2); m_Fractorium->m_XformsSelectionLayout->addRow(cb1, cb2); @@ -455,6 +457,7 @@ void FractoriumEmberController::FillXforms(int index) else if (i < count) { auto cb = new QCheckBox(MakeXformCaption(i), m_Fractorium); + QObject::connect(cb, &QCheckBox::stateChanged, [&](int state) { m_Fractorium->ui.GLDisplay->update(); }); m_Fractorium->m_XformSelections.push_back(cb); m_Fractorium->m_XformsSelectionLayout->addRow(cb, new QWidget(m_Fractorium)); i++; diff --git a/Source/Fractorium/Icons/document-hf-insert.png b/Source/Fractorium/Icons/document-hf-insert.png deleted file mode 100644 index dc98195..0000000 Binary files a/Source/Fractorium/Icons/document-hf-insert.png and /dev/null differ