--User changes

-Edits will not save back to the file in memory on render completion when preview renderer is running.

--Bug fixes
 -dc_perlin was crashing on Nvidia when using SP.
 -Duplicate images were randomly getting added to the file in memory.
 -Crash when opening an Xml with less than 2 flames in it.

--Code changes
 -Use raw array of floats in OpenCL for perlin noise, rather than float3/double3.
 -Add some default cases to dc_perlin.
 -Redo singleton pattern yet again. Deriving from a templated Singleton<T> class was creating a separate instance per module. Now only one instance of each type will ever be created and it will be wrapped in a shared_ptr which guarantees its deletion as main() exits.
This commit is contained in:
mfeemster 2016-04-13 20:59:57 -07:00
parent 7715910362
commit 0fbea60026
29 changed files with 264 additions and 220 deletions

View File

@ -239,7 +239,7 @@ public:
ember.m_FinalXform.m_ColorSpeed = 0;
ember.m_FinalXform.m_Motion.clear();
ember.m_FinalXform.ClearAndDeleteVariations();
ember.m_FinalXform.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR, 0));//Do this so it doesn't appear empty.
ember.m_FinalXform.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR, 0));//Do this so it doesn't appear empty.
}
}
@ -1036,7 +1036,7 @@ public:
m_Xforms[i].m_Affine.D(0);
m_Xforms[i].m_Affine.E(1);
m_Xforms[i].m_Affine.F(0);
m_Xforms[i].AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR));
m_Xforms[i].AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
result++;
sym = -sym;
}
@ -1058,7 +1058,7 @@ public:
m_Xforms[i].m_Affine.E(m_Xforms[i].m_Affine.A());
m_Xforms[i].m_Affine.C(0);
m_Xforms[i].m_Affine.F(0);
m_Xforms[i].AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR));
m_Xforms[i].AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
result++;
}
@ -1688,7 +1688,7 @@ private:
Xform<T> m_FinalXform;
//Single global reference to create variations with.
VariationList<T>& m_VariationList = VariationList<T>::Instance();
shared_ptr<VariationList<T>> m_VariationList = VariationList<T>::Instance();
/// <summary>
/// Interpolation function that takes the address of a member variable of type T as a template parameter.

View File

@ -44,7 +44,7 @@ public:
bool currentFinal, final = sourceEmbers[0].UseFinalXform();
size_t i, xf, currentCount, maxCount = sourceEmbers[0].XformCount();
Xform<T>* destOtherXform;
VariationList<T>& variationList(VariationList<T>::Instance());
auto variationList = VariationList<T>::Instance();
//Determine the max number of xforms present in sourceEmbers.
//Also check if final xforms are used in any of them.
@ -138,7 +138,7 @@ public:
destOtherXform->GetVariationById(eVariationId::VAR_WEDGE_SPH) ||
destOtherXform->GetVariationById(eVariationId::VAR_WEDGE_JULIA))
{
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_LINEAR, -1));
destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_LINEAR, -1));
//Set the coefs appropriately.
destXform->m_Affine.A(-1);
destXform->m_Affine.D(0);
@ -167,7 +167,7 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_RECTANGLES))
{
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_RECTANGLES))
if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_RECTANGLES))
{
var->SetParamVal("rectangles_x", 0);
var->SetParamVal("rectangles_y", 0);
@ -179,7 +179,7 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_RINGS2))
{
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_RINGS2))
if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_RINGS2))
{
var->SetParamVal("rings2_val", 0);
destXform->AddVariation(var);
@ -190,13 +190,13 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_FAN2))
{
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_FAN2));
destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_FAN2));
found++;
}
if (destOtherXform->GetVariationById(eVariationId::VAR_BLOB))
{
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_BLOB))
if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_BLOB))
{
var->SetParamVal("blob_low", 1);
destXform->AddVariation(var);
@ -207,13 +207,13 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_PERSPECTIVE))
{
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_PERSPECTIVE));
destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_PERSPECTIVE));
found++;
}
if (destOtherXform->GetVariationById(eVariationId::VAR_CURL))
{
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_CURL))
if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_CURL))
{
var->SetParamVal("curl_c1", 0);
destXform->AddVariation(var);
@ -224,7 +224,7 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_SUPER_SHAPE))
{
if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_SUPER_SHAPE))
if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_SUPER_SHAPE))
{
var->SetParamVal("super_shape_n1", 2);
var->SetParamVal("super_shape_n2", 2);
@ -254,13 +254,13 @@ public:
if (destOtherXform->GetVariationById(eVariationId::VAR_FAN))
{
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_FAN));
destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_FAN));
found++;
}
if (destOtherXform->GetVariationById(eVariationId::VAR_RINGS))
{
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_RINGS));
destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_RINGS));
found++;
}
}
@ -280,7 +280,7 @@ public:
//If there still are no matches, switch back to linear.
if (found == 0)
{
destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_LINEAR));
destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_LINEAR));
}
else if (found > 0)
{

View File

@ -83,9 +83,9 @@ public:
Xform<T> xform1(T(0.25), T(1), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.5), T(0.25));
Xform<T> xform2(T(0.25), T(0.66), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(-0.5), T(0.25));
Xform<T> xform3(T(0.25), T(0.33), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.0), T(-0.5));
xform1.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR));
xform2.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR));
xform3.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR));
xform1.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
xform2.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
xform3.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));
ember.AddXform(xform1);
ember.AddXform(xform2);
ember.AddXform(xform3);
@ -599,7 +599,7 @@ public:
bool postid, addfinal = false;
int var, samed, multid, samepost;
glm::length_t i, j, k, n;
size_t varCount = m_VariationList.Size();
size_t varCount = m_VariationList->Size();
Palette<T> palette;
static size_t xformDistrib[] =
{
@ -683,12 +683,12 @@ public:
if (var > -1)
{
if (xform->TotalVariationCount() < maxVars)
xform->AddVariation(m_VariationList.GetVariation(var)->Copy());//Use only one variation specified for all xforms.
xform->AddVariation(m_VariationList->GetVariation(var)->Copy());//Use only one variation specified for all xforms.
}
else if (multid && var == -1)
{
if (xform->TotalVariationCount() < maxVars)
xform->AddVariation(m_VariationList.GetVariation(m_Rand.Rand() % varCount)->Copy());//Choose a random var for this xform.
xform->AddVariation(m_VariationList->GetVariation(m_Rand.Rand() % varCount)->Copy());//Choose a random var for this xform.
}
else
{
@ -721,7 +721,7 @@ public:
if (var != -2)
{
//Pick a random variation and use a random weight from 0-1.
Variation<T>* v = m_VariationList.GetVariationCopy(static_cast<size_t>(m_Rand.Rand() % varCount), m_Rand.Frand<T>(T(0.001), 1));
Variation<T>* v = m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand() % varCount), m_Rand.Frand<T>(T(0.001), 1));
if (v && !xform->AddVariation(v))
delete v;//It already existed and therefore was not added.
@ -729,7 +729,7 @@ public:
else
{
//Pick a random variation from the suppled IDs and use a random weight from 0-1.
Variation<T>* v = m_VariationList.GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand<T>(T(0.001), 1));
Variation<T>* v = m_VariationList->GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand<T>(T(0.001), 1));
if (v && !xform->AddVariation(v))
delete v;
@ -759,12 +759,12 @@ public:
if (var != -2)
{
//Pick a random variation and use a random weight from 0-1.
xform->AddVariation(m_VariationList.GetVariationCopy(static_cast<size_t>(m_Rand.Rand() % varCount), m_Rand.Frand<T>(T(0.001), 1)));
xform->AddVariation(m_VariationList->GetVariationCopy(static_cast<size_t>(m_Rand.Rand() % varCount), m_Rand.Frand<T>(T(0.001), 1)));
}
else
{
//Pick a random variation from the suppled IDs and use a random weight from 0-1.
xform->AddVariation(m_VariationList.GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand<T>(T(0.001), 1)));
xform->AddVariation(m_VariationList->GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand<T>(T(0.001), 1)));
}
}
}
@ -1345,6 +1345,6 @@ private:
unique_ptr<Renderer<T, bucketT>> m_Renderer;
QTIsaac<ISAAC_SIZE, ISAAC_INT> m_Rand;
PaletteList<T> m_PaletteList;
VariationList<T>& m_VariationList;
shared_ptr<VariationList<T>> m_VariationList;
};
}

View File

@ -193,13 +193,16 @@ private:
/// member variables cannot be exported across module boundaries.
/// Derived classes should inherit from this using the CRTP, and declare a friend to it.
/// They also should make their constructors private and destructors public.
/// This has a severe flaw in that it cannot be used across module boundaries, else
/// every module will have its own copy. This makes it function as a per-module
/// singleton, which is unlikely to ever be desired.
/// Attribution: This class is a combination of
/// http://btorpey.github.io/blog/2014/02/12/shared-singletons/
/// and
/// http://enki-tech.blogspot.com/2012/08/c11-generic-singleton.html
/// </summary>
template <class T>
class Singleton
class EMBER_API Singleton
{
public:
/// <summary>
@ -243,6 +246,28 @@ public:
x(const x& other) = delete; \
const x& operator=(const x& other) = delete
//Use this if not deriving from the Singleton class and are declaring Instance() in a header and implementing it in a cpp file.
#define SINGLETON_INSTANCE_DECL(x) \
static std::shared_ptr<x> Instance(); \
x(const x& other) = delete; \
const x& operator=(const x& other) = delete//Semicolon deliberately omitted to force it on the caller.
//Use this if not deriving from the Singleton class and are implementing Instance() in a cpp file.
#define SINGLETON_INSTANCE_IMPL(x) \
std::shared_ptr<x> x::Instance() \
{ \
static weak_ptr<x> staticInstance; \
auto temp = staticInstance.lock(); \
\
if (!temp) \
{ \
temp.reset(new x()); \
staticInstance = temp; \
} \
\
return temp; \
}
/// <summary>
/// Open a file in binary mode and read its entire contents into a vector of bytes. Optionally null terminate.
/// </summary>

View File

@ -13,7 +13,7 @@ namespace EmberNs
/// This class is a singleton since all of its data is shared and read-only.
/// </summary>
template <typename T>
class EMBER_API VarFuncs : public Singleton<VarFuncs<T>>
class EMBER_API VarFuncs
{
public:
/// <summary>
@ -542,7 +542,7 @@ public:
}
}
SINGLETON_DERIVED_IMPL(VarFuncs<T>);
SINGLETON_INSTANCE_DECL(VarFuncs);//Implemented in VariationList.cpp
private:
/// <summary>

View File

@ -17,14 +17,12 @@ namespace EmberNs
m_Variations.push_back(new Post##varName##Variation<T>());
/// <summary>
/// Singleton pattern, return a reference to the only instance of this object in existence.
/// Singleton patterns, return a reference to the only instance of this object in existence.
/// </summary>
template <typename T>
VariationList<T>& VariationList<T>::Instance()
{
static VariationList<T> v;
return v;
}
SINGLETON_INSTANCE_IMPL(VarFuncs<T>)
template <typename T>
SINGLETON_INSTANCE_IMPL(VariationList<T>)
/// <summary>
/// Constructor which initializes all of the variation objects and stores them in the list.

View File

@ -21,10 +21,7 @@ template <typename T>
class EMBER_API VariationList
{
public:
static VariationList<T>& Instance();
~VariationList();
VariationList<T>(const VariationList<T>& varList) = delete;
VariationList<T>& operator = (const VariationList<T>& varList) = delete;
const Variation<T>* GetVariation(size_t index) const;
const Variation<T>* GetVariation(size_t index, eVariationType varType) const;
Variation<T>* GetVariationCopy(size_t index, T weight = 1) const;
@ -48,6 +45,8 @@ public:
const vector<Variation<T>*>& PreVars() const;
const vector<Variation<T>*>& PostVars() const;
SINGLETON_INSTANCE_DECL(VariationList);//Implemented in VariationList.cpp
private:
VariationList();
Variation<T>* MakeCopyWithWeight(const Variation<T>* var, T weight) const;

View File

@ -281,7 +281,6 @@ protected:
m_Params.push_back(ParamWithName<T>(&m_Scale, prefix + "hexes_scale", 1));
m_Params.push_back(ParamWithName<T>(true, &m_RotSin, prefix + "hexes_rotsin"));//Precalc.
m_Params.push_back(ParamWithName<T>(true, &m_RotCos, prefix + "hexes_rotcos"));
m_VarFuncs = VarFuncs<T>::Instance();
}
private:
@ -291,7 +290,7 @@ private:
T m_Scale;
T m_RotSin;//Precalc.
T m_RotCos;
std::shared_ptr<VarFuncs<T>> m_VarFuncs;
shared_ptr<VarFuncs<T>> m_VarFuncs = VarFuncs<T>::Instance();
};
/// <summary>
@ -3774,7 +3773,7 @@ public:
//No possible solution was found, so it is unused here.
//The full calculation is recomputed for every point.
return
"static void Position(__global real_t* p, __global real3* grad, int x, int y, real_t z, real_t s, real_t d, real2* v)\n"
"static void Position(__global real_t* p, __global real_t* grad, int x, int y, real_t z, real_t s, real_t d, real2* v)\n"
"{\n"
" real3 e, f;\n"
" e.x = x * 2.5;\n"
@ -3823,7 +3822,7 @@ public:
<< "\t\t{\n"
<< "\t\t for (dj = -1; dj < 2; dj++)\n"
<< "\t\t {\n"
<< "\t\t Position(globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n"
<< "\t\t Position(globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n"
<< "\t\t i++;\n"
<< "\t\t }\n"
<< "\t\t}\n"
@ -3839,7 +3838,7 @@ public:
<< "\t\t{\n"
<< "\t\t for (dj = -1; dj < 2; dj++)\n"
<< "\t\t {\n"
<< "\t\t Position(globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n"
<< "\t\t Position(globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n"
<< "\t\t i++;\n"
<< "\t\t }\n"
<< "\t\t}\n"
@ -3870,7 +3869,6 @@ protected:
void Init()
{
string prefix = Prefix();
m_VarFuncs = VarFuncs<T>::Instance();
m_Params.clear();
m_Params.reserve(8);
m_Params.push_back(ParamWithName<T>(&m_CellSize, prefix + "crackle_cellsize", 1));
@ -3912,7 +3910,7 @@ private:
T m_Z;
T m_HalfCellSize;//Precalc
v2T m_C[CACHE_WIDTH][CACHE_WIDTH];//Not kept as a precalc because it crashes Nvidia GPUs.
std::shared_ptr<VarFuncs<T>> m_VarFuncs;
shared_ptr<VarFuncs<T>> m_VarFuncs = VarFuncs<T>::Instance();
};
/// <summary>

View File

@ -1314,6 +1314,7 @@ public:
<< "\t\t break; \n"
<< "\n"
<< "\t\t case " << SHAPE_BLUR << ": \n"
<< "\t\t default: \n"
<< "\t\t r = (1 + " << edge << ") * MwcNext01(mwc); \n"
<< "\n"
<< "\t\t if (r > 1 - " << edge << ")\n"
@ -1369,6 +1370,7 @@ public:
<< "\t\t break; \n"
<< "\n"
<< "\t\t case " << MAP_BUBBLE2 << ": \n"
<< "\t\t default: \n"
<< "\t\t r = 0.25 - (SQR(vx) + SQR(vy)); \n"
<< "\n"
<< "\t\t if (r < 0)\n"
@ -1382,13 +1384,13 @@ public:
<< "\t\t break; \n"
<< "\t\t }\n"
<< "\n"
<< "\t\t p = PerlinNoise3D(&v, globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), " << amps << ", " << freqs << ", iOctaves); \n"
<< "\t\t p = PerlinNoise3D(&v, globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, " << amps << ", " << freqs << ", iOctaves); \n"
<< "\n"
<< "\t\t if (p > 0)\n"
<< "\t\t e = p * (1 + e * e * 20) + 2 * e; \n"
<< "\t\t else\n"
<< "\t\t e = p * (1 + e * e * 20) - 2 * e; \n"
<< "}\n"
<< "\t\t}\n"
<< "\t\twhile ((e < " << notchBottom << " || e > " << notchTop << ") && t++ < iBailout); \n"
<< "\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vx; \n"
@ -1413,7 +1415,6 @@ protected:
void Init()
{
string prefix = Prefix();
m_VarFuncs = VarFuncs<T>::Instance();
m_Params.clear();
m_Params.reserve(15);
m_Params.push_back(ParamWithName<T>(&m_Shape, prefix + "dc_perlin_shape", 0, eParamType::INTEGER, 0, 2));//Params.
@ -1448,7 +1449,7 @@ private:
T m_SelectBailout;
T m_NotchBottom;//Precalc.
T m_NotchTop;
shared_ptr<VarFuncs<T>> m_VarFuncs;
shared_ptr<VarFuncs<T>> m_VarFuncs = VarFuncs<T>::Instance();
};
MAKEPREPOSTPARVAR(DCBubble, dc_bubble, DC_BUBBLE)

View File

@ -879,7 +879,7 @@ public:
bool Flatten(vector<string>& names)
{
bool shouldFlatten = true;
VariationList<T>& vl(VariationList<T>::Instance());
auto vl = VariationList<T>::Instance();
if (GetVariationById(eVariationId::VAR_FLATTEN) == nullptr)
{
@ -898,7 +898,7 @@ public:
}
//Now traverse the parameters for this variation.
if (ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var))//If any parametric variation parameter is present and non-zero, don't flatten.
if (auto parVar = dynamic_cast<ParametricVariation<T>*>(var))//If any parametric variation parameter is present and non-zero, don't flatten.
{
for (auto& s : names)
{
@ -915,7 +915,7 @@ public:
if (shouldFlatten)//Flatten was not present and neither was any variation name or parameter in the list.
{
auto var = vl.GetVariationCopy(eVariationId::VAR_FLATTEN);
auto var = vl->GetVariationCopy(eVariationId::VAR_FLATTEN);
if (AddVariation(var))
{

View File

@ -337,8 +337,8 @@ public:
ScanForEmberNodes(rootnode, bn, embers, useDefaults);
xmlFreeDoc(doc);
emberSize = embers.size();
auto b = embers.begin();
auto secondToLast = Advance(embers.begin(), emberSize - 2);
auto first = embers.begin();
//t.Toc("ScanForEmberNodes");
//Check to see if the first control point or the second-to-last
@ -346,11 +346,16 @@ public:
//and should be reset to linear (with a warning).
if (emberSize > 0)
{
if (b->m_Interp == eInterp::EMBER_INTERP_SMOOTH)
b->m_Interp = eInterp::EMBER_INTERP_LINEAR;
if (first->m_Interp == eInterp::EMBER_INTERP_SMOOTH)
first->m_Interp = eInterp::EMBER_INTERP_LINEAR;
if (emberSize >= 2 && secondToLast->m_Interp == eInterp::EMBER_INTERP_SMOOTH)
secondToLast->m_Interp = eInterp::EMBER_INTERP_LINEAR;
if (emberSize >= 2)
{
auto secondToLast = Advance(embers.begin(), emberSize - 2);
if (secondToLast->m_Interp == eInterp::EMBER_INTERP_SMOOTH)
secondToLast->m_Interp = eInterp::EMBER_INTERP_LINEAR;
}
}
//Finally, ensure that consecutive 'rotate' parameters never exceed
@ -1263,7 +1268,7 @@ private:
//Only correct names if it came from an outside source. Names originating from this library are always considered correct.
string s = fromEmber ? string(CCX(curAtt->name)) : GetCorrectedVariationName(m_BadVariationNames, curAtt);
if (auto var = m_VariationList.GetVariation(s))
if (auto var = m_VariationList->GetVariation(s))
{
T weight = 0;
Aton(attStr, weight);
@ -1543,7 +1548,7 @@ private:
static bool m_Init;
static unordered_map<string, string> m_BadParamNames;
static vector<pair<pair<string, string>, vector<string>>> m_BadVariationNames;
VariationList<T>& m_VariationList;//The variation list used to make copies of variations to populate the embers with.
shared_ptr<VariationList<T>> m_VariationList;//The variation list used to make copies of variations to populate the embers with.
PaletteList<T> m_PaletteList;
};
}

View File

@ -176,7 +176,7 @@ FunctionMapper::FunctionMapper()
" return ratiomax;\n"
"}\n";
s_GlobalMap["SimplexNoise3D"] =
"inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real3* grad)\n"
"inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real_t* grad)\n"
"{\n"
" real3 c[4];\n"
" real_t n = 0;\n"
@ -195,6 +195,7 @@ FunctionMapper::FunctionMapper()
" c[0].z = (*v).z - z0;\n"
" int i1, j1, k1;\n"
" int i2, j2, k2;\n"
" real3 u;\n"
"\n"
" if (c[0].x >= c[0].y)\n"
" {\n"
@ -249,25 +250,28 @@ FunctionMapper::FunctionMapper()
" gi[1] = (int)p[ii + i1 + (int)p[jj + j1 + (int)p[kk + k1]]];\n"
" gi[2] = (int)p[ii + i2 + (int)p[jj + j2 + (int)p[kk + k2]]];\n"
" gi[3] = (int)p[ii + 1 + (int)p[jj + 1 + (int)p[kk + 1]]];\n"
"\n"
" for (uint corner = 0; corner < 4; corner++)\n"
" {\n"
" t = 0.6 - Sqr(c[corner].x) - Sqr(c[corner].y) - Sqr(c[corner].z);\n"
"\n"
" if (t > 0)\n"
" {\n"
" real3 u = grad[gi[corner]];\n"
" u.x = grad[(gi[corner] * 3)];\n"
" u.y = grad[(gi[corner] * 3) + 1];\n"
" u.z = grad[(gi[corner] * 3) + 2];\n"
" t *= t;\n"
" n += t * t * (u.x * c[corner].x + u.y * c[corner].y + u.z * c[corner].z);\n"
" }\n"
" }\n"
"\n"
" return 32 * n;\n"
" return 32.0 * n;\n"
"}\n";
s_GlobalMap["PerlinNoise3D"] =
"inline real_t PerlinNoise3D(real3* v, __global real_t* p, __global real3* grad, real_t aScale, real_t fScale, int octaves)\n"
"inline real_t PerlinNoise3D(real3* v, __global real_t* p, __global real_t* grad, real_t aScale, real_t fScale, int octaves)\n"
"{\n"
" int i;\n"
" real_t n = 0, a = 1;\n"
" real_t n = 0.0, a = 1.0;\n"
" real3 u = *v;\n"
"\n"
" for (i = 0; i < octaves; i++)\n"

View File

@ -68,6 +68,8 @@ OpenCLInfo::OpenCLInfo()
}
}
SINGLETON_INSTANCE_IMPL(OpenCLInfo)
/// <summary>
/// Get a const reference to the vector of available platforms.
/// </summary>

View File

@ -17,7 +17,7 @@ namespace EmberCLns
/// This class derives from EmberReport, so the caller is able
/// to retrieve a text dump of error information if any errors occur.
/// </summary>
class EMBERCL_API OpenCLInfo : public EmberReport, public Singleton<OpenCLInfo>
class EMBERCL_API OpenCLInfo : public EmberReport
{
public:
const vector<cl::Platform>& Platforms() const;
@ -54,7 +54,7 @@ public:
return val;
}
SINGLETON_DERIVED_IMPL(OpenCLInfo);
SINGLETON_INSTANCE_DECL(OpenCLInfo);
private:
OpenCLInfo();

View File

@ -64,13 +64,13 @@ bool EmberGenome(EmberOptions& opt)
return true;
}
VariationList<T>& varList(VariationList<T>::Instance());
auto varList = VariationList<T>::Instance();
if (opt.AllVars() || opt.RegVars() || opt.PreVars() || opt.PostVars())
{
if (opt.AllVars())
{
auto& vars = varList.AllVars();
auto& vars = varList->AllVars();
for (auto& v : vars)
cout << v->Name() << "\n";
@ -82,13 +82,13 @@ bool EmberGenome(EmberOptions& opt)
vector<Variation<T>*> vars;
if (opt.RegVars())
vars.insert(vars.end(), varList.RegVars().begin(), varList.RegVars().end());
vars.insert(vars.end(), varList->RegVars().begin(), varList->RegVars().end());
if (opt.PreVars())
vars.insert(vars.end(), varList.PreVars().begin(), varList.PreVars().end());
vars.insert(vars.end(), varList->PreVars().begin(), varList->PreVars().end());
if (opt.PostVars())
vars.insert(vars.end(), varList.PostVars().begin(), varList.PostVars().end());
vars.insert(vars.end(), varList->PostVars().begin(), varList->PostVars().end());
for (auto& v : vars)
cout << v->Name() << "\n";
@ -192,16 +192,16 @@ bool EmberGenome(EmberOptions& opt)
noVars.push_back(eVariationId::VAR_SPLITS);
//Loop over the novars and set ivars to the complement.
for (i = 0; i < varList.Size(); i++)
for (i = 0; i < varList->Size(); i++)
{
for (j = 0; j < noVars.size(); j++)
{
if (noVars[j] == varList.GetVariation(i)->VariationId())
if (noVars[j] == varList->GetVariation(i)->VariationId())
break;
}
if (j == noVars.size())
vars.push_back(varList.GetVariation(i)->VariationId());
vars.push_back(varList->GetVariation(i)->VariationId());
}
}
else
@ -214,7 +214,7 @@ bool EmberGenome(EmberOptions& opt)
{
if (parser.Aton(token.c_str(), val))
{
if (val < varList.Size())
if (val < varList->Size())
vars.push_back(static_cast<eVariationId>(val));
}
}
@ -227,22 +227,22 @@ bool EmberGenome(EmberOptions& opt)
{
if (parser.Aton(token.c_str(), val))
{
if (val < varList.Size())
if (val < varList->Size())
noVars.push_back(static_cast<eVariationId>(val));
}
}
//Loop over the novars and set ivars to the complement.
for (i = 0; i < varList.Size(); i++)
for (i = 0; i < varList->Size(); i++)
{
for (j = 0; j < noVars.size(); j++)
{
if (noVars[j] == varList.GetVariation(i)->VariationId())
if (noVars[j] == varList->GetVariation(i)->VariationId())
break;
}
if (j == noVars.size())
vars.push_back(varList.GetVariation(i)->VariationId());
vars.push_back(varList->GetVariation(i)->VariationId());
}
}
}

View File

@ -89,7 +89,7 @@ void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
{
uint index = 0;
ostringstream ss;
VariationList<T>& varList(VariationList<T>::Instance());
auto varList = VariationList<T>::Instance();
PaletteList<T> paletteList;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
paletteList.Add("flam3-palettes.xml");
@ -118,7 +118,7 @@ void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
emberNoVars.m_Palette = *paletteList.GetPalette(paletteList.m_DefaultFilename, 0);
embers.push_back(emberNoVars);
while (index < varList.RegSize())
while (index < varList->RegSize())
{
/* if (index != eVariationId::VAR_SYNTH)
{
@ -127,9 +127,9 @@ void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
}
*/
Ember<T> ember1;
unique_ptr<Variation<T>> regVar(varList.GetVariationCopy(index, eVariationType::VARTYPE_REG));
unique_ptr<Variation<T>> preVar(varList.GetVariationCopy("pre_" + regVar->Name()));
unique_ptr<Variation<T>> postVar(varList.GetVariationCopy("post_" + regVar->Name()));
unique_ptr<Variation<T>> regVar(varList->GetVariationCopy(index, eVariationType::VARTYPE_REG));
unique_ptr<Variation<T>> preVar(varList->GetVariationCopy("pre_" + regVar->Name()));
unique_ptr<Variation<T>> postVar(varList->GetVariationCopy("post_" + regVar->Name()));
ember1.m_FinalRasW = 640;
ember1.m_FinalRasH = 480;
ember1.m_Quality = 100;
@ -337,12 +337,12 @@ template <typename T>
static vector<Variation<T>*> FindVarsWith(vector<string>& stringVec, bool findAll = true)
{
int index = 0;
VariationList<T>& vl(VariationList<T>::Instance());
auto vl = VariationList<T>::Instance();
vector<Variation<T>*> vec;
while (index < vl.RegSize())
while (index < vl->RegSize())
{
auto regVar = vl.GetVariation(index, eVariationType::VARTYPE_REG);
auto regVar = vl->GetVariation(index, eVariationType::VARTYPE_REG);
if (SearchVar(regVar, stringVec, false))
{
@ -360,10 +360,10 @@ static vector<Variation<T>*> FindVarsWith(vector<string>& stringVec, bool findAl
bool TestVarCounts()
{
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
#ifdef DO_DOUBLE
VariationList<double>& vld(VariationList<double>::Instance());
bool success((vlf.Size() == vld.Size()) && (vlf.Size() == size_t(eVariationId::LAST_VAR)));
auto vld(VariationList<double>::Instance());
bool success((vlf->Size() == vld->Size()) && (vlf->Size() == size_t(eVariationId::LAST_VAR)));
#else
bool success = true;
#endif
@ -371,12 +371,12 @@ bool TestVarCounts()
if (!success)
{
cout << "Variation list size " << vlf.Size() << " does not equal the max var ID enum " << et(eVariationId::LAST_VAR) << "." << endl;
cout << "Variation list size " << vlf->Size() << " does not equal the max var ID enum " << et(eVariationId::LAST_VAR) << "." << endl;
}
for (; start < et(eVariationId::LAST_VAR); start++)
{
auto var = vlf.GetVariation((eVariationId)start);
auto var = vlf->GetVariation((eVariationId)start);
if (!var)
{
@ -392,15 +392,15 @@ template <typename T>
bool TestVarUnique()
{
bool success = true;
VariationList<T>& vl(VariationList<T>::Instance());
auto vl = VariationList<T>::Instance();
vector<eVariationId> ids;
vector<string> names;
ids.reserve(vl.Size());
names.reserve(vl.Size());
ids.reserve(vl->Size());
names.reserve(vl->Size());
for (size_t i = 0; i < vl.Size(); i++)
for (size_t i = 0; i < vl->Size(); i++)
{
auto var = vl.GetVariation(i);
auto var = vl->GetVariation(i);
if (std::find(ids.begin(), ids.end(), var->VariationId()) != ids.end())
{
@ -580,11 +580,11 @@ bool TestVarEqual(const Variation<sT>* var1, const Variation<dT>* var2)
bool TestVarPrePostNames()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
for (size_t i = 0; i < vlf.Size(); i++)
for (size_t i = 0; i < vlf->Size(); i++)
{
auto var = vlf.GetVariation(i);
auto var = vlf->GetVariation(i);
string name = var->Name();
if (var->VarType() == eVariationType::VARTYPE_REG)
@ -646,11 +646,11 @@ template <typename sT, typename dT>
bool TestVarCopy()
{
bool success = true;
VariationList<sT>& vlf(VariationList<sT>::Instance());
auto vlf(VariationList<sT>::Instance());
for (size_t i = 0; i < vlf.Size(); i++)
for (size_t i = 0; i < vlf->Size(); i++)
{
auto var = vlf.GetVariation(i);
auto var = vlf->GetVariation(i);
Variation<dT>* destVar = NULL;
unique_ptr<Variation<sT>> copyVar(var->Copy());//Test Copy().
@ -676,11 +676,11 @@ bool TestVarCopy()
bool TestParVars()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
for (size_t i = 0; i < vlf.ParametricSize(); i++)
for (size_t i = 0; i < vlf->ParametricSize(); i++)
{
if (auto parVar = vlf.GetParametricVariation(i))
if (auto parVar = vlf->GetParametricVariation(i))
{
if (parVar->ParamCount() < 1)
{
@ -730,19 +730,19 @@ bool TestParVars()
bool TestVarRegPrePost()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
for (size_t i = 0; i < vlf.RegSize(); i++)
for (size_t i = 0; i < vlf->RegSize(); i++)
{
auto regVar = vlf.GetVariation(i, eVariationType::VARTYPE_REG);
auto regVar = vlf->GetVariation(i, eVariationType::VARTYPE_REG);
if (regVar)
{
if (regVar->Name().find("dc_") != 0)
{
string name = regVar->Name();
auto preVar = vlf.GetVariation("pre_" + name);
auto postVar = vlf.GetVariation("post_" + name);
auto preVar = vlf->GetVariation("pre_" + name);
auto postVar = vlf->GetVariation("post_" + name);
if (!preVar)
{
@ -782,11 +782,11 @@ bool TestVarRegPrePost()
bool TestVarPrecalcUsedCL()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
for (size_t i = 0; i < vlf.Size(); i++)
for (size_t i = 0; i < vlf->Size(); i++)
{
auto var = vlf.GetVariation(i);
auto var = vlf->GetVariation(i);
string s = var->OpenCLString();
if (var->NeedPrecalcAngles())
@ -951,7 +951,7 @@ bool TestVarPrecalcUsedCL()
bool TestVarAssignTypes()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
vector<string> vset, vsum;
vset.push_back("vIn.x");
vset.push_back("vIn.y");
@ -972,9 +972,9 @@ bool TestVarAssignTypes()
vsum.push_back("precalcAtanxy");
vsum.push_back("precalcAtanyx");
for (size_t i = 0; i < vlf.Size(); i++)
for (size_t i = 0; i < vlf->Size(); i++)
{
auto var = vlf.GetVariation(i);
auto var = vlf->GetVariation(i);
string s = var->OpenCLString();
//Only test pre and post. The assign type for regular is ignored, and will always be summed.
@ -1009,7 +1009,7 @@ bool TestVarAssignTypes()
bool TestVarAssignVals()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
vector<string> xout, yout, zout;
xout.push_back("vOut.x =");
xout.push_back("vOut.x +=");
@ -1027,9 +1027,9 @@ bool TestVarAssignVals()
zout.push_back("vOut.z *=");
zout.push_back("vOut.z /=");
for (size_t i = 0; i < vlf.Size(); i++)
for (size_t i = 0; i < vlf->Size(); i++)
{
auto var = vlf.GetVariation(i);
auto var = vlf->GetVariation(i);
if (!SearchVar(var, xout, false))
{
@ -1056,13 +1056,13 @@ bool TestVarAssignVals()
bool TestZepsFloor()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
vector<string> zeps;
zeps.push_back("Zeps(floor");
for (size_t i = 0; i < vlf.Size(); i++)
for (size_t i = 0; i < vlf->Size(); i++)
{
auto var = vlf.GetVariation(i);
auto var = vlf->GetVariation(i);
if (SearchVar(var, zeps, false))
{
@ -1077,16 +1077,16 @@ bool TestZepsFloor()
bool TestConstants()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
vector<string> stringVec;
stringVec.push_back("2 * M_PI");
stringVec.push_back("2*M_PI");
stringVec.push_back("M_PI*2");
stringVec.push_back("M_PI * 2");
for (size_t i = 0; i < vlf.Size(); i++)
for (size_t i = 0; i < vlf->Size(); i++)
{
auto var = vlf.GetVariation(i);
auto var = vlf->GetVariation(i);
if (SearchVar(var, stringVec, false))
{
@ -1101,13 +1101,13 @@ bool TestConstants()
bool TestGlobalFuncs()
{
bool success = true;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
vector<string> funcs;
FunctionMapper mapper;
for (size_t i = 0; i < vlf.Size(); i++)
for (size_t i = 0; i < vlf->Size(); i++)
{
auto var = vlf.GetVariation(i);
auto var = vlf->GetVariation(i);
funcs = var->OpenCLGlobalFuncNames();
for (auto& func : funcs)
@ -1130,30 +1130,30 @@ bool TestGlobalFuncs()
void PrintAllVars()
{
uint i = 0;
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
while (auto var = vlf.GetVariation(i++))
while (auto var = vlf->GetVariation(i++))
cout << var->Name() << endl;
}
void TestXformsInOutPoints()
{
uint index = 0;
VariationList<float>& varList(VariationList<float>::Instance());
auto varList(VariationList<float>::Instance());
PaletteList<float> paletteList;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
paletteList.Add("flam3-palettes.xml");
while (index < varList.RegSize())
while (index < varList->RegSize())
{
vector<Xform<float>> xforms;
unique_ptr<Variation<float>> regVar(varList.GetVariationCopy(index, eVariationType::VARTYPE_REG));
unique_ptr<Variation<float>> regVar(varList->GetVariationCopy(index, eVariationType::VARTYPE_REG));
string s = regVar->OpenCLString() + regVar->OpenCLFuncsString();
if (s.find("MwcNext") == string::npos)
{
unique_ptr<Variation<float>> preVar(varList.GetVariationCopy("pre_" + regVar->Name()));
unique_ptr<Variation<float>> postVar(varList.GetVariationCopy("post_" + regVar->Name()));
unique_ptr<Variation<float>> preVar(varList->GetVariationCopy("pre_" + regVar->Name()));
unique_ptr<Variation<float>> postVar(varList->GetVariationCopy("post_" + regVar->Name()));
Xform<float> xform0(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>());
Xform<float> xform1(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>());
Xform<float> xform2(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>());
@ -1257,13 +1257,13 @@ void TestVarTime()
IteratorHelper<T> helper;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
vector<pair<string, double>> times;
times.reserve(vlf.RegSize());
times.reserve(vlf->RegSize());
while (i < vlf.RegSize())
while (i < vlf->RegSize())
{
double sum = 0;
Xform<T> xform;
Variation<T>* var = vlf.GetVariationCopy(i, eVariationType::VARTYPE_REG);
Variation<T>* var = vlf->GetVariationCopy(i, eVariationType::VARTYPE_REG);
xform.AddVariation(var);
for (int iter = 0; iter < iters; iter++)
@ -1365,18 +1365,18 @@ void TestVarsSimilar()
IteratorHelper<T> helper;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
vector<pair<string, double>> diffs;
diffs.reserve(vlf.RegSize());
diffs.reserve(vlf->RegSize());
while (i < vlf.RegSize())
while (i < vlf->RegSize())
{
double diff = 0, highest = TMAX;
Xform<T> xform;
Variation<T>* var = vlf.GetVariationCopy(i, eVariationType::VARTYPE_REG);
Variation<T>* var = vlf->GetVariationCopy(i, eVariationType::VARTYPE_REG);
pair<string, double> match("", TMAX);
compIndex = 0;
xform.AddVariation(var);
while (compIndex < vlf.RegSize())
while (compIndex < vlf->RegSize())
{
if (compIndex == i)
{
@ -1386,7 +1386,7 @@ void TestVarsSimilar()
double sum = 0, xdiff = 0, ydiff = 0, zdiff = 0;
Xform<T> xformComp;
Variation<T>* varComp = vlf.GetVariationCopy(compIndex, eVariationType::VARTYPE_REG);
Variation<T>* varComp = vlf->GetVariationCopy(compIndex, eVariationType::VARTYPE_REG);
xformComp.AddVariation(varComp);
ParametricVariation<T>* parVar = dynamic_cast<ParametricVariation<T>*>(var);
ParametricVariation<T>* parVarComp = dynamic_cast<ParametricVariation<T>*>(varComp);
@ -1536,11 +1536,11 @@ void TestCpuGpuResults(size_t platform, size_t device)
RendererCL<T, float> renderer(devices);
points.resize(renderer.TotalIterKernelCount());
while (i < vlf.RegSize())
while (i < vlf->RegSize())
{
bool bad = false;
double sum = 0;
Variation<T>* var = vlf.GetVariation(i, eVariationType::VARTYPE_REG);
Variation<T>* var = vlf->GetVariation(i, eVariationType::VARTYPE_REG);
string s = var->OpenCLString() + var->OpenCLFuncsString();
if (s.find("MwcNext") != string::npos)
@ -1631,7 +1631,7 @@ void TestGpuVectorRead(size_t platform, size_t device)
vector<pair<size_t, size_t>> devices{ std::make_pair(platform, device) };
RendererCL<T, float> renderer(devices);
points.resize(renderer.TotalIterKernelCount());
Variation<T>* var = vlf.GetVariation(eVariationId::VAR_LINEAR);
Variation<T>* var = vlf->GetVariation(eVariationId::VAR_LINEAR);
bool newAlloc = false;
Point<T> p, p2;
Ember<T> ember;
@ -2132,12 +2132,12 @@ int _tmain(int argc, _TCHAR* argv[])
TestCasting();
t.Toc("TestCasting()");
t.Tic();
VariationList<float>& vlf(VariationList<float>::Instance());
auto vlf(VariationList<float>::Instance());
t.Toc("Creating VariationList<float>");
cout << "There are " << vlf.Size() << " variations present." << endl;
cout << "There are " << vlf->Size() << " variations present." << endl;
#ifdef DO_DOUBLE
t.Tic();
VariationList<double>& vld(VariationList<double>::Instance());
auto vld(VariationList<double>::Instance());
t.Toc("Creating VariationList<double>");
#endif
t.Tic();

View File

@ -400,7 +400,7 @@ void FractoriumFinalRenderDialog::OnDoSequenceCheckBoxStateChanged(int state)
/// <param name="d">Ignored</param>
void FractoriumFinalRenderDialog::OnCurrentSpinChanged(int d)
{
m_Controller->SetEmber(d - 1);
m_Controller->SetEmber(d - 1, false);
m_Controller->SyncCurrentToGui();
SetMemory();
}
@ -743,7 +743,7 @@ bool FractoriumFinalRenderDialog::CreateControllerFromGUI(bool createRenderer)
if (m_Controller.get())
{
m_Controller->SetEmberFile(efd);//Convert float to double or set double verbatim;
m_Controller->SetEmber(index);
m_Controller->SetEmber(index, false);
}
}

View File

@ -406,7 +406,7 @@ template <typename T> void FinalRenderEmberController<T>::CopyEmberFile(EmberFil
/// </summary>
/// <param name="index">The index in the file from which to retrieve the ember</param>
template <typename T>
void FinalRenderEmberController<T>::SetEmber(size_t index)
void FinalRenderEmberController<T>::SetEmber(size_t index, bool verbatim)
{
if (index < m_EmberFile.Size())
{

View File

@ -109,7 +109,7 @@ public:
virtual void SetEmberFile(const EmberFile<double>& emberFile) override;
virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
#endif
virtual void SetEmber(size_t index) override;
virtual void SetEmber(size_t index, bool verbatim) override;
virtual bool Render() override;
virtual bool CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, bool shared = true) override;
virtual int ProgressFunc(Ember<T>& ember, void* foo, double fraction, int stage, double etaMs) override;

View File

@ -134,7 +134,7 @@ FractoriumEmberController<T>::~FractoriumEmberController() { }
/// 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); }
template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) { SetEmberPrivate<float>(ember, verbatim, updatePointer); }
template <typename T> void FractoriumEmberController<T>::CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); }
template <typename T> void FractoriumEmberController<T>::SetEmberFile(const EmberFile<float>& emberFile) { m_EmberFile = emberFile; }
template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation)
@ -146,7 +146,7 @@ template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile
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); }
template <typename T> void FractoriumEmberController<T>::SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) { SetEmberPrivate<double>(ember, verbatim, updatePointer); }
template <typename T> void FractoriumEmberController<T>::CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); }
template <typename T> void FractoriumEmberController<T>::SetEmberFile(const EmberFile<double>& emberFile) { m_EmberFile = emberFile; }
template <typename T> void FractoriumEmberController<T>::CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation)
@ -173,8 +173,9 @@ void FractoriumEmberController<T>::ConstrainDimensions(Ember<T>& ember)
/// Resets the rendering process.
/// </summary>
/// <param name="index">The index in the file from which to retrieve the ember</param>
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
template <typename T>
void FractoriumEmberController<T>::SetEmber(size_t index)
void FractoriumEmberController<T>::SetEmber(size_t index, bool verbatim)
{
if (index < m_EmberFile.Size())
{
@ -188,7 +189,7 @@ void FractoriumEmberController<T>::SetEmber(size_t index)
}
ClearUndo();
SetEmber(*m_EmberFile.Get(index));
SetEmber(*m_EmberFile.Get(index), verbatim, true);
}
}
@ -318,9 +319,10 @@ void FractoriumEmberController<T>::UpdateXform(std::function<void(Xform<T>*)> fu
/// </summary>
/// <param name="ember">The ember to set as the current</param>
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
/// <param name="updatePointer">If true, update the current ember pointer to the address of the one passed in.</param>
template <typename T>
template <typename U>
void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool verbatim)
void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer)
{
if (ember.m_Name != m_Ember.m_Name)
m_LastSaveCurrent = "";
@ -328,7 +330,9 @@ void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool v
size_t w = m_Ember.m_FinalRasW;//Cache values for use below.
size_t h = m_Ember.m_FinalRasH;
m_Ember = ember;
m_EmberFilePointer = &ember;
if (updatePointer)
m_EmberFilePointer = &ember;
if (!verbatim)
{

View File

@ -52,21 +52,21 @@ public:
virtual ~FractoriumEmberControllerBase();
//Embers.
virtual void SetEmber(const Ember<float>& ember, bool verbatim = false) { }
virtual void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) { }
virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }//Uncomment default lambdas once LLVM fixes a crash in their compiler with default lambda parameters.//TODO
virtual void SetEmberFile(const EmberFile<float>& emberFile) { }
virtual void CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) { }
virtual void SetTempPalette(const Palette<float>& palette) { }
virtual void CopyTempPalette(Palette<float>& palette) { }
#ifdef DO_DOUBLE
virtual void SetEmber(const Ember<double>& ember, bool verbatim = false) { }
virtual void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) { }
virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { }
virtual void SetEmberFile(const EmberFile<double>& emberFile) { }
virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) { }
virtual void SetTempPalette(const Palette<double>& palette) { }
virtual void CopyTempPalette(Palette<double>& palette) { }
#endif
virtual void SetEmber(size_t index) { }
virtual void SetEmber(size_t index, bool verbatim) { }
//virtual void Clear() { }
virtual void AddXform() { }
virtual void AddLinkedXform() { }
@ -95,7 +95,7 @@ public:
virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) { }
virtual void SaveCurrentAsXml() { }
virtual void SaveEntireFileAsXml() { }
virtual void SaveCurrentToOpenedFile() { }
virtual uint SaveCurrentToOpenedFile() { return 0; }
virtual void Undo() { }//Edit.
virtual void Redo() { }
virtual void CopyXml() { }
@ -290,21 +290,21 @@ public:
virtual ~FractoriumEmberController();
//Embers.
virtual void SetEmber(const Ember<float>& ember, bool verbatim = false) override;
virtual void SetEmber(const Ember<float>& ember, bool verbatim, bool updatePointer) override;
virtual void CopyEmber(Ember<float>& ember, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override;
virtual void SetEmberFile(const EmberFile<float>& emberFile) override;
virtual void CopyEmberFile(EmberFile<float>& emberFile, std::function<void(Ember<float>& ember)> perEmberOperation/* = [&](Ember<float>& ember) { }*/) override;
virtual void SetTempPalette(const Palette<float>& palette) override;
virtual void CopyTempPalette(Palette<float>& palette) override;
#ifdef DO_DOUBLE
virtual void SetEmber(const Ember<double>& ember, bool verbatim = false) override;
virtual void SetEmber(const Ember<double>& ember, bool verbatim, bool updatePointer) override;
virtual void CopyEmber(Ember<double>& ember, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
virtual void SetEmberFile(const EmberFile<double>& emberFile) override;
virtual void CopyEmberFile(EmberFile<double>& emberFile, std::function<void(Ember<double>& ember)> perEmberOperation/* = [&](Ember<double>& ember) { }*/) override;
virtual void SetTempPalette(const Palette<double>& palette) override;
virtual void CopyTempPalette(Palette<double>& palette) override;
#endif
virtual void SetEmber(size_t index) override;
virtual void SetEmber(size_t index, bool verbatim) override;
//virtual void Clear() override { }
virtual void AddXform() override;
virtual void AddLinkedXform() override;
@ -336,7 +336,7 @@ public:
virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) override;
virtual void SaveCurrentAsXml() override;
virtual void SaveEntireFileAsXml() override;
virtual void SaveCurrentToOpenedFile() override;
virtual uint SaveCurrentToOpenedFile() override;
virtual void Undo() override;
virtual void Redo() override;
virtual void CopyXml() override;
@ -472,7 +472,7 @@ public:
private:
//Embers.
void ApplyXmlSavingTemplate(Ember<T>& ember);
template <typename U> void SetEmberPrivate(const Ember<U>& ember, bool verbatim);
template <typename U> void SetEmberPrivate(const Ember<U>& ember, bool verbatim, bool updatePointer);
//Params.
void ParamsToEmber(Ember<T>& ember);
@ -509,7 +509,7 @@ private:
Xform<T> m_CopiedFinalXform;
Palette<T> m_TempPalette;
PaletteList<T> m_PaletteList;
VariationList<T>& m_VariationList;
shared_ptr<VariationList<T>> m_VariationList;
unique_ptr<SheepTools<T, float>> m_SheepTools;
unique_ptr<GLEmberController<T>> m_GLController;
unique_ptr<EmberNs::Renderer<T, float>> m_PreviewRenderer = make_unique<EmberNs::Renderer<T, float>>();

View File

@ -243,7 +243,7 @@ void FractoriumEmberController<T>::EmberTreeItemDoubleClicked(QTreeWidgetItem* i
{
//qDebug() << "Setting current ember to: " << QString::fromStdString(emberItem->GetEmber()->m_Name);
ClearUndo();
SetEmber(*emberItem->GetEmber());
SetEmber(*emberItem->GetEmber(), false, true);
}
}

View File

@ -76,7 +76,7 @@ void FractoriumEmberController<T>::NewFlock(size_t count)
void Fractorium::OnActionNewFlock(bool checked)
{
m_Controller->NewFlock(m_Settings->RandomCount());
m_Controller->SetEmber(0);
m_Controller->SetEmber(0, false);
}
/// <summary>
@ -102,7 +102,7 @@ void FractoriumEmberController<T>::NewEmptyFlameInCurrentFile()
m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync.
m_EmberFile.MakeNamesUnique();
UpdateLibraryTree();
SetEmber(m_EmberFile.Size() - 1);
SetEmber(m_EmberFile.Size() - 1, false);
}
void Fractorium::OnActionNewEmptyFlameInCurrentFile(bool checked) { m_Controller->NewEmptyFlameInCurrentFile(); }
@ -124,7 +124,7 @@ void FractoriumEmberController<T>::NewRandomFlameInCurrentFile()
m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync.
m_EmberFile.MakeNamesUnique();
UpdateLibraryTree();
SetEmber(m_EmberFile.Size() - 1);
SetEmber(m_EmberFile.Size() - 1, false);
}
void Fractorium::OnActionNewRandomFlameInCurrentFile(bool checked) { m_Controller->NewRandomFlameInCurrentFile(); }
@ -144,7 +144,7 @@ void FractoriumEmberController<T>::CopyFlameInCurrentFile()
m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync.
m_EmberFile.MakeNamesUnique();
UpdateLibraryTree();
SetEmber(m_EmberFile.Size() - 1);
SetEmber(m_EmberFile.Size() - 1, false);
}
void Fractorium::OnActionCopyFlameInCurrentFile(bool checked) { m_Controller->CopyFlameInCurrentFile(); }
@ -231,7 +231,7 @@ void FractoriumEmberController<T>::OpenAndPrepFiles(const QStringList& filenames
FillLibraryTree(append ? previousSize - 1 : 0);
ClearUndo();
SetEmber(previousSize);
SetEmber(previousSize, false);
}
}
@ -365,37 +365,45 @@ void Fractorium::OnActionSaveCurrentScreen(bool checked)
/// <summary>
/// Save the current ember back to its position in the opened file.
/// This will not take any action if the previews are still rendering because
/// this writes to memory the preview renderer might be reading, and also stops the
/// preview renderer.
/// This does not save to disk.
/// </summary>
template <typename T>
void FractoriumEmberController<T>::SaveCurrentToOpenedFile()
uint FractoriumEmberController<T>::SaveCurrentToOpenedFile()
{
uint i = 0;
bool fileFound = false;
for (auto& it : m_EmberFile.m_Embers)
if (!m_PreviewRunning)
{
if (&it == m_EmberFilePointer)//Just compare memory addresses.
for (auto& it : m_EmberFile.m_Embers)
{
it = m_Ember;//Save it to the opened file in memory.
fileFound = true;
break;
if (&it == m_EmberFilePointer)//Just compare memory addresses.
{
it = m_Ember;//Save it to the opened file in memory.
fileFound = true;
break;
}
i++;
}
i++;
if (!fileFound)
{
StopPreviewRender();
m_EmberFile.m_Embers.push_back(m_Ember);
m_EmberFile.MakeNamesUnique();
UpdateLibraryTree();
}
else
{
RenderPreviews(i, i + 1);
}
}
if (!fileFound)
{
StopPreviewRender();
m_EmberFile.m_Embers.push_back(m_Ember);
m_EmberFile.MakeNamesUnique();
UpdateLibraryTree();
}
else
{
RenderPreviews(i, i + 1);
}
return i;
}
/// <summary>
@ -419,9 +427,7 @@ void FractoriumEmberController<T>::Undo()
int index = m_Ember.GetTotalXformIndex(CurrentXform());
m_LastEditWasUndoRedo = true;
m_UndoIndex = std::max<size_t>(0u, m_UndoIndex - 1u);
auto temp = m_EmberFilePointer;//m_EmberFilePointer will be set to point to whatever is passed in, which we don't want since it's coming from the undo list...
SetEmber(m_UndoList[m_UndoIndex], true);
m_EmberFilePointer = temp;//...keep it pointing to the original one in the file.
SetEmber(m_UndoList[m_UndoIndex], true, false);//Don't update pointer because it's coming from the undo list...
m_EditState = eEditUndoState::UNDO_REDO;
if (index >= 0)
@ -445,9 +451,7 @@ void FractoriumEmberController<T>::Redo()
int index = m_Ember.GetTotalXformIndex(CurrentXform());
m_LastEditWasUndoRedo = true;
m_UndoIndex = std::min<size_t>(m_UndoIndex + 1, m_UndoList.size() - 1);
auto temp = m_EmberFilePointer;
SetEmber(m_UndoList[m_UndoIndex], true);
m_EmberFilePointer = temp;//...keep it pointing to the original one in the file.
SetEmber(m_UndoList[m_UndoIndex], true, false);
m_EditState = eEditUndoState::UNDO_REDO;
if (index >= 0)
@ -552,7 +556,7 @@ void FractoriumEmberController<T>::PasteXmlAppend()
m_EmberFile.MakeNamesUnique();
UpdateLibraryTree();
SetEmber(previousSize);
SetEmber(previousSize, false);
}
}
@ -611,7 +615,7 @@ void FractoriumEmberController<T>::PasteXmlOver()
m_EmberFile.MakeNamesUnique();
FillLibraryTree();
SetEmber(0);
SetEmber(0, false);
}
void Fractorium::OnActionPasteXmlOver(bool checked) { m_Controller->PasteXmlOver(); }

View File

@ -455,7 +455,7 @@ bool FractoriumEmberController<T>::Render()
gl->update();
if (ProcessState() == eProcessState::ACCUM_DONE)
SaveCurrentToOpenedFile();
SaveCurrentToOpenedFile();//Will not save if the previews are still rendering.
//Uncomment for debugging kernel build and execution errors.
//m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo()));
@ -671,6 +671,7 @@ bool Fractorium::CreateControllerFromOptions()
auto blur = m_PaletteBlurSpin->value();
auto freq = m_PaletteFrequencySpin->value();
double scale;
uint current = 0;
#ifdef DO_DOUBLE
Ember<double> ed;
EmberFile<double> efd;
@ -686,6 +687,7 @@ bool Fractorium::CreateControllerFromOptions()
if (m_Controller.get())
{
scale = m_Controller->LockedScale();
current = m_Controller->SaveCurrentToOpenedFile();
m_Controller->StopPreviewRender();//Must stop any previews first, else changing controllers will crash the program.
m_Controller->CopyTempPalette(tempPalette);//Convert float to double or save double verbatim;
//Replace below with this once LLVM fixes a crash in their compiler with default lambda parameters.//TODO
@ -713,8 +715,8 @@ bool Fractorium::CreateControllerFromOptions()
if (m_Controller.get())
{
ed.m_Palette = tempPalette;//Restore base temp palette. Adjustments will be then be applied and stored back in in m_Ember.m_Palette below.
m_Controller->SetEmber(ed);//Convert float to double or set double verbatim. This will assign m_Ember.m_Palette (which was just tempPalette) to m_TempPalette.
m_Controller->SetEmberFile(efd);
m_Controller->SetEmber(current, true);
m_Controller->LockedScale(scale);
//Setting these and updating the GUI overwrites the work of clearing them done in SetEmber() above.
//It's a corner case, but doesn't seem to matter.

View File

@ -279,7 +279,7 @@ void FractoriumEmberController<T>::AddFinalXform()
Update([&]()
{
Xform<T> final;
final.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR));//Just a placeholder so other parts of the code don't see it as being empty.
final.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));//Just a placeholder so other parts of the code don't see it as being empty.
m_Ember.SetFinalXform(final);
int index = int(m_Ember.TotalXformCount() - 1);//Set index to the last item.
FillXforms(index);

View File

@ -84,8 +84,8 @@ void FractoriumEmberController<T>::FilteredVariations()
m_FilteredVariations.clear();
m_FilteredVariations.reserve(map.size());
for (auto i = 0; i < m_VariationList.Size(); i++)
if (auto var = m_VariationList.GetVariation(i))
for (auto i = 0; i < m_VariationList->Size(); i++)
if (auto var = m_VariationList->GetVariation(i))
if (map.contains(var->Name().c_str()) && map[var->Name().c_str()].toBool())
m_FilteredVariations.push_back(var->VariationId());
}
@ -107,9 +107,9 @@ void FractoriumEmberController<T>::SetupVariationsTree()
tree->clear();
tree->blockSignals(true);
for (size_t i = 0; i < m_VariationList.Size(); i++)
for (size_t i = 0; i < m_VariationList->Size(); i++)
{
auto var = m_VariationList.GetVariation(i);
auto var = m_VariationList->GetVariation(i);
auto parVar = dynamic_cast<const ParametricVariation<T>*>(var);
//First add the variation, with a spinner for its weight.
auto item = new VariationTreeWidgetItem(var->VariationId(), tree);
@ -206,7 +206,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would
{
UpdateXform([&](Xform<T>* xform)
{
auto var = m_VariationList.GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only.
auto var = m_VariationList->GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only.
auto parVar = dynamic_cast<const ParametricVariation<T>*>(var);//The parametric cast of that variation.
auto xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform.
auto widgetItem = sender->WidgetItem();
@ -294,7 +294,7 @@ void FractoriumEmberController<T>::FillVariationTreeWithXform(Xform<T>* xform)
auto item = dynamic_cast<VariationTreeWidgetItem*>(tree->topLevelItem(i));
auto var = xform->GetVariationById(item->Id());//See if this variation in the tree was contained in the xform.
auto parVar = dynamic_cast<ParametricVariation<T>*>(var);//Attempt cast to parametric variation for later.
auto origParVar = dynamic_cast<const ParametricVariation<T>*>(m_VariationList.GetVariation(item->Id()));
auto origParVar = dynamic_cast<const ParametricVariation<T>*>(m_VariationList->GetVariation(item->Id()));
if (auto spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(tree->itemWidget(item, 1)))//Get the widget for the item, and cast the widget to the VariationTreeDoubleSpinBox type.
{

View File

@ -27,6 +27,8 @@ int main(int argc, char* argv[])
putenv(const_cast<char*>("GPU_MAX_ALLOC_PERCENT=100"));
#endif
int rv = -1;
auto vlf = VariationList<float>::Instance();//Create two instances that will stay alive until this function exits.
auto vld = VariationList<double>::Instance();//No further creations should occur after this.
try
{

View File

@ -128,26 +128,26 @@ void FractoriumVariationsDialog::OnSelectNoneButtonClicked(bool checked)
void FractoriumVariationsDialog::Populate()
{
auto table = ui.VariationsTable;
int size = int(std::max<size_t>(std::max<size_t>(m_VariationList.RegSize(), m_VariationList.PreSize()), m_VariationList.PostSize()));
int size = int(std::max<size_t>(std::max<size_t>(m_VariationList->RegSize(), m_VariationList->PreSize()), m_VariationList->PostSize()));
table->setRowCount(size);
for (auto i = 0; i < size; i++)
{
if (auto pre = m_VariationList.GetVariation(i, eVariationType::VARTYPE_PRE))
if (auto pre = m_VariationList->GetVariation(i, eVariationType::VARTYPE_PRE))
{
auto cb = new QTableWidgetItem(pre->Name().c_str());
table->setItem(i, 0, cb);
SetCheckFromMap(cb, pre);
}
if (auto reg = m_VariationList.GetVariation(i, eVariationType::VARTYPE_REG))
if (auto reg = m_VariationList->GetVariation(i, eVariationType::VARTYPE_REG))
{
auto cb = new QTableWidgetItem(reg->Name().c_str());
table->setItem(i, 1, cb);
SetCheckFromMap(cb, reg);
}
if (auto post = m_VariationList.GetVariation(i, eVariationType::VARTYPE_POST))
if (auto post = m_VariationList->GetVariation(i, eVariationType::VARTYPE_POST))
{
auto cb = new QTableWidgetItem(post->Name().c_str());
table->setItem(i, 2, cb);
@ -209,7 +209,7 @@ void FractoriumVariationsDialog::DataToGui()
{
ForEachCell([&](QTableWidgetItem * cb)
{
if (auto var = m_VariationList.GetVariation(cb->text().toStdString()))
if (auto var = m_VariationList->GetVariation(cb->text().toStdString()))
SetCheckFromMap(cb, var);
});
}
@ -221,7 +221,7 @@ void FractoriumVariationsDialog::GuiToData()
{
ForEachCell([&](QTableWidgetItem * cb)
{
if (auto var = m_VariationList.GetVariation(cb->text().toStdString()))
if (auto var = m_VariationList->GetVariation(cb->text().toStdString()))
m_Vars[cb->text()] = (cb->checkState() == Qt::Checked);
});
}

View File

@ -41,7 +41,7 @@ private:
void GuiToData();
void Populate();
void SetCheckFromMap(QTableWidgetItem* cb, const Variation<float>* var);
VariationList<float>& m_VariationList;
shared_ptr<VariationList<float>> m_VariationList;
QMap<QString, QVariant> m_Vars;
FractoriumSettings* m_Settings;
Ui::VariationsDialog ui;