diff --git a/.gitignore b/.gitignore index 6aa79b0..9ed10dc 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,6 @@ Builds/MSVC/VS2010/Obj/EmberGenome/x64/Debug/EmberGenome_manifest.rc Builds/MSVC/VS2010/Obj/EmberAnimate/x64/Debug/EmberAnimate_manifest.rc Builds/MSVC/VS2010/Obj/Ember/x64/Debug/Ember_manifest.rc Bin/x64/Release/testallvarsout.flame -Data/~$Bench.xlsx \ No newline at end of file +Data/~$Bench.xlsx +*.ps1 +Bin/x64/Release/Bench.flame \ No newline at end of file diff --git a/Builds/MSVC/VS2010/FractoriumInstaller/FractoriumInstaller.wixproj b/Builds/MSVC/VS2010/FractoriumInstaller/FractoriumInstaller.wixproj index a20adbe..05d849b 100644 --- a/Builds/MSVC/VS2010/FractoriumInstaller/FractoriumInstaller.wixproj +++ b/Builds/MSVC/VS2010/FractoriumInstaller/FractoriumInstaller.wixproj @@ -6,7 +6,7 @@ 3.7 {c8096c47-e358-438c-a520-146d46b0637d} 2.0 - Fractorium_Beta_0.4.1.1 + Fractorium_Beta_0.4.1.2 Package $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets diff --git a/Builds/MSVC/VS2010/FractoriumInstaller/Product.wxs b/Builds/MSVC/VS2010/FractoriumInstaller/Product.wxs index 1b211f4..b8a06e4 100644 --- a/Builds/MSVC/VS2010/FractoriumInstaller/Product.wxs +++ b/Builds/MSVC/VS2010/FractoriumInstaller/Product.wxs @@ -1,6 +1,6 @@ - + @@ -13,7 +13,7 @@ - + ::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way. #define ISAAC_SIZE 4 diff --git a/Source/Ember/Renderer.cpp b/Source/Ember/Renderer.cpp index 5311569..8abfbab 100644 --- a/Source/Ember/Renderer.cpp +++ b/Source/Ember/Renderer.cpp @@ -383,8 +383,7 @@ eRenderStatus Renderer::Run(vector& finalImage, doubl m_LastTemporalSample = 0; m_LastIter = 0; m_LastIterPercent = 0; - m_Stats.m_Iters = 0; - m_Stats.m_Badvals = 0; + m_Stats.Clear(); m_Gamma = 0; m_Vibrancy = 0;//Accumulate these after each temporal sample. m_VibGamCount = 0; @@ -541,6 +540,7 @@ eRenderStatus Renderer::Run(vector& finalImage, doubl m_LastIter += stats.m_Iters;//Sum of iter count of all threads, reset each temporal sample. m_Stats.m_Iters += stats.m_Iters;//Sum of iter count of all threads, cumulative from beginning to end. m_Stats.m_Badvals += stats.m_Badvals; + m_Stats.m_IterMs += stats.m_IterMs; //After each temporal sample, accumulate these. //Allow for incremental rendering by only taking action if the iter loop for this temporal sample is completely done. @@ -668,7 +668,7 @@ AccumOnly: if (AccumulatorToFinalImage(finalImage, finalOffset) == RENDER_OK) { - m_Stats.m_RenderSeconds = m_RenderTimer.Toc() / 1000.0;//Record total time from the very beginning to the very end, including all intermediate calls. + m_Stats.m_RenderMs = m_RenderTimer.Toc();//Record total time from the very beginning to the very end, including all intermediate calls. //Even though the ember changes throughought the inner loops because of interpolation, it's probably ok to assign here. //This will hold the last interpolated value (even though spatial and temporal filters were created based off of one of the first interpolated values). @@ -722,7 +722,7 @@ EmberImageComments Renderer::ImageComments(unsigned int printEditDep comments.m_Badvals = ss.str(); ss.str(""); ss << m_Stats.m_Iters; comments.m_NumIters = ss.str(); ss.str("");//Total iters. - ss << m_Stats.m_RenderSeconds; + ss << (m_Stats.m_RenderMs / 1000.0); comments.m_Runtime = ss.str();//Number of seconds for iterating, accumulating and filtering. return comments; @@ -1570,6 +1570,7 @@ template EmberStats Renderer::Iterate(unsigned __int64 iterCount, unsigned int pass, unsigned int temporalSample) { //Timing t2(4); + m_IterTimer.Tic(); unsigned int fuse = EarlyClip() ? 100 : 15;//EarlyClip was one way of detecting a later version of flam3, so it used 100 which is a better value. unsigned __int64 totalItersPerThread = (unsigned __int64)ceil((double)iterCount / (double)m_ThreadsToUse); double percent, etaMs; @@ -1663,7 +1664,8 @@ EmberStats Renderer::Iterate(unsigned __int64 iterCount, unsigned in #endif stats.m_Iters = std::accumulate(m_SubBatch.begin(), m_SubBatch.end(), 0ULL);//Sum of iter count of all threads. - stats.m_Badvals += std::accumulate(m_BadVals.begin(), m_BadVals.end(), 0ULL); + stats.m_Badvals = std::accumulate(m_BadVals.begin(), m_BadVals.end(), 0ULL); + stats.m_IterMs = m_IterTimer.Toc(); //t2.Toc(__FUNCTION__); return stats; } diff --git a/Source/Ember/Renderer.h b/Source/Ember/Renderer.h index c22e88f..ac0f202 100644 --- a/Source/Ember/Renderer.h +++ b/Source/Ember/Renderer.h @@ -58,14 +58,20 @@ public: /// Constructor which sets all values to 0. /// EmberStats() + { + Clear(); + } + + void Clear() { m_Iters = 0; m_Badvals = 0; - m_RenderSeconds = 0; + m_IterMs = 0; + m_RenderMs = 0; } unsigned __int64 m_Iters, m_Badvals; - double m_RenderSeconds; + double m_IterMs, m_RenderMs; }; /// @@ -403,7 +409,7 @@ protected: vector> m_Rand; tbb::task_group m_TaskGroup; CriticalSection m_RenderingCs, m_AccumCs, m_FinalAccumCs, m_ResizeCs; - Timing m_RenderTimer, m_ProgressTimer; + Timing m_RenderTimer, m_IterTimer, m_ProgressTimer; EmberToXml m_EmberToXml; }; diff --git a/Source/EmberAnimate/EmberAnimate.cpp b/Source/EmberAnimate/EmberAnimate.cpp index f7a0dd0..3164fb9 100644 --- a/Source/EmberAnimate/EmberAnimate.cpp +++ b/Source/EmberAnimate/EmberAnimate.cpp @@ -183,6 +183,9 @@ bool EmberAnimate(EmberOptions& opt) if (i > 0 && embers[i].m_Time <= embers[i - 1].m_Time) unsorted = true; + if (opt.Supersample() > 0) + embers[i].m_Supersample = opt.Supersample(); + embers[i].m_Quality *= T(opt.QualityScale()); embers[i].m_FinalRasW = (unsigned int)((T)embers[i].m_FinalRasW * opt.SizeScale()); embers[i].m_FinalRasH = (unsigned int)((T)embers[i].m_FinalRasH * opt.SizeScale()); @@ -244,6 +247,7 @@ bool EmberAnimate(EmberOptions& opt) os.imbue(std::locale("")); renderer->SetEmber(embers); renderer->EarlyClip(opt.EarlyClip()); + renderer->YAxisUp(opt.YAxisUp()); renderer->LockAccum(opt.LockAccum()); renderer->InsertPalette(opt.InsertPalette()); renderer->SubBatchSize(opt.SubBatchSize()); @@ -296,11 +300,13 @@ bool EmberAnimate(EmberOptions& opt) comments = renderer->ImageComments(opt.PrintEditDepth(), opt.IntPalette(), opt.HexPalette()); stats = renderer->Stats(); os.str(""); - os << comments.m_NumIters << "/" << renderer->TotalIterCount() << " (" << std::fixed << std::setprecision(2) << ((double)stats.m_Iters/(double)renderer->TotalIterCount() * 100) << "%)"; + os << comments.m_NumIters << " / " << renderer->TotalIterCount() << " (" << std::fixed << std::setprecision(2) << ((double)stats.m_Iters/(double)renderer->TotalIterCount() * 100) << "%)"; VerbosePrint("\nIters ran/requested: " + os.str()); VerbosePrint("Bad values: " << stats.m_Badvals); - VerbosePrint("Render time: " + t.Format(stats.m_RenderSeconds * 1000)); + VerbosePrint("Render time: " + t.Format(stats.m_RenderMs)); + VerbosePrint("Pure iter time: " + t.Format(stats.m_IterMs)); + VerbosePrint("Iters/sec: " << unsigned __int64(stats.m_Iters / (stats.m_IterMs / 1000.0)) << endl); VerbosePrint("Writing " + filename); if ((opt.Format() == "jpg" || opt.Format() == "bmp") && renderer->NumChannels() == 4) diff --git a/Source/EmberAnimate/EmberAnimate.rc b/Source/EmberAnimate/EmberAnimate.rc index 6bd8ff9..1ed1ed6 100644 --- a/Source/EmberAnimate/EmberAnimate.rc +++ b/Source/EmberAnimate/EmberAnimate.rc @@ -49,8 +49,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,4,1,1 - PRODUCTVERSION 0,4,1,1 + FILEVERSION 0,4,1,2 + PRODUCTVERSION 0,4,1,2 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -67,12 +67,12 @@ BEGIN BEGIN VALUE "CompanyName", "Open Source" VALUE "FileDescription", "Renders fractal flames as animations with motion blur" - VALUE "FileVersion", "0.4.1.1" + VALUE "FileVersion", "0.4.1.2" VALUE "InternalName", "EmberAnimate.rc" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "OriginalFilename", "EmberAnimate.rc" VALUE "ProductName", "Ember Animate" - VALUE "ProductVersion", "0.4.1.1" + VALUE "ProductVersion", "0.4.1.2" END END BLOCK "VarFileInfo" diff --git a/Source/EmberCL/RendererCL.cpp b/Source/EmberCL/RendererCL.cpp index 28fc380..8871e8e 100644 --- a/Source/EmberCL/RendererCL.cpp +++ b/Source/EmberCL/RendererCL.cpp @@ -616,6 +616,8 @@ EmberStats RendererCL::Iterate(unsigned __int64 iterCount, unsigned int pass, if (b) { + m_IterTimer.Tic();//Tic() here to avoid including build time in iter time measurement. + if (m_Stats.m_Iters == 0)//Only reset the call count on the beginning of a new render. Do not reset on KEEP_ITERATING. m_Calls = 0; @@ -623,6 +625,8 @@ EmberStats RendererCL::Iterate(unsigned __int64 iterCount, unsigned int pass, if (!b || stats.m_Iters == 0)//If no iters were executed, something went catastrophically wrong. m_Abort = true; + + stats.m_IterMs = m_IterTimer.Toc(); } else { diff --git a/Source/EmberCommon/EmberOptions.h b/Source/EmberCommon/EmberOptions.h index a41e633..33a2b60 100644 --- a/Source/EmberCommon/EmberOptions.h +++ b/Source/EmberCommon/EmberOptions.h @@ -39,6 +39,7 @@ enum eOptionIDs //Boolean args. OPT_OPENCL, OPT_EARLYCLIP, + OPT_POS_Y_UP, OPT_TRANSPARENCY, OPT_NAME_ENABLE, OPT_INT_PALETTE, @@ -59,6 +60,7 @@ enum eOptionIDs OPT_SEED, OPT_NTHREADS, OPT_STRIPS, + OPT_SUPERSAMPLE, OPT_BITS, OPT_BPC, OPT_SBS, @@ -278,9 +280,10 @@ public: //Execution bools. INITBOOLOPTION(EmberCL, Eob(OPT_USE_ALL, OPT_OPENCL, _T("--opencl"), false, SO_NONE, "\t--opencl Use OpenCL renderer (EmberCL) for rendering [default: false].\n")); INITBOOLOPTION(EarlyClip, Eob(OPT_USE_ALL, 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(Transparency, Eob(OPT_RENDER_ANIM, OPT_TRANSPARENCY, _T("--transparency"), false, SO_NONE, "\t--transparency Include alpha channel in final output [default: false except for PNG].\n")); + INITBOOLOPTION(YAxisUp, Eob(OPT_USE_ALL, 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(OPT_USE_ALL, OPT_TRANSPARENCY, _T("--transparency"), false, SO_NONE, "\t--transparency Include alpha channel in final output [default: false except for PNG].\n")); INITBOOLOPTION(NameEnable, Eob(OPT_USE_RENDER, 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(IntPalette, Eob(OPT_USE_ALL, OPT_INT_PALETTE, _T("--intpalette"), false, SO_NONE, "\t--intpalette Force palette RGB values to be integers [default: false (float)].\n")); + INITBOOLOPTION(IntPalette, Eob(OPT_RENDER_ANIM, OPT_INT_PALETTE, _T("--intpalette"), false, SO_NONE, "\t--intpalette Force palette RGB values to be integers [default: false (float)].\n")); INITBOOLOPTION(HexPalette, Eob(OPT_USE_ALL, OPT_HEX_PALETTE, _T("--hex_palette"), true, SO_NONE, "\t--hex_palette Force palette RGB values to be hex [default: true].\n")); INITBOOLOPTION(InsertPalette, Eob(OPT_RENDER_ANIM, 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(OPT_RENDER_ANIM, OPT_JPEG_COMMENTS, _T("--enable_jpeg_comments"), true, SO_NONE, "\t--enable_jpeg_comments Enables comments in the jpeg header [default: true].\n")); @@ -296,11 +299,12 @@ public: INITINTOPTION(Symmetry, Eoi(OPT_USE_GENOME, OPT_SYMMETRY, _T("--symmetry"), 0, SO_REQ_SEP, "\t--symmetry= Set symmetry of result [default: 0].\n")); INITINTOPTION(SheepGen, Eoi(OPT_USE_GENOME, OPT_SHEEP_GEN, _T("--sheep_gen"), -1, SO_REQ_SEP, "\t--sheep_gen= Sheep generation of this flame [default: -1].\n")); INITINTOPTION(SheepId, Eoi(OPT_USE_GENOME, OPT_SHEEP_ID, _T("--sheep_id"), -1, SO_REQ_SEP, "\t--sheep_id= Sheep ID of this flame [default: -1].\n")); - INITUINTOPTION(Platform, Eou(OPT_RENDER_ANIM, OPT_OPENCL_PLATFORM, _T("--platform"), 0, SO_REQ_SEP, "\t--platform The OpenCL platform index to use [default: 0].\n")); - INITUINTOPTION(Device, Eou(OPT_RENDER_ANIM, OPT_OPENCL_DEVICE, _T("--device"), 0, SO_REQ_SEP, "\t--device The OpenCL device index within the specified platform to use [default: 0].\n")); + INITUINTOPTION(Platform, Eou(OPT_USE_ALL, OPT_OPENCL_PLATFORM, _T("--platform"), 0, SO_REQ_SEP, "\t--platform The OpenCL platform index to use [default: 0].\n")); + INITUINTOPTION(Device, Eou(OPT_USE_ALL, OPT_OPENCL_DEVICE, _T("--device"), 0, SO_REQ_SEP, "\t--device The OpenCL device index within the specified platform to use [default: 0].\n")); INITUINTOPTION(Seed, Eou(OPT_USE_ALL, 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(OPT_USE_ALL, 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(OPT_USE_RENDER, 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(OPT_RENDER_ANIM, 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(BitsPerChannel, Eou(OPT_RENDER_ANIM, OPT_BPC, _T("--bpc"), 8, SO_REQ_SEP, "\t--bpc= Bits per channel. 8 or 16 for PNG, 8 for all others [default: 8].\n")); INITUINTOPTION(SubBatchSize, Eou(OPT_USE_ALL, OPT_SBS, _T("--sub_batch_size"), 10240, SO_REQ_SEP, "\t--sub_batch_size= The chunk size that iterating will be broken into [default: 10k].\n")); INITUINTOPTION(Bits, Eou(OPT_USE_ALL, OPT_BITS, _T("--bits"), 33, SO_REQ_SEP, "\t--bits= Determines the types used for the histogram and accumulator [default: 33].\n" @@ -309,7 +313,7 @@ public: "\t\t\t\t\t64: Histogram: double, Accumulator: double.\n")); INITUINTOPTION(PrintEditDepth, Eou(OPT_USE_ALL, 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(OPT_USE_ALL, OPT_JPEG, _T("--jpeg"), 95, SO_REQ_SEP, "\t--jpeg= Jpeg quality 0-100 for compression [default: 95].\n")); + INITUINTOPTION(JpegQuality, Eou(OPT_RENDER_ANIM, OPT_JPEG, _T("--jpeg"), 95, SO_REQ_SEP, "\t--jpeg= Jpeg quality 0-100 for compression [default: 95].\n")); INITUINTOPTION(FirstFrame, Eou(OPT_USE_ANIMATE, OPT_BEGIN, _T("--begin"), UINT_MAX, SO_REQ_SEP, "\t--begin= Time of first frame to render [default: first time specified in file].\n")); INITUINTOPTION(LastFrame, Eou(OPT_USE_ANIMATE, OPT_END, _T("--end"), UINT_MAX, SO_REQ_SEP, "\t--end= Time of last frame to render [default: last time specified in the input file].\n")); INITUINTOPTION(Time, Eou(OPT_ANIM_GENOME, OPT_TIME, _T("--time"), 0, SO_REQ_SEP, "\t--time= Time of first and last frame (ie do one frame).\n")); @@ -322,10 +326,10 @@ public: INITUINTOPTION(MaxXforms, Eou(OPT_USE_GENOME, OPT_MAX_XFORMS, _T("--maxxforms"), UINT_MAX, SO_REQ_SEP, "\t--maxxforms= The maximum number of xforms allowed in the final output.\n")); //Double. - INITDOUBLEOPTION(SizeScale, Eod(OPT_USE_ALL, OPT_SS, _T("--ss"), 1, SO_REQ_SEP, "\t--ss= Size scale. All dimensions are scaled by this amount [default: 1.0].\n")); - INITDOUBLEOPTION(QualityScale, Eod(OPT_USE_ALL, OPT_QS, _T("--qs"), 1, SO_REQ_SEP, "\t--qs= Quality scale. All quality values are scaled by this amount [default: 1.0].\n")); + INITDOUBLEOPTION(SizeScale, Eod(OPT_RENDER_ANIM, OPT_SS, _T("--ss"), 1, SO_REQ_SEP, "\t--ss= Size scale. All dimensions are scaled by this amount [default: 1.0].\n")); + INITDOUBLEOPTION(QualityScale, Eod(OPT_RENDER_ANIM, OPT_QS, _T("--qs"), 1, SO_REQ_SEP, "\t--qs= Quality scale. All quality values are scaled by this amount [default: 1.0].\n")); INITDOUBLEOPTION(AspectRatio, Eod(OPT_USE_ALL, OPT_PIXEL_ASPECT, _T("--pixel_aspect"), 1, SO_REQ_SEP, "\t--pixel_aspect= Aspect ratio of pixels (width over height), eg. 0.90909 for NTSC [default: 1.0].\n")); - INITDOUBLEOPTION(Stagger, Eod(OPT_USE_ALL, OPT_STAGGER, _T("--stagger"), 0, SO_REQ_SEP, "\t--stagger= Affects simultaneity of xform interpolation during flame interpolation.\n" + INITDOUBLEOPTION(Stagger, Eod(OPT_USE_GENOME, OPT_STAGGER, _T("--stagger"), 0, SO_REQ_SEP, "\t--stagger= Affects simultaneity of xform interpolation during flame interpolation.\n" "\t Represents how 'separate' the xforms are interpolated. Set to 1 for each\n" "\t xform to be interpolated individually, fractions control interpolation overlap [default: 0].\n")); INITDOUBLEOPTION(AvgThresh, Eod(OPT_USE_GENOME, OPT_AVG_THRESH, _T("--avg"), 20.0, SO_REQ_SEP, "\t--avg= Minimum average pixel channel sum (r + g + b) threshold from 0 - 765. Ignored if sequence, inter or rotate were specified [default: 20].\n")); @@ -338,10 +342,10 @@ public: //String. INITSTRINGOPTION(IsaacSeed, Eos(OPT_USE_ALL, OPT_ISAAC_SEED, _T("--isaac_seed"), "", SO_REQ_SEP, "\t--isaac_seed= Character-based seed for the random number generator [default: random].\n")); - INITSTRINGOPTION(Input, Eos(OPT_USE_ALL, OPT_IN, _T("--in"), "", SO_REQ_SEP, "\t--in= Name of the input file.\n")); - INITSTRINGOPTION(Out, Eos(OPT_USE_ALL, OPT_OUT, _T("--out"), "", SO_REQ_SEP, "\t--out= Name of a single output file. Not recommended when rendering more than one image.\n")); - INITSTRINGOPTION(Prefix, Eos(OPT_USE_ALL, OPT_PREFIX, _T("--prefix"), "", SO_REQ_SEP, "\t--prefix= Prefix to prepend to all output files.\n")); - INITSTRINGOPTION(Suffix, Eos(OPT_USE_ALL, OPT_SUFFIX, _T("--suffix"), "", SO_REQ_SEP, "\t--suffix= Suffix to append to all output files.\n")); + INITSTRINGOPTION(Input, Eos(OPT_RENDER_ANIM, OPT_IN, _T("--in"), "", SO_REQ_SEP, "\t--in= Name of the input file.\n")); + INITSTRINGOPTION(Out, Eos(OPT_RENDER_ANIM, OPT_OUT, _T("--out"), "", SO_REQ_SEP, "\t--out= Name of a single output file. Not recommended when rendering more than one image.\n")); + INITSTRINGOPTION(Prefix, Eos(OPT_RENDER_ANIM, OPT_PREFIX, _T("--prefix"), "", SO_REQ_SEP, "\t--prefix= Prefix to prepend to all output files.\n")); + INITSTRINGOPTION(Suffix, Eos(OPT_RENDER_ANIM, OPT_SUFFIX, _T("--suffix"), "", SO_REQ_SEP, "\t--suffix= Suffix to append to all output files.\n")); INITSTRINGOPTION(Format, Eos(OPT_RENDER_ANIM, OPT_FORMAT, _T("--format"), "png", SO_REQ_SEP, "\t--format= Format of the output file. Valid values are: bmp, jpg, png, ppm [default: jpg].\n")); INITSTRINGOPTION(PalettePath, Eos(OPT_USE_ALL, OPT_PALETTE_FILE, _T("--flam3_palettes"), "flam3-palettes.xml", SO_REQ_SEP, "\t--flam3_palettes= Path and name of the palette file [default: flam3-palettes.xml].\n")); INITSTRINGOPTION(PaletteImage, Eos(OPT_USE_ALL, OPT_PALETTE_IMAGE, _T("--image"), "", SO_REQ_SEP, "\t--image= Replace palette with png, jpg, or ppm image.\n")); @@ -409,6 +413,7 @@ public: PARSEBOOLOPTION(OPT_DUMP_OPENCL_INFO, OpenCLInfo); PARSEBOOLOPTION(OPT_OPENCL, EmberCL); PARSEBOOLOPTION(OPT_EARLYCLIP, EarlyClip); + PARSEBOOLOPTION(OPT_POS_Y_UP, YAxisUp); PARSEBOOLOPTION(OPT_TRANSPARENCY, Transparency); PARSEBOOLOPTION(OPT_NAME_ENABLE, NameEnable); PARSEBOOLOPTION(OPT_INT_PALETTE, IntPalette); @@ -431,6 +436,7 @@ public: PARSEUINTOPTION(OPT_SEED, Seed); PARSEUINTOPTION(OPT_NTHREADS, ThreadCount); PARSEUINTOPTION(OPT_STRIPS, Strips); + PARSEUINTOPTION(OPT_SUPERSAMPLE, Supersample); PARSEUINTOPTION(OPT_BITS, Bits); PARSEUINTOPTION(OPT_BPC, BitsPerChannel); PARSEUINTOPTION(OPT_SBS, SubBatchSize); @@ -617,6 +623,7 @@ public: EmberOptionEntry EmberCL;//Value bool. EmberOptionEntry EarlyClip; + EmberOptionEntry YAxisUp; EmberOptionEntry Transparency; EmberOptionEntry NameEnable; EmberOptionEntry IntPalette; @@ -639,6 +646,7 @@ public: EmberOptionEntry Seed; EmberOptionEntry ThreadCount; EmberOptionEntry Strips; + EmberOptionEntry Supersample; EmberOptionEntry BitsPerChannel; EmberOptionEntry SubBatchSize; EmberOptionEntry Bits; diff --git a/Source/EmberGenome/EmberGenome.cpp b/Source/EmberGenome/EmberGenome.cpp index ea03e5e..98cba97 100644 --- a/Source/EmberGenome/EmberGenome.cpp +++ b/Source/EmberGenome/EmberGenome.cpp @@ -101,8 +101,6 @@ bool EmberGenome(EmberOptions& opt) { if (opt.ThreadCount() != 0) renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : NULL); - - renderer->LockAccum(opt.LockAccum()); } else { @@ -494,8 +492,11 @@ bool EmberGenome(EmberOptions& opt) //Repeat. renderer->EarlyClip(opt.EarlyClip()); + renderer->YAxisUp(opt.YAxisUp()); + renderer->LockAccum(opt.LockAccum()); renderer->SubBatchSize(opt.SubBatchSize()); renderer->PixelAspectRatio(T(opt.AspectRatio())); + renderer->Transparency(opt.Transparency()); if (opt.Repeat() == 0) { diff --git a/Source/EmberGenome/EmberGenome.rc b/Source/EmberGenome/EmberGenome.rc index 12be5b4..593cad0 100644 --- a/Source/EmberGenome/EmberGenome.rc +++ b/Source/EmberGenome/EmberGenome.rc @@ -49,8 +49,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,4,1,1 - PRODUCTVERSION 0,4,1,1 + FILEVERSION 0,4,1,2 + PRODUCTVERSION 0,4,1,2 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -67,12 +67,12 @@ BEGIN BEGIN VALUE "CompanyName", "Open Source" VALUE "FileDescription", "Manipulates fractal flames parameter files" - VALUE "FileVersion", "0.4.1.1" + VALUE "FileVersion", "0.4.1.2" VALUE "InternalName", "EmberGenome.rc" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "OriginalFilename", "EmberGenome.rc" VALUE "ProductName", "Ember Genome" - VALUE "ProductVersion", "0.4.1.1" + VALUE "ProductVersion", "0.4.1.2" END END BLOCK "VarFileInfo" diff --git a/Source/EmberRender/EmberRender.cpp b/Source/EmberRender/EmberRender.cpp index 146ca40..b3cfdd4 100644 --- a/Source/EmberRender/EmberRender.cpp +++ b/Source/EmberRender/EmberRender.cpp @@ -143,6 +143,7 @@ bool EmberRender(EmberOptions& opt) //Final setup steps before running. os.imbue(std::locale("")); renderer->EarlyClip(opt.EarlyClip()); + renderer->YAxisUp(opt.YAxisUp()); renderer->LockAccum(opt.LockAccum()); renderer->InsertPalette(opt.InsertPalette()); renderer->SubBatchSize(opt.SubBatchSize()); @@ -159,6 +160,9 @@ bool EmberRender(EmberOptions& opt) else VerbosePrint(endl); + if (opt.Supersample() > 0) + embers[i].m_Supersample = opt.Supersample(); + embers[i].m_TemporalSamples = 1;//Force temporal samples to 1 for render. embers[i].m_Quality *= T(opt.QualityScale()); embers[i].m_FinalRasW = (unsigned int)((T)embers[i].m_FinalRasW * opt.SizeScale()); @@ -294,11 +298,13 @@ bool EmberRender(EmberOptions& opt) comments = renderer->ImageComments(opt.PrintEditDepth(), opt.IntPalette(), opt.HexPalette()); stats = renderer->Stats(); os.str(""); - os << comments.m_NumIters << "/" << renderer->TotalIterCount() << " (" << std::fixed << std::setprecision(2) << ((double)stats.m_Iters/(double)renderer->TotalIterCount() * 100) << "%)"; + os << comments.m_NumIters << " / " << renderer->TotalIterCount() << " (" << std::fixed << std::setprecision(2) << ((double)stats.m_Iters/(double)renderer->TotalIterCount() * 100) << "%)"; VerbosePrint("\nIters ran/requested: " + os.str()); VerbosePrint("Bad values: " << stats.m_Badvals); - VerbosePrint("Render time: " + t.Format(stats.m_RenderSeconds * 1000)); + VerbosePrint("Render time: " + t.Format(stats.m_RenderMs)); + VerbosePrint("Pure iter time: " + t.Format(stats.m_IterMs)); + VerbosePrint("Iters/sec: " << unsigned __int64(stats.m_Iters / (stats.m_IterMs / 1000.0)) << endl); VerbosePrint("Writing " + filename); if ((opt.Format() == "jpg" || opt.Format() == "bmp") && renderer->NumChannels() == 4) diff --git a/Source/EmberRender/EmberRender.rc b/Source/EmberRender/EmberRender.rc index 0ee29ce..530af1f 100644 --- a/Source/EmberRender/EmberRender.rc +++ b/Source/EmberRender/EmberRender.rc @@ -49,8 +49,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,4,1,1 - PRODUCTVERSION 0,4,1,1 + FILEVERSION 0,4,1,2 + PRODUCTVERSION 0,4,1,2 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -67,12 +67,12 @@ BEGIN BEGIN VALUE "CompanyName", "Open Source" VALUE "FileDescription", "Renders fractal flames as single images" - VALUE "FileVersion", "0.4.1.1" + VALUE "FileVersion", "0.4.1.2" VALUE "InternalName", "EmberRender.rc" VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3" VALUE "OriginalFilename", "EmberRender.rc" VALUE "ProductName", "Ember Render" - VALUE "ProductVersion", "0.4.1.1" + VALUE "ProductVersion", "0.4.1.2" END END BLOCK "VarFileInfo" diff --git a/Source/Fractorium/AboutDialog.ui b/Source/Fractorium/AboutDialog.ui index 5382776..c14ff39 100644 --- a/Source/Fractorium/AboutDialog.ui +++ b/Source/Fractorium/AboutDialog.ui @@ -52,7 +52,7 @@ - <html><head/><body><p align="center"><br/><span style=" font-size:12pt;">Fractorium 0.4.1.1 Beta</span></p><p align="center"><span style=" font-size:10pt;"><br/>A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><span style=" font-size:10pt;">Matt Feemster</span></p></body></html> + <html><head/><body><p align="center"><br/><span style=" font-size:12pt;">Fractorium 0.4.1.2 Beta</span></p><p align="center"><span style=" font-size:10pt;"><br/>A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><span style=" font-size:10pt;">Matt Feemster</span></p></body></html> Qt::RichText diff --git a/Source/Fractorium/FinalRenderEmberController.cpp b/Source/Fractorium/FinalRenderEmberController.cpp index a2b147e..7628741 100644 --- a/Source/Fractorium/FinalRenderEmberController.cpp +++ b/Source/Fractorium/FinalRenderEmberController.cpp @@ -200,7 +200,6 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD for (i = 0; i < m_EmberFile.m_Embers.size() && m_Run; i++) { m_Renderer->Reset();//Have to manually set this since the ember is not set each time through. - m_PureIterTime = 0; m_RenderTimer.Tic();//Toc() is called in the progress function. if (m_Renderer->Run(m_FinalImage, i) != RENDER_OK) @@ -223,7 +222,6 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD for (i = 0; i < m_EmberFile.m_Embers.size() && m_Run; i++) { m_Renderer->SetEmber(m_EmberFile.m_Embers[i]); - m_PureIterTime = 0; m_RenderTimer.Tic();//Toc() is called in the progress function. if (m_Renderer->Run(m_FinalImage) != RENDER_OK) @@ -241,7 +239,6 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD ResetProgress(); m_Ember.m_TemporalSamples = 1; m_Renderer->SetEmber(m_Ember); - m_PureIterTime = 0; memset(m_FinalImage.data(), 0, m_FinalImage.size() * sizeof(m_FinalImage[0])); m_RenderTimer.Tic();//Toc() is called in the progress function. @@ -293,12 +290,7 @@ int FinalRenderEmberController::ProgressFunc(Ember& ember, void* foo, doub int intFract = (int)fraction; if (stage == 0) - { QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderIterationProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, intFract)); - - if (intFract == 100) - m_PureIterTime = m_RenderTimer.Toc(); - } else if (stage == 1) QMetaObject::invokeMethod(m_FinalRender->ui.FinalRenderFilteringProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, intFract)); else if (stage == 2) @@ -312,7 +304,7 @@ int FinalRenderEmberController::ProgressFunc(Ember& ember, void* foo, doub QFileInfo original(filename); EmberStats stats = m_Renderer->Stats(); QString iters = QLocale(QLocale::English).toString(stats.m_Iters); - QString itersPerSec = QLocale(QLocale::English).toString(unsigned __int64(stats.m_Iters / (m_PureIterTime / 1000.0))); + QString itersPerSec = QLocale(QLocale::English).toString(unsigned __int64(stats.m_Iters / (stats.m_IterMs / 1000.0))); if (m_GuiState.m_DoAll && m_EmberFile.m_Embers.size() > 1) filename = original.absolutePath() + QDir::separator() + m_GuiState.m_Prefix + QString::fromStdString(m_EmberFile.m_Embers[m_FinishedImageCount].m_Name) + m_GuiState.m_Suffix + "." + m_GuiState.m_DoAllExt; diff --git a/Source/Fractorium/FinalRenderEmberController.h b/Source/Fractorium/FinalRenderEmberController.h index 373d7d0..dedaf29 100644 --- a/Source/Fractorium/FinalRenderEmberController.h +++ b/Source/Fractorium/FinalRenderEmberController.h @@ -75,7 +75,6 @@ protected: bool m_PreviewRun; unsigned int m_ImageCount; unsigned int m_FinishedImageCount; - double m_PureIterTime; QFuture m_Result; QFuture m_FinalPreviewResult; diff --git a/Source/Fractorium/Fractorium.rc b/Source/Fractorium/Fractorium.rc index a4c5e63..788b6ac 100644 Binary files a/Source/Fractorium/Fractorium.rc and b/Source/Fractorium/Fractorium.rc differ