2014-07-08 03:11:14 -04:00
# include "EmberPch.h"
# include "Renderer.h"
namespace EmberNs
{
2017-07-05 02:08:06 -04:00
/// <summary>
/// Constructor that allocates various pieces of memory.
/// </summary>
template < typename T , typename bucketT >
Renderer < T , bucketT > : : Renderer ( )
{
2017-07-22 16:43:35 -04:00
//Use a very large number regardless of the size of the output pixels. This should be sufficient granularity, even though
//it's technically less than the number of distinct values representable by a 32-bit float.
2021-04-19 23:07:24 -04:00
m_Csa . resize ( static_cast < size_t > ( CURVES_LENGTH ) ) ;
2018-09-15 06:11:12 -04:00
//Ensure the renderer at least has sane values for the camera upon startup.
//This is needed because due to timing/threading disconnects, the GUI can use the camera
//values before the render has started, which will lead to corrupt values.
Ember < T > ember ;
2018-09-27 20:02:34 -04:00
SetEmber ( ember , eProcessAction : : NOTHING , false ) ;
//Manually call these instead of passing true to SetEmber() because it would have created the spatial filter
//which we don't want to do until rendering starts (this is so the derived RendererCL can properly create the needed buffers).
ComputeBounds ( ) ;
ComputeQuality ( ) ;
ComputeCamera ( ) ;
2017-07-05 02:08:06 -04:00
}
2014-07-08 03:11:14 -04:00
/// <summary>
2014-10-14 11:53:15 -04:00
/// Non-virtual processing functions.
2014-07-08 03:11:14 -04:00
/// </summary>
/// <summary>
2014-10-14 11:53:15 -04:00
/// Add an ember to the end of the embers vector and reset the rendering process.
/// Reset the rendering process.
2014-07-08 03:11:14 -04:00
/// </summary>
2014-10-14 11:53:15 -04:00
/// <param name="ember">The ember to add</param>
2014-07-08 03:11:14 -04:00
template < typename T , typename bucketT >
2014-10-14 11:53:15 -04:00
void Renderer < T , bucketT > : : AddEmber ( Ember < T > & ember )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
ChangeVal ( [ & ]
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
m_Embers . push_back ( ember ) ;
2014-09-10 01:41:26 -04:00
2014-10-14 11:53:15 -04:00
if ( m_Embers . size ( ) = = 1 )
m_Ember = m_Embers [ 0 ] ;
2015-12-31 19:00:36 -05:00
} , eProcessAction : : FULL_RENDER ) ;
2020-03-18 22:34:56 -04:00
Prepare ( ) ;
2014-10-14 11:53:15 -04:00
}
/// <summary>
/// Set the m_Iterator member to point to the appropriate
/// iterator based on whether the ember currently being rendered
/// contains xaos.
/// After assigning, initialize the xform selection buffer.
/// </summary>
/// <returns>True if assignment and distribution initialization succeeded, else false.</returns>
template < typename T , typename bucketT >
bool Renderer < T , bucketT > : : AssignIterator ( )
{
//Setup iterator and distributions.
//Both iterator types were setup in the constructor (add more in the future if needed).
//So simply assign the pointer to the correct type and re-initialize its distributions
//based on the current ember.
if ( XaosPresent ( ) )
m_Iterator = m_XaosIterator . get ( ) ;
else
m_Iterator = m_StandardIterator . get ( ) ;
//Timing t;
return m_Iterator - > InitDistributions ( m_Ember ) ;
//t.Toc("Distrib creation");
}
/// <summary>
/// Virtual processing functions overriden from RendererBase.
/// </summary>
2020-03-18 22:34:56 -04:00
/// <summary>
/// Prepare values for the filters, bounds, quality and camera.
/// </summary>
template < typename T , typename bucketT >
void Renderer < T , bucketT > : : Prepare ( )
{
bool b = false ;
CreateSpatialFilter ( b ) ;
CreateTemporalFilter ( b ) ;
ComputeBounds ( ) ;
ComputeQuality ( ) ;
ComputeCamera ( ) ;
m_CarToRas . UpdateCachedHalf ( m_CarToRas . CarHalfX ( ) , m_CarToRas . CarHalfY ( ) ) ;
}
2014-10-14 11:53:15 -04:00
/// <summary>
/// Compute the bounds of the histogram and density filtering buffers.
/// These are affected by the final requested dimensions, spatial and density
/// filter sizes and supersampling.
/// </summary>
template < typename T , typename bucketT >
void Renderer < T , bucketT > : : ComputeBounds ( )
{
2016-03-28 21:49:10 -04:00
//Original did a lot of work to compute a gutter that changes size based on various parameters, which seems to be of no benefit.
//It also prevents the renderer from only performing filtering or final accum based on a filter parameter change, since that
//change may have changed the gutter.
//By using a fixed gutter, a filter change can be applied without fully restarting iteration.
m_GutterWidth = 10 * Supersample ( ) ; //Should be enough to fully accommodate most spatial and density filter widths.
2014-10-14 11:53:15 -04:00
m_SuperRasW = ( Supersample ( ) * FinalRasW ( ) ) + ( 2 * m_GutterWidth ) ;
m_SuperRasH = ( Supersample ( ) * FinalRasH ( ) ) + ( 2 * m_GutterWidth ) ;
m_SuperSize = m_SuperRasW * m_SuperRasH ;
2014-07-08 03:11:14 -04:00
}
2015-03-21 18:27:37 -04:00
/// <summary>
/// Compute the scale based on the zoom, then the quality based on the computed scale.
/// This must be called before ComputeCamera() which will use scale.
/// </summary>
template < typename T , typename bucketT >
void Renderer < T , bucketT > : : ComputeQuality ( )
{
2021-04-19 23:07:24 -04:00
m_Scale = std : : pow ( static_cast < T > ( 2 ) , Zoom ( ) ) ;
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
m_ScaledQuality = Quality ( ) * SQR ( m_Scale ) ;
2015-03-21 18:27:37 -04:00
}
/// <summary>
/// Compute the camera.
/// This sets up the bounds of the cartesian plane that the raster bounds correspond to.
/// This must be called after ComputeBounds() which sets up the raster bounds.
/// </summary>
template < typename T , typename bucketT >
void Renderer < T , bucketT > : : ComputeCamera ( )
{
m_PixelsPerUnitX = PixelsPerUnit ( ) * m_Scale ;
m_PixelsPerUnitY = m_PixelsPerUnitX ;
m_PixelsPerUnitX / = PixelAspectRatio ( ) ;
T shift = 0 ;
2021-04-19 23:07:24 -04:00
T t0 = static_cast < T > ( m_GutterWidth ) / ( Supersample ( ) * m_PixelsPerUnitX ) ;
T t1 = static_cast < T > ( m_GutterWidth ) / ( Supersample ( ) * m_PixelsPerUnitY ) ;
2015-03-21 18:27:37 -04:00
//These go from ll to ur, moving from negative to positive.
2021-04-19 23:07:24 -04:00
m_LowerLeftX = CenterX ( ) - FinalRasW ( ) / m_PixelsPerUnitX / static_cast < T > ( 2 ) ;
m_LowerLeftY = CenterY ( ) - FinalRasH ( ) / m_PixelsPerUnitY / static_cast < T > ( 2 ) ;
2015-03-21 18:27:37 -04:00
m_UpperRightX = m_LowerLeftX + FinalRasW ( ) / m_PixelsPerUnitX ;
m_UpperRightY = m_LowerLeftY + FinalRasH ( ) / m_PixelsPerUnitY ;
T carLlX = m_LowerLeftX - t0 ;
T carLlY = m_LowerLeftY - t1 + shift ;
T carUrX = m_UpperRightX + t0 ;
T carUrY = m_UpperRightY + t1 + shift ;
m_RotMat . MakeID ( ) ;
2016-02-12 00:38:21 -05:00
m_RotMat . Rotate ( - Rotate ( ) * DEG_2_RAD_T ) ;
2015-03-21 18:27:37 -04:00
m_CarToRas . Init ( carLlX , carLlY , carUrX , carUrY , m_SuperRasW , m_SuperRasH , PixelAspectRatio ( ) ) ;
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Set the current ember.
/// This will also populate the vector of embers with a single element copy
/// of the ember passed in.
/// Temporal samples will be set to 1 since there's only a single ember.
/// </summary>
/// <param name="ember">The ember to assign</param>
/// <param name="action">The requested process action. Note that it's critical the user supply the proper value here.
2015-12-31 19:00:36 -05:00
/// For example: Changing dimensions without setting action to eProcessAction::FULL_RENDER will crash the program.
2014-07-08 03:11:14 -04:00
/// However, changing only the brightness and setting action to ACCUM_ONLY is perfectly fine.
2017-05-12 18:31:48 -04:00
/// <param name="prep">Whether to also compute bounds, camera, filters etc. This is useful when other code outside of this needs these values
/// before the render actually starts. Default: false.</param>
2014-07-08 03:11:14 -04:00
/// </param>
template < typename T , typename bucketT >
2017-05-12 18:31:48 -04:00
void Renderer < T , bucketT > : : SetEmber ( const Ember < T > & ember , eProcessAction action , bool prep )
2014-07-08 03:11:14 -04:00
{
ChangeVal ( [ & ]
2014-09-10 01:41:26 -04:00
{
2014-07-08 03:11:14 -04:00
m_Embers . clear ( ) ;
m_Embers . push_back ( ember ) ;
m_Embers [ 0 ] . m_TemporalSamples = 1 ; //Set temporal samples here to 1 because using the real value only makes sense when using a vector of Embers for animation.
m_Ember = m_Embers [ 0 ] ;
2016-04-03 21:55:12 -04:00
m_EmbersP = & m_Embers ;
2014-07-08 03:11:14 -04:00
} , action ) ;
2017-05-12 18:31:48 -04:00
if ( prep )
2020-03-18 22:34:56 -04:00
Prepare ( ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
2016-04-03 21:55:12 -04:00
/// Copy the embers in the passed in container to the internal vector of embers
/// and set the m_Ember member to a copy of the first element.
2014-07-08 03:11:14 -04:00
/// Reset the rendering process.
/// </summary>
2016-04-03 21:55:12 -04:00
/// <param name="embers">The container of embers to be copied</param>
2014-07-08 03:11:14 -04:00
template < typename T , typename bucketT >
2016-04-03 21:55:12 -04:00
template < typename C >
void Renderer < T , bucketT > : : SetEmber ( const C & embers )
2014-07-08 03:11:14 -04:00
{
ChangeVal ( [ & ]
{
2016-04-03 21:55:12 -04:00
CopyCont ( m_Embers , embers ) ;
m_EmbersP = & m_Embers ;
2014-07-08 03:11:14 -04:00
if ( ! m_Embers . empty ( ) )
m_Ember = m_Embers [ 0 ] ;
2020-03-18 22:34:56 -04:00
2015-12-31 19:00:36 -05:00
} , eProcessAction : : FULL_RENDER ) ;
2020-03-18 22:34:56 -04:00
Prepare ( ) ; //Always prepare with a collection.
2014-07-08 03:11:14 -04:00
}
2016-04-03 21:55:12 -04:00
/// <summary>
/// Move the embers in the passed in vector to the internal vector of embers
/// and set the m_Ember member to a copy of the first element.
/// Reset the rendering process.
/// This is preferred over SetEmber when the size of embers is large and/or
/// the caller no longer needs to use the argument after this function returns.
/// </summary>
/// <param name="embers">The vector of embers to be moved</param>
template < typename T , typename bucketT >
void Renderer < T , bucketT > : : MoveEmbers ( vector < Ember < T > > & embers )
{
ChangeVal ( [ & ]
{
m_Embers = std : : move ( embers ) ;
m_EmbersP = & m_Embers ;
if ( ! m_Embers . empty ( ) )
m_Ember = m_Embers [ 0 ] ;
2020-03-18 22:34:56 -04:00
2016-04-03 21:55:12 -04:00
} , eProcessAction : : FULL_RENDER ) ;
2020-03-18 22:34:56 -04:00
Prepare ( ) ;
2016-04-03 21:55:12 -04:00
}
template < typename T , typename bucketT >
void Renderer < T , bucketT > : : SetExternalEmbersPointer ( vector < Ember < T > > * embers )
{
ChangeVal ( [ & ]
{
m_Embers . clear ( ) ;
m_EmbersP = embers ;
if ( ! m_EmbersP - > empty ( ) )
m_Ember = ( * m_EmbersP ) [ 0 ] ;
2020-03-18 22:34:56 -04:00
2016-04-03 21:55:12 -04:00
} , eProcessAction : : FULL_RENDER ) ;
2020-03-18 22:34:56 -04:00
Prepare ( ) ;
2016-04-03 21:55:12 -04:00
}
2014-07-08 03:11:14 -04:00
/// <summary>
2014-10-14 11:53:15 -04:00
/// Create the density filter if the current filter parameters differ
/// from the last density filter created.
/// The filter will be deleted if the max DE radius is 0, in which case regular
/// log scale filtering will be used.
2014-07-08 03:11:14 -04:00
/// </summary>
2014-10-14 11:53:15 -04:00
/// <param name="newAlloc">True if a new filter instance was created, else false.</param>
/// <returns>True if the filter is not nullptr (whether a new one was created or not) or if max rad is 0, else false.</returns>
2014-07-08 03:11:14 -04:00
template < typename T , typename bucketT >
2014-10-14 11:53:15 -04:00
bool Renderer < T , bucketT > : : CreateDEFilter ( bool & newAlloc )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
//If they wanted DE, create it if needed, else clear the last DE filter which means we'll do regular log filtering after iters are done.
newAlloc = false ;
if ( m_Ember . m_MaxRadDE > 0 )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
//Use intelligent testing so it isn't created every time a new ember is passed in.
if ( ( ! m_DensityFilter . get ( ) ) | |
2015-12-31 19:00:36 -05:00
( m_Ember . m_MinRadDE ! = m_DensityFilter - > MinRad ( ) ) | |
( m_Ember . m_MaxRadDE ! = m_DensityFilter - > MaxRad ( ) ) | |
( m_Ember . m_CurveDE ! = m_DensityFilter - > Curve ( ) ) | |
( m_Ember . m_Supersample ! = m_DensityFilter - > Supersample ( ) ) )
2014-10-14 11:53:15 -04:00
{
2021-04-19 23:07:24 -04:00
m_DensityFilter = make_unique < DensityFilter < bucketT > > ( static_cast < bucketT > ( m_Ember . m_MinRadDE ) , static_cast < bucketT > ( m_Ember . m_MaxRadDE ) ,
static_cast < bucketT > ( m_Ember . m_CurveDE ) , m_Ember . m_Supersample ) ;
2014-10-14 11:53:15 -04:00
newAlloc = true ;
}
2014-07-08 03:11:14 -04:00
2014-10-14 11:53:15 -04:00
if ( newAlloc )
{
if ( ! m_DensityFilter . get ( ) ) { return false ; } //Did object creation succeed?
2015-12-31 19:00:36 -05:00
2014-10-14 11:53:15 -04:00
if ( ! m_DensityFilter - > Create ( ) ) { return false ; } //Object creation succeeded, did filter creation succeed?
}
2015-12-31 19:00:36 -05:00
else if ( ! m_DensityFilter - > Valid ( ) ) { return false ; } //Previously created, are values ok?
2014-10-14 11:53:15 -04:00
}
else
{
m_DensityFilter . reset ( ) ; //They want to do log filtering. Return true because even though the filter is being deleted, nothing went wrong.
}
return true ;
}
/// <summary>
/// Create the spatial filter if the current filter parameters differ
/// from the last spatial filter created.
/// </summary>
/// <param name="newAlloc">True if a new filter instance was created, else false.</param>
/// <returns>True if the filter is not nullptr (whether a new one was created or not), else false.</returns>
template < typename T , typename bucketT >
bool Renderer < T , bucketT > : : CreateSpatialFilter ( bool & newAlloc )
{
newAlloc = false ;
//Use intelligent testing so it isn't created every time a new ember is passed in.
if ( ( ! m_SpatialFilter . get ( ) ) | |
2015-12-31 19:00:36 -05:00
( m_Ember . m_SpatialFilterType ! = m_SpatialFilter - > FilterType ( ) ) | |
( m_Ember . m_SpatialFilterRadius ! = m_SpatialFilter - > FilterRadius ( ) ) | |
( m_Ember . m_Supersample ! = m_SpatialFilter - > Supersample ( ) ) | |
( m_PixelAspectRatio ! = m_SpatialFilter - > PixelAspectRatio ( ) ) )
2014-10-14 11:53:15 -04:00
{
2015-08-10 23:10:23 -04:00
m_SpatialFilter = unique_ptr < SpatialFilter < bucketT > > (
2021-04-19 23:07:24 -04:00
SpatialFilterCreator < bucketT > : : Create ( m_Ember . m_SpatialFilterType ,
static_cast < bucketT > ( m_Ember . m_SpatialFilterRadius ) , m_Ember . m_Supersample , static_cast < bucketT > ( m_PixelAspectRatio ) ) ) ;
2014-10-17 02:05:08 -04:00
m_Ember . m_SpatialFilterRadius = m_SpatialFilter - > FilterRadius ( ) ; //It may have been changed internally if it was too small, so ensure they're synced.
2014-10-14 11:53:15 -04:00
newAlloc = true ;
}
return m_SpatialFilter . get ( ) ! = nullptr ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Create the temporal filter if the current filter parameters differ
/// from the last temporal filter created.
/// </summary>
/// <param name="newAlloc">True if a new filter instance was created, else false.</param>
2014-09-10 01:41:26 -04:00
/// <returns>True if the filter is not nullptr (whether a new one was created or not), else false.</returns>
2014-07-08 03:11:14 -04:00
template < typename T , typename bucketT >
bool Renderer < T , bucketT > : : CreateTemporalFilter ( bool & newAlloc )
{
newAlloc = false ;
2021-04-19 23:07:24 -04:00
//static int i = 0;
2014-07-08 03:11:14 -04:00
//Use intelligent testing so it isn't created every time a new ember is passed in.
2014-08-03 19:16:10 -04:00
if ( ( ! m_TemporalFilter . get ( ) ) | |
2015-12-31 19:00:36 -05:00
( m_Ember . m_TemporalSamples ! = m_TemporalFilter - > TemporalSamples ( ) ) | |
( m_Ember . m_TemporalFilterType ! = m_TemporalFilter - > FilterType ( ) ) | |
( m_Ember . m_TemporalFilterWidth ! = m_TemporalFilter - > FilterWidth ( ) ) | |
( m_Ember . m_TemporalFilterExp ! = m_TemporalFilter - > FilterExp ( ) ) )
2014-07-08 03:11:14 -04:00
{
2014-09-10 01:41:26 -04:00
m_TemporalFilter = unique_ptr < TemporalFilter < T > > (
2015-12-31 19:00:36 -05:00
TemporalFilterCreator < T > : : Create ( m_Ember . m_TemporalFilterType , m_Ember . m_TemporalSamples , m_Ember . m_TemporalFilterWidth , m_Ember . m_TemporalFilterExp ) ) ;
2014-07-08 03:11:14 -04:00
newAlloc = true ;
2021-04-19 23:07:24 -04:00
//auto name = TemporalFilterCreator<T>::ToString(m_TemporalFilter->FilterType());
//ostringstream os;
//os << "./" << ++i << "_" << name << "_filter.txt";
//ofstream of (os.str());
//auto str = m_TemporalFilter->ToString();
//
//if (of.is_open())
// of << str;
2014-07-08 03:11:14 -04:00
}
2014-09-10 01:41:26 -04:00
return m_TemporalFilter . get ( ) ! = nullptr ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// The main render loop. This is the core of the algorithm.
/// The processing steps are: Iterating, density filtering, final accumulation.
/// Various functions in it are virtual so they will resolve
/// to whatever overrides are provided in derived classes. This
/// future-proofs the algorithm for GPU-based renderers.
/// If the caller calls Abort() at any time, or the progress function returns 0,
/// the entire rendering process will exit as soon as it can.
2014-11-03 02:16:34 -05:00
/// The concept of passes from flam3 has been removed as it was never used.
2014-07-08 03:11:14 -04:00
/// The loop structure is:
/// {
2014-11-03 02:16:34 -05:00
/// Temporal Samples (Default 1 for single image)
2014-07-08 03:11:14 -04:00
/// {
2014-11-03 02:16:34 -05:00
/// Iterate (Either to completion or to a specified number of iterations)
2014-07-08 03:11:14 -04:00
/// {
/// }
/// }
///
/// Density filtering (Basic log, or full density estimation)
/// Final accumulation (Color correction and spatial filtering)
/// }
/// This loop structure has admittedly been severely butchered from what
/// flam3 did. The reason is that it was made to support interactive rendering
/// that can exit the process and pick up where it left off in response to the
/// user changing values in a fractal flame GUI editor.
/// To achieve this, each step in the rendering process is given an enumeration state
/// as well as a goto label. This allows the renderer to pick up in the state it left
/// off in if no changes prohibiting that have been made.
/// It also allows for the bare minimum amount of processing needed to complete the requested
/// action. For example, if the process has completed and the user only adjusts the brightness
/// of the last rendered ember then there is no need to perform the entire iteration process
/// over again. Rather, only final accumulation is needed.
/// </summary>
/// <param name="finalImage">Storage for the final image. It will be allocated if needed.</param>
/// <param name="time">The time if animating, else ignored.</param>
/// <param name="subBatchCountOverride">Run a specified number of sub batches. Default: 0, meaning run to completion.</param>
/// <param name="forceOutput">True to force rendering a complete image even if iterating is not complete, else don't. Default: false.</param>
/// <param name="finalOffset">Offset in finalImage to store the pixels to. Default: 0.</param>
/// <returns>True if nothing went wrong, else false.</returns>
template < typename T , typename bucketT >
2017-07-22 16:43:35 -04:00
eRenderStatus Renderer < T , bucketT > : : Run ( vector < v4F > & finalImage , double time , size_t subBatchCountOverride , bool forceOutput , size_t finalOffset )
2014-07-08 03:11:14 -04:00
{
m_InRender = true ;
EnterRender ( ) ;
m_Abort = false ;
2015-12-31 19:00:36 -05:00
bool filterAndAccumOnly = m_ProcessAction = = eProcessAction : : FILTER_AND_ACCUM ;
bool accumOnly = m_ProcessAction = = eProcessAction : : ACCUM_ONLY ;
bool resume = m_ProcessState ! = eProcessState : : NONE ;
2014-07-08 03:11:14 -04:00
bool newFilterAlloc ;
2017-07-05 02:08:06 -04:00
size_t temporalSample = 0 ;
2014-09-01 00:25:15 -04:00
T deTime ;
2015-12-31 19:00:36 -05:00
auto success = eRenderStatus : : RENDER_OK ;
2014-07-08 03:11:14 -04:00
//Reset timers and progress percent if: Beginning anew or only filtering and/or accumulating.
if ( ! resume | | accumOnly | | filterAndAccumOnly )
{
if ( ! resume ) //Only set this if it's the first run through.
2015-12-31 19:00:36 -05:00
m_ProcessState = eProcessState : : ITER_STARTED ;
2014-07-08 03:11:14 -04:00
m_ProgressTimer . Tic ( ) ;
}
if ( ! resume ) //Beginning, reset everything.
{
2020-04-09 18:41:49 -04:00
m_RenderTimer . Tic ( ) ;
2014-07-08 03:11:14 -04:00
m_LastTemporalSample = 0 ;
m_LastIter = 0 ;
m_LastIterPercent = 0 ;
2014-08-06 00:50:52 -04:00
m_Stats . Clear ( ) ;
2014-07-08 03:11:14 -04:00
m_Gamma = 0 ;
m_Vibrancy = 0 ; //Accumulate these after each temporal sample.
m_VibGamCount = 0 ;
2015-03-21 18:27:37 -04:00
m_CurvesSet = false ;
2014-07-08 03:11:14 -04:00
m_Background . Clear ( ) ;
}
//User requested an increase in quality after finishing.
2015-12-31 19:00:36 -05:00
else if ( m_ProcessState = = eProcessState : : ITER_STARTED & & m_ProcessAction = = eProcessAction : : KEEP_ITERATING & & TemporalSamples ( ) = = 1 )
2014-07-08 03:11:14 -04:00
{
2020-04-09 18:41:49 -04:00
m_RenderTimer . Tic ( ) ;
2014-07-08 03:11:14 -04:00
m_LastTemporalSample = 0 ;
m_LastIter = m_Stats . m_Iters ;
m_LastIterPercent = 0 ; //Might skip a progress update, but shouldn't matter.
m_Gamma = 0 ;
m_Vibrancy = 0 ;
m_VibGamCount = 0 ;
m_Background . Clear ( ) ;
2015-03-21 18:27:37 -04:00
ComputeQuality ( ) ; //Must recompute quality when doing a quality increase.
2014-07-08 03:11:14 -04:00
}
//Make sure values are within valid range.
2021-04-19 23:07:24 -04:00
ClampGteRef ( m_Ember . m_Supersample , static_cast < size_t > ( 1 ) ) ;
2014-07-08 03:11:14 -04:00
//Make sure to get most recent update since loop won't be entered to call Interp().
//Vib, gam and background are normally summed for each temporal sample. However if iteration is skipped, make sure to get the latest.
if ( ( filterAndAccumOnly | | accumOnly ) & & TemporalSamples ( ) = = 1 ) //Disallow jumping when temporal samples > 1.
{
2016-04-03 21:55:12 -04:00
m_Ember = ( * m_EmbersP ) [ 0 ] ;
2015-08-10 23:10:23 -04:00
m_Vibrancy = Vibrancy ( ) ;
m_Gamma = Gamma ( ) ;
2014-07-08 03:11:14 -04:00
m_Background = m_Ember . m_Background ;
2014-09-10 01:41:26 -04:00
2014-07-08 03:11:14 -04:00
if ( filterAndAccumOnly )
goto FilterAndAccum ;
2014-09-10 01:41:26 -04:00
2014-07-08 03:11:14 -04:00
if ( accumOnly )
goto AccumOnly ;
}
//it.Tic();
//Interpolate.
2016-04-03 21:55:12 -04:00
if ( m_EmbersP - > size ( ) > 1 )
2021-04-19 23:07:24 -04:00
m_Interpolater . Interpolate ( * m_EmbersP , static_cast < T > ( time ) , 0 , m_Ember ) ;
2015-12-31 19:00:36 -05:00
2014-07-08 03:11:14 -04:00
//it.Toc("Interp 1");
//Save only for palette insertion.
2016-04-11 21:15:14 -04:00
if ( m_InsertPalette )
2014-07-08 03:11:14 -04:00
m_TempEmber = m_Ember ;
2016-03-28 21:49:10 -04:00
if ( ! resume ) //Only need to create this when starting a new render.
{
CreateSpatialFilter ( newFilterAlloc ) ; //Will be checked and recreated again if necessary right before final output.
CreateTemporalFilter ( newFilterAlloc ) ; //But create here just to ensure allocation succeeded.
ComputeBounds ( ) ;
}
2014-07-08 03:11:14 -04:00
2014-09-10 01:41:26 -04:00
if ( m_SpatialFilter . get ( ) = = nullptr | | m_TemporalFilter . get ( ) = = nullptr )
2014-07-08 03:11:14 -04:00
{
2015-12-10 23:19:41 -05:00
AddToReport ( " Spatial and temporal filter allocations failed, aborting. \n " ) ;
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ERROR ;
2014-07-08 03:11:14 -04:00
goto Finish ;
}
if ( ! resume & & ! Alloc ( ) )
{
2015-12-10 23:19:41 -05:00
AddToReport ( " Histogram, accumulator and samples buffer allocations failed, aborting. \n " ) ;
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ERROR ;
2014-07-08 03:11:14 -04:00
goto Finish ;
}
if ( ! resume )
2017-08-28 00:24:33 -04:00
{
if ( ! ResetBuckets ( true , false ) ) //Only reset hist here and do accum when needed later on.
{
success = eRenderStatus : : RENDER_ERROR ;
goto Finish ;
}
}
2014-07-08 03:11:14 -04:00
2021-04-19 23:07:24 -04:00
deTime = static_cast < T > ( time ) + * m_TemporalFilter - > Deltas ( ) ;
2014-11-03 02:16:34 -05:00
//Interpolate and get an ember for DE purposes.
//Additional interpolation will be done in the temporal samples loop.
//it.Tic();
2016-04-03 21:55:12 -04:00
if ( m_EmbersP - > size ( ) > 1 )
2016-04-23 12:02:09 -04:00
m_Interpolater . Interpolate ( * m_EmbersP , deTime , 0 , m_Ember ) ;
2014-11-03 02:16:34 -05:00
2015-12-31 19:00:36 -05:00
//it.Toc("Interp 2");
2015-03-21 18:27:37 -04:00
ClampGteRef < T > ( m_Ember . m_MinRadDE , 0 ) ;
ClampGteRef < T > ( m_Ember . m_MaxRadDE , 0 ) ;
ClampGteRef < T > ( m_Ember . m_MaxRadDE , m_Ember . m_MinRadDE ) ;
2014-11-03 02:16:34 -05:00
2016-03-28 21:49:10 -04:00
if ( ! CreateDEFilter ( newFilterAlloc ) ) //Will be checked and recreated again if necessary right before density filtering.
2014-07-08 03:11:14 -04:00
{
2015-12-10 23:19:41 -05:00
AddToReport ( " Density filter creation failed, aborting. \n " ) ;
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ERROR ;
2014-11-03 02:16:34 -05:00
goto Finish ;
}
//Temporal samples, loop 1.
temporalSample = resume ? m_LastTemporalSample : 0 ;
2015-12-31 19:00:36 -05:00
2014-11-03 02:16:34 -05:00
for ( ; ( temporalSample < TemporalSamples ( ) ) & & ! m_Abort ; )
{
T colorScalar = m_TemporalFilter - > Filter ( ) [ temporalSample ] ;
2021-04-19 23:07:24 -04:00
T temporalTime = static_cast < T > ( time ) + m_TemporalFilter - > Deltas ( ) [ temporalSample ] ;
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
//Interpolate again.
2014-07-08 03:11:14 -04:00
//it.Tic();
2016-04-03 21:55:12 -04:00
if ( TemporalSamples ( ) > 1 & & m_EmbersP - > size ( ) > 1 )
2016-04-23 12:02:09 -04:00
m_Interpolater . Interpolate ( * m_EmbersP , temporalTime , 0 , m_Ember ) ; //This will perform all necessary precalcs via the ember/xform/variation assignment operators.
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
//it.Toc("Interp 3");
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
if ( ! resume & & ! AssignIterator ( ) )
2014-07-08 03:11:14 -04:00
{
2015-12-10 23:19:41 -05:00
AddToReport ( " Iterator assignment failed, aborting. \n " ) ;
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ERROR ;
2014-07-08 03:11:14 -04:00
goto Finish ;
}
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
//Do this every iteration for an animation, or else do it once for a single image.
2015-03-21 18:27:37 -04:00
if ( TemporalSamples ( ) > 1 | | ! resume )
{
ComputeQuality ( ) ;
ComputeCamera ( ) ;
2020-03-18 22:34:56 -04:00
//m_CarToRas.UpdateCachedHalf(m_CarToRas.CarHalfX(), m_CarToRas.CarHalfY());
2015-03-21 18:27:37 -04:00
MakeDmap ( colorScalar ) ; //For each temporal sample, the palette m_Dmap needs to be re-created with color scalar. 1 if no temporal samples.
}
2014-10-27 17:21:06 -04:00
2014-11-03 02:16:34 -05:00
//The actual number of times to iterate. Each thread will get (totalIters / ThreadCount) iters to do.
2015-03-21 18:27:37 -04:00
//This is based on zoom and scale calculated in ComputeQuality().
2014-11-03 02:16:34 -05:00
//Note that the iter count is based on the final image dimensions, and not the super sampled dimensions.
size_t itersPerTemporalSample = ItersPerTemporalSample ( ) ; //The total number of iterations for this temporal sample without overrides.
size_t sampleItersToDo ; //The number of iterations to actually do in this sample, considering overrides.
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
if ( subBatchCountOverride > 0 )
sampleItersToDo = subBatchCountOverride * SubBatchSize ( ) * ThreadCount ( ) ; //Run a specific number of sub batches.
else
sampleItersToDo = itersPerTemporalSample ; //Run as many iters as specified to complete this temporal sample.
2014-09-01 00:25:15 -04:00
2015-03-21 18:27:37 -04:00
sampleItersToDo = std : : min < size_t > ( sampleItersToDo , itersPerTemporalSample - m_LastIter ) ;
2014-11-03 02:16:34 -05:00
EmberStats stats = Iterate ( sampleItersToDo , temporalSample ) ; //The heavy work is done here.
2014-07-08 03:11:14 -04:00
2018-10-05 22:50:38 -04:00
//Abort does not indicate an error, it just means the process was interrupted, most likely by the user on the GUI.
if ( m_Abort )
2014-11-03 02:16:34 -05:00
{
2018-10-05 22:50:38 -04:00
success = eRenderStatus : : RENDER_ABORT ;
2014-11-03 02:16:34 -05:00
goto Finish ;
}
2014-07-08 03:11:14 -04:00
2018-10-05 22:50:38 -04:00
//If no iters were executed, something went catastrophically wrong.
if ( ! stats . m_Success & & stats . m_Iters = = 0 )
2014-11-03 02:16:34 -05:00
{
2018-10-05 22:50:38 -04:00
AddToReport ( " Zero iterations ran, rendering failed, aborting. \n " ) ;
success = eRenderStatus : : RENDER_ERROR ;
Abort ( ) ;
2014-11-03 02:16:34 -05:00
goto Finish ;
}
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
//Accumulate stats whether this batch ran to completion or exited prematurely.
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 ;
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
//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.
if ( m_LastIter > = itersPerTemporalSample )
{
2015-08-10 23:10:23 -04:00
m_Vibrancy + = Vibrancy ( ) ;
m_Gamma + = Gamma ( ) ;
2021-04-19 23:07:24 -04:00
m_Background . r + = static_cast < bucketT > ( m_Ember . m_Background . r ) ;
m_Background . g + = static_cast < bucketT > ( m_Ember . m_Background . g ) ;
m_Background . b + = static_cast < bucketT > ( m_Ember . m_Background . b ) ;
2014-11-03 02:16:34 -05:00
m_VibGamCount + + ;
m_LastIter = 0 ;
temporalSample + + ;
}
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
m_LastTemporalSample = temporalSample ;
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
if ( subBatchCountOverride > 0 ) //Don't keep going through this loop if only doing an incremental render.
break ;
} //Temporal samples.
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
//If we've completed all temporal samples, then it was a complete render, so report progress.
if ( temporalSample > = TemporalSamples ( ) )
{
2015-12-31 19:00:36 -05:00
m_ProcessState = eProcessState : : ITER_DONE ;
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
if ( m_Callback & & ! m_Callback - > ProgressFunc ( m_Ember , m_ProgressParameter , 100.0 , 0 , 0 ) )
2014-07-08 03:11:14 -04:00
{
2014-11-03 02:16:34 -05:00
Abort ( ) ;
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ABORT ;
2014-11-03 02:16:34 -05:00
goto Finish ;
2014-07-08 03:11:14 -04:00
}
2014-11-03 02:16:34 -05:00
}
2014-07-08 03:11:14 -04:00
FilterAndAccum :
2015-12-31 19:00:36 -05:00
2014-11-03 02:16:34 -05:00
if ( filterAndAccumOnly | | temporalSample > = TemporalSamples ( ) | | forceOutput )
{
//t.Toc("Iterating and accumulating");
//Compute k1 and k2.
2015-12-31 19:00:36 -05:00
auto fullRun = eRenderStatus : : RENDER_OK ; //Whether density filtering was run to completion without aborting prematurely or triggering an error.
2014-11-03 02:16:34 -05:00
T area = FinalRasW ( ) * FinalRasH ( ) / ( m_PixelsPerUnitX * m_PixelsPerUnitY ) ; //Need to use temps from field if ever implemented.
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
m_K1 = Brightness ( ) ;
2014-07-08 03:11:14 -04:00
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
if ( ! m_Ember . m_K2 | | forceOutput )
2014-11-03 02:16:34 -05:00
{
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
//When doing an interactive render, force output early on in the render process, before all iterations are done.
//This presents a problem with the normal calculation of K2 since it relies on the quality value; it will scale the colors
//to be very dark. Correct it by pretending the number of iters done is the exact quality desired and then scale according to that.
if ( forceOutput )
{
2021-04-19 23:07:24 -04:00
T quality = ( static_cast < T > ( m_Stats . m_Iters ) / static_cast < T > ( FinalDimensions ( ) ) ) * ( m_Scale * m_Scale ) ;
m_K2 = static_cast < bucketT > ( ( Supersample ( ) * Supersample ( ) ) / ( area * quality * m_TemporalFilter - > SumFilt ( ) ) ) ;
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
}
else
2021-04-19 23:07:24 -04:00
m_K2 = static_cast < bucketT > ( ( Supersample ( ) * Supersample ( ) ) / ( area * m_ScaledQuality * m_TemporalFilter - > SumFilt ( ) ) ) ;
2014-11-03 02:16:34 -05:00
}
else
2021-04-19 23:07:24 -04:00
m_K2 = static_cast < bucketT > ( m_Ember . m_K2 ) ;
2014-07-08 03:11:14 -04:00
2017-08-28 00:24:33 -04:00
if ( ! ResetBuckets ( false , true ) ) //Only the histogram was reset above, now reset the density filtering buffer.
{
success = eRenderStatus : : RENDER_ERROR ;
goto Finish ;
}
2014-11-03 02:16:34 -05:00
//t.Tic();
2016-03-28 21:49:10 -04:00
//Make sure a density filter was created with the latest values.
ClampGteRef < T > ( m_Ember . m_MinRadDE , 0 ) ;
ClampGteRef < T > ( m_Ember . m_MaxRadDE , 0 ) ;
ClampGteRef < T > ( m_Ember . m_MaxRadDE , m_Ember . m_MinRadDE ) ;
CreateDEFilter ( newFilterAlloc ) ;
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
//Apply appropriate filter if iterating is complete.
if ( filterAndAccumOnly | | temporalSample > = TemporalSamples ( ) )
{
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
fullRun = m_DensityFilter . get ( ) ? GaussianDensityFilter ( ) : LogScaleDensityFilter ( forceOutput ) ;
2014-11-03 02:16:34 -05:00
}
else
{
//Apply requested filter for a forced output during interactive rendering.
2015-12-31 19:00:36 -05:00
if ( m_DensityFilter . get ( ) & & m_InteractiveFilter = = eInteractiveFilter : : FILTER_DE )
2014-11-03 02:16:34 -05:00
fullRun = GaussianDensityFilter ( ) ;
2015-12-31 19:00:36 -05:00
else if ( ! m_DensityFilter . get ( ) | | m_InteractiveFilter = = eInteractiveFilter : : FILTER_LOG )
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
fullRun = LogScaleDensityFilter ( forceOutput ) ;
2014-10-14 11:53:15 -04:00
}
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
//Only update state if iterating and filtering finished completely (didn't arrive here via forceOutput).
2015-12-31 19:00:36 -05:00
if ( fullRun = = eRenderStatus : : RENDER_OK & & m_ProcessState = = eProcessState : : ITER_DONE )
m_ProcessState = eProcessState : : FILTER_DONE ;
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
//Take special action if filtering exited prematurely.
2015-12-31 19:00:36 -05:00
if ( fullRun ! = eRenderStatus : : RENDER_OK )
2014-11-03 02:16:34 -05:00
{
2017-08-28 00:24:33 -04:00
if ( ! ResetBuckets ( false , true ) ) //Reset the accumulator, come back and try again on the next call.
success = eRenderStatus : : RENDER_ERROR ;
else
success = fullRun ;
2014-11-03 02:16:34 -05:00
goto Finish ;
}
2014-07-08 03:11:14 -04:00
2014-11-03 02:16:34 -05:00
if ( m_Abort )
{
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ABORT ;
2014-11-03 02:16:34 -05:00
goto Finish ;
}
2015-12-31 19:00:36 -05:00
2014-11-03 02:16:34 -05:00
//t.Toc("Density estimation filtering time: ", true);
}
2014-07-08 03:11:14 -04:00
2014-10-14 11:53:15 -04:00
AccumOnly :
2015-12-31 19:00:36 -05:00
if ( m_ProcessState = = eProcessState : : FILTER_DONE | | forceOutput )
2014-07-08 03:11:14 -04:00
{
2015-06-28 20:48:26 -04:00
//Original only allowed stages 0 and 1. Add 2 to mean final accum.
//Do not update state/progress on forced output because it will be immediately overwritten.
if ( m_Callback & & ! forceOutput & & ! m_Callback - > ProgressFunc ( m_Ember , m_ProgressParameter , 0 , 2 , 0 ) )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
Abort ( ) ;
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ABORT ;
2014-10-14 11:53:15 -04:00
goto Finish ;
2014-07-08 03:11:14 -04:00
}
2014-10-14 11:53:15 -04:00
//Make sure a filter has been created.
CreateSpatialFilter ( newFilterAlloc ) ;
2021-04-19 23:07:24 -04:00
m_DensityFilterOffset = m_GutterWidth - static_cast < size_t > ( Clamp < T > ( ( static_cast < T > ( m_SpatialFilter - > FinalFilterWidth ( ) ) - static_cast < T > ( Supersample ( ) ) ) / 2 , 0 , static_cast < T > ( m_GutterWidth ) ) ) ;
2015-03-21 18:27:37 -04:00
m_CurvesSet = m_Ember . m_Curves . CurvesSet ( ) ;
2017-07-22 16:43:35 -04:00
ComputeCurves ( ) ; //Color curves must be re-calculated as well.
2015-03-21 18:27:37 -04:00
2015-12-31 19:00:36 -05:00
if ( AccumulatorToFinalImage ( finalImage , finalOffset ) = = eRenderStatus : : RENDER_OK )
2014-10-14 11:53:15 -04:00
{
2020-04-09 18:41:49 -04:00
m_Stats . m_RenderMs + = m_RenderTimer . Toc ( ) ; //Record total time from the very beginning to the very end, including all intermediate calls.
2014-10-14 11:53:15 -04:00
//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).
m_LastEmber = m_Ember ;
2014-07-08 03:11:14 -04:00
2015-12-31 19:00:36 -05:00
if ( m_ProcessState = = eProcessState : : FILTER_DONE ) //Only update state if gotten here legitimately, and not via forceOutput.
2014-07-08 03:11:14 -04:00
{
2015-12-31 19:00:36 -05:00
m_ProcessState = eProcessState : : ACCUM_DONE ;
2014-10-14 11:53:15 -04:00
if ( m_Callback & & ! m_Callback - > ProgressFunc ( m_Ember , m_ProgressParameter , 100.0 , 2 , 0 ) ) //Finished.
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
Abort ( ) ;
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ABORT ;
2014-10-14 11:53:15 -04:00
goto Finish ;
2014-07-08 03:11:14 -04:00
}
}
}
2014-10-14 11:53:15 -04:00
else
{
2015-12-31 19:00:36 -05:00
success = eRenderStatus : : RENDER_ERROR ;
2014-10-14 11:53:15 -04:00
}
}
2015-12-31 19:00:36 -05:00
2014-10-14 11:53:15 -04:00
Finish :
2015-12-31 19:00:36 -05:00
if ( success = = eRenderStatus : : RENDER_OK & & m_Abort ) //If everything ran ok, but they've aborted, record abort as the status.
success = eRenderStatus : : RENDER_ABORT ;
else if ( success ! = eRenderStatus : : RENDER_OK ) //Regardless of abort status, if there was an error, leave that as the return status.
2014-10-14 11:53:15 -04:00
Abort ( ) ;
LeaveRender ( ) ;
m_InRender = false ;
return success ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
2014-10-14 11:53:15 -04:00
/// Return EmberImageComments object with image comments filled out.
/// Run() should have completed before calling this.
2014-07-08 03:11:14 -04:00
/// </summary>
2014-10-14 11:53:15 -04:00
/// <param name="printEditDepth">The depth of the edit tags</param>
/// <param name="hexPalette">If true, embed a hexadecimal palette instead of Xml Color tags, else use Xml color tags.</param>
/// <returns>The EmberImageComments object with image comments filled out</returns>
2014-07-08 03:11:14 -04:00
template < typename T , typename bucketT >
2016-04-03 21:55:12 -04:00
EmberImageComments Renderer < T , bucketT > : : ImageComments ( const EmberStats & stats , size_t printEditDepth , bool hexPalette )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
ostringstream ss ;
EmberImageComments comments ;
ss . imbue ( std : : locale ( " " ) ) ;
2016-04-03 21:55:12 -04:00
comments . m_Genome = m_EmberToXml . ToString ( m_Ember , " " , printEditDepth , false , hexPalette ) ;
2021-04-19 23:07:24 -04:00
ss < < ( static_cast < double > ( stats . m_Badvals ) / static_cast < double > ( stats . m_Iters ) ) ; //Percentage of bad values to iters.
2014-10-14 11:53:15 -04:00
comments . m_Badvals = ss . str ( ) ; ss . str ( " " ) ;
ss < < stats . m_Iters ;
comments . m_NumIters = ss . str ( ) ; ss . str ( " " ) ; //Total iters.
ss < < ( stats . m_RenderMs / 1000.0 ) ;
comments . m_Runtime = ss . str ( ) ; //Number of seconds for iterating, accumulating and filtering.
return comments ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
2014-10-14 11:53:15 -04:00
/// New virtual functions to be overridden in derived renderers that use the GPU, but not accessed outside.
2014-07-08 03:11:14 -04:00
/// </summary>
/// <summary>
/// Make the final palette used for iteration.
/// </summary>
/// <param name="colorScalar">The color scalar to multiply the ember's palette by</param>
template < typename T , typename bucketT >
void Renderer < T , bucketT > : : MakeDmap ( T colorScalar )
{
2021-04-19 23:07:24 -04:00
m_Ember . m_Palette . template MakeDmap < bucketT > ( m_Dmap , static_cast < bucketT > ( colorScalar ) ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Allocate various buffers if the image dimensions, thread count, or sub batch size
/// has changed.
/// </summary>
/// <returns>True if success, else false</returns>
template < typename T , typename bucketT >
--User changes
-Add support for multiple GPU devices.
--These options are present in the command line and in Fractorium.
-Change scheme of specifying devices from platform,device to just total device index.
--Single number on the command line.
--Change from combo boxes for device selection to a table of all devices in Fractorium.
-Temporal samples defaults to 100 instead of 1000 which was needless overkill.
--Bug fixes
-EmberAnimate, EmberRender, FractoriumSettings, FinalRenderDialog: Fix wrong order of arguments to Clamp() when assigning thread priority.
-VariationsDC.h: Fix NVidia OpenCL compilation error in DCTriangleVariation.
-FractoriumXformsColor.cpp: Checking for null pixmap pointer is not enough, must also check if the underlying buffer is null via call to QPixmap::isNull().
--Code changes
-Ember.h: Add case for FLAME_MOTION_NONE and default in ApplyFlameMotion().
-EmberMotion.h: Call base constructor.
-EmberPch.h: #pragma once only on Windows.
-EmberToXml.h:
--Handle different types of exceptions.
--Add default cases to ToString().
-Isaac.h: Remove unused variable in constructor.
-Point.h: Call base constructor in Color().
-Renderer.h/cpp:
--Add bool to Alloc() to only allocate memory for the histogram. Needed for multi-GPU.
--Make CoordMap() return a const ref, not a pointer.
-SheepTools.h:
--Use 64-bit types like the rest of the code already does.
--Fix some comment misspellings.
-Timing.h: Make BeginTime(), EndTime(), ElapsedTime() and Format() be const functions.
-Utils.h:
--Add new functions Equal() and Split().
--Handle more exception types in ReadFile().
--Get rid of most legacy blending of C and C++ argument parsing.
-XmlToEmber.h:
--Get rid of most legacy blending of C and C++ code from flam3.
--Remove some unused variables.
-EmberAnimate:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
--If a render fails, exit since there is no point in continuing an animation with a missing frame.
--Pass variables to threaded save better, which most likely fixes a very subtle bug that existed before.
--Remove some unused variables.
-EmberGenome, EmberRender:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
-EmberRender:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
--Only print values when not rendering with OpenCL, since they're always 0 in that case.
-EmberCLPch.h:
--#pragma once only on Windows.
--#include <atomic>.
-IterOpenCLKernelCreator.h: Add new kernel for summing two histograms. This is needed for multi-GPU.
-OpenCLWrapper.h:
--Move all OpenCL info related code into its own class OpenCLInfo.
--Add members to cache the values of global memory size and max allocation size.
-RendererCL.h/cpp:
--Redesign to accomodate multi-GPU.
--Constructor now takes a vector of devices.
--Remove DumpErrorReport() function, it's handled in the base.
--ClearBuffer(), ReadPoints(), WritePoints(), ReadHist() and WriteHist() now optionally take a device index as a parameter.
--MakeDmap() override and m_DmapCL member removed because it no longer applies since the histogram is always float since the last commit.
--Add new function SumDeviceHist() to sum histograms from two devices by first copying to a temporary on the host, then a temporary on the device, then summing.
--m_Calls member removed, as it's now per-device.
--OpenCLWrapper removed.
--m_Seeds member is now a vector of vector of seeds, to accomodate a separate and different array of seeds for each device.
--Added member m_Devices, a vector of unique_ptr of RendererCLDevice.
-EmberCommon.h
--Added Devices() function to convert from a vector of device indices to a vector of platform,device indices.
--Changed CreateRenderer() to accept a vector of devices to create a single RendererCL which will split work across multiple devices.
--Added CreateRenderers() function to accept a vector of devices to create multiple RendererCL, each which will render on a single device.
--Add more comments to some existing functions.
-EmberCommonPch.h: #pragma once only on Windows.
-EmberOptions.h:
--Remove --platform option, it's just sequential device number now with the --device option.
--Make --out be OPT_USE_RENDER instead of OPT_RENDER_ANIM since it's an error condition when animating. It makes no sense to write all frames to a single image.
--Add Devices() function to parse comma separated --device option string and return a vector of device indices.
--Make int and uint types be 64-bit, so intmax_t and size_t.
--Make better use of macros.
-JpegUtils.h: Make string parameters to WriteJpeg() and WritePng() be const ref.
-All project files: Turn off buffer security check option in Visual Studio (/Gs-)
-deployment.pri: Remove the line OTHER_FILES +=, it's pointless and was causing problems.
-Ember.pro, EmberCL.pro: Add CONFIG += plugin, otherwise it wouldn't link.
-EmberCL.pro: Add new files for multi-GPU support.
-build_all.sh: use -j4 and QMAKE=${QMAKE:/usr/bin/qmake}
-shared_settings.pri:
-Add version string.
-Remove old DESTDIR definitions.
-Add the following lines or else nothing would build:
CONFIG(release, debug|release) {
CONFIG += warn_off
DESTDIR = ../../../Bin/release
}
CONFIG(debug, debug|release) {
DESTDIR = ../../../Bin/debug
}
QMAKE_POST_LINK += $$quote(cp --update ../../../Data/flam3-palettes.xml $${DESTDIR}$$escape_expand(\n\t))
LIBS += -L/usr/lib -lpthread
-AboutDialog.ui: Another futile attempt to make it look correct on Linux.
-FinalRenderDialog.h/cpp:
--Add support for multi-GPU.
--Change from combo boxes for device selection to a table of all devices.
--Ensure device selection makes sense.
--Remove "FinalRender" prefix of various function names, it's implied given the context.
-FinalRenderEmberController.h/cpp:
--Add support for multi-GPU.
--Change m_FinishedImageCount to be atomic.
--Move CancelRender() from the base to FinalRenderEmberController<T>.
--Refactor RenderComplete() to omit any progress related functionality or image saving since it can be potentially ran in a thread.
--Consolidate setting various renderer fields into SyncGuiToRenderer().
-Fractorium.cpp: Allow for resizing of the options dialog to show the entire device table.
-FractoriumCommon.h: Add various functions to handle a table showing the available OpenCL devices on the system.
-FractoriumEmberController.h/cpp: Remove m_FinalImageIndex, it's no longer needed.
-FractoriumRender.cpp: Scale the interactive sub batch count and quality by the number of devices used.
-FractoriumSettings.h/cpp:
--Temporal samples defaults to 100 instead of 1000 which was needless overkill.
--Add multi-GPU support, remove old device,platform pair.
-FractoriumToolbar.cpp: Disable OpenCL toolbar button if there are no devices present on the system.
-FractoriumOptionsDialog.h/cpp:
--Add support for multi-GPU.
--Consolidate more assignments in DataToGui().
--Enable/disable CPU/OpenCL items in response to OpenCL checkbox event.
-Misc: Convert almost everything to size_t for unsigned, intmax_t for signed.
2015-09-12 21:33:45 -04:00
bool Renderer < T , bucketT > : : Alloc ( bool histOnly )
2014-07-08 03:11:14 -04:00
{
2021-04-19 23:07:24 -04:00
auto b = true ;
const auto lock =
2014-07-08 03:11:14 -04:00
( m_SuperSize ! = m_HistBuckets . size ( ) ) | |
( m_SuperSize ! = m_AccumulatorBuckets . size ( ) ) | |
( m_ThreadsToUse ! = m_Samples . size ( ) ) | |
2014-11-28 04:37:51 -05:00
( m_Samples [ 0 ] . size ( ) ! = SubBatchSize ( ) ) ;
2014-07-08 03:11:14 -04:00
if ( lock )
EnterResize ( ) ;
if ( m_SuperSize ! = m_HistBuckets . size ( ) )
{
m_HistBuckets . resize ( m_SuperSize ) ;
if ( m_ReclaimOnResize )
m_HistBuckets . shrink_to_fit ( ) ;
b & = ( m_HistBuckets . size ( ) = = m_SuperSize ) ;
}
--User changes
-Add support for multiple GPU devices.
--These options are present in the command line and in Fractorium.
-Change scheme of specifying devices from platform,device to just total device index.
--Single number on the command line.
--Change from combo boxes for device selection to a table of all devices in Fractorium.
-Temporal samples defaults to 100 instead of 1000 which was needless overkill.
--Bug fixes
-EmberAnimate, EmberRender, FractoriumSettings, FinalRenderDialog: Fix wrong order of arguments to Clamp() when assigning thread priority.
-VariationsDC.h: Fix NVidia OpenCL compilation error in DCTriangleVariation.
-FractoriumXformsColor.cpp: Checking for null pixmap pointer is not enough, must also check if the underlying buffer is null via call to QPixmap::isNull().
--Code changes
-Ember.h: Add case for FLAME_MOTION_NONE and default in ApplyFlameMotion().
-EmberMotion.h: Call base constructor.
-EmberPch.h: #pragma once only on Windows.
-EmberToXml.h:
--Handle different types of exceptions.
--Add default cases to ToString().
-Isaac.h: Remove unused variable in constructor.
-Point.h: Call base constructor in Color().
-Renderer.h/cpp:
--Add bool to Alloc() to only allocate memory for the histogram. Needed for multi-GPU.
--Make CoordMap() return a const ref, not a pointer.
-SheepTools.h:
--Use 64-bit types like the rest of the code already does.
--Fix some comment misspellings.
-Timing.h: Make BeginTime(), EndTime(), ElapsedTime() and Format() be const functions.
-Utils.h:
--Add new functions Equal() and Split().
--Handle more exception types in ReadFile().
--Get rid of most legacy blending of C and C++ argument parsing.
-XmlToEmber.h:
--Get rid of most legacy blending of C and C++ code from flam3.
--Remove some unused variables.
-EmberAnimate:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
--If a render fails, exit since there is no point in continuing an animation with a missing frame.
--Pass variables to threaded save better, which most likely fixes a very subtle bug that existed before.
--Remove some unused variables.
-EmberGenome, EmberRender:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
-EmberRender:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
--Only print values when not rendering with OpenCL, since they're always 0 in that case.
-EmberCLPch.h:
--#pragma once only on Windows.
--#include <atomic>.
-IterOpenCLKernelCreator.h: Add new kernel for summing two histograms. This is needed for multi-GPU.
-OpenCLWrapper.h:
--Move all OpenCL info related code into its own class OpenCLInfo.
--Add members to cache the values of global memory size and max allocation size.
-RendererCL.h/cpp:
--Redesign to accomodate multi-GPU.
--Constructor now takes a vector of devices.
--Remove DumpErrorReport() function, it's handled in the base.
--ClearBuffer(), ReadPoints(), WritePoints(), ReadHist() and WriteHist() now optionally take a device index as a parameter.
--MakeDmap() override and m_DmapCL member removed because it no longer applies since the histogram is always float since the last commit.
--Add new function SumDeviceHist() to sum histograms from two devices by first copying to a temporary on the host, then a temporary on the device, then summing.
--m_Calls member removed, as it's now per-device.
--OpenCLWrapper removed.
--m_Seeds member is now a vector of vector of seeds, to accomodate a separate and different array of seeds for each device.
--Added member m_Devices, a vector of unique_ptr of RendererCLDevice.
-EmberCommon.h
--Added Devices() function to convert from a vector of device indices to a vector of platform,device indices.
--Changed CreateRenderer() to accept a vector of devices to create a single RendererCL which will split work across multiple devices.
--Added CreateRenderers() function to accept a vector of devices to create multiple RendererCL, each which will render on a single device.
--Add more comments to some existing functions.
-EmberCommonPch.h: #pragma once only on Windows.
-EmberOptions.h:
--Remove --platform option, it's just sequential device number now with the --device option.
--Make --out be OPT_USE_RENDER instead of OPT_RENDER_ANIM since it's an error condition when animating. It makes no sense to write all frames to a single image.
--Add Devices() function to parse comma separated --device option string and return a vector of device indices.
--Make int and uint types be 64-bit, so intmax_t and size_t.
--Make better use of macros.
-JpegUtils.h: Make string parameters to WriteJpeg() and WritePng() be const ref.
-All project files: Turn off buffer security check option in Visual Studio (/Gs-)
-deployment.pri: Remove the line OTHER_FILES +=, it's pointless and was causing problems.
-Ember.pro, EmberCL.pro: Add CONFIG += plugin, otherwise it wouldn't link.
-EmberCL.pro: Add new files for multi-GPU support.
-build_all.sh: use -j4 and QMAKE=${QMAKE:/usr/bin/qmake}
-shared_settings.pri:
-Add version string.
-Remove old DESTDIR definitions.
-Add the following lines or else nothing would build:
CONFIG(release, debug|release) {
CONFIG += warn_off
DESTDIR = ../../../Bin/release
}
CONFIG(debug, debug|release) {
DESTDIR = ../../../Bin/debug
}
QMAKE_POST_LINK += $$quote(cp --update ../../../Data/flam3-palettes.xml $${DESTDIR}$$escape_expand(\n\t))
LIBS += -L/usr/lib -lpthread
-AboutDialog.ui: Another futile attempt to make it look correct on Linux.
-FinalRenderDialog.h/cpp:
--Add support for multi-GPU.
--Change from combo boxes for device selection to a table of all devices.
--Ensure device selection makes sense.
--Remove "FinalRender" prefix of various function names, it's implied given the context.
-FinalRenderEmberController.h/cpp:
--Add support for multi-GPU.
--Change m_FinishedImageCount to be atomic.
--Move CancelRender() from the base to FinalRenderEmberController<T>.
--Refactor RenderComplete() to omit any progress related functionality or image saving since it can be potentially ran in a thread.
--Consolidate setting various renderer fields into SyncGuiToRenderer().
-Fractorium.cpp: Allow for resizing of the options dialog to show the entire device table.
-FractoriumCommon.h: Add various functions to handle a table showing the available OpenCL devices on the system.
-FractoriumEmberController.h/cpp: Remove m_FinalImageIndex, it's no longer needed.
-FractoriumRender.cpp: Scale the interactive sub batch count and quality by the number of devices used.
-FractoriumSettings.h/cpp:
--Temporal samples defaults to 100 instead of 1000 which was needless overkill.
--Add multi-GPU support, remove old device,platform pair.
-FractoriumToolbar.cpp: Disable OpenCL toolbar button if there are no devices present on the system.
-FractoriumOptionsDialog.h/cpp:
--Add support for multi-GPU.
--Consolidate more assignments in DataToGui().
--Enable/disable CPU/OpenCL items in response to OpenCL checkbox event.
-Misc: Convert almost everything to size_t for unsigned, intmax_t for signed.
2015-09-12 21:33:45 -04:00
if ( histOnly )
{
if ( lock )
LeaveResize ( ) ;
return b ;
}
2014-07-08 03:11:14 -04:00
if ( m_SuperSize ! = m_AccumulatorBuckets . size ( ) )
{
m_AccumulatorBuckets . resize ( m_SuperSize ) ;
if ( m_ReclaimOnResize )
m_AccumulatorBuckets . shrink_to_fit ( ) ;
b & = ( m_AccumulatorBuckets . size ( ) = = m_SuperSize ) ;
}
if ( m_ThreadsToUse ! = m_Samples . size ( ) )
{
m_Samples . resize ( m_ThreadsToUse ) ;
if ( m_ReclaimOnResize )
m_Samples . shrink_to_fit ( ) ;
b & = ( m_Samples . size ( ) = = m_ThreadsToUse ) ;
}
2015-05-03 20:13:14 -04:00
for ( auto & sample : m_Samples )
2014-07-08 03:11:14 -04:00
{
2015-05-03 20:13:14 -04:00
if ( sample . size ( ) ! = SubBatchSize ( ) )
2014-07-08 03:11:14 -04:00
{
2015-05-03 20:13:14 -04:00
sample . resize ( SubBatchSize ( ) ) ;
2014-07-08 03:11:14 -04:00
if ( m_ReclaimOnResize )
2015-05-03 20:13:14 -04:00
sample . shrink_to_fit ( ) ;
2014-07-08 03:11:14 -04:00
2015-05-03 20:13:14 -04:00
b & = ( sample . size ( ) = = SubBatchSize ( ) ) ;
2014-07-08 03:11:14 -04:00
}
}
--User changes
-Support 4k monitors, and in general, properly scale any monitor that is not HD.
-Allow for a spatial filter of radius zero, which means do not use a spatial filter.
-Add new variations: concentric, cpow3, helicoid, helix, rand_cubes, sphereblur.
-Use a new method for computing elliptic which is more precise. Developed by Discord user Claude.
-Remove the 8 variation per xform limitation on the GPU.
-Allow for loading the last flame file on startup, rather than randoms.
-Use two different default quality values in the interactive renderer, one each for CPU and GPU.
-Creating linked xforms was using non-standard behavior. Make it match Apo and also support creating multiple linked xforms at once.
--Bug fixes
-No variations in an xform used to have the same behavior as a single linear variation with weight 1. While sensible, this breaks backward compatibility. No variations now sets the output point to zeroes.
-Prevent crashing the program when adjusting a value on the main window while a final render is in progress.
-The xaos table was inverted.
--Code changes
-Convert projects to Visual Studio 2017.
-Change bad vals from +- 1e10 to +-1e20.
-Reintroduce the symmetry tag in xforms for legacy support in programs that do not use color_speed.
-Compiler will not let us use default values in templated member functions anymore.
2017-11-26 20:27:00 -05:00
if ( ! m_StandardIterator . get ( ) )
m_StandardIterator = make_unique < StandardIterator < T > > ( ) ;
if ( ! m_XaosIterator . get ( ) )
m_XaosIterator = make_unique < XaosIterator < T > > ( ) ;
2014-07-08 03:11:14 -04:00
if ( lock )
LeaveResize ( ) ;
return b ;
}
/// <summary>
/// Clear histogram and/or density filtering buffers to all zeroes.
/// </summary>
/// <param name="resetHist">Clear histogram if true, else don't.</param>
/// <param name="resetAccum">Clear density filtering buffer if true, else don't.</param>
/// <returns>True if anything was cleared, else false.</returns>
template < typename T , typename bucketT >
bool Renderer < T , bucketT > : : ResetBuckets ( bool resetHist , bool resetAccum )
{
2014-10-14 11:53:15 -04:00
if ( resetHist & & ! m_HistBuckets . empty ( ) )
Memset ( m_HistBuckets ) ;
2015-12-31 19:00:36 -05:00
2014-10-14 11:53:15 -04:00
if ( resetAccum & & ! m_AccumulatorBuckets . empty ( ) )
Memset ( m_AccumulatorBuckets ) ;
2014-07-08 03:11:14 -04:00
return resetHist | | resetAccum ;
}
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
/// <summary>
2017-07-22 16:43:35 -04:00
/// THIS IS UNUSED.
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
/// Log scales a single row with a specially structured loop that will be vectorized by the compiler.
/// Note this adds an epsilon to the denomiator used to compute the logScale
/// value because the conditional check for zero would have prevented the loop from
/// being vectorized.
/// </summary>
/// <param name="row">The absolute element index in the histogram this row starts on</param>
/// <param name="rowEnd">The absolute element index in the histogram this row ends on</param>
template < typename T , typename bucketT >
void Renderer < T , bucketT > : : VectorizedLogScale ( size_t row , size_t rowEnd )
{
2021-04-19 23:07:24 -04:00
const auto k1 = static_cast < float > ( m_K1 ) ; //All types must be float.
const auto k2 = static_cast < float > ( m_K2 ) ;
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
auto * __restrict hist = m_HistBuckets . data ( ) ; //Vectorizer can't tell these point to different locations.
auto * __restrict acc = m_AccumulatorBuckets . data ( ) ;
for ( size_t i = row ; i < rowEnd ; i + + )
{
2021-04-19 23:07:24 -04:00
const float logScale = ( k1 * std : : log ( 1.0f + hist [ i ] . a * k2 ) ) / ( hist [ i ] . a + std : : numeric_limits < float > : : epsilon ( ) ) ;
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
acc [ i ] . r = hist [ i ] . r * logScale ; //Must break these out individually. Vectorizer can't reason about vec4's overloaded * operator.
acc [ i ] . g = hist [ i ] . g * logScale ;
acc [ i ] . b = hist [ i ] . b * logScale ;
acc [ i ] . a = hist [ i ] . a * logScale ;
}
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Perform log scale density filtering.
/// Base case for simple log scale density estimation as discussed (mostly) in the paper
/// in section 4, p. 6-9.
/// </summary>
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
/// <param name="forceOutput">Whether this output was forced due to an interactive render</param>
2014-07-08 03:11:14 -04:00
/// <returns>True if not prematurely aborted, else false.</returns>
template < typename T , typename bucketT >
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
eRenderStatus Renderer < T , bucketT > : : LogScaleDensityFilter ( bool forceOutput )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
size_t startRow = 0 ;
size_t endRow = m_SuperRasH ;
size_t endCol = m_SuperRasW ;
2014-07-08 03:11:14 -04:00
//Timing t(4);
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
//Original didn't parallelize this, doing so gives a 50-75% speedup.
//The value can be directly assigned, which is quicker than summing.
2021-12-30 01:10:54 -05:00
parallel_for ( startRow , endRow , m_ThreadsToUse , [ & ] ( size_t j )
2014-07-08 03:11:14 -04:00
{
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
size_t row = j * m_SuperRasW ;
size_t rowEnd = row + endCol ;
2014-09-10 01:41:26 -04:00
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
if ( ! m_Abort )
{
for ( size_t i = row ; i < rowEnd ; i + + )
2014-07-08 03:11:14 -04:00
{
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
//Check for visibility first before doing anything else to avoid all possible unnecessary calculations.
if ( m_HistBuckets [ i ] . a ! = 0 )
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
{
2021-04-19 23:07:24 -04:00
const bucketT logScale = ( m_K1 * std : : log ( 1 + m_HistBuckets [ i ] . a * m_K2 ) ) / m_HistBuckets [ i ] . a ;
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
//Original did a temporary assignment, then *= logScale, then passed the result to bump_no_overflow().
//Combine here into one operation for a slight speedup.
//Vectorized version:
bucketT * __restrict hist = glm : : value_ptr ( m_HistBuckets [ i ] ) ; //Vectorizer can't tell these point to different locations.
bucketT * __restrict acc = glm : : value_ptr ( m_AccumulatorBuckets [ i ] ) ;
2017-07-22 16:43:35 -04:00
for ( size_t v = 0 ; v < 4 ; v + + ) //Vectorized by compiler.
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
acc [ v ] = hist [ v ] * logScale ;
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
}
2014-07-08 03:11:14 -04:00
}
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
}
2021-12-30 01:10:54 -05:00
} ) ;
2017-09-03 02:01:10 -04:00
if ( m_Callback & & ! m_Abort )
if ( ! m_Callback - > ProgressFunc ( m_Ember , m_ProgressParameter , 100.0 , 1 , 0 ) )
Abort ( ) ;
2014-07-08 03:11:14 -04:00
//t.Toc(__FUNCTION__);
2015-12-31 19:00:36 -05:00
return m_Abort ? eRenderStatus : : RENDER_ABORT : eRenderStatus : : RENDER_OK ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Perform the more advanced Gaussian density filter.
/// More advanced density estimation filtering given less mention in the paper, but used
/// much more in practice as it gives the best results.
/// Section 8, p. 11-13.
/// </summary>
/// <returns>True if not prematurely aborted, else false.</returns>
template < typename T , typename bucketT >
eRenderStatus Renderer < T , bucketT > : : GaussianDensityFilter ( )
{
Timing totalTime , localTime ;
2014-10-14 11:53:15 -04:00
bool scf = ! ( Supersample ( ) & 1 ) ;
2021-04-19 23:07:24 -04:00
intmax_t ss = Floor < T > ( Supersample ( ) / static_cast < T > ( 2 ) ) ;
T scfact = std : : pow ( Supersample ( ) / ( Supersample ( ) + static_cast < T > ( 1 ) ) , static_cast < T > ( 2 ) ) ;
2014-10-14 11:53:15 -04:00
size_t startRow = Supersample ( ) - 1 ;
size_t endRow = m_SuperRasH - ( Supersample ( ) - 1 ) ; //Original did + which is most likely wrong.
intmax_t startCol = Supersample ( ) - 1 ;
intmax_t endCol = m_SuperRasW - ( Supersample ( ) - 1 ) ;
2021-12-30 01:10:54 -05:00
size_t chunkSize = static_cast < size_t > ( std : : ceil ( static_cast < double > ( endRow - startRow ) / static_cast < double > ( m_ThreadsToUse ) ) ) ;
2014-07-08 03:11:14 -04:00
//parallel_for scales very well, dividing the work almost perfectly among all processors.
2021-12-30 01:10:54 -05:00
parallel_for ( static_cast < size_t > ( 0 ) , m_ThreadsToUse , m_ThreadsToUse , [ & ] ( size_t threadIndex )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
size_t pixelNumber = 0 ;
2021-04-19 23:07:24 -04:00
const auto localStartRow = static_cast < intmax_t > ( std : : min < size_t > ( startRow + ( threadIndex * chunkSize ) , endRow - 1 ) ) ;
const auto localEndRow = static_cast < intmax_t > ( std : : min < size_t > ( localStartRow + chunkSize , endRow ) ) ;
const size_t pixelsThisThread = static_cast < size_t > ( localEndRow - localStartRow ) * m_SuperRasW ;
2014-07-08 03:11:14 -04:00
double lastPercent = 0 ;
2015-03-21 18:27:37 -04:00
tvec4 < bucketT , glm : : defaultp > logScaleBucket ;
2014-10-15 11:19:59 -04:00
2014-10-14 11:53:15 -04:00
for ( intmax_t j = localStartRow ; ( j < localEndRow ) & & ! m_Abort ; j + + )
2014-07-08 03:11:14 -04:00
{
2021-04-19 23:07:24 -04:00
const auto buckets = m_HistBuckets . data ( ) ;
const auto bucketRowStart = buckets + ( j * m_SuperRasW ) ; //Pull out of inner loop for optimization.
const auto filterCoefs = m_DensityFilter - > Coefs ( ) ;
const auto filterWidths = m_DensityFilter - > Widths ( ) ;
2014-10-15 11:19:59 -04:00
2014-10-14 11:53:15 -04:00
for ( intmax_t i = startCol ; i < endCol ; i + + )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
intmax_t ii , jj , arrFilterWidth ;
size_t filterSelectInt , filterCoefIndex ;
2014-07-08 03:11:14 -04:00
T filterSelect = 0 ;
06/09/2017
--User changes
-dark.qss is now per-OS.
-Properly set/reload palette when coming from the palette editor. The latter must be done if they've modified the current palette even if they've clicked cancel.
--Bug fixes
-Make the following variations safer by using Zeps(): conic, bipolar, edisc, whorl, tan, csc, cot, tanh, sech, csch, coth, auger, bwraps, hypertile3d, hypertile3d1, ortho, poincare, rational3, barycentroid, sschecks, cscq, cschq, scry_3D, splitbrdr, hexcrop, nblur, crob.
-Fix bug enabling/disabling overwrite button in palette editor.
-Small optimization for gdoffs, use precalcAtanYX.
-Properly propagate z through circlesplit, cylinder2 and tile_log variations.
-Some values in truchet_fill could've been NaN.
--Code changes
-Make most installation files read only.
-Qualify many calls with std:: to ensure they're not colliding with glm::
-Use auto in more places.
2017-06-09 22:38:06 -04:00
auto bucket = bucketRowStart + i ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
//Don't do anything if there's no hits here. Must also put this first to avoid dividing by zero below.
if ( bucket - > a = = 0 )
continue ;
2014-10-15 11:19:59 -04:00
2021-04-19 23:07:24 -04:00
const bucketT cacheLog = ( m_K1 * std : : log ( 1 + bucket - > a * m_K2 ) ) / bucket - > a ; //Caching this calculation gives a 30% speedup.
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
if ( ss = = 0 )
{
filterSelect = bucket - > a ;
}
else
{
//The original contained a glaring flaw as it would run past the boundaries of the buffers
//when calculating the density for a box centered on the last row or column.
//Clamp here to not run over the edge.
2021-04-19 23:07:24 -04:00
const intmax_t densityBoxLeftX = ( i - std : : min ( i , ss ) ) ;
const intmax_t densityBoxRightX = ( i + std : : min ( ss , static_cast < intmax_t > ( m_SuperRasW ) - i - 1 ) ) ;
const intmax_t densityBoxTopY = ( j - std : : min ( j , ss ) ) ;
const intmax_t densityBoxBottomY = ( j + std : : min ( ss , static_cast < intmax_t > ( m_SuperRasH ) - j - 1 ) ) ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
//Count density in ssxss area.
//Original went one col at a time, which is cache inefficient. Go one row at at time here for a slight speedup.
for ( jj = densityBoxTopY ; jj < = densityBoxBottomY ; jj + + )
for ( ii = densityBoxLeftX ; ii < = densityBoxRightX ; ii + + )
filterSelect + = buckets [ ii + ( jj * m_SuperRasW ) ] . a ; //Original divided by 255 in every iteration. Omit here because colors are already in the range of [0..1].
}
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
//Scale if supersample > 1 for equal iters.
if ( scf )
filterSelect * = scfact ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
if ( filterSelect > m_DensityFilter - > MaxFilteredCounts ( ) )
filterSelectInt = m_DensityFilter - > MaxFilterIndex ( ) ;
else if ( filterSelect < = DE_THRESH )
2021-04-19 23:07:24 -04:00
filterSelectInt = static_cast < size_t > ( std : : ceil ( filterSelect ) ) - 1 ;
2014-07-08 03:11:14 -04:00
else
2021-04-19 23:07:24 -04:00
filterSelectInt = DE_THRESH + static_cast < size_t > ( Floor < T > ( std : : pow ( filterSelect - DE_THRESH , m_DensityFilter - > Curve ( ) ) ) ) ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
//If the filter selected below the min specified clamp it to the min.
if ( filterSelectInt > m_DensityFilter - > MaxFilterIndex ( ) )
filterSelectInt = m_DensityFilter - > MaxFilterIndex ( ) ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
//Only have to calculate the values for ~1/8 of the square.
filterCoefIndex = filterSelectInt * m_DensityFilter - > KernelSize ( ) ;
2021-04-19 23:07:24 -04:00
arrFilterWidth = static_cast < intmax_t > ( std : : ceil ( filterWidths [ filterSelectInt ] ) ) - 1 ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
for ( jj = 0 ; jj < = arrFilterWidth ; jj + + )
{
for ( ii = 0 ; ii < = jj ; ii + + , filterCoefIndex + + )
{
//Skip if coef is 0.
if ( filterCoefs [ filterCoefIndex ] = = 0 )
continue ;
2014-10-15 11:19:59 -04:00
2015-08-10 23:10:23 -04:00
bucketT logScale = filterCoefs [ filterCoefIndex ] * cacheLog ;
2014-07-08 03:11:14 -04:00
//Original first assigned the fields, then scaled them. Combine into a single step for a 1% optimization.
2015-08-10 23:10:23 -04:00
logScaleBucket = ( * bucket * logScale ) ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
if ( jj = = 0 & & ii = = 0 )
{
AddToAccum ( logScaleBucket , i , ii , j , jj ) ;
}
else if ( ii = = 0 )
{
AddToAccum ( logScaleBucket , i , 0 , j , - jj ) ;
AddToAccum ( logScaleBucket , i , - jj , j , 0 ) ;
AddToAccum ( logScaleBucket , i , jj , j , 0 ) ;
AddToAccum ( logScaleBucket , i , 0 , j , jj ) ;
}
else if ( jj = = ii )
{
AddToAccum ( logScaleBucket , i , - ii , j , - jj ) ;
AddToAccum ( logScaleBucket , i , ii , j , - jj ) ;
AddToAccum ( logScaleBucket , i , - ii , j , jj ) ;
AddToAccum ( logScaleBucket , i , ii , j , jj ) ;
}
else
{
//Attempting to optimize cache access by putting these in order makes no difference, even on large images, but do it anyway.
AddToAccum ( logScaleBucket , i , - ii , j , - jj ) ;
AddToAccum ( logScaleBucket , i , ii , j , - jj ) ;
AddToAccum ( logScaleBucket , i , - jj , j , - ii ) ;
AddToAccum ( logScaleBucket , i , jj , j , - ii ) ;
AddToAccum ( logScaleBucket , i , - jj , j , ii ) ;
AddToAccum ( logScaleBucket , i , jj , j , ii ) ;
AddToAccum ( logScaleBucket , i , - ii , j , jj ) ;
AddToAccum ( logScaleBucket , i , ii , j , jj ) ;
}
}
}
}
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
if ( m_Callback & & threadIndex = = 0 )
{
pixelNumber + = m_SuperRasW ;
2021-04-19 23:07:24 -04:00
const auto percent = ( static_cast < double > ( pixelNumber ) / static_cast < double > ( pixelsThisThread ) ) * 100.0 ;
const auto percentDiff = percent - lastPercent ;
const auto toc = localTime . Toc ( ) ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
if ( percentDiff > = 10 | | ( toc > 1000 & & percentDiff > = 1 ) )
{
2021-04-19 23:07:24 -04:00
const auto etaMs = ( ( 100.0 - percent ) / percent ) * totalTime . Toc ( ) ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
if ( ! m_Callback - > ProgressFunc ( m_Ember , m_ProgressParameter , percent , 1 , etaMs ) )
Abort ( ) ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
lastPercent = percent ;
localTime . Tic ( ) ;
}
}
}
2021-12-30 01:10:54 -05:00
} ) ;
2014-10-15 11:19:59 -04:00
2014-07-08 03:11:14 -04:00
if ( m_Callback & & ! m_Abort )
m_Callback - > ProgressFunc ( m_Ember , m_ProgressParameter , 100.0 , 1 , 0 ) ;
//totalTime.Toc(__FUNCTION__);
2015-12-31 19:00:36 -05:00
return m_Abort ? eRenderStatus : : RENDER_ABORT : eRenderStatus : : RENDER_OK ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
2018-04-29 01:28:05 -04:00
/// Produce a final, visible image by clipping, gamma correcting and spatial filtering the color values
/// in the density filtering buffer and save to the passed in buffer.
2014-07-08 03:11:14 -04:00
/// </summary>
/// <param name="pixels">The pixel vector to allocate and store the final image in</param>
/// <param name="finalOffset">Offset in the buffer to store the pixels to</param>
/// <returns>True if not prematurely aborted, else false.</returns>
template < typename T , typename bucketT >
2017-07-22 16:43:35 -04:00
eRenderStatus Renderer < T , bucketT > : : AccumulatorToFinalImage ( vector < v4F > & pixels , size_t finalOffset )
2014-07-08 03:11:14 -04:00
{
2018-04-29 01:28:05 -04:00
EnterFinalAccum ( ) ;
2014-07-08 03:11:14 -04:00
2018-04-29 01:28:05 -04:00
if ( ! PrepFinalAccumVector ( pixels ) )
{
LeaveFinalAccum ( ) ;
2015-12-31 19:00:36 -05:00
return eRenderStatus : : RENDER_ERROR ;
2018-04-29 01:28:05 -04:00
}
2014-07-08 03:11:14 -04:00
//Timing t(4);
2021-04-19 23:07:24 -04:00
const size_t filterWidth = m_SpatialFilter - > FinalFilterWidth ( ) ;
2015-08-10 23:10:23 -04:00
bucketT g , linRange , vibrancy ;
Color < bucketT > background ;
2018-04-29 01:28:05 -04:00
auto p = pixels . data ( ) ;
p + = finalOffset ;
2017-07-05 02:08:06 -04:00
PrepFinalAccumVals ( background , g , linRange , vibrancy ) ; //After this, background has been scaled from 0-1 to 0-255.
2014-07-08 03:11:14 -04:00
//If early clip, go through the entire accumulator and perform gamma correction first.
//The original does it this way as well and it's roughly 11 times faster to do it this way than inline below with each pixel.
if ( EarlyClip ( ) )
{
2021-12-30 01:10:54 -05:00
parallel_for ( static_cast < size_t > ( 0 ) , m_SuperRasH , m_ThreadsToUse , [ & ] ( size_t j )
2014-07-08 03:11:14 -04:00
{
2016-03-28 21:49:10 -04:00
auto rowStart = m_AccumulatorBuckets . data ( ) + ( j * m_SuperRasW ) ; //Pull out of inner loop for optimization.
2021-04-19 23:07:24 -04:00
const auto rowEnd = rowStart + m_SuperRasW ;
2014-09-10 01:41:26 -04:00
2016-03-28 21:49:10 -04:00
while ( rowStart < rowEnd & & ! m_Abort ) //Use the pointer itself as the offset to save an extra addition per iter.
2014-07-08 03:11:14 -04:00
{
2017-07-22 16:43:35 -04:00
GammaCorrection ( * rowStart , background , g , linRange , vibrancy , false , glm : : value_ptr ( * rowStart ) ) ; //Write back in place.
2016-03-28 21:49:10 -04:00
rowStart + + ;
2014-07-08 03:11:14 -04:00
}
2021-12-30 01:10:54 -05:00
} ) ;
2014-07-08 03:11:14 -04:00
}
if ( m_Abort )
{
LeaveFinalAccum ( ) ;
2015-12-31 19:00:36 -05:00
return eRenderStatus : : RENDER_ABORT ;
2014-07-08 03:11:14 -04:00
}
//Note that abort is not checked here. The final accumulation must run to completion
//otherwise artifacts that resemble page tearing will occur in an interactive run. It's
//critical to never exit this loop prematurely.
2014-10-14 11:53:15 -04:00
//for (size_t j = 0; j < FinalRasH(); j++)//Keep around for debugging.
2021-12-30 01:10:54 -05:00
parallel_for ( static_cast < size_t > ( 0 ) , FinalRasH ( ) , m_ThreadsToUse , [ & ] ( size_t j )
2014-07-08 03:11:14 -04:00
{
Color < bucketT > newBucket ;
2017-07-22 16:43:35 -04:00
size_t pixelsRowStart = ( m_YAxisUp ? ( ( FinalRasH ( ) - j ) - 1 ) : j ) * FinalRasW ( ) ; //Pull out of inner loop for optimization.
2014-10-14 11:53:15 -04:00
size_t y = m_DensityFilterOffset + ( j * Supersample ( ) ) ; //Start at the beginning row of each super sample block.
2016-03-28 21:49:10 -04:00
size_t clampedFilterH = std : : min ( filterWidth , m_SuperRasH - y ) ; //Make sure the filter doesn't go past the bottom of the gutter.
2018-04-29 01:28:05 -04:00
auto pv4T = p + pixelsRowStart ;
2014-07-08 03:11:14 -04:00
2017-07-22 16:43:35 -04:00
for ( size_t i = 0 ; i < FinalRasW ( ) ; i + + , pv4T + + )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
size_t ii , jj ;
2021-04-19 23:07:24 -04:00
const size_t x = m_DensityFilterOffset + ( i * Supersample ( ) ) ; //Start at the beginning column of each super sample block.
const size_t clampedFilterW = std : : min ( filterWidth , m_SuperRasW - x ) ; //Make sure the filter doesn't go past the right of the gutter.
2014-07-08 03:11:14 -04:00
newBucket . Clear ( ) ;
2014-09-10 01:41:26 -04:00
2014-07-08 03:11:14 -04:00
//Original was iterating column-wise, which is slow.
//Here, iterate one row at a time, giving a 10% speed increase.
2016-03-28 21:49:10 -04:00
for ( jj = 0 ; jj < clampedFilterH ; jj + + )
2014-07-08 03:11:14 -04:00
{
2016-03-28 21:49:10 -04:00
size_t filterKRowIndex = jj * filterWidth ; //Use the full, non-clamped width to get the filter value.
2014-10-14 11:53:15 -04:00
size_t accumRowIndex = ( y + jj ) * m_SuperRasW ; //Pull out of inner loop for optimization.
2014-09-10 01:41:26 -04:00
2016-03-28 21:49:10 -04:00
for ( ii = 0 ; ii < clampedFilterW ; ii + + )
2014-07-08 03:11:14 -04:00
{
//Need to dereference the spatial filter pointer object to use the [] operator. Makes no speed difference.
2016-03-28 21:49:10 -04:00
bucketT k = ( ( * m_SpatialFilter ) [ filterKRowIndex + ii ] ) ;
newBucket + = ( m_AccumulatorBuckets [ accumRowIndex + ( x + ii ) ] * k ) ;
2014-07-08 03:11:14 -04:00
}
}
2014-09-10 01:41:26 -04:00
2017-07-22 16:43:35 -04:00
auto pf = reinterpret_cast < float * > ( pv4T ) ;
GammaCorrection ( * ( reinterpret_cast < tvec4 < bucketT , glm : : defaultp > * > ( & newBucket ) ) , background , g , linRange , vibrancy , true , pf ) ;
2014-07-08 03:11:14 -04:00
}
2021-12-30 01:10:54 -05:00
} ) ;
2014-09-10 01:41:26 -04:00
2016-04-11 21:15:14 -04:00
//Insert the palette into the image for debugging purposes. Not implemented on the GPU.
if ( m_InsertPalette )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
size_t i , j , ph = 100 ;
2014-07-08 03:11:14 -04:00
if ( ph > = FinalRasH ( ) )
ph = FinalRasH ( ) ;
2014-09-10 01:41:26 -04:00
2017-07-22 16:43:35 -04:00
for ( j = 0 ; j < ph ; j + + )
2016-04-11 21:15:14 -04:00
{
2017-07-22 16:43:35 -04:00
for ( i = 0 ; i < FinalRasW ( ) ; i + + )
2016-04-11 21:15:14 -04:00
{
2021-04-19 23:07:24 -04:00
const auto pp = p + ( i + j * FinalRasW ( ) ) ;
2018-04-29 01:28:05 -04:00
pp - > r = m_TempEmber . m_Palette [ i * 256 / FinalRasW ( ) ] [ 0 ] ;
pp - > g = m_TempEmber . m_Palette [ i * 256 / FinalRasW ( ) ] [ 1 ] ;
pp - > b = m_TempEmber . m_Palette [ i * 256 / FinalRasW ( ) ] [ 2 ] ;
pp - > a = 1 ;
2014-07-08 03:11:14 -04:00
}
}
}
2015-12-31 19:00:36 -05:00
//t.Toc(__FUNCTION__);
2014-07-08 03:11:14 -04:00
LeaveFinalAccum ( ) ;
2015-12-31 19:00:36 -05:00
return m_Abort ? eRenderStatus : : RENDER_ABORT : eRenderStatus : : RENDER_OK ;
2014-07-08 03:11:14 -04:00
}
//#define TG 1
//#define NEWSUBBATCH 1
/// <summary>
/// Run the iteration algorithm for the specified number of iterations.
/// This is only called after all other setup has been done.
/// This function will be called multiple times for an interactive rendering, and
/// once for a straight through render.
/// The iteration is reset and fused in each thread after each sub batch is done
2014-11-28 04:37:51 -05:00
/// which by default is 10,240 iterations.
2014-07-08 03:11:14 -04:00
/// </summary>
/// <param name="iterCount">The number of iterations to run</param>
2014-11-03 02:16:34 -05:00
/// <param name="temporalSample">The temporal sample this is running for</param>
2014-07-08 03:11:14 -04:00
/// <returns>Rendering statistics</returns>
template < typename T , typename bucketT >
2014-11-03 02:16:34 -05:00
EmberStats Renderer < T , bucketT > : : Iterate ( size_t iterCount , size_t temporalSample )
2014-07-08 03:11:14 -04:00
{
//Timing t2(4);
2014-08-06 00:50:52 -04:00
m_IterTimer . Tic ( ) ;
2021-04-19 23:07:24 -04:00
const size_t totalItersPerThread = static_cast < size_t > ( std : : ceil ( static_cast < double > ( iterCount ) / static_cast < double > ( m_ThreadsToUse ) ) ) ;
2014-07-08 03:11:14 -04:00
EmberStats stats ;
2016-12-05 22:04:33 -05:00
//vector<double> accumTimes(4);
2014-07-08 03:11:14 -04:00
--User changes
-Add new variations: bubbleT3D, crob, hexaplay3D, hexcrop, hexes, hexnix3D, loonie2, loonie3, nBlur, octapol and synth.
-Allow for pre/post versions of dc_bubble, dc_cylinder and dc_linear whereas before they were omitted.
-When saving a file with multiple embers in it, detect if time values are all the same and if so, start them at zero and increment by 1 for each ember.
-Allow for numerous quality increases to be coalesced into one. It will pick up at the end of the current render.
-Show selection highlight on variations tree in response to mouse hover. This makes it easier to see for which variation or param the current mouse wheel action will apply.
-Make default temporal samples be 100, whereas before it was 1000 which was overkill.
-Require the shift key to be held with delete for deleting an ember to prevent it from triggering when the user enters delete in the edit box.
-This wasn't otherwise fixable without writing a lot more code.
--Bug fixes
-EmberGenome was crashing when generating a sequence from a source file with more than 2 embers in it.
-EmberGenome was improperly handling the first frame of a merge after the last frame of the loop.
-These bugs were due to a previous commit. Revert parts of that commit.
-Prevent a zoom value of less than 0 when reading from xml.
-Slight optimization of the crescents, and mask variations, if the compiler wasn't doing it already.
-Unique file naming was broken because it was looking for _# and the default names ended with -#.
-Disallow renaming of an ember in the library tree to an empty string.
-Severe bug that prevented some variations from being read correctly from params generated outside this program.
-Severe OpenCL randomization bug. The first x coordinates of the first points in the first kernel call of the first ember of a render since the OpenCL renderer object was created were not random and were mostly -1.
-Severe bug when populating xform selection distributions that could sometimes cause a crash due to roundoff error. Fix by using double.
-Limit the max number of variations in a random ember to MAX_CL_VARS, which is 8. This ensures they'll look the same on CPU and GPU.
-Prevent user from saving stylesheet to default.qss, it's a special reserved filename.
--Code changes
-Generalize using the running sum output point inside of a variation for all cases: pre, reg and post.
-Allow for array variables in variations where the address of each element is stored in m_Params.
-Qualify all math functions with std::
-No longer use our own Clamp() in OpenCL, instead use the standard clamp().
-Redesign how functions are used in the variations OpenCL code.
-Add tests to EmberTester to verify some of the new functionality.
-Place more const and override qualifiers on functions where appropriate.
-Add a global rand with a lock to be used very sparingly.
-Use a map instead of a vector for bad param names in Xml parsing.
-Prefix affine interpolation mode defines with "AFFINE_" to make their purpose more clear.
-Allow for variations that change state during iteration by sending a separate copy of the ember to each rendering thread.
-Implement this same functionality with a local struct in OpenCL. It's members are the total of all variables that need to change state within an ember.
-Add Contains() function to Utils.h.
-EmberRender: print names of kernels being printed with --dump_kernel option.
-Clean up EmberTester to handle some of the recent changes.
-Fix various casts.
-Replace % 2 with & 1, even though the compiler was likely doing this already.
-Add new file Variations06.h to accommodate new variations.
-General cleanup.
2015-11-22 17:15:07 -05:00
//Do this every iteration for an animation, or else do it once for a single image. CPU only.
if ( ! m_LastIter )
{
m_ThreadEmbers . clear ( ) ;
m_ThreadEmbers . insert ( m_ThreadEmbers . begin ( ) , m_ThreadsToUse , m_Ember ) ;
}
2015-12-31 19:00:36 -05:00
2021-12-30 01:10:54 -05:00
parallel_for ( static_cast < size_t > ( 0 ) , m_ThreadsToUse , m_ThreadsToUse , [ & ] ( size_t threadIndex )
2014-07-08 03:11:14 -04:00
{
2016-03-01 20:26:45 -05:00
# if defined(_WIN32)
2021-04-19 23:07:24 -04:00
SetThreadPriority ( GetCurrentThread ( ) , static_cast < int > ( m_Priority ) ) ;
2015-06-22 10:03:15 -04:00
# elif defined(__APPLE__)
2016-12-05 22:04:33 -05:00
sched_param sp = { 0 } ;
2021-04-19 23:07:24 -04:00
sp . sched_priority = static_cast < int > ( m_Priority ) ;
2016-12-05 22:04:33 -05:00
pthread_setschedparam ( pthread_self ( ) , SCHED_RR , & sp ) ;
2015-06-17 23:05:53 -04:00
# else
2021-04-19 23:07:24 -04:00
pthread_setschedprio ( pthread_self ( ) , static_cast < int > ( m_Priority ) ) ;
2014-07-08 03:11:14 -04:00
# endif
2016-12-05 22:04:33 -05:00
//Timing t;
IterParams < T > params ;
m_BadVals [ threadIndex ] = 0 ;
params . m_Count = std : : min ( totalItersPerThread , SubBatchSize ( ) ) ;
params . m_Skip = FuseCount ( ) ;
//params.m_OneColDiv2 = m_CarToRas.OneCol() / 2;
//params.m_OneRowDiv2 = m_CarToRas.OneRow() / 2;
//Sub batch iterations, loop 2.
for ( m_SubBatch [ threadIndex ] = 0 ; ( m_SubBatch [ threadIndex ] < totalItersPerThread ) & & ! m_Abort ; m_SubBatch [ threadIndex ] + = params . m_Count )
{
//Must recalculate the number of iters to run on each sub batch because the last batch will most likely have less than SubBatchSize iters.
//For example, if 51,000 are requested, and the sbs is 10,000, it should run 5 sub batches of 10,000 iters, and one final sub batch of 1,000 iters.
params . m_Count = std : : min ( params . m_Count , totalItersPerThread - m_SubBatch [ threadIndex ] ) ;
//Use first as random point, the rest are iterated points.
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
//Note that this gets reset with a new random point for each SubBatchSize iterations.
2016-12-05 22:04:33 -05:00
//This helps correct if iteration happens to be on a bad trajectory.
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
m_Samples [ threadIndex ] [ 0 ] . m_X = m_Rand [ threadIndex ] . template Frand < T > ( - m_ThreadEmbers [ threadIndex ] . m_RandPointRange , m_ThreadEmbers [ threadIndex ] . m_RandPointRange ) ;
m_Samples [ threadIndex ] [ 0 ] . m_Y = m_Rand [ threadIndex ] . template Frand < T > ( - m_ThreadEmbers [ threadIndex ] . m_RandPointRange , m_ThreadEmbers [ threadIndex ] . m_RandPointRange ) ;
2016-12-05 22:04:33 -05:00
m_Samples [ threadIndex ] [ 0 ] . m_Z = 0 ; //m_Ember.m_CamZPos;//Apo set this to 0, then made the user use special variations to kick it. It seems easier to just set it to zpos.
m_Samples [ threadIndex ] [ 0 ] . m_ColorX = m_Rand [ threadIndex ] . template Frand01 < T > ( ) ;
2018-03-30 12:56:24 -04:00
//Check if the user wanted to suspend the process.
while ( Paused ( ) )
std : : this_thread : : sleep_for ( 500 ms ) ;
2016-12-05 22:04:33 -05:00
//Finally, iterate.
//t.Tic();
//Iterating, loop 3.
2020-01-19 01:29:08 -05:00
m_BadVals [ threadIndex ] + = m_Iterator - > Iterate ( m_ThreadEmbers [ threadIndex ] , params , m_CarToRas , m_Samples [ threadIndex ] . data ( ) , m_Rand [ threadIndex ] ) ;
2016-12-05 22:04:33 -05:00
//iterationTime += t.Toc();
if ( m_LockAccum )
m_AccumCs . lock ( ) ;
//t.Tic();
//Map temp buffer samples into the histogram using the palette for color.
Accumulate ( m_Rand [ threadIndex ] , m_Samples [ threadIndex ] . data ( ) , params . m_Count , & m_Dmap ) ;
//accumTimes[threadIndex] += t.Toc();
if ( m_LockAccum )
m_AccumCs . unlock ( ) ;
if ( m_Callback & & threadIndex = = 0 )
2014-07-08 03:11:14 -04:00
{
2021-01-21 23:48:45 -05:00
auto percent = 100.0 *
2021-04-19 23:07:24 -04:00
static_cast < double >
2021-01-21 23:48:45 -05:00
(
2021-04-19 23:07:24 -04:00
static_cast < double >
2021-01-21 23:48:45 -05:00
(
2021-04-19 23:07:24 -04:00
static_cast < double >
2021-01-21 23:48:45 -05:00
(
//Takes progress of current thread and multiplies by thread count.
//This assumes the threads progress at roughly the same speed.
//Adding m_LastIter is done so that an incremental render still gives an accurate percentage.
2021-04-19 23:07:24 -04:00
static_cast < double > ( m_LastIter + ( m_SubBatch [ threadIndex ] * m_ThreadsToUse ) ) / static_cast < double > ( ItersPerTemporalSample ( ) )
2021-01-21 23:48:45 -05:00
) + temporalSample
2021-04-19 23:07:24 -04:00
) / static_cast < double > ( TemporalSamples ( ) )
2021-01-21 23:48:45 -05:00
) ;
2021-04-19 23:07:24 -04:00
const auto percentDiff = percent - m_LastIterPercent ;
const auto toc = m_ProgressTimer . Toc ( ) ;
2016-12-05 22:04:33 -05:00
if ( percentDiff > = 10 | | ( toc > 1000 & & percentDiff > = 1 ) ) //Call callback function if either 10% has passed, or one second (and 1%).
{
2021-04-19 23:07:24 -04:00
const auto startingpercent = 100.0 * ( m_LastIter / static_cast < double > ( ItersPerTemporalSample ( ) ) ) ; //This is done to support incremental renders, starting from the percentage it left off on.
const auto currentpercent = percent - startingpercent ; //Current percent in terms of starting percentage. So starting at 50% and progressing 5% will give a value of 5%, not 55%.
const auto etaMs = currentpercent = = 0 ? 0 : ( ( ( 100.0 - startingpercent ) - currentpercent ) / currentpercent ) * m_RenderTimer . Toc ( ) ; //Subtract startingpercent from 100% so that it's properly scaled, meaning rendering from 50% - 100% will be treated as 0% - 100%.
2014-09-10 01:41:26 -04:00
2016-12-05 22:04:33 -05:00
if ( ! m_Callback - > ProgressFunc ( m_Ember , m_ProgressParameter , percent , 0 , etaMs ) )
Abort ( ) ;
2014-07-08 03:11:14 -04:00
2016-12-05 22:04:33 -05:00
m_LastIterPercent = percent ;
m_ProgressTimer . Tic ( ) ;
2014-07-08 03:11:14 -04:00
}
}
2016-12-05 22:04:33 -05:00
}
2021-12-30 01:10:54 -05:00
} ) ;
2014-07-08 03:11:14 -04:00
stats . m_Iters = std : : accumulate ( m_SubBatch . begin ( ) , m_SubBatch . end ( ) , 0ULL ) ; //Sum of iter count of all threads.
2014-08-06 00:50:52 -04:00
stats . m_Badvals = std : : accumulate ( m_BadVals . begin ( ) , m_BadVals . end ( ) , 0ULL ) ;
stats . m_IterMs = m_IterTimer . Toc ( ) ;
2016-12-05 22:04:33 -05:00
//cout << "Accum time: " << std::accumulate(accumTimes.begin(), accumTimes.end(), 0.0) << endl;
2014-07-08 03:11:14 -04:00
//t2.Toc(__FUNCTION__);
return stats ;
}
/// <summary>
2014-10-14 11:53:15 -04:00
/// Non-virtual render properties, getters and setters.
2014-07-26 15:03:51 -04:00
/// </summary>
2014-07-08 03:11:14 -04:00
/// <summary>
2014-10-14 11:53:15 -04:00
/// Get the pixel aspect ratio of the output image.
2014-07-08 03:11:14 -04:00
/// Default: 1.
/// </summary>
2014-10-14 11:53:15 -04:00
/// <returns>The pixel aspect ratio.</returns>
template < typename T , typename bucketT > T Renderer < T , bucketT > : : PixelAspectRatio ( ) const { return m_PixelAspectRatio ; }
2014-07-08 03:11:14 -04:00
/// <summary>
2014-10-14 11:53:15 -04:00
/// Set the pixel aspect ratio of the output image.
/// Reset the rendering process.
2014-07-08 03:11:14 -04:00
/// </summary>
2014-10-14 11:53:15 -04:00
/// <param name="pixelAspectRatio">The pixel aspect ratio.</param>
2014-07-08 03:11:14 -04:00
template < typename T , typename bucketT >
2014-10-14 11:53:15 -04:00
void Renderer < T , bucketT > : : PixelAspectRatio ( T pixelAspectRatio )
2014-07-08 03:11:14 -04:00
{
2015-12-31 19:00:36 -05:00
ChangeVal ( [ & ] { m_PixelAspectRatio = pixelAspectRatio ; } , eProcessAction : : FULL_RENDER ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
2014-10-14 11:53:15 -04:00
/// Non-virtual renderer properties, getters only.
2014-07-08 03:11:14 -04:00
/// </summary>
2015-03-21 18:27:37 -04:00
template < typename T , typename bucketT > T Renderer < T , bucketT > : : Scale ( ) const { return m_Scale ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : PixelsPerUnitX ( ) const { return m_PixelsPerUnitX ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : PixelsPerUnitY ( ) const { return m_PixelsPerUnitY ; }
2015-08-10 23:10:23 -04:00
template < typename T , typename bucketT > bucketT Renderer < T , bucketT > : : K1 ( ) const { return m_K1 ; }
template < typename T , typename bucketT > bucketT Renderer < T , bucketT > : : K2 ( ) const { return m_K2 ; }
--User changes
-Add support for multiple GPU devices.
--These options are present in the command line and in Fractorium.
-Change scheme of specifying devices from platform,device to just total device index.
--Single number on the command line.
--Change from combo boxes for device selection to a table of all devices in Fractorium.
-Temporal samples defaults to 100 instead of 1000 which was needless overkill.
--Bug fixes
-EmberAnimate, EmberRender, FractoriumSettings, FinalRenderDialog: Fix wrong order of arguments to Clamp() when assigning thread priority.
-VariationsDC.h: Fix NVidia OpenCL compilation error in DCTriangleVariation.
-FractoriumXformsColor.cpp: Checking for null pixmap pointer is not enough, must also check if the underlying buffer is null via call to QPixmap::isNull().
--Code changes
-Ember.h: Add case for FLAME_MOTION_NONE and default in ApplyFlameMotion().
-EmberMotion.h: Call base constructor.
-EmberPch.h: #pragma once only on Windows.
-EmberToXml.h:
--Handle different types of exceptions.
--Add default cases to ToString().
-Isaac.h: Remove unused variable in constructor.
-Point.h: Call base constructor in Color().
-Renderer.h/cpp:
--Add bool to Alloc() to only allocate memory for the histogram. Needed for multi-GPU.
--Make CoordMap() return a const ref, not a pointer.
-SheepTools.h:
--Use 64-bit types like the rest of the code already does.
--Fix some comment misspellings.
-Timing.h: Make BeginTime(), EndTime(), ElapsedTime() and Format() be const functions.
-Utils.h:
--Add new functions Equal() and Split().
--Handle more exception types in ReadFile().
--Get rid of most legacy blending of C and C++ argument parsing.
-XmlToEmber.h:
--Get rid of most legacy blending of C and C++ code from flam3.
--Remove some unused variables.
-EmberAnimate:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
--If a render fails, exit since there is no point in continuing an animation with a missing frame.
--Pass variables to threaded save better, which most likely fixes a very subtle bug that existed before.
--Remove some unused variables.
-EmberGenome, EmberRender:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
-EmberRender:
--Support multi-GPU processing that alternates full frames between devices.
--Use OpenCLInfo instead of OpenCLWrapper for --openclinfo option.
--Remove bucketT template parameter, and hard code float in its place.
--Only print values when not rendering with OpenCL, since they're always 0 in that case.
-EmberCLPch.h:
--#pragma once only on Windows.
--#include <atomic>.
-IterOpenCLKernelCreator.h: Add new kernel for summing two histograms. This is needed for multi-GPU.
-OpenCLWrapper.h:
--Move all OpenCL info related code into its own class OpenCLInfo.
--Add members to cache the values of global memory size and max allocation size.
-RendererCL.h/cpp:
--Redesign to accomodate multi-GPU.
--Constructor now takes a vector of devices.
--Remove DumpErrorReport() function, it's handled in the base.
--ClearBuffer(), ReadPoints(), WritePoints(), ReadHist() and WriteHist() now optionally take a device index as a parameter.
--MakeDmap() override and m_DmapCL member removed because it no longer applies since the histogram is always float since the last commit.
--Add new function SumDeviceHist() to sum histograms from two devices by first copying to a temporary on the host, then a temporary on the device, then summing.
--m_Calls member removed, as it's now per-device.
--OpenCLWrapper removed.
--m_Seeds member is now a vector of vector of seeds, to accomodate a separate and different array of seeds for each device.
--Added member m_Devices, a vector of unique_ptr of RendererCLDevice.
-EmberCommon.h
--Added Devices() function to convert from a vector of device indices to a vector of platform,device indices.
--Changed CreateRenderer() to accept a vector of devices to create a single RendererCL which will split work across multiple devices.
--Added CreateRenderers() function to accept a vector of devices to create multiple RendererCL, each which will render on a single device.
--Add more comments to some existing functions.
-EmberCommonPch.h: #pragma once only on Windows.
-EmberOptions.h:
--Remove --platform option, it's just sequential device number now with the --device option.
--Make --out be OPT_USE_RENDER instead of OPT_RENDER_ANIM since it's an error condition when animating. It makes no sense to write all frames to a single image.
--Add Devices() function to parse comma separated --device option string and return a vector of device indices.
--Make int and uint types be 64-bit, so intmax_t and size_t.
--Make better use of macros.
-JpegUtils.h: Make string parameters to WriteJpeg() and WritePng() be const ref.
-All project files: Turn off buffer security check option in Visual Studio (/Gs-)
-deployment.pri: Remove the line OTHER_FILES +=, it's pointless and was causing problems.
-Ember.pro, EmberCL.pro: Add CONFIG += plugin, otherwise it wouldn't link.
-EmberCL.pro: Add new files for multi-GPU support.
-build_all.sh: use -j4 and QMAKE=${QMAKE:/usr/bin/qmake}
-shared_settings.pri:
-Add version string.
-Remove old DESTDIR definitions.
-Add the following lines or else nothing would build:
CONFIG(release, debug|release) {
CONFIG += warn_off
DESTDIR = ../../../Bin/release
}
CONFIG(debug, debug|release) {
DESTDIR = ../../../Bin/debug
}
QMAKE_POST_LINK += $$quote(cp --update ../../../Data/flam3-palettes.xml $${DESTDIR}$$escape_expand(\n\t))
LIBS += -L/usr/lib -lpthread
-AboutDialog.ui: Another futile attempt to make it look correct on Linux.
-FinalRenderDialog.h/cpp:
--Add support for multi-GPU.
--Change from combo boxes for device selection to a table of all devices.
--Ensure device selection makes sense.
--Remove "FinalRender" prefix of various function names, it's implied given the context.
-FinalRenderEmberController.h/cpp:
--Add support for multi-GPU.
--Change m_FinishedImageCount to be atomic.
--Move CancelRender() from the base to FinalRenderEmberController<T>.
--Refactor RenderComplete() to omit any progress related functionality or image saving since it can be potentially ran in a thread.
--Consolidate setting various renderer fields into SyncGuiToRenderer().
-Fractorium.cpp: Allow for resizing of the options dialog to show the entire device table.
-FractoriumCommon.h: Add various functions to handle a table showing the available OpenCL devices on the system.
-FractoriumEmberController.h/cpp: Remove m_FinalImageIndex, it's no longer needed.
-FractoriumRender.cpp: Scale the interactive sub batch count and quality by the number of devices used.
-FractoriumSettings.h/cpp:
--Temporal samples defaults to 100 instead of 1000 which was needless overkill.
--Add multi-GPU support, remove old device,platform pair.
-FractoriumToolbar.cpp: Disable OpenCL toolbar button if there are no devices present on the system.
-FractoriumOptionsDialog.h/cpp:
--Add support for multi-GPU.
--Consolidate more assignments in DataToGui().
--Enable/disable CPU/OpenCL items in response to OpenCL checkbox event.
-Misc: Convert almost everything to size_t for unsigned, intmax_t for signed.
2015-09-12 21:33:45 -04:00
template < typename T , typename bucketT > const CarToRas < T > & Renderer < T , bucketT > : : CoordMap ( ) const { return m_CarToRas ; }
2015-03-21 18:27:37 -04:00
template < typename T , typename bucketT > tvec4 < bucketT , glm : : defaultp > * Renderer < T , bucketT > : : HistBuckets ( ) { return m_HistBuckets . data ( ) ; }
template < typename T , typename bucketT > tvec4 < bucketT , glm : : defaultp > * Renderer < T , bucketT > : : AccumulatorBuckets ( ) { return m_AccumulatorBuckets . data ( ) ; }
2015-08-10 23:10:23 -04:00
template < typename T , typename bucketT > SpatialFilter < bucketT > * Renderer < T , bucketT > : : GetSpatialFilter ( ) { return m_SpatialFilter . get ( ) ; }
2015-03-21 18:27:37 -04:00
template < typename T , typename bucketT > TemporalFilter < T > * Renderer < T , bucketT > : : GetTemporalFilter ( ) { return m_TemporalFilter . get ( ) ; }
2014-07-08 03:11:14 -04:00
/// <summary>
2014-10-14 11:53:15 -04:00
/// Virtual renderer properties overridden from RendererBase, getters only.
2014-07-08 03:11:14 -04:00
/// </summary>
2021-04-19 23:07:24 -04:00
template < typename T , typename bucketT > double Renderer < T , bucketT > : : ScaledQuality ( ) const { return static_cast < double > ( m_ScaledQuality ) ; }
template < typename T , typename bucketT > double Renderer < T , bucketT > : : LowerLeftX ( bool gutter ) const { return static_cast < double > ( gutter ? m_CarToRas . CarLlX ( ) : m_LowerLeftX ) ; }
template < typename T , typename bucketT > double Renderer < T , bucketT > : : LowerLeftY ( bool gutter ) const { return static_cast < double > ( gutter ? m_CarToRas . CarLlY ( ) : m_LowerLeftY ) ; }
template < typename T , typename bucketT > double Renderer < T , bucketT > : : UpperRightX ( bool gutter ) const { return static_cast < double > ( gutter ? m_CarToRas . CarUrX ( ) : m_UpperRightX ) ; }
template < typename T , typename bucketT > double Renderer < T , bucketT > : : UpperRightY ( bool gutter ) const { return static_cast < double > ( gutter ? m_CarToRas . CarUrY ( ) : m_UpperRightY ) ; }
2014-10-14 11:53:15 -04:00
template < typename T , typename bucketT > DensityFilterBase * Renderer < T , bucketT > : : GetDensityFilter ( ) { return m_DensityFilter . get ( ) ; }
2014-07-08 03:11:14 -04:00
/// <summary>
2014-10-14 11:53:15 -04:00
/// Non-virtual ember wrappers, getters only.
2014-07-08 03:11:14 -04:00
/// </summary>
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
template < typename T , typename bucketT > bool Renderer < T , bucketT > : : XaosPresent ( ) const { return m_Ember . XaosPresent ( ) ; }
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : Supersample ( ) const { return m_Ember . m_Supersample ; }
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : PaletteIndex ( ) const { return m_Ember . PaletteIndex ( ) ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : Time ( ) const { return m_Ember . m_Time ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : Quality ( ) const { return m_Ember . m_Quality ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : SpatialFilterRadius ( ) const { return m_Ember . m_SpatialFilterRadius ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : PixelsPerUnit ( ) const { return m_Ember . m_PixelsPerUnit ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : Zoom ( ) const { return m_Ember . m_Zoom ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : CenterX ( ) const { return m_Ember . m_CenterX ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : CenterY ( ) const { return m_Ember . m_CenterY ; }
template < typename T , typename bucketT > T Renderer < T , bucketT > : : Rotate ( ) const { return m_Ember . m_Rotate ; }
2021-04-19 23:07:24 -04:00
template < typename T , typename bucketT > bucketT Renderer < T , bucketT > : : Brightness ( ) const { return static_cast < bucketT > ( m_Ember . m_Brightness ) ; }
template < typename T , typename bucketT > bucketT Renderer < T , bucketT > : : Gamma ( ) const { return static_cast < bucketT > ( m_Ember . m_Gamma ) ; }
template < typename T , typename bucketT > bucketT Renderer < T , bucketT > : : Vibrancy ( ) const { return static_cast < bucketT > ( m_Ember . m_Vibrancy ) ; }
template < typename T , typename bucketT > bucketT Renderer < T , bucketT > : : GammaThresh ( ) const { return static_cast < bucketT > ( m_Ember . m_GammaThresh ) ; }
template < typename T , typename bucketT > bucketT Renderer < T , bucketT > : : HighlightPower ( ) const { return static_cast < bucketT > ( m_Ember . m_HighlightPower ) ; }
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
template < typename T , typename bucketT > Color < T > Renderer < T , bucketT > : : Background ( ) const { return m_Ember . m_Background ; }
template < typename T , typename bucketT > const Xform < T > * Renderer < T , bucketT > : : Xforms ( ) const { return m_Ember . Xforms ( ) ; }
template < typename T , typename bucketT > Xform < T > * Renderer < T , bucketT > : : NonConstXforms ( ) { return m_Ember . NonConstXforms ( ) ; }
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : XformCount ( ) const { return m_Ember . XformCount ( ) ; }
template < typename T , typename bucketT > const Xform < T > * Renderer < T , bucketT > : : FinalXform ( ) const { return m_Ember . FinalXform ( ) ; }
template < typename T , typename bucketT > Xform < T > * Renderer < T , bucketT > : : NonConstFinalXform ( ) { return m_Ember . NonConstFinalXform ( ) ; }
template < typename T , typename bucketT > bool Renderer < T , bucketT > : : UseFinalXform ( ) const { return m_Ember . UseFinalXform ( ) ; }
template < typename T , typename bucketT > const Palette < float > * Renderer < T , bucketT > : : GetPalette ( ) const { return & m_Ember . m_Palette ; }
template < typename T , typename bucketT > ePaletteMode Renderer < T , bucketT > : : PaletteMode ( ) const { return m_Ember . m_PaletteMode ; }
2014-07-08 03:11:14 -04:00
/// <summary>
2014-10-14 11:53:15 -04:00
/// Virtual ember wrappers overridden from RendererBase, getters only.
2014-07-08 03:11:14 -04:00
/// </summary>
2014-10-14 11:53:15 -04:00
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : TemporalSamples ( ) const { return m_Ember . m_TemporalSamples ; }
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : FinalRasW ( ) const { return m_Ember . m_FinalRasW ; }
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : FinalRasH ( ) const { return m_Ember . m_FinalRasH ; }
2014-11-28 04:37:51 -05:00
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : SubBatchSize ( ) const { return m_Ember . m_SubBatchSize ; }
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : FuseCount ( ) const { return m_Ember . m_FuseCount ; }
2014-07-08 03:11:14 -04:00
/// <summary>
2014-10-14 11:53:15 -04:00
/// Non-virtual iterator wrappers.
2014-07-08 03:11:14 -04:00
/// </summary>
2015-10-27 00:31:35 -04:00
template < typename T , typename bucketT > const byte * Renderer < T , bucketT > : : XformDistributions ( ) const { return m_Iterator ? m_Iterator - > XformDistributions ( ) : nullptr ; }
template < typename T , typename bucketT > size_t Renderer < T , bucketT > : : XformDistributionsSize ( ) const { return m_Iterator ? m_Iterator - > XformDistributionsSize ( ) : 0 ; }
2014-12-07 02:51:44 -05:00
template < typename T , typename bucketT > Point < T > * Renderer < T , bucketT > : : Samples ( size_t threadIndex ) const { return threadIndex < m_Samples . size ( ) ? const_cast < Point < T > * > ( m_Samples [ threadIndex ] . data ( ) ) : nullptr ; }
2014-07-08 03:11:14 -04:00
/// <summary>
/// Non-virtual functions that might be needed by a derived class.
/// </summary>
/// <summary>
/// Prepare various values needed for producing a final output image.
/// </summary>
/// <param name="background">The computed background value, which may differ from the background member</param>
/// <param name="g">The computed gamma</param>
/// <param name="linRange">The computed linear range</param>
/// <param name="vibrancy">The computed vibrancy</param>
template < typename T , typename bucketT >
2015-08-10 23:10:23 -04:00
void Renderer < T , bucketT > : : PrepFinalAccumVals ( Color < bucketT > & background , bucketT & g , bucketT & linRange , bucketT & vibrancy )
2014-07-08 03:11:14 -04:00
{
//If they are doing incremental rendering, they can get here without doing a full temporal
//sample, which means the values will be zero.
2015-08-10 23:10:23 -04:00
vibrancy = m_Vibrancy = = 0 ? Vibrancy ( ) : m_Vibrancy ;
2014-10-14 11:53:15 -04:00
size_t vibGamCount = m_VibGamCount = = 0 ? 1 : m_VibGamCount ;
2021-04-19 23:07:24 -04:00
const bucketT gamma = m_Gamma = = 0 ? Gamma ( ) : m_Gamma ;
g = 1 / ClampGte < bucketT > ( gamma / vibGamCount , static_cast < bucketT > ( 0.01 ) ) ; //Ensure a divide by zero doesn't occur.
2014-07-08 03:11:14 -04:00
linRange = GammaThresh ( ) ;
vibrancy / = vibGamCount ;
2021-04-19 23:07:24 -04:00
background . x = ( IsNearZero ( m_Background . r ) ? static_cast < bucketT > ( m_Ember . m_Background . r ) : m_Background . r ) / vibGamCount ;
background . y = ( IsNearZero ( m_Background . g ) ? static_cast < bucketT > ( m_Ember . m_Background . g ) : m_Background . g ) / vibGamCount ;
background . z = ( IsNearZero ( m_Background . b ) ? static_cast < bucketT > ( m_Ember . m_Background . b ) : m_Background . b ) / vibGamCount ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
2014-10-14 11:53:15 -04:00
/// Miscellaneous non-virtual functions used only in this class.
2014-07-08 03:11:14 -04:00
/// </summary>
/// <summary>
/// Accumulate the samples to the histogram.
/// To be called after a sub batch is finished iterating.
/// </summary>
/// <param name="samples">The samples to accumulate</param>
/// <param name="sampleCount">The number of samples</param>
/// <param name="palette">The palette to use</param>
template < typename T , typename bucketT >
2014-11-28 04:37:51 -05:00
void Renderer < T , bucketT > : : Accumulate ( QTIsaac < ISAAC_SIZE , ISAAC_INT > & rand , Point < T > * samples , size_t sampleCount , const Palette < bucketT > * palette )
2014-07-08 03:11:14 -04:00
{
2014-10-14 11:53:15 -04:00
size_t histIndex , intColorIndex , histSize = m_HistBuckets . size ( ) ;
2014-07-08 03:11:14 -04:00
bucketT colorIndex , colorIndexFrac ;
2021-04-19 23:07:24 -04:00
const auto psm1 = m_Ember . m_Palette . Size ( ) - 1 ;
2014-11-28 04:37:51 -05:00
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
//Linear is a linear scale for when the color index is not a whole number, which is most of the time.
//It uses a portion of the value of the index, and the remainder of the next index.
//Example: index = 25.7
//Fraction = 0.7
//Color = (dmap[25] * 0.3) + (dmap[26] * 0.7)
//Use overloaded addition and multiplication operators in vec4 to perform the accumulation.
if ( PaletteMode ( ) = = ePaletteMode : : PALETTE_LINEAR )
{
2021-04-19 23:07:24 -04:00
const auto psm2 = psm1 - 1 ;
2019-04-23 22:50:42 -04:00
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
//It's critical to understand what's going on here as it's one of the most important parts of the algorithm.
//A color value gets retrieved from the palette and
//its RGB values are added to the existing RGB values in the histogram bucket.
//Alpha is always 1 in the palettes, so that serves as the hit count.
//This differs from the original since redundantly adding both an alpha component and a hit count is omitted.
//This will eventually leave us with large values for pixels with many hits, which will be log scaled down later.
//Original used a function called bump_no_overflow(). Just do a straight add because the type will always be float or double.
//Doing so gives a 25% speed increase.
//Splitting these conditionals into separate loops makes no speed difference.
for ( size_t i = 0 ; i < sampleCount & & ! m_Abort ; i + + )
2014-07-08 03:11:14 -04:00
{
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
Point < T > p ( samples [ i ] ) ; //Slightly faster to cache this.
2014-07-08 03:11:14 -04:00
2017-03-27 21:05:06 -04:00
if ( p . m_Opacity ! = 0 )
2014-07-08 03:11:14 -04:00
{
2017-03-27 21:05:06 -04:00
if ( Rotate ( ) ! = 0 )
{
2020-03-15 03:40:57 -04:00
T p00 = p . m_X - m_Ember . m_CenterX ;
2020-03-17 10:16:14 -04:00
T p11 = p . m_Y - m_Ember . m_RotCenterY ;
2020-03-15 03:40:57 -04:00
p . m_X = ( p00 * m_RotMat . A ( ) ) + ( p11 * m_RotMat . B ( ) ) + m_Ember . m_CenterX ;
2020-03-17 10:16:14 -04:00
p . m_Y = ( p00 * m_RotMat . D ( ) ) + ( p11 * m_RotMat . E ( ) ) + m_Ember . m_RotCenterY ;
2017-03-27 21:05:06 -04:00
}
2014-09-10 01:41:26 -04:00
2017-03-27 21:05:06 -04:00
//Checking this first before converting gives better performance than converting and checking a single value, which the original did.
//Second, an interesting optimization observation is that when keeping the bounds vars within m_CarToRas and calling its InBounds() member function,
//rather than here as members, about a 7% speedup is achieved. This is possibly due to the fact that data from m_CarToRas is accessed
//right after the call to Convert(), so some caching efficiencies get realized.
if ( m_CarToRas . InBounds ( p ) )
2014-07-08 03:11:14 -04:00
{
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
m_CarToRas . Convert ( p , histIndex ) ;
//There is a very slim chance that a point will be right on the border and will technically be in bounds, passing the InBounds() test,
//but ends up being mapped to a histogram bucket that is out of bounds due to roundoff error. Perform one final check before proceeding.
//This will result in a few points at the very edges getting discarded, but prevents a crash and doesn't seem to make a speed difference.
if ( histIndex < histSize )
2014-07-08 03:11:14 -04:00
{
2021-04-19 23:07:24 -04:00
colorIndex = static_cast < bucketT > ( p . m_ColorX ) * psm1 ;
intColorIndex = static_cast < size_t > ( colorIndex ) ;
2014-07-08 03:11:14 -04:00
if ( intColorIndex < 0 )
{
intColorIndex = 0 ;
colorIndexFrac = 0 ;
}
2019-04-23 22:50:42 -04:00
else if ( intColorIndex > = psm1 )
2014-07-08 03:11:14 -04:00
{
2019-04-23 22:50:42 -04:00
intColorIndex = psm2 ;
2014-07-08 03:11:14 -04:00
colorIndexFrac = 1 ;
}
else
{
2021-04-19 23:07:24 -04:00
colorIndexFrac = colorIndex - static_cast < bucketT > ( intColorIndex ) ; //Interpolate between intColorIndex and intColorIndex + 1.
2014-07-08 03:11:14 -04:00
}
2014-09-10 01:41:26 -04:00
2016-12-05 22:04:33 -05:00
bucketT * __restrict hist = glm : : value_ptr ( m_HistBuckets [ histIndex ] ) ; //Vectorizer can't tell these point to different locations.
const bucketT * __restrict pal = glm : : value_ptr ( palette - > m_Entries [ intColorIndex ] ) ;
const bucketT * __restrict pal2 = glm : : value_ptr ( palette - > m_Entries [ intColorIndex + 1 ] ) ;
2021-04-19 23:07:24 -04:00
const auto cifm1 = static_cast < bucketT > ( 1 ) - colorIndexFrac ;
2016-12-05 22:04:33 -05:00
//Loops are unrolled to allow auto vectorization.
2017-03-27 21:05:06 -04:00
if ( p . m_Opacity = = 1 )
2016-12-05 22:04:33 -05:00
{
hist [ 0 ] + = ( pal [ 0 ] * cifm1 ) + ( pal2 [ 0 ] * colorIndexFrac ) ;
hist [ 1 ] + = ( pal [ 1 ] * cifm1 ) + ( pal2 [ 1 ] * colorIndexFrac ) ;
hist [ 2 ] + = ( pal [ 2 ] * cifm1 ) + ( pal2 [ 2 ] * colorIndexFrac ) ;
hist [ 3 ] + = ( pal [ 3 ] * cifm1 ) + ( pal2 [ 3 ] * colorIndexFrac ) ;
}
2014-07-08 03:11:14 -04:00
else
2016-12-05 22:04:33 -05:00
{
2021-04-19 23:07:24 -04:00
const auto va = static_cast < bucketT > ( p . m_Opacity ) ;
2016-12-05 22:04:33 -05:00
hist [ 0 ] + = ( ( pal [ 0 ] * cifm1 ) + ( pal2 [ 0 ] * colorIndexFrac ) ) * va ;
hist [ 1 ] + = ( ( pal [ 1 ] * cifm1 ) + ( pal2 [ 1 ] * colorIndexFrac ) ) * va ;
hist [ 2 ] + = ( ( pal [ 2 ] * cifm1 ) + ( pal2 [ 2 ] * colorIndexFrac ) ) * va ;
hist [ 3 ] + = ( ( pal [ 3 ] * cifm1 ) + ( pal2 [ 3 ] * colorIndexFrac ) ) * va ;
}
2014-07-08 03:11:14 -04:00
}
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
}
}
}
}
else if ( PaletteMode ( ) = = ePaletteMode : : PALETTE_STEP ) //Duplicate of above, but for step mode.
{
for ( size_t i = 0 ; i < sampleCount & & ! m_Abort ; i + + )
{
Point < T > p ( samples [ i ] ) ; //Slightly faster to cache this.
2017-03-27 21:05:06 -04:00
if ( p . m_Opacity ! = 0 )
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
{
2017-03-27 21:05:06 -04:00
if ( Rotate ( ) ! = 0 )
{
2021-04-19 23:07:24 -04:00
const T p00 = p . m_X - m_Ember . m_CenterX ;
const T p11 = p . m_Y - m_Ember . m_RotCenterY ;
2020-03-15 03:40:57 -04:00
p . m_X = ( p00 * m_RotMat . A ( ) ) + ( p11 * m_RotMat . B ( ) ) + m_Ember . m_CenterX ;
2020-03-17 10:16:14 -04:00
p . m_Y = ( p00 * m_RotMat . D ( ) ) + ( p11 * m_RotMat . E ( ) ) + m_Ember . m_RotCenterY ;
2017-03-27 21:05:06 -04:00
}
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
2017-03-27 21:05:06 -04:00
if ( m_CarToRas . InBounds ( p ) )
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
{
m_CarToRas . Convert ( p , histIndex ) ;
if ( histIndex < histSize )
2014-07-08 03:11:14 -04:00
{
2021-04-19 23:07:24 -04:00
intColorIndex = Clamp < size_t > ( static_cast < size_t > ( p . m_ColorX * psm1 ) , 0 , psm1 ) ;
2016-12-05 22:04:33 -05:00
bucketT * __restrict hist = glm : : value_ptr ( m_HistBuckets [ histIndex ] ) ; //Vectorizer can't tell these point to different locations.
const bucketT * __restrict pal = glm : : value_ptr ( palette - > m_Entries [ intColorIndex ] ) ;
2014-07-08 03:11:14 -04:00
2017-03-27 21:05:06 -04:00
if ( p . m_Opacity = = 1 )
2016-12-05 22:04:33 -05:00
{
hist [ 0 ] + = pal [ 0 ] ;
hist [ 1 ] + = pal [ 1 ] ;
hist [ 2 ] + = pal [ 2 ] ;
hist [ 3 ] + = pal [ 3 ] ;
}
2014-07-08 03:11:14 -04:00
else
2016-12-05 22:04:33 -05:00
{
2021-04-19 23:07:24 -04:00
auto va = static_cast < bucketT > ( p . m_Opacity ) ;
2016-12-05 22:04:33 -05:00
hist [ 0 ] + = pal [ 0 ] * va ;
hist [ 1 ] + = pal [ 1 ] * va ;
hist [ 2 ] + = pal [ 2 ] * va ;
hist [ 3 ] + = pal [ 3 ] * va ;
}
2014-07-08 03:11:14 -04:00
}
}
}
}
}
}
/// <summary>
/// Add a value to the density filtering buffer with a bounds check.
/// </summary>
/// <param name="bucket">The bucket being filtered</param>
/// <param name="i">The column of the bucket</param>
/// <param name="ii">The offset to add to the column</param>
/// <param name="j">The row of the bucket</param>
/// <param name="jj">The offset to add to the row</param>
template < typename T , typename bucketT >
2015-03-21 18:27:37 -04:00
void Renderer < T , bucketT > : : AddToAccum ( const tvec4 < bucketT , glm : : defaultp > & bucket , intmax_t i , intmax_t ii , intmax_t j , intmax_t jj )
2014-07-08 03:11:14 -04:00
{
2021-04-19 23:07:24 -04:00
if ( j + jj > = 0 & & j + jj < static_cast < intmax_t > ( m_SuperRasH ) & & i + ii > = 0 & & i + ii < static_cast < intmax_t > ( m_SuperRasW ) )
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
{
auto * __restrict accum = m_AccumulatorBuckets . data ( ) + ( ( i + ii ) + ( ( j + jj ) * m_SuperRasW ) ) ; //For vectorizer, results in a 33% speedup.
accum - > r + = bucket . r ;
accum - > g + = bucket . g ;
accum - > b + = bucket . b ;
accum - > a + = bucket . a ;
}
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Clip and gamma correct a pixel.
/// Because this code is used in both early and late clipping, a few extra arguments are passed
/// to specify what actions to take. Coupled with an additional template argument, this allows
/// using one function to perform all color clipping, gamma correction and final accumulation.
2017-07-22 16:43:35 -04:00
/// Template argument accumT is expected to always be float4.
2014-07-08 03:11:14 -04:00
/// </summary>
/// <param name="bucket">The pixel to correct</param>
/// <param name="background">The background color</param>
/// <param name="g">The gamma to use</param>
/// <param name="linRange">The linear range to use</param>
/// <param name="vibrancy">The vibrancy to use</param>
/// <param name="scale">True if late clip, else false.</param>
/// <param name="correctedChannels">The storage space for the corrected values to be written to</param>
template < typename T , typename bucketT >
template < typename accumT >
2017-07-22 16:43:35 -04:00
void Renderer < T , bucketT > : : GammaCorrection ( tvec4 < bucketT , glm : : defaultp > & bucket , Color < bucketT > & background , bucketT g , bucketT linRange , bucketT vibrancy , bool scale , accumT * correctedChannels )
2014-07-08 03:11:14 -04:00
{
2021-04-19 23:07:24 -04:00
auto bt1 = static_cast < bucketT > ( 1 ) ;
2014-07-08 03:11:14 -04:00
2017-07-22 16:43:35 -04:00
if ( scale & & EarlyClip ( ) )
2014-07-08 03:11:14 -04:00
{
2017-07-22 16:43:35 -04:00
if ( m_CurvesSet )
{
CurveAdjust ( bucket . r , 1 ) ;
CurveAdjust ( bucket . g , 2 ) ;
CurveAdjust ( bucket . b , 3 ) ;
}
2021-04-19 23:07:24 -04:00
correctedChannels [ 0 ] = static_cast < accumT > ( Clamp < bucketT > ( bucket . r , 0 , bt1 ) ) ;
correctedChannels [ 1 ] = static_cast < accumT > ( Clamp < bucketT > ( bucket . g , 0 , bt1 ) ) ;
correctedChannels [ 2 ] = static_cast < accumT > ( Clamp < bucketT > ( bucket . b , 0 , bt1 ) ) ;
correctedChannels [ 3 ] = static_cast < accumT > ( Clamp < bucketT > ( bucket . a , 0 , bt1 ) ) ;
2014-07-08 03:11:14 -04:00
}
else
{
2017-07-22 16:43:35 -04:00
bucketT alpha , ls , a , newRgb [ 3 ] ; //Would normally use a Color<bucketT>, but don't want to call a needless constructor every time this function is called, which is once per pixel.
2014-07-08 03:11:14 -04:00
2017-07-22 16:43:35 -04:00
if ( bucket . a < = 0 )
2014-07-08 03:11:14 -04:00
{
2017-07-22 16:43:35 -04:00
alpha = 0 ;
ls = 0 ;
2014-07-08 03:11:14 -04:00
}
else
{
2017-07-22 16:43:35 -04:00
alpha = Palette < bucketT > : : CalcAlpha ( bucket . a , g , linRange ) ;
ls = vibrancy * alpha / bucket . a ;
ClampRef < bucketT > ( alpha , 0 , 1 ) ;
2014-07-08 03:11:14 -04:00
}
2017-07-22 16:43:35 -04:00
Palette < bucketT > : : template CalcNewRgb < bucketT > ( glm : : value_ptr ( bucket ) , ls , HighlightPower ( ) , newRgb ) ;
for ( glm : : length_t rgbi = 0 ; rgbi < 3 ; rgbi + + )
2015-03-21 18:27:37 -04:00
{
2017-07-22 16:43:35 -04:00
a = newRgb [ rgbi ] + ( ( 1 - vibrancy ) * std : : pow ( std : : abs ( bucket [ rgbi ] ) , g ) ) ; //Must use abs(), else it it could be a negative value and return NAN.
a + = ( 1 - alpha ) * background [ rgbi ] ;
2017-07-05 02:08:06 -04:00
2017-07-22 16:43:35 -04:00
if ( scale & & m_CurvesSet )
2015-03-21 18:27:37 -04:00
CurveAdjust ( a , rgbi + 1 ) ;
2021-04-19 23:07:24 -04:00
correctedChannels [ rgbi ] = static_cast < accumT > ( Clamp < bucketT > ( a , 0 , bt1 ) ) ; //Early clip, just assign directly.
2015-03-21 18:27:37 -04:00
}
2014-07-08 03:11:14 -04:00
2021-04-19 23:07:24 -04:00
correctedChannels [ 3 ] = static_cast < accumT > ( alpha ) ;
2014-07-08 03:11:14 -04:00
}
}
2014-12-05 21:30:46 -05:00
2017-07-05 02:08:06 -04:00
/// <summary>
/// Setup the curve values when they are being used.
/// </summary>
template < typename T , typename bucketT >
2017-07-22 16:43:35 -04:00
void Renderer < T , bucketT > : : ComputeCurves ( )
2017-07-05 02:08:06 -04:00
{
if ( m_CurvesSet )
{
auto st = m_Csa . size ( ) ;
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
for ( glm : : length_t i = 0 ; i < m_Ember . m_Curves . m_Points . size ( ) ; i + + ) //Overall, r, g, b.
{
2019-04-26 01:34:09 -04:00
if ( ! m_Ember . m_Curves . m_Points [ i ] . empty ( ) )
{
Spline < float > spline ( m_Ember . m_Curves . m_Points [ i ] ) ; //Will internally sort.
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
2019-04-26 01:34:09 -04:00
for ( glm : : length_t j = 0 ; j < st ; j + + )
m_Csa [ j ] [ i ] = spline . Interpolate ( j * ONE_OVER_CURVES_LENGTH_M1 ) ;
}
--User changes:
-Show common folder locations such as documents, downloads, pictures in the sidebar in all file dialogs.
-Warning message about exceeding memory in final render dialog now suggests strips as the solution to the problem.
-Strips now has a tooltip explaining what it does.
-Allow more digits in the spinners on the color section the flame tab.
-Add manually adjustable size spinners in the final render dialog. Percentage scale and absolute size are fully synced.
-Default prefix in final render is now the filename when doing animations (coming from sequence section of the library tab).
-Changed the elliptic variation back to using a less precise version for float, and a more precise version for double. The last release had it always using double.
-New applied xaos table that shows a read-only view of actual weights by taking the base xform weights and multiplying them by the xaos values.
-New table in the xaos tab that gives a graphical representation of the probability that each xform is chosen, with and without xaos.
-Add button to transpose the xaos rows and columns.
-Add support for importing .chaos files from Chaotica.
--Pasting back to Chaotica will work for most, but not all, variations due to incompatible parameter names in some.
-Curves are now splines instead of Bezier. This adds compatibility with Chaotica, but breaks it for Apophysis. Xmls are still pastable, but the color curves will look different.
--The curve editor on the palette tab can now add points by clicking on the lines and remove points by clicking on the points themselves, just like Chaotica.
--Splines are saved in four new xml fields: overall_curve, red_curve, green_curve and blue_curve.
-Allow for specifying the percentage of a sub batch each thread should iterate through per kernel call when running with OpenCL. This gives a roughly 1% performance increase due to having to make less kernel calls while iterating.
--This field is present for interactive editing (where it's not very useful) and in the final render dialog.
--On the command line, this is specified as --sbpctth for EmberRender and EmberAnimate.
-Allow double clicking to toggle the supersample field in the flame tab between 1 and 2 for easily checking the effect of the field.
-When showing affine values as polar coordinates, show angles normalized to 360 to match Chaotica.
-Fuse Count spinner now toggles between 15 and 100 when double clicking for easily checking the effect of the field.
-Added field for limiting the range in the x and y direction that the initial points are chosen from.
-Added a field called K2 which is an alternative way to set brightness, ignored when zero.
--This has no effect for many variations, but hs a noticeable effect for some.
-Added new variations:
arcsech
arcsech2
arcsinh
arctanh
asteria
block
bwraps_rand
circlecrop2
coth_spiral
crackle2
depth_blur
depth_blur2
depth_gaussian
depth_gaussian2
depth_ngon
depth_ngon2
depth_sine
depth_sine2
dragonfire
dspherical
dust
excinis
exp2
flipx
flowerdb
foci_p
gaussian
glynnia2
glynnsim4
glynnsim5
henon
henon
hex_rand
hex_truchet
hypershift
lazyjess
lens
lozi
lozi
modulusx
modulusy
oscilloscope2
point_symmetry
pointsymmetry
projective
pulse
rotate
scry2
shift
smartshape
spher
squares
starblur2
swirl3
swirl3r
tanh_spiral
target0
target2
tile_hlp
truchet_glyph
truchet_inv
truchet_knot
unicorngaloshen
vibration
vibration2
--hex_truchet, hex_rand should always use double. They are extremely sensitive.
--Bug fixes:
-Bounds sign was flipped for x coordinate of world space when center was not zero.
-Right clicking and dragging spinner showed menu on mouse up, even if it was very far away.
-Text boxes for size in final render dialog were hard to type in. Same bug as xform weight used to be so fix the same way.
-Fix spelling to be plural in toggle color speed box.
-Stop using the blank user palette to generate flames. Either put colored palettes in it, or exclude it from randoms.
-Clicking the random palette button for a palette file with only one palette in it would freeze the program.
-Clicking none scale in final render did not re-render the preview.
-Use less precision on random xaos. No need for 12 decimal places.
-The term sub batch is overloaded in the options dialog. Change the naming and tooltip of those settings for cpu and opencl.
--Also made clear in the tooltip for the default opencl quality setting that the value is per device.
-The arrows spinner in palette editor appears like a read-only label. Made it look like a spinner.
-Fix border colors for various spin boxes and table headers in the style sheet. Requires reload.
-Fix a bug in the bwraps variation which would produce different results than Chaotica and Apophysis.
-Synth was allowed to be selected for random flame generation when using an Nvidia card but it shouldn't have been because Nvidia has a hard time compiling synth.
-A casting bug in the OpenCL kernels for log scaling and density filtering was preventing successful compilations on Intel iGPUs. Fixed even though we don't support anything other than AMD and Nvidia.
-Palette rotation (click and drag) position was not being reset when loading a new flame.
-When the xform circles were hidden, opening and closing the options dialog would improperly reshow them.
-Double click toggle was broken on integer spin boxes.
-Fixed tab order of some controls.
-Creating a palette from a jpg in the palette editor only produced a single color.
--Needed to package imageformats/qjpeg.dll with the Windows installer.
-The basic memory benchmark test flame was not really testing memory. Make it more spread out.
-Remove the temporal samples field from the flame tab, it was never used because it's only an animation parameter which is specified in the final render dialog or on the command line with EmberAnimate.
--Code changes:
-Add IsEmpty() to Palette to determine if a palette is all black.
-Attempt to avoid selecting a blank palette in PaletteList::GetRandomPalette().
-Add function ScanForChaosNodes() and some associated helper functions in XmlToEmber.
-Make variation param name correction be case insensitive in XmlToEmber.
-Report error when assigning a variation param value in XmlToEmber.
-Add SubBatchPercentPerThread() method to RendererCL.
-Override enterEvent() and leaveEvent() in DoubleSpinBox and SpinBox to prevent the context menu from showing up on right mouse up after already leaving the spinner.
-Filtering the mouse wheel event in TableWidget no longer appears to be needed. It was probably an old Qt bug that has been fixed.
-Gui/ember syncing code in the final render dialog needed to be reworked to accommodate absolute sizes.
2019-04-13 22:00:46 -04:00
}
2017-07-05 02:08:06 -04:00
}
}
/// <summary>
/// Apply the curve adjustment to a single channel.
/// </summary>
2017-07-22 16:43:35 -04:00
/// <param name="aScaled">The value of the channel to apply curve adjustment to.</param>
2017-07-05 02:08:06 -04:00
/// <param name="index">The index of the channel to apply curve adjustment to</param>
2015-03-21 18:27:37 -04:00
template < typename T , typename bucketT >
2017-07-22 16:43:35 -04:00
void Renderer < T , bucketT > : : CurveAdjust ( bucketT & a , const glm : : length_t & index )
2015-03-21 18:27:37 -04:00
{
2021-04-19 23:07:24 -04:00
size_t tempIndex = static_cast < size_t > ( Clamp < bucketT > ( a * CURVES_LENGTH_M1 , 0 , CURVES_LENGTH_M1 ) ) ;
size_t tempIndex2 = static_cast < size_t > ( Clamp < bucketT > ( m_Csa [ tempIndex ] . x * CURVES_LENGTH_M1 , 0 , CURVES_LENGTH_M1 ) ) ;
2017-07-22 16:43:35 -04:00
a = m_Csa [ tempIndex2 ] [ index ] ;
2015-03-21 18:27:37 -04:00
}
2014-12-05 21:30:46 -05:00
//This class had to be implemented in a cpp file because the compiler was breaking.
//So the explicit instantiation must be declared here rather than in Ember.cpp where
//all of the other classes are done.
template EMBER_API class Renderer < float , float > ;
2016-04-03 21:55:12 -04:00
template EMBER_API void Renderer < float , float > : : SetEmber ( const vector < Ember < float > > & embers ) ;
template EMBER_API void Renderer < float , float > : : SetEmber ( const list < Ember < float > > & embers ) ;
2014-12-05 21:30:46 -05:00
# ifdef DO_DOUBLE
2015-08-10 23:10:23 -04:00
template EMBER_API class Renderer < double , float > ;
2016-04-03 21:55:12 -04:00
template EMBER_API void Renderer < double , float > : : SetEmber ( const vector < Ember < double > > & embers ) ;
template EMBER_API void Renderer < double , float > : : SetEmber ( const list < Ember < double > > & embers ) ;
2014-12-05 21:30:46 -05:00
# endif
2014-09-10 01:41:26 -04:00
}