mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-07-01 05:46:06 -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.
This commit is contained in:
@ -136,6 +136,12 @@ void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
|
||||
|
||||
while (index < varList.RegSize())
|
||||
{
|
||||
/*if (index != VAR_SYNTH)
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
Ember<T> ember1;
|
||||
unique_ptr<Variation<T>> regVar(varList.GetVariationCopy(index, VARTYPE_REG));
|
||||
unique_ptr<Variation<T>> preVar(varList.GetVariationCopy("pre_" + regVar->Name()));
|
||||
@ -422,7 +428,7 @@ bool TestVarUnique()
|
||||
|
||||
for (size_t i = 0; i < vl.Size(); i++)
|
||||
{
|
||||
Variation<T>* var = vl.GetVariation(i);
|
||||
auto var = vl.GetVariation(i);
|
||||
|
||||
if (std::find(ids.begin(), ids.end(), var->VariationId()) != ids.end())
|
||||
{
|
||||
@ -490,7 +496,7 @@ bool TestVarPrecalcEqual(const Variation<sT>* var1, const Variation<dT>* var2)
|
||||
}
|
||||
|
||||
template <typename sT, typename dT>
|
||||
bool TestVarEqual(Variation<sT>* var1, Variation<dT>* var2)
|
||||
bool TestVarEqual(const Variation<sT>* var1, const Variation<dT>* var2)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
@ -530,8 +536,8 @@ bool TestVarEqual(Variation<sT>* var1, Variation<dT>* var2)
|
||||
success = false;
|
||||
}
|
||||
|
||||
ParametricVariation<sT>* parVar1 = dynamic_cast<ParametricVariation<sT>*>(var1);
|
||||
ParametricVariation<dT>* parVar2 = dynamic_cast<ParametricVariation<dT>*>(var2);
|
||||
auto parVar1 = dynamic_cast<const ParametricVariation<sT>*>(var1);
|
||||
auto parVar2 = dynamic_cast<const ParametricVariation<dT>*>(var2);
|
||||
|
||||
if (parVar1 && parVar2)
|
||||
{
|
||||
@ -585,10 +591,13 @@ bool TestVarEqual(Variation<sT>* var1, Variation<dT>* var2)
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsClose<sT>(params1[i].ParamVal(), (sT)params2[i].ParamVal(), sT(1e-4)))
|
||||
if (!params1[i].IsState() && !params2[i].IsState())//Don't compare state params, they can be different if set to random vals.
|
||||
{
|
||||
cout << "Param " << params1[i].Name() << " Val were not equal: " << params1[i].ParamVal() << " != " << params2[i].ParamVal() << endl;
|
||||
success = false;
|
||||
if (!IsClose<sT>(params1[i].ParamVal(), (sT)params2[i].ParamVal(), sT(1e-4)))
|
||||
{
|
||||
cout << "Param " << params1[i].Name() << " Val were not equal: " << params1[i].ParamVal() << " != " << params2[i].ParamVal() << endl;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -669,7 +678,7 @@ bool TestVarCopy()
|
||||
|
||||
for (size_t i = 0; i < vlf.Size(); i++)
|
||||
{
|
||||
Variation<sT>* var = vlf.GetVariation(i);
|
||||
auto var = vlf.GetVariation(i);
|
||||
Variation<dT>* destVar = NULL;
|
||||
unique_ptr<Variation<sT>> copyVar(var->Copy());//Test Copy().
|
||||
|
||||
@ -1126,6 +1135,36 @@ bool TestConstants()
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TestGlobalFuncs()
|
||||
{
|
||||
bool success = true;
|
||||
VariationList<float> vlf;
|
||||
vector<string> funcs;
|
||||
FunctionMapper mapper;
|
||||
|
||||
for (size_t i = 0; i < vlf.Size(); i++)
|
||||
{
|
||||
auto var = vlf.GetVariation(i);
|
||||
|
||||
funcs = var->OpenCLGlobalFuncNames();
|
||||
|
||||
for (auto& func : funcs)
|
||||
{
|
||||
if (!mapper.GetGlobalFunc(func))
|
||||
{
|
||||
cout << "Variation " << var->Name() << " used unknown global funcion " << func << endl;
|
||||
success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//cout << "Variation " << var->Name() << " used valid global funcion " << func << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void PrintAllVars()
|
||||
{
|
||||
uint i = 0;
|
||||
@ -1506,17 +1545,20 @@ void TestVarsSimilar()
|
||||
#ifdef TEST_CL
|
||||
|
||||
template <typename T>
|
||||
void TestAllVarsCLBuild(bool printSuccess = true)
|
||||
bool TestAllVarsCLBuild(size_t platform, size_t device, bool printSuccess = true)
|
||||
{
|
||||
bool success = true;
|
||||
vector<Ember<T>> embers;
|
||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
|
||||
RendererCL<T> renderer;
|
||||
vector<pair<size_t, size_t>> devices{ std::make_pair(platform, device) };
|
||||
RendererCL<T, float> renderer(devices);
|
||||
|
||||
const char* loc = __FUNCTION__;
|
||||
|
||||
if (!renderer.Init(1, 0, false, 0))
|
||||
if (!renderer.Ok())
|
||||
{
|
||||
cout << loc << "Creating RendererCL failed, tests will not be run." << endl;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
MakeTestAllVarsRegPrePost(embers);
|
||||
@ -1531,12 +1573,18 @@ void TestAllVarsCLBuild(bool printSuccess = true)
|
||||
cout << loc << ": Build succeeded for ember " << it.m_Name << endl;
|
||||
}
|
||||
else
|
||||
cout << loc << ": OpenCL program build failed:\n" << renderer.ErrorReport() << endl;
|
||||
{
|
||||
success = false;
|
||||
cout << loc << ": OpenCL program build failed for ember " << it.m_Name << ":\n" << renderer.ErrorReportString() << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestCpuGpuResults()
|
||||
void TestCpuGpuResults(size_t platform, size_t device)
|
||||
{
|
||||
bool breakOnBad = true;
|
||||
int i = 0;//(int)VAR_TARGET;//Start at the one you want to test.
|
||||
@ -1547,10 +1595,8 @@ void TestCpuGpuResults()
|
||||
VariationList<T> vlf;
|
||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
|
||||
vector<PointCL<T>> points;
|
||||
RendererCL<T> renderer;
|
||||
|
||||
if (!renderer.Init(1, 0, false, 0))
|
||||
return;
|
||||
vector<pair<size_t, size_t>> devices{ std::make_pair(platform, device) };
|
||||
RendererCL<T, float> renderer(devices);
|
||||
|
||||
points.resize(renderer.TotalIterKernelCount());
|
||||
|
||||
@ -1637,7 +1683,7 @@ void TestCpuGpuResults()
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestGpuVectorRead()
|
||||
void TestGpuVectorRead(size_t platform, size_t device)
|
||||
{
|
||||
T minx = TMAX, miny = TMAX, minz = TMAX, mincolorx = TMAX;
|
||||
T maxx = TLOW, maxy = TLOW, maxz = TLOW, maxcolorx = TLOW;
|
||||
@ -1649,10 +1695,8 @@ void TestGpuVectorRead()
|
||||
VariationList<T> vlf;
|
||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
|
||||
vector<PointCL<T>> points;
|
||||
RendererCL<T> renderer;
|
||||
|
||||
if (!renderer.Init(1, 0, false, 0))
|
||||
return;
|
||||
vector<pair<size_t, size_t>> devices{ std::make_pair(platform, device) };
|
||||
RendererCL<T, float> renderer(devices);
|
||||
|
||||
points.resize(renderer.TotalIterKernelCount());
|
||||
|
||||
@ -1918,17 +1962,110 @@ void TestThreadedKernel()
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DistribTester()
|
||||
{
|
||||
size_t i;
|
||||
size_t distribCount = 1;
|
||||
size_t xformCount = 3;
|
||||
vector<byte> m_XformDistributions;
|
||||
//const Xform<T>* xforms = 3;
|
||||
size_t j = 0;
|
||||
vector<T> weights { T(0.333333), T(1.0), T(0.25) };
|
||||
double tempDensity = 0, currentDensityLimit = 0, densityPerElement;
|
||||
|
||||
if (m_XformDistributions.size() < CHOOSE_XFORM_GRAIN * distribCount)
|
||||
m_XformDistributions.resize(CHOOSE_XFORM_GRAIN * distribCount);
|
||||
|
||||
if (m_XformDistributions.size() < CHOOSE_XFORM_GRAIN * distribCount)
|
||||
return;
|
||||
|
||||
for (size_t distrib = 0; distrib < distribCount; distrib++)
|
||||
{
|
||||
double totalDensity = 0;
|
||||
|
||||
//First find the total densities of all xforms.
|
||||
for (i = 0; i < xformCount; i++)
|
||||
{
|
||||
T d = weights[i];
|
||||
|
||||
totalDensity += d;
|
||||
}
|
||||
|
||||
//Original returned false if all were 0, but it's allowed here
|
||||
//which will just end up setting all elements to 0 which means
|
||||
//only the first xform will get used.
|
||||
|
||||
//Calculate how much of a fraction of a the total density each element represents.
|
||||
j = 0;
|
||||
tempDensity = 0;
|
||||
currentDensityLimit = 0;
|
||||
densityPerElement = totalDensity / CHOOSE_XFORM_GRAIN;
|
||||
|
||||
//Assign xform indices in order to each element of m_XformDistributions.
|
||||
//The number of elements assigned a given index is proportional to that xform's
|
||||
//density relative to the sum of all densities.
|
||||
for (i = 0; i < xformCount; i++)
|
||||
{
|
||||
T temp = weights[i];
|
||||
currentDensityLimit += temp;
|
||||
|
||||
//Populate points corresponding to this xform's weight/density.
|
||||
//Also check that j is within the bounds of the distribution array just to be safe in the case of a rounding error.
|
||||
while (tempDensity < currentDensityLimit && j < CHOOSE_XFORM_GRAIN)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
//Ensure distribution contains no out of bounds indices.
|
||||
if (byte(i) >= xformCount)
|
||||
throw "Out of bounds xform index in selection distribution.";
|
||||
#endif
|
||||
//printf("offset = %d, xform = %d, running sum = %f\n", j, i, tempDensity);
|
||||
m_XformDistributions[(distrib * CHOOSE_XFORM_GRAIN) + j] = byte(i);
|
||||
tempDensity += densityPerElement;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Flam3 did this, which gives the same result.
|
||||
//T t = xforms[0].m_Weight;
|
||||
//
|
||||
//if (distrib > 0)
|
||||
// t *= xforms[distrib - 1].Xaos(0);
|
||||
//
|
||||
//T r = 0;
|
||||
//
|
||||
//for (i = 0; i < CHOOSE_XFORM_GRAIN; i++)
|
||||
//{
|
||||
// while (r >= t)
|
||||
// {
|
||||
// j++;
|
||||
//
|
||||
// if (distrib > 0)
|
||||
// t += xforms[j].m_Weight * xforms[distrib - 1].Xaos(j);
|
||||
// else
|
||||
// t += xforms[j].m_Weight;
|
||||
// }
|
||||
//
|
||||
// m_XformDistributions[(distrib * CHOOSE_XFORM_GRAIN) + i] = j;
|
||||
// r += densityPerElement;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
{
|
||||
//int i;
|
||||
bool b = true;
|
||||
Timing t(4);
|
||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand(1, 2, 3);
|
||||
mt19937 meow(1729);
|
||||
MakeTestAllVarsRegPrePostComboFile("testallvarsout.flame");
|
||||
|
||||
/*MakeTestAllVarsRegPrePostComboFile("testallvarsout.flame");
|
||||
return 0;
|
||||
|
||||
|
||||
/*TestThreadedKernel();
|
||||
TestThreadedKernel();
|
||||
|
||||
PaletteList<float> palf;
|
||||
Palette<float>* pal = palf.GetRandomPalette();
|
||||
@ -1939,7 +2076,7 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
cout << "log10(" << d << ") = " << std::max<uint>(1u, uint(log10(d)) + 1u) << endl;
|
||||
cout << "log10(" << d << ") = " << std::max<uint>(1u, uint(std::log10(d)) + 1u) << endl;
|
||||
d *= 10;
|
||||
}
|
||||
|
||||
@ -2041,7 +2178,7 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
|
||||
//cd2 = sin(cd);
|
||||
|
||||
/*t.Tic();
|
||||
t.Tic();
|
||||
TestCasting();
|
||||
t.Toc("TestCasting()");
|
||||
|
||||
@ -2088,6 +2225,7 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
TestVarCopy<double, float>();
|
||||
t.Toc("TestVarCopy<double, float>()");
|
||||
#endif
|
||||
|
||||
t.Tic();
|
||||
TestVarRegPrePost();
|
||||
t.Toc("TestVarRegPrePost()");
|
||||
@ -2121,17 +2259,22 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
t.Toc("TestConstants()");
|
||||
|
||||
t.Tic();
|
||||
TestGlobalFuncs();
|
||||
t.Toc("TestGlobalFuncs()");
|
||||
|
||||
/*t.Tic();
|
||||
TestXformsInOutPoints();
|
||||
t.Toc("TestXformsInOutPoints()");
|
||||
|
||||
t.Tic();
|
||||
TestVarTime<float>();
|
||||
t.Toc("TestVarTime()");
|
||||
|
||||
*/
|
||||
|
||||
t.Tic();
|
||||
TestOperations<float>();
|
||||
t.Toc("TestOperations()");
|
||||
*/
|
||||
|
||||
//t.Tic();
|
||||
//TestVarsSimilar<float>();
|
||||
//t.Toc("TestVarsSimilar()");
|
||||
@ -2141,18 +2284,34 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
//TestCpuGpuResults<float>();
|
||||
//t.Toc("TestCpuGpuResults<float>()");
|
||||
|
||||
t.Tic();
|
||||
TestAllVarsCLBuild<float>();
|
||||
t.Toc("TestAllVarsCLBuild<float>()");
|
||||
//t.Tic();
|
||||
//b = TestAllVarsCLBuild<float>(0, 0, true);
|
||||
//t.Toc("TestAllVarsCLBuild<float>()");
|
||||
|
||||
if (b)
|
||||
{
|
||||
t.Tic();
|
||||
b = TestAllVarsCLBuild<float>(1, 0, true);
|
||||
t.Toc("TestAllVarsCLBuild<float>()");
|
||||
}
|
||||
|
||||
#ifdef DO_DOUBLE
|
||||
//t.Tic();
|
||||
//TestCpuGpuResults<double>();
|
||||
//t.Toc("TestCpuGpuResults<double>()");
|
||||
if (b)
|
||||
{
|
||||
t.Tic();
|
||||
TestAllVarsCLBuild<double>(0, 0, true);
|
||||
t.Toc("TestAllVarsCLBuild<double>()");
|
||||
|
||||
t.Tic();
|
||||
TestAllVarsCLBuild<double>();
|
||||
t.Toc("TestAllVarsCLBuild<double>()");
|
||||
if (b)
|
||||
{
|
||||
t.Tic();
|
||||
TestAllVarsCLBuild<double>(1, 0, true);
|
||||
t.Toc("TestAllVarsCLBuild<double>()");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user