mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-02-01 10:30:08 -05:00
0.4.1.1 Beta 08/03/2014
--Bug Fixes Spatial filter would not be correctly recreated on subsequent runs of differing supersample values during final render. Fix DCBubble, Funnel, SphericalN, Wrong logic with some usage of DO_DOUBLE. Only relevant for testing. Use uint64 for iters/sec calculation on final render dialog. int was overflowing on extremely fast GPU renders. --Code Changes Make density, spatial and temporal filters preserve the values they were created with. This helps in determining when a new instance is needed. Better NULL checks when copying embers and xforms. Rename members in FractoriumEmberControllerBase.h to omit duplicating the members declared in the base.
This commit is contained in:
parent
152318a567
commit
570d3bcf1d
@ -6,7 +6,7 @@
|
||||
<ProductVersion>3.7</ProductVersion>
|
||||
<ProjectGuid>{c8096c47-e358-438c-a520-146d46b0637d}</ProjectGuid>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<OutputName>Fractorium_Beta_0.4.1.0</OutputName>
|
||||
<OutputName>Fractorium_Beta_0.4.1.1</OutputName>
|
||||
<OutputType>Package</OutputType>
|
||||
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<?define ProductVersion="0.4.1.0" ?>
|
||||
<?define ProductVersion="0.4.1.1" ?>
|
||||
<?define ProductName="Fractorium Beta $(var.ProductVersion) ($(var.GpuType))" ?>
|
||||
<?define UpgradeCode="{4714cd15-bfba-44f6-8059-9e1466ebfa6e}"?>
|
||||
<?define Manufacturer="Fractorium"?>
|
||||
@ -13,7 +13,7 @@
|
||||
<!--
|
||||
Change this for every release.
|
||||
-->
|
||||
<?define ProductCode="{11E92742-0C6F-4FBB-9F24-5B94984AFCC9}"?>
|
||||
<?define ProductCode="{478E2A85-97E3-4F2D-90AE-6509209D9240}"?>
|
||||
|
||||
<Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
|
||||
<Package
|
||||
|
BIN
Data/Bench.xlsx
BIN
Data/Bench.xlsx
Binary file not shown.
@ -1,4 +1,15 @@
|
||||
0.4.0.9 Beta 07/29/2014
|
||||
0.4.1.1 Beta 08/03/2014
|
||||
--Bug Fixes
|
||||
Spatial filter would not be correctly recreated on subsequent runs of differing supersample values during final render.
|
||||
Fix DCBubble, Funnel, SphericalN,
|
||||
Wrong logic with some usage of DO_DOUBLE. Only relevant for testing.
|
||||
|
||||
--Code Changes
|
||||
Make density, spatial and temporal filters preserve the values they were created with. This helps in determining when a new instance is needed.
|
||||
Better NULL checks when copying embers and xforms.
|
||||
Rename members in FractoriumEmberControllerBase.h to omit duplicating the members declared in the base.
|
||||
|
||||
0.4.1.0 Beta 07/29/2014
|
||||
--Bug Fixes
|
||||
Final render dialog didn't create the renderer properly on first run when more than one platform was present.
|
||||
|
||||
|
@ -312,6 +312,7 @@ public:
|
||||
inline T MinRad() const { return m_MinRad; }
|
||||
inline T MaxRad() const { return m_MaxRad; }
|
||||
inline T Curve() const { return m_Curve; }
|
||||
inline unsigned int Supersample() const { return m_Supersample; }
|
||||
inline unsigned int KernelSize() const { return m_KernelSize; }
|
||||
inline unsigned int MaxFilterIndex() const { return m_MaxFilterIndex; }
|
||||
inline unsigned int MaxFilteredCounts() const { return m_MaxFilteredCounts; }
|
||||
|
@ -143,10 +143,13 @@ public:
|
||||
|
||||
for (unsigned int i = 0; i < ember.XformCount(); i++)
|
||||
{
|
||||
Xform<T> xform = *ember.GetXform(i);//Will call assignment operator to convert between types T and U.
|
||||
if (Xform<U>* p = ember.GetXform(i))
|
||||
{
|
||||
Xform<T> xform = *p;//Will call assignment operator to convert between types T and U.
|
||||
|
||||
AddXform(xform);
|
||||
}
|
||||
}
|
||||
|
||||
Xform<T> finalXform = *ember.FinalXform();//Will call assignment operator to convert between types T and U.
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace EmberNs
|
||||
extern void sincos(double x, double *s, double *c);
|
||||
#endif
|
||||
|
||||
#define EMBER_VERSION "0.4.1.0"
|
||||
#define EMBER_VERSION "0.4.1.1"
|
||||
#define EPS6 T(1e-6)
|
||||
#define EPS std::numeric_limits<T>::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
|
||||
#define ISAAC_SIZE 4
|
||||
|
@ -263,12 +263,12 @@ bool Renderer<T, bucketT>::CreateTemporalFilter(bool& newAlloc)
|
||||
newAlloc = false;
|
||||
|
||||
//Use intelligent testing so it isn't created every time a new ember is passed in.
|
||||
if ((m_TemporalFilter.get() == NULL) ||
|
||||
(m_Ember.m_Passes != m_LastEmber.m_Passes) ||
|
||||
(m_Ember.m_TemporalSamples != m_LastEmber.m_TemporalSamples) ||
|
||||
if ((!m_TemporalFilter.get()) ||
|
||||
(m_Ember.m_Passes != m_TemporalFilter->Passes()) ||
|
||||
(m_Ember.m_TemporalSamples != m_TemporalFilter->TemporalSamples()) ||
|
||||
(m_Ember.m_TemporalFilterType != m_TemporalFilter->FilterType()) ||
|
||||
(m_Ember.m_TemporalFilterWidth != m_LastEmber.m_TemporalFilterWidth) ||
|
||||
(m_Ember.m_TemporalFilterExp != m_LastEmber.m_TemporalFilterExp))
|
||||
(m_Ember.m_TemporalFilterWidth != m_TemporalFilter->FilterWidth()) ||
|
||||
(m_Ember.m_TemporalFilterExp != m_TemporalFilter->FilterExp()))
|
||||
{
|
||||
m_TemporalFilter = auto_ptr<TemporalFilter<T>>(
|
||||
TemporalFilterCreator<T>::Create(m_Ember.m_TemporalFilterType, m_Ember.m_Passes, m_Ember.m_TemporalSamples, m_Ember.m_TemporalFilterWidth, m_Ember.m_TemporalFilterExp));
|
||||
@ -296,11 +296,11 @@ bool Renderer<T, bucketT>::PrepFinalAccumVector(vector<unsigned char>& pixels)
|
||||
if (m_ReclaimOnResize)
|
||||
{
|
||||
if (pixels.size() != size)
|
||||
{
|
||||
pixels.resize(size);
|
||||
|
||||
if (m_ReclaimOnResize)
|
||||
pixels.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pixels.size() < size)
|
||||
@ -850,11 +850,11 @@ bool Renderer<T, bucketT>::CreateDEFilter(bool& newAlloc)
|
||||
if (m_Ember.m_MaxRadDE > 0)
|
||||
{
|
||||
//Use intelligent testing so it isn't created every time a new ember is passed in.
|
||||
if ((m_DensityFilter.get() == NULL) ||
|
||||
if ((!m_DensityFilter.get()) ||
|
||||
(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_LastEmber.m_Supersample))
|
||||
(m_Ember.m_Supersample != m_DensityFilter->Supersample()))
|
||||
{
|
||||
m_DensityFilter = auto_ptr<DensityFilter<T>>(new DensityFilter<T>(m_Ember.m_MinRadDE, m_Ember.m_MaxRadDE, m_Ember.m_CurveDE, m_Ember.m_Supersample));
|
||||
newAlloc = true;
|
||||
@ -889,10 +889,10 @@ 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() == NULL) ||
|
||||
if ((!m_SpatialFilter.get()) ||
|
||||
(m_Ember.m_SpatialFilterType != m_SpatialFilter->FilterType()) ||
|
||||
(m_Ember.m_SpatialFilterRadius != m_SpatialFilter->FilterRadius()) ||
|
||||
(m_Ember.m_Supersample != m_LastEmber.m_Supersample) ||
|
||||
(m_Ember.m_Supersample != m_SpatialFilter->Supersample()) ||
|
||||
(m_PixelAspectRatio != m_SpatialFilter->PixelAspectRatio()))
|
||||
{
|
||||
m_SpatialFilter = auto_ptr<SpatialFilter<T>>(
|
||||
@ -1007,7 +1007,7 @@ void Renderer<T, bucketT>::ThreadCount(unsigned int threads, const char* seedStr
|
||||
#ifdef ISAAC_FLAM3_DEBUG
|
||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> isaac(0, 0, 0, seeds);
|
||||
#else
|
||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> isaac(newSize, newSize * newSize, newSize * newSize * newSize, seeds);
|
||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> isaac(newSize, newSize * 2, newSize * 3, seeds);
|
||||
#endif
|
||||
m_Rand.push_back(isaac);
|
||||
|
||||
|
@ -40,9 +40,13 @@ public:
|
||||
{
|
||||
unsigned int i, steps = passes * temporalSamples;
|
||||
|
||||
m_Passes = passes;
|
||||
m_TemporalSamples = temporalSamples;
|
||||
m_FilterWidth = filterWidth;
|
||||
m_Deltas.resize(steps);
|
||||
m_Filter.resize(steps);
|
||||
m_FilterType = filterType;
|
||||
m_FilterExp = 1;
|
||||
|
||||
if (steps == 1)
|
||||
{
|
||||
@ -83,6 +87,10 @@ public:
|
||||
{
|
||||
if (this != &filter)
|
||||
{
|
||||
m_Passes = filter.m_Passes;
|
||||
m_TemporalSamples = filter.m_TemporalSamples;
|
||||
m_FilterWidth = filter.m_FilterWidth;
|
||||
m_FilterExp = filter.m_FilterExp;
|
||||
m_SumFilt = filter.m_SumFilt;
|
||||
m_Deltas = filter.m_Deltas;
|
||||
m_Filter = filter.m_Filter;
|
||||
@ -127,6 +135,10 @@ public:
|
||||
/// Accessors.
|
||||
/// </summary>
|
||||
size_t Size() const { return m_Filter.size(); }
|
||||
unsigned int Passes() const { return m_Passes; }
|
||||
unsigned int TemporalSamples() const { return m_TemporalSamples; }
|
||||
T FilterWidth() const { return m_FilterWidth; }
|
||||
T FilterExp() const { return m_FilterExp; }
|
||||
T SumFilt() const { return m_SumFilt; }
|
||||
T* Deltas() { return &m_Deltas[0]; }
|
||||
T* Filter() { return &m_Filter[0]; }
|
||||
@ -151,6 +163,10 @@ protected:
|
||||
}
|
||||
|
||||
T m_SumFilt;//The sum of all filter values.
|
||||
T m_FilterWidth;
|
||||
T m_FilterExp;
|
||||
unsigned int m_Passes;
|
||||
unsigned int m_TemporalSamples;
|
||||
vector<T> m_Deltas;//Delta vector.
|
||||
vector<T> m_Filter;//Filter vector.
|
||||
eTemporalFilterType m_FilterType;//The type of filter this is.
|
||||
@ -192,6 +208,7 @@ public:
|
||||
maxFilt = m_Filter[i];
|
||||
}
|
||||
|
||||
m_FilterExp = filterExp;
|
||||
FinishFilter(maxFilt);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
|
||||
void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
|
||||
{
|
||||
T temp = 1 / cos(helper.In.y) + m_Effect * T(M_PI);
|
||||
T temp = 1 / Zeps(cos(helper.In.y)) + m_Effect * T(M_PI);
|
||||
|
||||
helper.Out.x = m_Weight * (tanh(helper.In.x) * temp);
|
||||
helper.Out.y = m_Weight * (tanh(helper.In.y) * temp);
|
||||
@ -36,7 +36,7 @@ public:
|
||||
string effect = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
|
||||
ss << "\t{\n"
|
||||
<< "\t\treal_t temp = 1 / cos(vIn.y) + " << effect << " * M_PI;\n"
|
||||
<< "\t\treal_t temp = 1 / Zeps(cos(vIn.y)) + " << effect << " * M_PI;\n"
|
||||
<< "\n"
|
||||
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * (tanh(vIn.x) * temp);\n"
|
||||
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (tanh(vIn.y) * temp);\n"
|
||||
@ -276,11 +276,9 @@ public:
|
||||
|
||||
void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
|
||||
{
|
||||
T r = pow(helper.m_PrecalcSqrtSumSquares, m_Dist);
|
||||
T r = Zeps(pow(helper.m_PrecalcSqrtSumSquares, m_Dist));
|
||||
int n = Floor<T>(m_Power * rand.Frand01<T>());
|
||||
T alpha = helper.m_PrecalcAtanyx + n * M_2PI / Floor<T>(m_Power);
|
||||
//int n = (int)floor(m_Power * rand.Frand01<T>());
|
||||
//T alpha = helper.m_PrecalcAtanyx + n * M_2PI / floor(m_Power);
|
||||
T alpha = helper.m_PrecalcAtanyx + n * M_2PI / Zeps<T>((T)Floor<T>(m_Power));
|
||||
T sina = sin(alpha);
|
||||
T cosa = cos(alpha);
|
||||
|
||||
@ -299,9 +297,9 @@ public:
|
||||
string dist = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||
|
||||
ss << "\t{\n"
|
||||
<< "\t\treal_t r = pow(precalcSqrtSumSquares, " << dist << ");\n"
|
||||
<< "\t\treal_t r = Zeps(pow(precalcSqrtSumSquares, " << dist << "));\n"
|
||||
<< "\t\tint n = floor(" << power << " * MwcNext01(mwc));\n"
|
||||
<< "\t\treal_t alpha = precalcAtanyx + n * M_2PI / floor(" << power << ");\n"
|
||||
<< "\t\treal_t alpha = precalcAtanyx + n * M_2PI / Zeps(floor(" << power << "));\n"
|
||||
<< "\t\treal_t sina = sin(alpha);\n"
|
||||
<< "\t\treal_t cosa = cos(alpha);\n"
|
||||
<< "\n"
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
|
||||
{
|
||||
T r = helper.m_PrecalcSumSquares;
|
||||
T r4_1 = r / 4 + 1;
|
||||
T r4_1 = Zeps(r / 4 + 1);
|
||||
r4_1 = m_Weight / r4_1;
|
||||
|
||||
helper.Out.x = r4_1 * helper.In.x;
|
||||
@ -49,7 +49,7 @@ public:
|
||||
|
||||
ss << "\t{\n"
|
||||
<< "\t\treal_t r = precalcSumSquares;\n"
|
||||
<< "\t\treal_t r4_1 = r / 4 + 1;\n"
|
||||
<< "\t\treal_t r4_1 = Zeps(r / 4 + 1);\n"
|
||||
<< "\t\tr4_1 = xform->m_VariationWeights[" << varIndex << "] / r4_1;\n"
|
||||
<< "\n"
|
||||
<< "\t\tvOut.x = r4_1 * vIn.x;\n"
|
||||
|
@ -172,9 +172,12 @@ public:
|
||||
{
|
||||
Variation<T>* var = NULL;
|
||||
|
||||
xform.GetVariation(i)->Copy(var);//Will convert from type U to type T.
|
||||
if (Variation<U>* varOrig = xform.GetVariation(i))
|
||||
{
|
||||
varOrig->Copy(var);//Will convert from type U to type T.
|
||||
AddVariation(var);//Will internally call SetPrecalcFlags().
|
||||
}
|
||||
}
|
||||
|
||||
if (TotalVariationCount() == 0)
|
||||
SetPrecalcFlags();
|
||||
|
@ -49,8 +49,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,4,1,0
|
||||
PRODUCTVERSION 0,4,1,0
|
||||
FILEVERSION 0,4,1,1
|
||||
PRODUCTVERSION 0,4,1,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -67,12 +67,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Open Source"
|
||||
VALUE "FileDescription", "Renders fractal flames as animations with motion blur"
|
||||
VALUE "FileVersion", "0.4.1.0"
|
||||
VALUE "FileVersion", "0.4.1.1"
|
||||
VALUE "InternalName", "EmberAnimate.rc"
|
||||
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3"
|
||||
VALUE "OriginalFilename", "EmberAnimate.rc"
|
||||
VALUE "ProductName", "Ember Animate"
|
||||
VALUE "ProductVersion", "0.4.1.0"
|
||||
VALUE "ProductVersion", "0.4.1.1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -49,7 +49,7 @@ RendererCL<T>::RendererCL(unsigned int platform, unsigned int device, bool share
|
||||
m_PaletteFormat.image_channel_order = CL_RGBA;
|
||||
m_PaletteFormat.image_channel_data_type = CL_FLOAT;
|
||||
m_FinalFormat.image_channel_order = CL_RGBA;
|
||||
m_FinalFormat.image_channel_data_type = CL_UNORM_INT8;//Change if this ever supports 2BPP outputs for PNG.
|
||||
m_FinalFormat.image_channel_data_type = CL_UNORM_INT8;//Change if this ever supports 2BPC outputs for PNG.
|
||||
|
||||
Init(platform, device, shared, outputTexID);//Init OpenCL upon construction and create programs that will not change.
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,4,1,0
|
||||
PRODUCTVERSION 0,4,1,0
|
||||
FILEVERSION 0,4,1,1
|
||||
PRODUCTVERSION 0,4,1,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -67,12 +67,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Open Source"
|
||||
VALUE "FileDescription", "Manipulates fractal flames parameter files"
|
||||
VALUE "FileVersion", "0.4.1.0"
|
||||
VALUE "FileVersion", "0.4.1.1"
|
||||
VALUE "InternalName", "EmberGenome.rc"
|
||||
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3"
|
||||
VALUE "OriginalFilename", "EmberGenome.rc"
|
||||
VALUE "ProductName", "Ember Genome"
|
||||
VALUE "ProductVersion", "0.4.1.0"
|
||||
VALUE "ProductVersion", "0.4.1.1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -49,8 +49,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,4,1,0
|
||||
PRODUCTVERSION 0,4,1,0
|
||||
FILEVERSION 0,4,1,1
|
||||
PRODUCTVERSION 0,4,1,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -67,12 +67,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Open Source"
|
||||
VALUE "FileDescription", "Renders fractal flames as single images"
|
||||
VALUE "FileVersion", "0.4.1.0"
|
||||
VALUE "FileVersion", "0.4.1.1"
|
||||
VALUE "InternalName", "EmberRender.rc"
|
||||
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2013, GPL v3"
|
||||
VALUE "OriginalFilename", "EmberRender.rc"
|
||||
VALUE "ProductName", "Ember Render"
|
||||
VALUE "ProductVersion", "0.4.1.0"
|
||||
VALUE "ProductVersion", "0.4.1.1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -1074,6 +1074,28 @@ bool TestVarAssignVals()
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TestZepsFloor()
|
||||
{
|
||||
bool success = true;
|
||||
VariationList<float> vlf;
|
||||
vector<string> zeps;
|
||||
|
||||
zeps.push_back("Zeps(floor");
|
||||
|
||||
for (size_t i = 0; i < vlf.Size(); i++)
|
||||
{
|
||||
Variation<float>* var = vlf.GetVariation(i);
|
||||
|
||||
if (SearchVar(var, zeps, false))
|
||||
{
|
||||
cout << "Variation " << var->Name() << " contains Zeps(floor()). This is fine for the GPU, but ensure the CPU uses Zeps<T>((T)Floor<T>())." << endl;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TestConstants()
|
||||
{
|
||||
bool success = true;
|
||||
@ -1864,6 +1886,10 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
TestVarAssignVals();
|
||||
t.Toc("TestVarAssignVals()");
|
||||
|
||||
t.Tic();
|
||||
TestZepsFloor();
|
||||
t.Toc("TestZepsFloor()");
|
||||
|
||||
t.Tic();
|
||||
TestConstants();
|
||||
t.Toc("TestConstants()");
|
||||
|
@ -52,7 +52,7 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p align="center"><br/><span style=" font-size:12pt;">Fractorium 0.4.1.0 Beta</span></p><p align="center"><span style=" font-size:10pt;"><br/>A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><span style=" font-size:10pt;">Matt Feemster</span></p></body></html></string>
|
||||
<string><html><head/><body><p align="center"><br/><span style=" font-size:12pt;">Fractorium 0.4.1.1 Beta</span></p><p align="center"><span style=" font-size:10pt;"><br/>A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><span style=" font-size:10pt;">Matt Feemster</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
|
@ -83,16 +83,16 @@ template<typename T>
|
||||
FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderDialog* finalRender)
|
||||
: FinalRenderEmberControllerBase(finalRender)
|
||||
{
|
||||
m_PreviewRenderer = auto_ptr<EmberNs::Renderer<T, T>>(new EmberNs::Renderer<T, T>());
|
||||
m_PreviewRenderer->Callback(NULL);
|
||||
m_PreviewRenderer->NumChannels(4);
|
||||
m_PreviewRenderer->ReclaimOnResize(true);
|
||||
m_FinalPreviewRenderer = auto_ptr<EmberNs::Renderer<T, T>>(new EmberNs::Renderer<T, T>());
|
||||
m_FinalPreviewRenderer->Callback(NULL);
|
||||
m_FinalPreviewRenderer->NumChannels(4);
|
||||
m_FinalPreviewRenderer->ReclaimOnResize(true);
|
||||
|
||||
m_PreviewRenderFunc = [&]()
|
||||
m_FinalPreviewRenderFunc = [&]()
|
||||
{
|
||||
m_PreviewCs.Enter();//Thread prep.
|
||||
m_PreviewRun = true;
|
||||
m_PreviewRenderer->Abort();
|
||||
m_FinalPreviewRenderer->Abort();
|
||||
|
||||
QLabel* widget = m_FinalRender->ui.FinalRenderPreviewLabel;
|
||||
unsigned int maxDim = 100u;
|
||||
@ -106,21 +106,20 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
||||
|
||||
m_PreviewEmber = m_Ember;
|
||||
m_PreviewEmber.m_Quality = 100;
|
||||
m_PreviewEmber.m_Supersample = 1;
|
||||
m_PreviewEmber.m_TemporalSamples = 1;
|
||||
m_PreviewEmber.m_FinalRasW = min(maxDim, unsigned int(scalePercentage * m_Ember.m_FinalRasW));
|
||||
m_PreviewEmber.m_FinalRasH = min(maxDim, unsigned int(scalePercentage * m_Ember.m_FinalRasH));
|
||||
m_PreviewEmber.m_PixelsPerUnit = scalePercentage * m_Ember.m_PixelsPerUnit;
|
||||
|
||||
while (!m_PreviewRenderer->Aborted() || m_PreviewRenderer->InRender())
|
||||
while (!m_FinalPreviewRenderer->Aborted() || m_FinalPreviewRenderer->InRender())
|
||||
QApplication::processEvents();
|
||||
|
||||
m_PreviewRenderer->EarlyClip(m_FinalRender->EarlyClip());
|
||||
m_PreviewRenderer->YAxisUp(m_FinalRender->YAxisUp());
|
||||
m_PreviewRenderer->Transparency(m_FinalRender->Transparency());
|
||||
m_PreviewRenderer->SetEmber(m_PreviewEmber);
|
||||
m_FinalPreviewRenderer->EarlyClip(m_FinalRender->EarlyClip());
|
||||
m_FinalPreviewRenderer->YAxisUp(m_FinalRender->YAxisUp());
|
||||
m_FinalPreviewRenderer->Transparency(m_FinalRender->Transparency());
|
||||
m_FinalPreviewRenderer->SetEmber(m_PreviewEmber);
|
||||
|
||||
if (m_PreviewRenderer->Run(m_PreviewFinalImage) == RENDER_OK)
|
||||
if (m_FinalPreviewRenderer->Run(m_PreviewFinalImage) == RENDER_OK)
|
||||
{
|
||||
QImage image(m_PreviewEmber.m_FinalRasW, m_PreviewEmber.m_FinalRasH, QImage::Format_RGBA8888);//The label wants RGBA.
|
||||
memcpy(image.scanLine(0), m_PreviewFinalImage.data(), m_PreviewFinalImage.size() * sizeof(m_PreviewFinalImage[0]));//Memcpy the data in.
|
||||
@ -135,7 +134,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
||||
//The main rendering function which will be called in a Qt thread.
|
||||
//A backup Xml is made before the rendering process starts just in case it crashes before finishing.
|
||||
//If it finishes successfully, delete the backup file.
|
||||
m_RenderFunc = [&]()
|
||||
m_FinalRenderFunc = [&]()
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@ -243,6 +242,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
||||
m_Ember.m_TemporalSamples = 1;
|
||||
m_Renderer->SetEmber(m_Ember);
|
||||
m_PureIterTime = 0;
|
||||
memset(m_FinalImage.data(), 0, m_FinalImage.size() * sizeof(m_FinalImage[0]));
|
||||
m_RenderTimer.Tic();//Toc() is called in the progress function.
|
||||
|
||||
if (m_Renderer->Run(m_FinalImage) != RENDER_OK)
|
||||
@ -266,6 +266,7 @@ template <typename T> void FinalRenderEmberController<T>::SetEmber(const Ember<f
|
||||
template <typename T> void FinalRenderEmberController<T>::CopyEmber(Ember<float>& ember) { ember = m_Ember; }
|
||||
template <typename T> void FinalRenderEmberController<T>::SetEmberFile(const EmberFile<float>& emberFile) { m_EmberFile = emberFile; }
|
||||
template <typename T> void FinalRenderEmberController<T>::CopyEmberFile(EmberFile<float>& emberFile) { emberFile = m_EmberFile; }
|
||||
template <typename T> void FinalRenderEmberController<T>::SetOriginalEmber(Ember<float>& ember) { m_OriginalEmber = ember; }
|
||||
template <typename T> double FinalRenderEmberController<T>::OriginalAspect() { return double(m_OriginalEmber.m_OrigFinalRasW) / m_OriginalEmber.m_OrigFinalRasH; }
|
||||
#ifdef DO_DOUBLE
|
||||
template <typename T> void FinalRenderEmberController<T>::SetEmber(const Ember<double>& ember, bool verbatim) { m_Ember = ember; }
|
||||
@ -273,8 +274,6 @@ template <typename T> void FinalRenderEmberController<T>::CopyEmber(Ember<double
|
||||
template <typename T> void FinalRenderEmberController<T>::SetEmberFile(const EmberFile<double>& emberFile) { m_EmberFile = emberFile; }
|
||||
template <typename T> void FinalRenderEmberController<T>::CopyEmberFile(EmberFile<double>& emberFile) { emberFile = m_EmberFile; }
|
||||
template <typename T> void FinalRenderEmberController<T>::SetOriginalEmber(Ember<double>& ember) { m_OriginalEmber = ember; }
|
||||
#else
|
||||
template <typename T> void FinalRenderEmberController<T>::SetOriginalEmber(Ember<float>& ember) { m_OriginalEmber = ember; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@ -313,7 +312,7 @@ int FinalRenderEmberController<T>::ProgressFunc(Ember<T>& ember, void* foo, doub
|
||||
QFileInfo original(filename);
|
||||
EmberStats stats = m_Renderer->Stats();
|
||||
QString iters = QLocale(QLocale::English).toString(stats.m_Iters);
|
||||
QString itersPerSec = QLocale(QLocale::English).toString(int(stats.m_Iters / (m_PureIterTime / 1000.0)));
|
||||
QString itersPerSec = QLocale(QLocale::English).toString(unsigned __int64(stats.m_Iters / (m_PureIterTime / 1000.0)));
|
||||
|
||||
if (m_GuiState.m_DoAll && m_EmberFile.m_Embers.size() > 1)
|
||||
filename = original.absolutePath() + QDir::separator() + m_GuiState.m_Prefix + QString::fromStdString(m_EmberFile.m_Embers[m_FinishedImageCount].m_Name) + m_GuiState.m_Suffix + "." + m_GuiState.m_DoAllExt;
|
||||
@ -409,7 +408,7 @@ bool FinalRenderEmberController<T>::Render()
|
||||
//parallel iteration loops inside of the CPU renderer to finish. The result is that
|
||||
//the renderer ends up using ThreadCount - 1 to iterate, instead of ThreadCount.
|
||||
//By using a Qt thread here, and tbb inside the renderer, all cores can be maxed out.
|
||||
m_Result = QtConcurrent::run(m_RenderFunc);
|
||||
m_Result = QtConcurrent::run(m_FinalRenderFunc);
|
||||
m_Settings->sync();
|
||||
return true;
|
||||
}
|
||||
@ -469,7 +468,7 @@ bool FinalRenderEmberController<T>::CreateRenderer(eRendererType renderType, uns
|
||||
|
||||
m_Renderer->Callback(this);
|
||||
m_Renderer->NumChannels(channels);
|
||||
m_Renderer->ReclaimOnResize(false);
|
||||
m_Renderer->ReclaimOnResize(true);
|
||||
m_Renderer->EarlyClip(m_FinalRender->EarlyClip());
|
||||
m_Renderer->YAxisUp(m_FinalRender->YAxisUp());
|
||||
m_Renderer->ThreadCount(m_FinalRender->ThreadCount());
|
||||
@ -506,9 +505,9 @@ unsigned __int64 FinalRenderEmberController<T>::SyncAndComputeMemory()
|
||||
m_Renderer->NumChannels(channels);
|
||||
m_Renderer->ComputeBounds();
|
||||
CancelPreviewRender();
|
||||
//m_PreviewResult = QtConcurrent::run(m_PreviewRenderFunc);
|
||||
//while (!m_PreviewResult.isRunning()) { QApplication::processEvents(); }//Wait for it to start up.
|
||||
m_PreviewRenderFunc();
|
||||
//m_FinalPreviewResult = QtConcurrent::run(m_PreviewRenderFunc);
|
||||
//while (!m_FinalPreviewResult.isRunning()) { QApplication::processEvents(); }//Wait for it to start up.
|
||||
m_FinalPreviewRenderFunc();
|
||||
return m_Renderer->MemoryRequired(true);
|
||||
}
|
||||
|
||||
@ -536,11 +535,11 @@ void FinalRenderEmberController<T>::ResetProgress(bool total)
|
||||
template <typename T>
|
||||
void FinalRenderEmberController<T>::CancelPreviewRender()
|
||||
{
|
||||
m_PreviewRenderer->Abort();
|
||||
m_FinalPreviewRenderer->Abort();
|
||||
|
||||
while (m_PreviewRenderer->InRender()) { QApplication::processEvents(); }
|
||||
while (m_FinalPreviewRenderer->InRender()) { QApplication::processEvents(); }
|
||||
while (m_PreviewRun) { QApplication::processEvents(); }
|
||||
while (m_PreviewResult.isRunning()) { QApplication::processEvents(); }
|
||||
while (m_FinalPreviewResult.isRunning()) { QApplication::processEvents(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -61,10 +61,9 @@ public:
|
||||
virtual unsigned __int64 SyncAndComputeMemory() { return 0; }
|
||||
virtual QString Name() const { return ""; }
|
||||
virtual void ResetProgress(bool total = true) { }
|
||||
virtual void SetOriginalEmber(Ember<float>& ember) { }
|
||||
#ifdef DO_DOUBLE
|
||||
virtual void SetOriginalEmber(Ember<double>& ember) { }
|
||||
#else
|
||||
virtual void SetOriginalEmber(Ember<float>& ember) { }
|
||||
#endif
|
||||
virtual double OriginalAspect() { return 1; }
|
||||
|
||||
@ -79,10 +78,9 @@ protected:
|
||||
double m_PureIterTime;
|
||||
|
||||
QFuture<void> m_Result;
|
||||
QFuture<void> m_PreviewResult;
|
||||
std::function<void (void)> m_RenderFunc;
|
||||
std::function<void (void)> m_PreviewRenderFunc;
|
||||
vector<unsigned char> m_PreviewFinalImage;
|
||||
QFuture<void> m_FinalPreviewResult;
|
||||
std::function<void (void)> m_FinalRenderFunc;
|
||||
std::function<void (void)> m_FinalPreviewRenderFunc;
|
||||
|
||||
FractoriumSettings* m_Settings;
|
||||
FractoriumFinalRenderDialog* m_FinalRender;
|
||||
@ -108,14 +106,13 @@ public:
|
||||
virtual void CopyEmber(Ember<float>& ember);
|
||||
virtual void SetEmberFile(const EmberFile<float>& emberFile);
|
||||
virtual void CopyEmberFile(EmberFile<float>& emberFile);
|
||||
virtual void SetOriginalEmber(Ember<float>& ember);
|
||||
#ifdef DO_DOUBLE
|
||||
virtual void SetEmber(const Ember<double>& ember, bool verbatim = false);
|
||||
virtual void CopyEmber(Ember<double>& ember);
|
||||
virtual void SetEmberFile(const EmberFile<double>& emberFile);
|
||||
virtual void CopyEmberFile(EmberFile<double>& emberFile);
|
||||
virtual void SetOriginalEmber(Ember<double>& ember);
|
||||
#else
|
||||
virtual void SetOriginalEmber(Ember<float>& ember);
|
||||
#endif
|
||||
virtual double OriginalAspect();
|
||||
virtual int ProgressFunc(Ember<T>& ember, void* foo, double fraction, int stage, double etaMs);
|
||||
@ -135,7 +132,7 @@ protected:
|
||||
Ember<T> m_PreviewEmber;
|
||||
EmberFile<T> m_EmberFile;
|
||||
EmberToXml<T> m_XmlWriter;
|
||||
auto_ptr<EmberNs::Renderer<T, T>> m_PreviewRenderer;
|
||||
auto_ptr<EmberNs::Renderer<T, T>> m_FinalPreviewRenderer;
|
||||
};
|
||||
|
||||
template class FinalRenderEmberController<float>;
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user