2014-07-08 03:11:14 -04:00
# include "FractoriumPch.h"
# include "FractoriumEmberController.h"
# include "Fractorium.h"
# include "GLEmberController.h"
2015-01-02 18:11:36 -05:00
# define SAVE_EACH 1
2014-07-08 03:11:14 -04:00
/// <summary>
/// Constructor which initializes the non-templated members contained in this class.
/// The renderer, other templated members and GUI setup will be done in the templated derived controller class.
/// </summary>
/// <param name="fractorium">Pointer to the main window.</param>
FractoriumEmberControllerBase : : FractoriumEmberControllerBase ( Fractorium * fractorium )
--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
: m_Info ( OpenCLInfo : : Instance ( ) )
2014-07-08 03:11:14 -04:00
{
Timing t ;
m_Rendering = false ;
m_Shared = true ;
m_FailedRenders = 0 ;
m_UndoIndex = 0 ;
m_RenderType = CPU_RENDERER ;
m_OutputTexID = 0 ;
m_SubBatchCount = 1 ; //Will be ovewritten by the options on first render.
m_Fractorium = fractorium ;
2015-01-02 18:11:36 -05:00
m_RenderTimer = nullptr ;
m_RenderRestartTimer = nullptr ;
2014-07-08 03:11:14 -04:00
m_Rand = QTIsaac < ISAAC_SIZE , ISAAC_INT > ( ISAAC_INT ( t . Tic ( ) ) , ISAAC_INT ( t . Tic ( ) * 2 ) , ISAAC_INT ( t . Tic ( ) * 3 ) ) ; //Ensure a different rand seed on each instance.
m_RenderTimer = new QTimer ( m_Fractorium ) ;
m_RenderTimer - > setInterval ( 0 ) ;
m_Fractorium - > connect ( m_RenderTimer , SIGNAL ( timeout ( ) ) , SLOT ( IdleTimer ( ) ) ) ;
m_RenderRestartTimer = new QTimer ( m_Fractorium ) ;
m_Fractorium - > connect ( m_RenderRestartTimer , SIGNAL ( timeout ( ) ) , SLOT ( StartRenderTimer ( ) ) ) ;
}
/// <summary>
/// Destructor which stops rendering and deletes the timers.
/// All other memory is cleared automatically through the use of STL.
/// </summary>
FractoriumEmberControllerBase : : ~ FractoriumEmberControllerBase ( )
{
StopRenderTimer ( true ) ;
if ( m_RenderTimer )
{
m_RenderTimer - > stop ( ) ;
delete m_RenderTimer ;
2015-01-02 18:11:36 -05:00
m_RenderTimer = nullptr ;
2014-07-08 03:11:14 -04:00
}
if ( m_RenderRestartTimer )
{
m_RenderRestartTimer - > stop ( ) ;
delete m_RenderRestartTimer ;
2015-01-02 18:11:36 -05:00
m_RenderRestartTimer = nullptr ;
2014-07-08 03:11:14 -04:00
}
}
/// <summary>
/// Constructor which passes the main window parameter to the base, initializes the templated members contained in this class.
/// Then sets up the parts of the GUI that require templated Widgets, such as the variations tree and the palette table.
/// Note the renderer is not setup here automatically. Instead, it must be manually created by the caller later.
/// </summary>
/// <param name="fractorium">Pointer to the main window.</param>
template < typename T >
FractoriumEmberController < T > : : FractoriumEmberController ( Fractorium * fractorium )
2014-10-14 11:53:15 -04:00
: FractoriumEmberControllerBase ( fractorium )
2014-07-08 03:11:14 -04:00
{
m_PreviewRun = false ;
m_PreviewRunning = false ;
2015-08-10 23:10:23 -04:00
m_SheepTools = unique_ptr < SheepTools < T , float > > ( new SheepTools < T , float > (
2015-07-24 06:10:18 -04:00
QString ( QApplication : : applicationDirPath ( ) + " flam3-palettes.xml " ) . toLocal8Bit ( ) . data ( ) ,
2015-08-10 23:10:23 -04:00
new EmberNs : : Renderer < T , float > ( ) ) ) ;
2014-10-18 17:07:07 -04:00
m_GLController = unique_ptr < GLEmberController < T > > ( new GLEmberController < T > ( fractorium , fractorium - > ui . GLDisplay , this ) ) ;
2015-08-10 23:10:23 -04:00
m_PreviewRenderer = unique_ptr < EmberNs : : Renderer < T , float > > ( new EmberNs : : Renderer < T , float > ( ) ) ;
2015-04-08 21:23:29 -04:00
//Initial combo change event to fill the palette table will be called automatically later.
2015-12-01 12:33:27 -05:00
// TODO: Use QStandardPaths::DataLocation(), on linux one of the paths it
// returns should be "/usr/share/fractorium". It might have to be lowercased
// to make sure.
//
// http://doc.qt.io/qt-5/qstandardpaths.html#StandardLocation-enum
if ( ! InitPaletteList ( QString ( " /usr/share/fractorium " ) . toLocal8Bit ( ) . data ( ) ) )
2015-04-08 21:23:29 -04:00
throw " No palettes found, exiting. " ;
2014-07-08 03:11:14 -04:00
BackgroundChanged ( QColor ( 0 , 0 , 0 ) ) ; //Default to black.
ClearUndo ( ) ;
2015-01-02 18:11:36 -05:00
m_PreviewRenderer - > Callback ( nullptr ) ;
2014-07-08 03:11:14 -04:00
m_PreviewRenderer - > NumChannels ( 4 ) ;
2014-07-26 15:03:51 -04:00
m_PreviewRenderer - > EarlyClip ( m_Fractorium - > m_Settings - > EarlyClip ( ) ) ;
m_PreviewRenderer - > YAxisUp ( m_Fractorium - > m_Settings - > YAxisUp ( ) ) ;
2014-07-08 03:11:14 -04:00
m_PreviewRenderer - > SetEmber ( m_Ember ) ; //Give it an initial ember, will be updated many times later.
//m_PreviewRenderer->ThreadCount(1);//For debugging.
2014-12-06 00:05:09 -05:00
m_PreviewRenderFunc = [ & ] ( uint start , uint end )
2014-07-08 03:11:14 -04:00
{
while ( m_PreviewRun | | m_PreviewRunning )
{
}
m_PreviewRun = true ;
m_PreviewRunning = true ;
2015-03-21 18:27:37 -04:00
m_PreviewRenderer - > ThreadCount ( std : : max ( 1u , Timing : : ProcessorCount ( ) - 1 ) ) ; //Leave one processor free so the GUI can breathe.
2014-07-08 03:11:14 -04:00
QTreeWidget * tree = m_Fractorium - > ui . LibraryTree ;
if ( QTreeWidgetItem * top = tree - > topLevelItem ( 0 ) )
{
2014-10-14 11:53:15 -04:00
for ( size_t i = start ; m_PreviewRun & & i < end & & i < m_EmberFile . Size ( ) ; i + + )
2014-07-08 03:11:14 -04:00
{
Ember < T > ember = m_EmberFile . m_Embers [ i ] ;
2014-11-29 12:44:23 -05:00
ember . SyncSize ( ) ;
2014-07-08 03:11:14 -04:00
ember . SetSizeAndAdjustScale ( PREVIEW_SIZE , PREVIEW_SIZE , false , SCALE_WIDTH ) ;
ember . m_TemporalSamples = 1 ;
ember . m_Quality = 25 ;
ember . m_Supersample = 1 ;
m_PreviewRenderer - > SetEmber ( ember ) ;
if ( m_PreviewRenderer - > Run ( m_PreviewFinalImage ) = = RENDER_OK )
{
if ( EmberTreeWidgetItem < T > * treeItem = dynamic_cast < EmberTreeWidgetItem < T > * > ( top - > child ( i ) ) )
{
//It is critical that Qt::BlockingQueuedConnection is passed because this is running on a different thread than the UI.
//This ensures the events are processed in order as each preview is updated, and that control does not return here
//until the update is complete.
QMetaObject : : invokeMethod ( m_Fractorium , " SetLibraryTreeItemData " , Qt : : BlockingQueuedConnection ,
2014-12-11 00:50:15 -05:00
Q_ARG ( EmberTreeWidgetItemBase * , dynamic_cast < EmberTreeWidgetItemBase * > ( treeItem ) ) ,
2014-12-06 00:05:09 -05:00
Q_ARG ( vector < byte > & , m_PreviewFinalImage ) ,
Q_ARG ( uint , PREVIEW_SIZE ) ,
Q_ARG ( uint , PREVIEW_SIZE ) ) ;
2014-07-08 03:11:14 -04:00
//treeItem->SetImage(m_PreviewFinalImage, PREVIEW_SIZE, PREVIEW_SIZE);
}
}
}
}
m_PreviewRun = false ;
m_PreviewRunning = false ;
} ;
}
/// <summary>
/// Empty destructor that does nothing.
/// </summary>
template < typename T >
FractoriumEmberController < T > : : ~ FractoriumEmberController ( ) { }
/// <summary>
/// Setters for embers, ember files and palettes which convert between float and double types.
/// These are used to preserve the current ember/file when switching between renderers.
/// Note that some precision will be lost when going from double to float.
/// </summary>
template < typename T > void FractoriumEmberController < T > : : SetEmber ( const Ember < float > & ember , bool verbatim ) { SetEmberPrivate < float > ( ember , verbatim ) ; }
2014-10-14 11:53:15 -04:00
template < typename T > void FractoriumEmberController < T > : : CopyEmber ( Ember < float > & ember , std : : function < void ( Ember < float > & ember ) > perEmberOperation ) { ember = m_Ember ; perEmberOperation ( ember ) ; }
2014-07-08 03:11:14 -04:00
template < typename T > void FractoriumEmberController < T > : : SetEmberFile ( const EmberFile < float > & emberFile ) { m_EmberFile = emberFile ; }
2014-10-14 11:53:15 -04:00
template < typename T > void FractoriumEmberController < T > : : CopyEmberFile ( EmberFile < float > & emberFile , std : : function < void ( Ember < float > & ember ) > perEmberOperation )
{
emberFile . m_Filename = m_EmberFile . m_Filename ;
CopyVec ( emberFile . m_Embers , m_EmberFile . m_Embers , perEmberOperation ) ;
}
2014-07-08 03:11:14 -04:00
template < typename T > void FractoriumEmberController < T > : : SetTempPalette ( const Palette < float > & palette ) { m_TempPalette = palette ; }
template < typename T > void FractoriumEmberController < T > : : CopyTempPalette ( Palette < float > & palette ) { palette = m_TempPalette ; }
# ifdef DO_DOUBLE
template < typename T > void FractoriumEmberController < T > : : SetEmber ( const Ember < double > & ember , bool verbatim ) { SetEmberPrivate < double > ( ember , verbatim ) ; }
2014-10-14 11:53:15 -04:00
template < typename T > void FractoriumEmberController < T > : : CopyEmber ( Ember < double > & ember , std : : function < void ( Ember < double > & ember ) > perEmberOperation ) { ember = m_Ember ; perEmberOperation ( ember ) ; }
2014-07-08 03:11:14 -04:00
template < typename T > void FractoriumEmberController < T > : : SetEmberFile ( const EmberFile < double > & emberFile ) { m_EmberFile = emberFile ; }
2014-10-14 11:53:15 -04:00
template < typename T > void FractoriumEmberController < T > : : CopyEmberFile ( EmberFile < double > & emberFile , std : : function < void ( Ember < double > & ember ) > perEmberOperation )
{
emberFile . m_Filename = m_EmberFile . m_Filename ;
CopyVec ( emberFile . m_Embers , m_EmberFile . m_Embers , perEmberOperation ) ;
}
2014-07-08 03:11:14 -04:00
template < typename T > void FractoriumEmberController < T > : : SetTempPalette ( const Palette < double > & palette ) { m_TempPalette = palette ; }
template < typename T > void FractoriumEmberController < T > : : CopyTempPalette ( Palette < double > & palette ) { palette = m_TempPalette ; }
# endif
template < typename T > Ember < T > * FractoriumEmberController < T > : : CurrentEmber ( ) { return & m_Ember ; }
2014-10-14 11:53:15 -04:00
template < typename T >
void FractoriumEmberController < T > : : ConstrainDimensions ( Ember < T > & ember )
{
ember . m_FinalRasW = std : : min < int > ( m_Fractorium - > ui . GLDisplay - > MaxTexSize ( ) , ember . m_FinalRasW ) ;
ember . m_FinalRasH = std : : min < int > ( m_Fractorium - > ui . GLDisplay - > MaxTexSize ( ) , ember . m_FinalRasH ) ;
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Set the ember at the specified index from the currently opened file as the current Ember.
/// Clears the undo state.
/// Resets the rendering process.
/// </summary>
/// <param name="index">The index in the file from which to retrieve the ember</param>
template < typename T >
void FractoriumEmberController < T > : : SetEmber ( size_t index )
{
2014-10-14 11:53:15 -04:00
if ( index < m_EmberFile . Size ( ) )
2014-07-08 03:11:14 -04:00
{
if ( QTreeWidgetItem * top = m_Fractorium - > ui . LibraryTree - > topLevelItem ( 0 ) )
{
2014-12-06 00:05:09 -05:00
for ( uint i = 0 ; i < top - > childCount ( ) ; i + + )
2014-07-08 03:11:14 -04:00
{
if ( EmberTreeWidgetItem < T > * emberItem = dynamic_cast < EmberTreeWidgetItem < T > * > ( top - > child ( i ) ) )
emberItem - > setSelected ( i = = index ) ;
}
}
ClearUndo ( ) ;
SetEmber ( m_EmberFile . m_Embers [ index ] ) ;
}
}
/// <summary>
/// Wrapper to call a function, then optionally add the requested action to the rendering queue.
/// </summary>
/// <param name="func">The function to call</param>
2015-03-21 18:27:37 -04:00
/// <param name="updateRender">True to update renderer, else false. Default: true.</param>
2014-07-08 03:11:14 -04:00
/// <param name="action">The action to add to the rendering queue. Default: FULL_RENDER.</param>
template < typename T >
void FractoriumEmberController < T > : : Update ( std : : function < void ( void ) > func , bool updateRender , eProcessAction action )
{
func ( ) ;
if ( updateRender )
UpdateRender ( action ) ;
}
/// <summary>
2015-04-27 01:11:56 -04:00
/// Wrapper to call a function on the specified xforms, then optionally add the requested action to the rendering queue.
/// If no xforms are selected via the checkboxes, and the update type is UPDATE_SELECTED, then the function will be called only on the currently selected xform.
2014-07-08 03:11:14 -04:00
/// </summary>
/// <param name="func">The function to call</param>
2015-04-27 01:11:56 -04:00
/// <param name="updateType">Whether to apply this update operation on the current, all or selected xforms. Default: UPDATE_CURRENT.</param>
2014-11-04 20:38:20 -05:00
/// <param name="updateRender">True to update renderer, else false. Default: true.</param>
2014-07-08 03:11:14 -04:00
/// <param name="action">The action to add to the rendering queue. Default: FULL_RENDER.</param>
template < typename T >
2015-04-27 01:11:56 -04:00
void FractoriumEmberController < T > : : UpdateXform ( std : : function < void ( Xform < T > * ) > func , eXformUpdate updateType , bool updateRender , eProcessAction action )
2014-07-08 03:11:14 -04:00
{
2015-04-27 01:11:56 -04:00
size_t i = 0 ;
bool isCurrentFinal = m_Ember . IsFinalXform ( CurrentXform ( ) ) ;
bool doFinal = updateType ! = eXformUpdate : : UPDATE_SELECTED_EXCEPT_FINAL & & updateType ! = eXformUpdate : : UPDATE_ALL_EXCEPT_FINAL ;
switch ( updateType )
2014-07-08 03:11:14 -04:00
{
2015-04-27 01:11:56 -04:00
case eXformUpdate : : UPDATE_CURRENT :
{
if ( Xform < T > * xform = CurrentXform ( ) )
func ( xform ) ;
}
break ;
case eXformUpdate : : UPDATE_SELECTED :
case eXformUpdate : : UPDATE_SELECTED_EXCEPT_FINAL :
{
bool anyUpdated = false ;
while ( Xform < T > * xform = ( doFinal ? m_Ember . GetTotalXform ( i ) : m_Ember . GetXform ( i ) ) )
{
if ( QLayoutItem * child = m_Fractorium - > m_XformsSelectionLayout - > itemAt ( i ) )
{
2015-07-23 21:16:36 -04:00
if ( auto * w = qobject_cast < QCheckBox * > ( child - > widget ( ) ) )
2015-04-27 01:11:56 -04:00
{
if ( w - > isChecked ( ) )
{
func ( xform ) ;
anyUpdated = true ;
}
}
}
i + + ;
}
2014-07-08 03:11:14 -04:00
2015-04-27 01:11:56 -04:00
if ( ! anyUpdated ) //None were selected, so just apply to the current.
if ( doFinal | | ! isCurrentFinal ) //If do final, call func regardless. If not, only call if current is not final.
if ( Xform < T > * xform = CurrentXform ( ) )
func ( xform ) ;
}
break ;
case eXformUpdate : : UPDATE_ALL :
{
while ( Xform < T > * xform = m_Ember . GetTotalXform ( i + + ) )
func ( xform ) ;
}
break ;
case eXformUpdate : : UPDATE_ALL_EXCEPT_FINAL :
default :
{
while ( Xform < T > * xform = m_Ember . GetXform ( i + + ) )
func ( xform ) ;
}
break ;
2014-07-08 03:11:14 -04:00
}
2015-04-27 01:11:56 -04:00
if ( updateRender )
UpdateRender ( action ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Set the current ember, but use GUI values for the fields which make sense to
/// keep the same between ember selection changes.
/// Note the extra template parameter U allows for assigning ember of different types.
/// Resets the rendering process.
/// </summary>
/// <param name="ember">The ember to set as the current</param>
2015-07-15 23:27:32 -04:00
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
2014-07-08 03:11:14 -04:00
template < typename T >
template < typename U >
void FractoriumEmberController < T > : : SetEmberPrivate ( const Ember < U > & ember , bool verbatim )
{
if ( ember . m_Name ! = m_Ember . m_Name )
m_LastSaveCurrent = " " ;
2015-01-02 18:11:36 -05:00
size_t w = m_Ember . m_FinalRasW ; //Cache values for use below.
size_t h = m_Ember . m_FinalRasH ;
2014-07-08 03:11:14 -04:00
m_Ember = ember ;
if ( ! verbatim )
{
2014-10-14 11:53:15 -04:00
//m_Ember.SetSizeAndAdjustScale(m_Fractorium->ui.GLDisplay->width(), m_Fractorium->ui.GLDisplay->height(), true, SCALE_WIDTH);
2014-07-08 03:11:14 -04:00
m_Ember . m_TemporalSamples = 1 ; //Change once animation is supported.
m_Ember . m_Quality = m_Fractorium - > m_QualitySpin - > value ( ) ;
m_Ember . m_Supersample = m_Fractorium - > m_SupersampleSpin - > value ( ) ;
}
2015-01-02 18:11:36 -05:00
# ifdef SAVE_EACH
static EmberToXml < T > writer ;
string filename = " last.flame " ;
writer . Save ( filename . c_str ( ) , m_Ember , 0 , true , false , true ) ;
# endif
m_GLController - > ResetMouseState ( ) ;
2015-04-27 01:11:56 -04:00
FillXforms ( ) ; //Must do this first because the palette setup in FillParamTablesAndPalette() uses the xforms combo.
2014-07-08 03:11:14 -04:00
FillParamTablesAndPalette ( ) ;
2015-07-15 23:27:32 -04:00
FillSummary ( ) ;
2015-01-02 18:11:36 -05:00
//If a resize happened, this won't do anything because the new size is not reflected in the scroll area yet.
//However, it will have been taken care of in SyncSizes() in that case, so it's ok.
//This is for when a new ember with the same size was loaded. If it was larger than the scroll area, and was scrolled, re-center it.
if ( m_Ember . m_FinalRasW = = w & & m_Ember . m_FinalRasH = = h )
m_Fractorium - > CenterScrollbars ( ) ;
2014-12-11 00:50:15 -05:00
}
template class FractoriumEmberController < float > ;
# ifdef DO_DOUBLE
template class FractoriumEmberController < double > ;
# endif