diff --git a/Source/Ember/Affine2D.cpp b/Source/Ember/Affine2D.cpp index 4e50208..fea7519 100644 --- a/Source/Ember/Affine2D.cpp +++ b/Source/Ember/Affine2D.cpp @@ -208,16 +208,25 @@ void Affine2D::Scale(T amount) /// /// The angle to rotate by template -void Affine2D::Rotate(T angle) +void Affine2D::Rotate(T rad) { m4T origMat4 = ToMat4ColMajor(true);//Must center and use column major for glm to work. - m4T newMat4 = glm::rotate(origMat4, angle * DEG_2_RAD_T, v3T(0, 0, 1));//Assuming only rotating around z. + m4T newMat4 = glm::rotate(origMat4, rad, v3T(0, 0, 1));//Assuming only rotating around z. A(newMat4[0][0]);//Use direct assignments instead of constructor to skip assigning C and F. B(newMat4[0][1]); D(newMat4[1][0]); E(newMat4[1][1]); } +template +void Affine2D::RotateTrans(T rad) +{ + m4T origMat4 = TransToMat4ColMajor();//Only put translation in this matrix. + m4T newMat4 = glm::rotate(origMat4, rad, v3T(0, 0, 1));//Assuming only rotating around z. + C(newMat4[0][3]);//Use direct assignments instead of constructor to skip assigning A, B, D, E. + F(newMat4[1][3]); +} + /// /// Move by v. /// @@ -341,6 +350,16 @@ typename m4T Affine2D::ToMat4RowMajor(bool center) const return mat; } +template +typename m4T Affine2D::TransToMat4ColMajor() const +{ + m4T mat(1, 0, 0, C(), //Col0... + 0, 1, 0, F(), //1 + 0, 0, 1, 0, //2 + 0, 0, 0, 1);//3 + return mat; +} + /// /// Accessors. /// @@ -366,6 +385,19 @@ template void Affine2D::X(const v2T& x) { A(x.x); D(x.y); }//X A template void Affine2D::Y(const v2T& y) { B(y.x); E(y.y); }//Y Axis. template void Affine2D::O(const v2T& t) { C(t.x); F(t.y); }//Translation. +template +string Affine2D::ToString() const +{ + ostringstream ss; + ss << "A: " << A() << " " + << "B: " << B() << " " + << "C: " << C() + << "\nD: " << D() << " " + << "E: " << E() << " " + << "F: " << F(); + return ss.str(); +} + /// /// Rotate and scale this affine transform and return as a copy. Orginal is unchanged. /// diff --git a/Source/Ember/Affine2D.h b/Source/Ember/Affine2D.h index 9aea528..e30110e 100644 --- a/Source/Ember/Affine2D.h +++ b/Source/Ember/Affine2D.h @@ -77,7 +77,8 @@ public: bool IsEmpty() const; void Scale(T amount); Affine2D ScaleCopy(T amount); - void Rotate(T angle); + void Rotate(T rad); + void RotateTrans(T rad); void Translate(const v2T& v); void RotateScaleXTo(const v2T& v); void RotateScaleYTo(const v2T& v); @@ -88,6 +89,7 @@ public: m2T ToMat2RowMajor() const; m4T ToMat4ColMajor(bool center = false) const; m4T ToMat4RowMajor(bool center = false) const; + m4T TransToMat4ColMajor() const; //Note that returning a copy is actually faster than a const ref&. T A() const; @@ -112,6 +114,8 @@ public: void Y(const v2T& y); void O(const v2T& t); + string ToString() const; + static Affine2D CalcRotateScale(const v2T& from, const v2T& to); static void CalcRSAC(const v2T& from, const v2T& to, T& a, T& c); diff --git a/Source/Ember/CarToRas.h b/Source/Ember/CarToRas.h index 89c5381..265782b 100644 --- a/Source/Ember/CarToRas.h +++ b/Source/Ember/CarToRas.h @@ -99,7 +99,6 @@ public: m_PadCarLlY = T(carToRas.PadCarLlY()); m_PadCarUrX = T(carToRas.PadCarUrX()); m_PadCarUrY = T(carToRas.PadCarUrY()); - return *this; } @@ -117,29 +116,22 @@ public: { m_RasWidth = rasW; m_RasHeight = rasH; - m_CarLlX = carLlX; m_CarLlY = carLlY; m_CarUrX = carUrX; m_CarUrY = carUrY; - T carW = m_CarUrX - m_CarLlX;//Right minus left. T carH = m_CarUrY - m_CarLlY;//Top minus bottom. T invSizeW = T(1.0) / carW; T invSizeH = T(1.0) / carH; - m_PixPerImageUnitW = static_cast(rasW) * invSizeW; m_RasLlX = m_PixPerImageUnitW * carLlX; - m_PixPerImageUnitH = static_cast(rasH) * invSizeH; m_RasLlY = m_PixPerImageUnitH * carLlY; - m_OneRow = abs(m_CarUrY - m_CarLlY) / m_RasHeight; m_OneCol = abs(m_CarUrX - m_CarLlX) / m_RasWidth; - m_PadCarLlX = m_CarLlX + m_OneCol; m_PadCarUrX = m_CarUrX - m_OneCol; - m_PadCarLlY = m_CarLlY + m_OneRow; m_PadCarUrY = m_CarUrY - m_OneRow; } @@ -209,9 +201,8 @@ public: //if (point.m_Y > m_CarLlY && point.m_Y <= m_PadCarLlY && //Mapped to top row... // point.m_X > m_CarLlX && point.m_X <= m_PadCarLlX)//...first col. //{ - // cout << "First pixel hit." << endl; + // cout << "First pixel hit.\n"; //} - return point.m_X >= m_CarLlX && point.m_X < m_CarUrX && point.m_Y < m_CarUrY && diff --git a/Source/Ember/DensityFilter.h b/Source/Ember/DensityFilter.h index 166241a..a22cf73 100644 --- a/Source/Ember/DensityFilter.h +++ b/Source/Ember/DensityFilter.h @@ -115,10 +115,8 @@ public: T finalMinRad = m_MinRad * m_Supersample + 1;//Should scale the filter width by the oversample. T finalMaxRad = m_MaxRad * m_Supersample + 1;//The '+1' comes from the assumed distance to the first pixel. GaussianFilter gaussianFilter(m_MaxRad, m_Supersample); - m_KernelSize = 0; m_MaxFilterIndex = 0; - //Calculate how many filter kernels are needed based on the decay function // // num filters = (de_max_width / de_min_width)^(1 / estimator_curve) @@ -146,7 +144,6 @@ public: rowSize = static_cast(2 * ceil(finalMaxRad) - 1); m_FilterWidth = (rowSize - 1) / 2; m_KernelSize = (m_FilterWidth + 1) * (2 + m_FilterWidth) / 2; - m_Coefs.resize(maxIndex * m_KernelSize); m_Widths.resize(maxIndex); @@ -261,7 +258,6 @@ public: { T finalMaxRad = m_MaxRad * m_Supersample + 1; T finalMinRad = m_MinRad * m_Supersample + 1; - return std::pow(finalMaxRad / finalMinRad, T(1.0) / m_Curve) <= 1e7; } @@ -273,30 +269,28 @@ public: { size_t i, j, coefIndex = 0, w = m_FilterWidth + 1; stringstream ss; - ss - << "Density Filter:" << endl - << " Min radius: " << MinRad() << endl - << " Max radius: " << MaxRad() << endl - << " Curve: " << Curve() << endl - << " Kernel size: " << KernelSize() << endl - << " Max filter index: " << MaxFilterIndex() << endl - << "Max Filtered counts: " << MaxFilteredCounts() << endl - << " Filter width: " << FilterWidth() << endl; - - ss << "Coefficients: " << endl; + << "Density Filter:" + << "\n Min radius: " << MinRad() + << "\n Max radius: " << MaxRad() + << "\n Curve: " << Curve() + << "\n Kernel size: " << KernelSize() + << "\n Max filter index: " << MaxFilterIndex() + << "\nMax Filtered counts: " << MaxFilteredCounts() + << "\n Filter width: " << FilterWidth(); + ss << "\nCoefficients: \n"; for (i = 0; i < m_Widths.size(); i++) { for (coefIndex = 0; coefIndex < m_KernelSize; coefIndex++) - ss << "Kernel[" << i << "].Coefs[" << coefIndex << "]: " << m_Coefs[(i * m_KernelSize) + coefIndex] << endl; + ss << "Kernel[" << i << "].Coefs[" << coefIndex << "]: " << m_Coefs[(i * m_KernelSize) + coefIndex] << "\n"; } - ss << endl << "Widths: " << endl; + ss << "\nWidths: \n"; for (i = 0; i < m_Widths.size(); i++) { - ss << "Widths[" << i << "]: " << m_Widths[i] << endl; + ss << "Widths[" << i << "]: " << m_Widths[i] << "\n"; } for (i = 0; i < w; i++) @@ -306,7 +300,7 @@ public: cout << std::setw(2) << std::setfill('0') << m_CoefIndices[i * w + j] << "\t"; } - cout << endl; + cout << "\n"; } return ss.str(); diff --git a/Source/Ember/Ember.cpp b/Source/Ember/Ember.cpp index 7161b8e..c8c2ecd 100644 --- a/Source/Ember/Ember.cpp +++ b/Source/Ember/Ember.cpp @@ -5,7 +5,7 @@ namespace EmberNs { template<> unique_ptr> QTIsaac::GlobalRand = unique_ptr>(new QTIsaac()); -template<> CriticalSection QTIsaac::m_CS = CriticalSection(); +template<> std::recursive_mutex QTIsaac::s_CS = std::recursive_mutex(); } #include "Curves.h" @@ -56,7 +56,7 @@ uint Timing::m_ProcessorCount; #define EXPORT_SINGLE_TYPE_EMBER(T) \ template<> const char* PaletteList::m_DefaultFilename = "flam3-palettes.xml"; \ - template<> map>> PaletteList::m_Palettes = map>>(); \ + template<> map>> PaletteList::s_Palettes = map>>(); \ template<> bool XmlToEmber::m_Init = false; \ template<> vector XmlToEmber::m_FlattenNames = vector(); \ template<> unordered_map XmlToEmber::m_BadParamNames = unordered_map(); \ diff --git a/Source/Ember/Ember.h b/Source/Ember/Ember.h index 6124fcc..142aca7 100644 --- a/Source/Ember/Ember.h +++ b/Source/Ember/Ember.h @@ -1034,7 +1034,7 @@ public: if (m_Xforms[i].Empty() && m_AffineInterp != eAffineInterp::AFFINE_INTERP_LOG) continue; - m_Xforms[i].m_Affine.Rotate(angle); + m_Xforms[i].m_Affine.Rotate(angle * DEG_2_RAD_T); //Don't rotate post. } } diff --git a/Source/Ember/EmberDefines.h b/Source/Ember/EmberDefines.h index 1b4d3f9..938b643 100644 --- a/Source/Ember/EmberDefines.h +++ b/Source/Ember/EmberDefines.h @@ -74,6 +74,7 @@ namespace EmberNs #define EMPTYFIELD -9999 typedef std::chrono::high_resolution_clock Clock; typedef uint et; +typedef std::lock_guard rlg; /// /// Thin wrapper around getting the current time in milliseconds. diff --git a/Source/Ember/EmberPch.h b/Source/Ember/EmberPch.h index 60ef744..83a2d30 100644 --- a/Source/Ember/EmberPch.h +++ b/Source/Ember/EmberPch.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/Source/Ember/EmberToXml.h b/Source/Ember/EmberToXml.h index 2dcc99e..763dbb9 100644 --- a/Source/Ember/EmberToXml.h +++ b/Source/Ember/EmberToXml.h @@ -116,18 +116,18 @@ public: } else { - cout << "Error: Writing flame " << filename << " failed." << endl; + cout << "Error: Writing flame " << filename << " failed.\n"; b = false; } } catch (const std::exception& e) { - cout << "Error: Writing flame " << filename << " failed: " << e.what() << endl; + cout << "Error: Writing flame " << filename << " failed: " << e.what() << "\n"; b = false; } catch (...) { - cout << "Error: Writing flame " << filename << " failed." << endl; + cout << "Error: Writing flame " << filename << " failed.\n"; b = false; } @@ -275,7 +275,7 @@ public: os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][2] * 255)); } - os << endl; + os << "\n"; } os << " \n"; @@ -472,7 +472,7 @@ public: } else { - cout << "Failed to parse comment into Xml." << endl; + cout << "Failed to parse comment into Xml.\n"; } } diff --git a/Source/Ember/Interpolate.h b/Source/Ember/Interpolate.h index cb8cfc2..6e09bee 100644 --- a/Source/Ember/Interpolate.h +++ b/Source/Ember/Interpolate.h @@ -639,7 +639,7 @@ public: } else { - cout << loc << ": xform " << xfi << " is missing when it was expected, something is severely wrong." << endl; + cout << loc << ": xform " << xfi << " is missing when it was expected, something is severely wrong.\n"; } } @@ -684,7 +684,7 @@ public: } else { - cout << loc << ": xform " << xfi << " is missing when it was expected, something is severely wrong." << endl; + cout << loc << ": xform " << xfi << " is missing when it was expected, something is severely wrong.\n"; } } } diff --git a/Source/Ember/Isaac.h b/Source/Ember/Isaac.h index 39a841e..3b6fbdf 100644 --- a/Source/Ember/Isaac.h +++ b/Source/Ember/Isaac.h @@ -32,8 +32,8 @@ /// #ifndef __ISAAC64 - typedef uint ISAAC_INT; - const ISAAC_INT GOLDEN_RATIO = ISAAC_INT(0x9e3779b9); + typedef uint ISAAC_INT; + const ISAAC_INT GOLDEN_RATIO = ISAAC_INT(0x9e3779b9); #else typedef size_t ISAAC_INT; const ISAAC_INT GOLDEN_RATIO = ISAAC_INT(0x9e3779b97f4a7c13); @@ -63,9 +63,9 @@ public: /// Global ISAAC RNG to be used from anywhere. This is not thread safe, so take caution to only /// use it when no other threads are. /// - static unique_ptr > GlobalRand; + static unique_ptr> GlobalRand; - static CriticalSection m_CS; + static std::recursive_mutex s_CS; /// /// The structure which holds all of the random information. @@ -124,9 +124,8 @@ public: /// The next random integer in the range of 0-255 static inline T LockedRandByte() { - m_CS.Enter(); + rlg l(s_CS); T t = GlobalRand->RandByte(); - m_CS.Leave(); return t; } @@ -137,9 +136,9 @@ public: inline T Rand() { #ifdef ISAAC_FLAM3_DEBUG - return (!m_Rc.randcnt-- ? (Isaac(&m_Rc), m_Rc.randcnt=N-1, m_Rc.randrsl[m_Rc.randcnt]) : m_Rc.randrsl[m_Rc.randcnt]); + return (!m_Rc.randcnt-- ? (Isaac(&m_Rc), m_Rc.randcnt = N - 1, m_Rc.randrsl[m_Rc.randcnt]) : m_Rc.randrsl[m_Rc.randcnt]); #else - return (m_Rc.randcnt++ == N ? (Isaac(&m_Rc), m_Rc.randcnt=0, m_Rc.randrsl[m_Rc.randcnt]) : m_Rc.randrsl[m_Rc.randcnt]); + return (m_Rc.randcnt++ == N ? (Isaac(&m_Rc), m_Rc.randcnt = 0, m_Rc.randrsl[m_Rc.randcnt]) : m_Rc.randrsl[m_Rc.randcnt]); #endif } @@ -149,9 +148,8 @@ public: /// The next random integer static inline T LockedRand() { - m_CS.Enter(); + rlg l(s_CS); T t = GlobalRand->Rand(); - m_CS.Leave(); return t; } @@ -172,9 +170,8 @@ public: /// A value between 0 and the value passed in minus 1 static inline T LockedRand(T upper) { - m_CS.Enter(); + rlg l(s_CS); T t = GlobalRand->Rand(upper); - m_CS.Leave(); return t; } @@ -201,9 +198,8 @@ public: template static inline floatType LockedFrand(floatType fMin, floatType fMax) { - m_CS.Enter(); + rlg l(s_CS); floatType t = GlobalRand->template Frand(fMin, fMax); - m_CS.Leave(); return t; } @@ -229,9 +225,8 @@ public: template static inline floatType LockedFrand01() { - m_CS.Enter(); + rlg l(s_CS); floatType t = GlobalRand->template Frand01(); - m_CS.Leave(); return t; } @@ -257,9 +252,8 @@ public: template static inline floatType LockedFrand11() { - m_CS.Enter(); + rlg l(s_CS); floatType t = GlobalRand->template Frand11(); - m_CS.Leave(); return t; } @@ -280,9 +274,8 @@ public: template static inline floatType LockedGoldenBit() { - m_CS.Enter(); + rlg l(s_CS); floatType t = GlobalRand->template GoldenBit(); - m_CS.Leave(); return t; } @@ -301,9 +294,8 @@ public: /// A random 0 or 1 static inline uint LockedRandBit() { - m_CS.Enter(); + rlg l(s_CS); uint t = GlobalRand->RandBit(); - m_CS.Leave(); return t; } @@ -329,7 +321,6 @@ public: T a, b, c, d, e, f, g, h; T* m = ctx->randmem; T* r = ctx->randrsl; - a = b = c = d = e = f = g = h = GOLDEN_RATIO; if (!useSeed) @@ -352,9 +343,7 @@ public: { a += r[i ]; b += r[i + 1]; c += r[i + 2]; d += r[i + 3]; e += r[i + 4]; f += r[i + 5]; g += r[i + 6]; h += r[i + 7]; - Shuffle(a, b, c, d, e, f, g, h); - m[i ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d; m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h; } @@ -364,9 +353,7 @@ public: { a += m[i ]; b += m[i + 1]; c += m[i + 2]; d += m[i + 3]; e += m[i + 4]; f += m[i + 5]; g += m[i + 6]; h += m[i + 7]; - Shuffle(a, b, c, d, e, f, g, h); - m[i ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d; m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h; } @@ -375,7 +362,6 @@ public: { //Fill in mm[] with messy stuff. Shuffle(a, b, c, d, e, f, g, h); - m[i ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d; m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h; } @@ -406,6 +392,7 @@ public: } #ifndef ISAAC_FLAM3_DEBUG + if (a == 0 && b == 0 && c == 0) { m_Rc.randa = static_cast(NowMs()); @@ -430,48 +417,45 @@ protected: /// The context to populate. void Isaac(randctx* ctx) { - T x,y; - + T x, y; T* mm = ctx->randmem; T* r = ctx->randrsl; - T a = (ctx->randa); T b = (ctx->randb + (++ctx->randc)); - T* m = mm; T* m2 = (m + (N / 2)); T* mend = m2; - for(; m < mend; ) + for (; m < mend; ) { - #ifndef __ISAAC64 +#ifndef __ISAAC64 RngStep((a << 13), a, b, mm, m, m2, r, x, y); RngStep((a >> 6) , a, b, mm, m, m2, r, x, y); RngStep((a << 2) , a, b, mm, m, m2, r, x, y); RngStep((a >> 16), a, b, mm, m, m2, r, x, y); - #else // __ISAAC64 +#else // __ISAAC64 RngStep(~(a ^ (a << 21)), a, b, mm, m, m2, r, x, y); RngStep( a ^ (a >> 5) , a, b, mm, m, m2, r, x, y); RngStep( a ^ (a << 12) , a, b, mm, m, m2, r, x, y); RngStep( a ^ (a >> 33) , a, b, mm, m, m2, r, x, y); - #endif // __ISAAC64 +#endif // __ISAAC64 } m2 = mm; - for(; m2> 6) , a, b, mm, m, m2, r, x, y); RngStep((a << 2) , a, b, mm, m, m2, r, x, y); RngStep((a >> 16), a, b, mm, m, m2, r, x, y); - #else // __ISAAC64 +#else // __ISAAC64 RngStep(~(a ^ (a << 21)), a, b, mm, m, m2, r, x, y); RngStep( a ^ (a >> 5) , a, b, mm, m, m2, r, x, y); RngStep( a ^ (a << 12) , a, b, mm, m, m2, r, x, y); RngStep( a ^ (a >> 33) , a, b, mm, m, m2, r, x, y); - #endif // __ISAAC64 +#endif // __ISAAC64 } ctx->randb = b; diff --git a/Source/Ember/PaletteList.h b/Source/Ember/PaletteList.h index a100caa..c8492c9 100644 --- a/Source/Ember/PaletteList.h +++ b/Source/Ember/PaletteList.h @@ -38,7 +38,7 @@ public: bool Add(const string& filename, bool force = false) { bool added = true; - auto palettes = m_Palettes.insert(make_pair(filename, vector>())); + auto palettes = s_Palettes.insert(make_pair(filename, vector>())); if (force || palettes.second) { @@ -53,7 +53,6 @@ public: { auto rootNode = xmlDocGetRootElement(doc); auto pfilename = shared_ptr(new string(filename)); - palettes.first->second.clear(); palettes.first->second.reserve(buf.size() / 2048);//Roughly what it takes per palette. ParsePalettes(rootNode, pfilename, palettes.first->second); @@ -62,14 +61,14 @@ public: else { added = false; - m_Palettes.erase(filename); + s_Palettes.erase(filename); AddToReport(string(loc) + " : Couldn't load xml doc"); } } else { added = false; - m_Palettes.erase(filename); + s_Palettes.erase(filename); AddToReport(string(loc) + " : Couldn't read palette file " + filename); } } @@ -82,11 +81,11 @@ public: /// Palette* GetRandomPalette() { - auto p = m_Palettes.begin(); + auto p = s_Palettes.begin(); size_t i = 0, paletteFileIndex = QTIsaac::GlobalRand->Rand() % Size(); - + //Move p forward i elements. - while (i < paletteFileIndex && p != m_Palettes.end()) + while (i < paletteFileIndex && p != s_Palettes.end()) { ++i; ++p; @@ -111,7 +110,7 @@ public: /// A pointer to the requested palette if the index was in range, else nullptr. Palette* GetPalette(const string& filename, size_t i) { - auto& palettes = m_Palettes[filename]; + auto& palettes = s_Palettes[filename]; if (!palettes.empty() && i < palettes.size()) return &palettes[i]; @@ -127,7 +126,7 @@ public: /// A pointer to the palette if found, else nullptr Palette* GetPaletteByName(const string& filename, const string& name) { - for (auto& palettes : m_Palettes) + for (auto& palettes : s_Palettes) if (palettes.first == filename) for (auto& palette : palettes.second) if (palette.m_Name == name) @@ -163,7 +162,7 @@ public: /// void Clear() { - m_Palettes.clear(); + s_Palettes.clear(); } /// @@ -171,7 +170,7 @@ public: /// This will be the number of files read. /// /// The size of the palettes map - size_t Size() { return m_Palettes.size(); } + size_t Size() { return s_Palettes.size(); } /// /// Get the size of specified palette vector in the palettes map. @@ -181,9 +180,9 @@ public: size_t Size(size_t index) { size_t i = 0; - auto p = m_Palettes.begin(); + auto p = s_Palettes.begin(); - while (i < index && p != m_Palettes.end()) + while (i < index && p != s_Palettes.end()) { ++i; ++p; @@ -199,7 +198,7 @@ public: /// The size of the palette vector at the specified index in the palettes map size_t Size(const string& s) { - return m_Palettes[s].size(); + return s_Palettes[s].size(); } /// @@ -210,9 +209,9 @@ public: const string& Name(size_t index) { size_t i = 0; - auto p = m_Palettes.begin(); + auto p = s_Palettes.begin(); - while (i < index && p != m_Palettes.end()) + while (i < index && p != s_Palettes.end()) { ++i; ++p; @@ -257,7 +256,7 @@ private: do { - int ret = sscanf_s(static_cast(&(val[colorIndex])),"00%2x%2x%2x", &r, &g, &b); + int ret = sscanf_s(static_cast(&(val[colorIndex])), "00%2x%2x%2x", &r, &g, &b); if (ret != 3) { @@ -274,9 +273,9 @@ private: palette[colorCount].r = T(r) / T(255);//Store as normalized colors in the range of 0-1. palette[colorCount].g = T(g) / T(255); palette[colorCount].b = T(b) / T(255); - colorCount++; - } while (colorCount < COLORMAP_LENGTH); + } + while (colorCount < COLORMAP_LENGTH); } else if (!Compare(attr->name, "number")) { @@ -306,6 +305,6 @@ private: } } - static map>> m_Palettes;//The map of filenames to vectors that store the palettes. + static map>> s_Palettes;//The map of filenames to vectors that store the palettes. }; } diff --git a/Source/Ember/Renderer.cpp b/Source/Ember/Renderer.cpp index 2ff5cc5..f485f31 100644 --- a/Source/Ember/Renderer.cpp +++ b/Source/Ember/Renderer.cpp @@ -139,7 +139,7 @@ void Renderer::ComputeCamera() T carUrX = m_UpperRightX + t0; T carUrY = m_UpperRightY + t1 + shift; m_RotMat.MakeID(); - m_RotMat.Rotate(-Rotate()); + m_RotMat.Rotate(-Rotate() * DEG_2_RAD_T); m_CarToRas.Init(carLlX, carLlY, carUrX, carUrY, m_SuperRasW, m_SuperRasH, PixelAspectRatio()); } @@ -215,8 +215,6 @@ bool Renderer::CreateDEFilter(bool& newAlloc) if (!m_DensityFilter.get()) { return false; }//Did object creation succeed? if (!m_DensityFilter->Create()) { return false; }//Object creation succeeded, did filter creation succeed? - - //cout << m_DensityFilter->ToString() << endl; } else if (!m_DensityFilter->Valid()) { return false; } //Previously created, are values ok? } @@ -1299,7 +1297,7 @@ EmberStats Renderer::Iterate(size_t iterCount, size_t temporalSample //iterationTime += t.Toc(); if (m_LockAccum) - m_AccumCs.Enter(); + m_AccumCs.lock(); //t.Tic(); //Map temp buffer samples into the histogram using the palette for color. @@ -1307,7 +1305,7 @@ EmberStats Renderer::Iterate(size_t iterCount, size_t temporalSample //accumulationTime += t.Toc(); if (m_LockAccum) - m_AccumCs.Leave(); + m_AccumCs.unlock(); if (m_Callback && threadIndex == 0) { diff --git a/Source/Ember/RendererBase.cpp b/Source/Ember/RendererBase.cpp index 0db051a..30265e8 100644 --- a/Source/Ember/RendererBase.cpp +++ b/Source/Ember/RendererBase.cpp @@ -263,12 +263,12 @@ size_t RendererBase::MemoryAvailable() } else { - cout << "Warning: unable to determine physical memory." << endl; + cout << "Warning: unable to determine physical memory.\n"; memAvailable = 4e9; } #else - cout << "Warning: unable to determine physical memory." << endl; + cout << "Warning: unable to determine physical memory.\n"; memAvailable = 4e9; #endif return memAvailable; @@ -610,14 +610,14 @@ void RendererBase::Reset() m_ProcessAction = eProcessAction::FULL_RENDER; } -void RendererBase::EnterRender() { m_RenderingCs.Enter(); } -void RendererBase::LeaveRender() { m_RenderingCs.Leave(); } +void RendererBase::EnterRender() { m_RenderingCs.lock(); } +void RendererBase::LeaveRender() { m_RenderingCs.unlock(); } -void RendererBase::EnterFinalAccum() { m_FinalAccumCs.Enter(); m_InFinalAccum = true; } -void RendererBase::LeaveFinalAccum() { m_FinalAccumCs.Leave(); m_InFinalAccum = false; } +void RendererBase::EnterFinalAccum() { m_FinalAccumCs.lock(); m_InFinalAccum = true; } +void RendererBase::LeaveFinalAccum() { m_FinalAccumCs.unlock(); m_InFinalAccum = false; } -void RendererBase::EnterResize() { m_ResizeCs.Enter(); } -void RendererBase::LeaveResize() { m_ResizeCs.Leave(); } +void RendererBase::EnterResize() { m_ResizeCs.lock(); } +void RendererBase::LeaveResize() { m_ResizeCs.unlock(); } void RendererBase::Abort() { m_Abort = true; } bool RendererBase::Aborted() { return m_Abort; } diff --git a/Source/Ember/RendererBase.h b/Source/Ember/RendererBase.h index 055d125..fbdcabc 100644 --- a/Source/Ember/RendererBase.h +++ b/Source/Ember/RendererBase.h @@ -228,7 +228,7 @@ protected: vector m_BadVals; vector> m_Rand; auto_ptr m_TaskGroup; - CriticalSection m_RenderingCs, m_AccumCs, m_FinalAccumCs, m_ResizeCs; + std::recursive_mutex m_RenderingCs, m_AccumCs, m_FinalAccumCs, m_ResizeCs; Timing m_RenderTimer, m_IterTimer, m_ProgressTimer; }; } diff --git a/Source/Ember/SheepTools.h b/Source/Ember/SheepTools.h index a2903e7..121ff17 100644 --- a/Source/Ember/SheepTools.h +++ b/Source/Ember/SheepTools.h @@ -804,7 +804,7 @@ public: if (best < 0) { - cout << "Error in TryColors(), skipping ImproveColors()" << endl; + cout << "Error in TryColors(), skipping ImproveColors()\n"; return; } @@ -815,7 +815,7 @@ public: if (b < 0) { - cout << "Error in TryColors, aborting tries." << endl; + cout << "Error in TryColors, aborting tries.\n"; break; } @@ -861,7 +861,7 @@ public: if (m_Renderer->Run(m_FinalImage) != eRenderStatus::RENDER_OK) { - cout << "Error rendering test image for TryColors(). Aborting." << endl; + cout << "Error rendering test image for TryColors(). Aborting.\n"; return -1; } @@ -902,7 +902,7 @@ public: else { ember.m_Palette.Clear(false); - cout << "Error retrieving random palette, setting to all white" << endl; + cout << "Error retrieving random palette, setting to all white.\n"; } } diff --git a/Source/Ember/SpatialFilter.h b/Source/Ember/SpatialFilter.h index 92537ec..4419acc 100644 --- a/Source/Ember/SpatialFilter.h +++ b/Source/Ember/SpatialFilter.h @@ -159,18 +159,18 @@ public: size_t i; stringstream ss; ss - << "Spatial Filter:" << endl - << " Support: " << m_Support << endl - << " Filter radius: " << m_FilterRadius << endl - << " Supersample: " << m_Supersample << endl - << "Pixel aspect ratio: " << m_PixelAspectRatio << endl - << "Final filter width: " << m_FinalFilterWidth << endl - << "Filter buffer size: " << m_Filter.size() << endl; - ss << "Filter: " << endl; + << "Spatial Filter:" + << "\n Support: " << m_Support + << "\n Filter radius: " << m_FilterRadius + << "\n Supersample: " << m_Supersample + << "\nPixel aspect ratio: " << m_PixelAspectRatio + << "\nFinal filter width: " << m_FinalFilterWidth + << "\nFilter buffer size: " << m_Filter.size(); + ss << "\nFilter: \n"; for (i = 0; i < m_Filter.size(); i++) { - ss << "Filter[" << i << "]: " << m_Filter[i] << endl; + ss << "Filter[" << i << "]: " << m_Filter[i] << "\n"; } return ss.str(); diff --git a/Source/Ember/TemporalFilter.h b/Source/Ember/TemporalFilter.h index b0030b5..9582754 100644 --- a/Source/Ember/TemporalFilter.h +++ b/Source/Ember/TemporalFilter.h @@ -115,22 +115,22 @@ public: { size_t i; stringstream ss; - ss << "Temporal Filter:" << endl - << " Size: " << Size() << endl - << " Type: " << TemporalFilterCreator::ToString(m_FilterType) << endl - << " Sum Filt: " << SumFilt() << endl; - ss << "Deltas: " << endl; + ss << "Temporal Filter:\n" + << "\n Size: " << Size() + << "\n Type: " << TemporalFilterCreator::ToString(m_FilterType) + << "\n Sum Filt: " << SumFilt(); + ss << "\nDeltas: \n"; for (i = 0; i < m_Deltas.size(); i++) { - ss << "Deltas[" << i << "]: " << m_Deltas[i] << endl; + ss << "Deltas[" << i << "]: " << m_Deltas[i] << "\n"; } - ss << "Filter: " << endl; + ss << "Filter: \n"; for (i = 0; i < m_Filter.size(); i++) { - ss << "Filter[" << i << "]: " << m_Filter[i] << endl; + ss << "Filter[" << i << "]: " << m_Filter[i] << "\n"; } return ss.str(); diff --git a/Source/Ember/Timing.h b/Source/Ember/Timing.h index f5c1c07..2d6330a 100644 --- a/Source/Ember/Timing.h +++ b/Source/Ember/Timing.h @@ -52,7 +52,7 @@ public: if (str) { - cout << string(str) << (fullString ? "" : " processing time: ") << Format(ms) << endl; + cout << string(str) << (fullString ? "" : " processing time: ") << Format(ms) << "\n"; } return ms; @@ -77,7 +77,6 @@ public: double ElapsedTime() const { duration elapsed = duration_cast(m_EndTime - m_BeginTime); - return elapsed.count() * 1000.0; } @@ -92,7 +91,6 @@ public: string Format(double ms) const { stringstream ss; - double x = ms / 1000; double secs = fmod(x, 60); x /= 60; @@ -146,78 +144,4 @@ private: static bool m_TimingInit;//Whether the performance info has bee queried. static uint m_ProcessorCount;//The number of cores on the system, set in Init(). }; - -/// -/// Cross platform critical section class which can be used for thread locking. -/// -class EMBER_API CriticalSection -{ -public: - -#ifdef _WIN32 - /// - /// Constructor which initialized the underlying CRITICAL_SECTION object. - /// - CriticalSection() { InitializeCriticalSection(&m_CriticalSection); } - - /// - /// Constructor which initialized the underlying CRITICAL_SECTION object - /// with the specified spin count value. - /// - /// The spin count. - CriticalSection(DWORD spinCount) { InitializeCriticalSectionAndSpinCount(&m_CriticalSection, spinCount); } - - /// - /// Deletes the underlying CRITICAL_SECTION object. - /// - ~CriticalSection() { DeleteCriticalSection(&m_CriticalSection); } - - /// - /// Lock the critical section. - /// - void Enter() { EnterCriticalSection(&m_CriticalSection); } - - /// - /// Unlock the critical section. - /// - void Leave() { LeaveCriticalSection(&m_CriticalSection); } - -private: - CRITICAL_SECTION m_CriticalSection;//The Windows specific critical section object. - -#else - - /// - /// Constructor which initialized the underlying pthread_mutex_t object. - /// - CriticalSection() - { - pthread_mutexattr_t attr; - - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); - pthread_mutex_init(&m_CriticalSection, &attr); - pthread_mutexattr_destroy(&attr); - } - - /// - /// Deletes the underlying pthread_mutex_t object. - /// - ~CriticalSection() { pthread_mutex_destroy(&m_CriticalSection); } - - /// - /// Lock the critical section. - /// - void Enter() { pthread_mutex_lock(&m_CriticalSection); } - - /// - /// Unlock the critical section. - /// - void Leave() { pthread_mutex_unlock(&m_CriticalSection); } - -private: - pthread_mutex_t m_CriticalSection;//The *nix/pthread specific critical section object. - -#endif -}; } diff --git a/Source/Ember/Utils.h b/Source/Ember/Utils.h index 02d8b0e..4635c3a 100644 --- a/Source/Ember/Utils.h +++ b/Source/Ember/Utils.h @@ -169,7 +169,7 @@ public: { stringstream ss; - for (auto& s : errorReport) ss << s << endl; + for (auto& s : errorReport) ss << s << "\n"; return ss.str(); } @@ -288,12 +288,12 @@ static bool ReadFile(const char* filename, string& buf, bool nullTerminate = tru } catch (const std::exception& e) { - cout << "Error: Reading file " << filename << " failed: " << e.what() << endl; + cout << "Error: Reading file " << filename << " failed: " << e.what() << "\n"; b = false; } catch (...) { - cout << "Error: Reading file " << filename << " failed." << endl; + cout << "Error: Reading file " << filename << " failed.\n"; b = false; } diff --git a/Source/Ember/VarFuncs.h b/Source/Ember/VarFuncs.h index a607bb4..c2cdfa4 100644 --- a/Source/Ember/VarFuncs.h +++ b/Source/Ember/VarFuncs.h @@ -288,7 +288,7 @@ public: //released under CC share-alike license. //Less accurate for faster rendering (still very precise). T const CA = T(0.0003);//The accuracy is the square of CA. - T a, b, c, d, em[13], en[13]; + T a, b, c, d = 1, em[13], en[13]; int bo; int l; int ii; diff --git a/Source/Ember/Variation.h b/Source/Ember/Variation.h index 7cbb5a7..2edcfe5 100644 --- a/Source/Ember/Variation.h +++ b/Source/Ember/Variation.h @@ -2023,9 +2023,9 @@ public: virtual string ToString() const override { ostringstream ss; - ss << Variation::ToString() << endl; + ss << Variation::ToString() << "\n"; - for (auto& param : m_Params) ss << param.ToString() << endl; + for (auto& param : m_Params) ss << param.ToString() << "\n"; return ss.str(); } diff --git a/Source/Ember/Variations01.h b/Source/Ember/Variations01.h index 0d8cf58..90deb0c 100644 --- a/Source/Ember/Variations01.h +++ b/Source/Ember/Variations01.h @@ -1971,7 +1971,7 @@ public: virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { int sl = int(rand.Frand01() * m_Slices + T(0.5)); - T a = m_Rotation + M_2PI * (sl + rand.Frand01() * m_Thickness) / m_Slices; + T a = m_Rotation + m_Pi2Slices * (sl + m_Thickness * rand.Frand01()); T r = m_Weight * rand.Frand01(); helper.Out.x = r * std::cos(a); helper.Out.y = r * std::sin(a); @@ -1987,9 +1987,10 @@ public: string slices = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rotation = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string thickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index; + string pi2Slices = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" << "\t\tint sl = (int)(MwcNext01(mwc) * " << slices << " + (real_t)(0.5));\n" - << "\t\treal_t a = " << rotation << " + M_2PI * (sl + MwcNext01(mwc) * " << thickness << ") / " << slices << ";\n" + << "\t\treal_t a = " << rotation << " + " << pi2Slices << " * (sl + " << thickness << " * MwcNext01(mwc));\n" << "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * MwcNext01(mwc);\n" << "\n" << "\t\tvOut.x = r * cos(a);\n" @@ -1999,6 +2000,11 @@ public: return ss.str(); } + virtual void Precalc() override + { + m_Pi2Slices = M_2PI / m_Slices; + } + virtual void Random(QTIsaac& rand) override { m_Params[0].Set(10 * rand.Frand01());//Slices. @@ -2014,12 +2020,14 @@ protected: m_Params.push_back(ParamWithName(&m_Slices, prefix + "pie_slices", 6, eParamType::INTEGER_NONZERO, 1)); m_Params.push_back(ParamWithName(&m_Rotation, prefix + "pie_rotation", T(0.5), eParamType::REAL_CYCLIC, 0, M_2PI)); m_Params.push_back(ParamWithName(&m_Thickness, prefix + "pie_thickness", T(0.5), eParamType::REAL, 0, 1)); + m_Params.push_back(ParamWithName(true, &m_Pi2Slices, prefix + "pie_pi2_slices")); } private: T m_Slices; T m_Rotation; T m_Thickness; + T m_Pi2Slices;//Precalc }; /// diff --git a/Source/Ember/Variations02.h b/Source/Ember/Variations02.h index cf33d3f..66990a9 100644 --- a/Source/Ember/Variations02.h +++ b/Source/Ember/Variations02.h @@ -88,15 +88,13 @@ public: << "\t\t{\n" << "\t\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * t * cos(theta);\n" << "\t\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * t * sin(theta);\n" - << "\t\t\tvOut.z = 0;\n" << "\t\t}\n" << "\t\telse\n" << "\t\t{\n" << "\t\t\tvOut.x = 0;\n" << "\t\t\tvOut.y = 0;\n" - << "\t\t\tvOut.z = 0;\n" << "\t\t}\n" - << "\t\tvOut.Z = " << DefaultZCl() + << "\t\tvOut.z = " << DefaultZCl() << "\t}\n"; return ss.str(); } @@ -2726,8 +2724,8 @@ public: virtual void Precalc() override { - T pa = 2 * T(M_PI) / m_P; - T qa = 2 * T(M_PI) / m_Q; + T pa = 2 * T(M_PI) / Zeps(m_P); + T qa = 2 * T(M_PI) / Zeps(m_Q); T r = (1 - std::cos(pa)) / (std::cos(pa) + std::cos(qa)) + 1; T a = m_N * pa; @@ -2822,15 +2820,15 @@ public: virtual void Precalc() override { - T r2 = 1 - (std::cos(2 * T(M_PI) / m_P) - 1) / - (std::cos(2 * T(M_PI) / m_P) + std::cos(2 * T(M_PI) / m_Q)); + T r2 = 1 - (std::cos(2 * T(M_PI) / Zeps(m_P)) - 1) / + (std::cos(2 * T(M_PI) / Zeps(m_P)) + std::cos(2 * T(M_PI) / Zeps(m_Q))); if (r2 > 0) m_R = 1 / std::sqrt(r2); else m_R = 1; - m_Pa = 2 * T(M_PI) / m_P; + m_Pa = 2 * T(M_PI) / Zeps(m_P); } protected: @@ -2841,7 +2839,7 @@ protected: m_Params.push_back(ParamWithName(&m_P, prefix + "hypertile1_p", 3, eParamType::INTEGER, 3, T(0x7fffffff))); m_Params.push_back(ParamWithName(&m_Q, prefix + "hypertile1_q", 7, eParamType::INTEGER, 3, T(0x7fffffff))); m_Params.push_back(ParamWithName(true, &m_Pa, prefix + "hypertile1_pa"));//Precalc. - m_Params.push_back(ParamWithName(true, &m_R, prefix + "hypertile1_r")); + m_Params.push_back(ParamWithName(true, &m_R, prefix + "hypertile1_r")); } private: @@ -2913,15 +2911,15 @@ public: virtual void Precalc() override { - T r2 = 1 - (std::cos(2 * T(M_PI) / m_P) - 1) / - (std::cos(2 * T(M_PI) / m_P) + std::cos(2 * T(M_PI) / m_Q)); + T r2 = 1 - (std::cos(2 * T(M_PI) / Zeps(m_P)) - 1) / + (std::cos(2 * T(M_PI) / Zeps(m_P)) + std::cos(2 * T(M_PI) / Zeps(m_Q))); if (r2 > 0) m_R = 1 / std::sqrt(r2); else m_R = 1; - m_Pa = 2 * T(M_PI) / m_P; + m_Pa = 2 * T(M_PI) / Zeps(m_P); } protected: @@ -3001,13 +2999,13 @@ public: virtual void Precalc() override { - T pa = 2 * T(M_PI) / m_P; - T qa = 2 * T(M_PI) / m_Q; - T r = -(std::cos(pa) - 1) / (std::cos(pa) + std::cos(qa)); + T pa = 2 * T(M_PI) / Zeps(m_P); + T qa = 2 * T(M_PI) / Zeps(m_Q); + T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa)); T na = m_N * pa; if (r > 0) - r = 1 / std::sqrt(1 + r); + r = 1 / Zeps(std::sqrt(1 + r)); else r = 1; @@ -3119,12 +3117,12 @@ public: virtual void Precalc() override { - T pa = M_2PI / m_P; - T qa = M_2PI / m_Q; - T r = -(std::cos(pa) - 1) / (std::cos(pa) + std::cos(qa)); + T pa = M_2PI / Zeps(m_P); + T qa = M_2PI / Zeps(m_Q); + T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa)); if (r > 0) - r = 1 / std::sqrt(1 + r); + r = 1 / Zeps(std::sqrt(1 + r)); else r = 1; @@ -3219,12 +3217,12 @@ public: virtual void Precalc() override { - T pa = M_2PI / m_P; - T qa = M_2PI / m_Q; - T r = -(std::cos(pa) - 1) / (std::cos(pa) + std::cos(qa)); + T pa = M_2PI / Zeps(m_P); + T qa = M_2PI / Zeps(m_Q); + T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa)); if (r > 0) - r = 1 / std::sqrt(1 + r); + r = 1 / Zeps(std::sqrt(1 + r)); else r = 1; diff --git a/Source/Ember/Variations05.h b/Source/Ember/Variations05.h index 5041573..64a825d 100644 --- a/Source/Ember/Variations05.h +++ b/Source/Ember/Variations05.h @@ -3466,7 +3466,7 @@ public: int loc; T tempx, tempy; T lrmaj = m_Weight;//Sets hexagon length radius - major plane. - T boost;//Boost is the separation distance between the two planes. + T boost = 1;//Boost is the separation distance between the two planes. T sumX, sumY; if (m_VarType == eVariationType::VARTYPE_REG) @@ -3561,7 +3561,7 @@ public: << "\t\tint loc;\n" << "\t\treal_t tempx, tempy;\n" << "\t\treal_t lrmaj = xform->m_VariationWeights[" << varIndex << "];\n" - << "\t\treal_t boost;\n" + << "\t\treal_t boost = 1;\n" << "\t\treal_t sumX, sumY;\n\n"; if (m_VarType == eVariationType::VARTYPE_REG) diff --git a/Source/Ember/Variations06.h b/Source/Ember/Variations06.h index 1fec36c..712be46 100644 --- a/Source/Ember/Variations06.h +++ b/Source/Ember/Variations06.h @@ -1495,7 +1495,7 @@ public: /// The rand. virtual void Func(IteratorHelper& helper, Point& outPoint, QTIsaac& rand) override { - T gradTmp, secTmp, xTmp, yTmp; + T gradTmp, secTmp, xTmp = 0, yTmp = 0; if ((helper.In.x < m_LeftBorder) || (helper.In.x > m_RightBorder) || (helper.In.y < m_TopBorder) || (helper.In.y > m_BottomBorder)) { @@ -1591,7 +1591,7 @@ public: string leftBorder = "parVars[" + ToUpper(m_Params[i++].Name()) + index; string rightBorder = "parVars[" + ToUpper(m_Params[i++].Name()) + index; ss << "\t{\n" - << "\t\treal_t gradTmp, secTmp, xTmp, yTmp;\n" + << "\t\treal_t gradTmp, secTmp, xTmp = 0, yTmp = 0;\n" << "\n" << "\t\tif ((vIn.x < " << leftBorder << ") || (vIn.x > " << rightBorder << ") || (vIn.y < " << topBorder << ") || (vIn.y > " << bottomBorder << "))\n" << "\t\t{\n" @@ -3626,8 +3626,6 @@ private: case LERP_BEZIER: return BezierQuadMap(x, m); } - - return x * m; } inline void SynthSinCos(SynthStruct& synth, T theta, T& s, T& c, int sineType) diff --git a/Source/Ember/Variations07.h b/Source/Ember/Variations07.h index f5bcdfa..796b2f0 100644 --- a/Source/Ember/Variations07.h +++ b/Source/Ember/Variations07.h @@ -573,7 +573,7 @@ public: { int posNeg = 1; T th = 0; - T sth, cth, pang, wig, wag, wag2, wag3, wag12, waggle; + T sth, cth, pang, wig, wag, wag2, wag3, wag12 = 0, waggle = 0; T rad = helper.m_PrecalcSqrtSumSquares; T curve1 = rad / m_L; T curve2 = Sqr(curve1); diff --git a/Source/Ember/Xform.h b/Source/Ember/Xform.h index 21ee809..31a7505 100644 --- a/Source/Ember/Xform.h +++ b/Source/Ember/Xform.h @@ -1113,7 +1113,7 @@ public: << "C: " << m_Affine.C() << " " << "D: " << m_Affine.D() << " " << "E: " << m_Affine.E() << " " - << "F: " << m_Affine.F() << " " << endl; + << "F: " << m_Affine.F() << " \n"; if (m_HasPost) { @@ -1122,27 +1122,27 @@ public: << "Post C: " << m_Post.C() << " " << "Post D: " << m_Post.D() << " " << "Post E: " << m_Post.E() << " " - << "Post F: " << m_Post.F() << " " << endl; + << "Post F: " << m_Post.F() << " \n"; } - ss << "Weight: " << m_Weight << endl; - ss << "ColorX: " << m_ColorX << endl; - ss << "ColorY: " << m_ColorY << endl; - ss << "Direct Color: " << m_DirectColor << endl; - ss << "Color Speed: " << m_ColorSpeed << endl; - ss << "Animate: " << m_Animate << endl; - ss << "Opacity: " << m_Opacity << endl; - ss << "Viz Adjusted: " << m_VizAdjusted << endl; - ss << "Wind: " << m_Wind[0] << ", " << m_Wind[1] << endl; - ss << "Motion Frequency: " << m_MotionFreq << endl; - ss << "Motion Func: " << m_MotionFunc << endl; - ss << "Motion Offset: " << m_MotionOffset << endl; + ss << "Weight: " << m_Weight; + ss << "\nColorX: " << m_ColorX; + ss << "\nColorY: " << m_ColorY; + ss << "\nDirect Color: " << m_DirectColor; + ss << "\nColor Speed: " << m_ColorSpeed; + ss << "\nAnimate: " << m_Animate; + ss << "\nOpacity: " << m_Opacity; + ss << "\nViz Adjusted: " << m_VizAdjusted; + ss << "\nWind: " << m_Wind[0] << ", " << m_Wind[1]; + ss << "\nMotion Frequency: " << m_MotionFreq; + ss << "\nMotion Func: " << m_MotionFunc; + ss << "\nMotion Offset: " << m_MotionOffset; const_cast*>(this)->AllVarsFunc([&] (vector*>& variations, bool & keepGoing) { for (auto var : variations) - ss << var->ToString() << endl; + ss << var->ToString() << "\n"; - ss << endl; + ss << "\n"; }); if (XaosPresent()) @@ -1150,7 +1150,7 @@ public: for (auto xaos : m_Xaos) ss << xaos << " "; - ss << endl; + ss << "\n"; } return ss.str(); diff --git a/Source/Ember/XmlToEmber.h b/Source/Ember/XmlToEmber.h index e2e91d1..f4d81bf 100644 --- a/Source/Ember/XmlToEmber.h +++ b/Source/Ember/XmlToEmber.h @@ -35,10 +35,10 @@ public: m_OriginalLocale = setlocale(category, nullptr);//Query. if (m_OriginalLocale.empty()) - cout << "Couldn't get original locale." << endl; + cout << "Couldn't get original locale.\n"; if (setlocale(category, loc) == nullptr)//Set. - cout << "Couldn't set new locale " << category << ", " << loc << "." << endl; + cout << "Couldn't set new locale " << category << ", " << loc << ".\n"; } /// @@ -48,7 +48,7 @@ public: { if (!m_OriginalLocale.empty()) if (setlocale(m_Category, m_OriginalLocale.c_str()) == nullptr)//Restore. - cout << "Couldn't restore original locale " << m_Category << ", " << m_OriginalLocale << "." << endl; + cout << "Couldn't restore original locale " << m_Category << ", " << m_OriginalLocale << ".\n"; } private: @@ -327,13 +327,13 @@ public: { if (embers[0].m_Interp == eInterp::EMBER_INTERP_SMOOTH) { - cout << "Warning: smooth interpolation cannot be used for first segment.\n switching to linear.\n" << endl; + cout << "Warning: smooth interpolation cannot be used for first segment.\n switching to linear.\n"; embers[0].m_Interp = eInterp::EMBER_INTERP_LINEAR; } if (emberSize >= 2 && embers[emberSize - 2].m_Interp == eInterp::EMBER_INTERP_SMOOTH) { - cout << "Warning: smooth interpolation cannot be used for last segment.\n switching to linear.\n" << endl; + cout << "Warning: smooth interpolation cannot be used for last segment.\n switching to linear.\n"; embers[emberSize - 2].m_Interp = eInterp::EMBER_INTERP_LINEAR; } } @@ -526,7 +526,7 @@ private: char* attStr; const char* loc = __FUNCTION__; int soloXform = -1; - size_t i, count, index = 0; + size_t i, count = 0, index = 0; double vals[16]; xmlAttrPtr att, curAtt; xmlNodePtr editNode, childNode, motionNode; diff --git a/Source/EmberAnimate/EmberAnimate.cpp b/Source/EmberAnimate/EmberAnimate.cpp index d244f1a..e76787c 100644 --- a/Source/EmberAnimate/EmberAnimate.cpp +++ b/Source/EmberAnimate/EmberAnimate.cpp @@ -15,11 +15,11 @@ bool EmberAnimate(EmberOptions& opt) std::cout.imbue(std::locale("")); if (opt.DumpArgs()) - cout << opt.GetValues(eOptionUse::OPT_USE_ANIMATE) << endl; + cout << opt.GetValues(eOptionUse::OPT_USE_ANIMATE) << "\n"; if (opt.OpenCLInfo()) { - cout << "\nOpenCL Info: " << endl; + cout << "\nOpenCL Info: \n"; cout << info->DumpInfo(); return true; } @@ -41,7 +41,7 @@ bool EmberAnimate(EmberOptions& opt) unique_ptr> progress; vector>> renderers; vector errorReport; - CriticalSection verboseCs; + std::recursive_mutex verboseCs; if (opt.EmberCL()) { @@ -53,7 +53,7 @@ bool EmberAnimate(EmberOptions& opt) if (!renderers.size() || renderers.size() != devices.size()) { - cout << "Only created " << renderers.size() << " renderers out of " << devices.size() << " requested, exiting." << endl; + cout << "Only created " << renderers.size() << " renderers out of " << devices.size() << " requested, exiting.\n"; return false; } @@ -63,19 +63,19 @@ bool EmberAnimate(EmberOptions& opt) renderers[0]->Callback(progress.get()); } - cout << "Using OpenCL to render." << endl; + cout << "Using OpenCL to render.\n"; if (opt.Verbose()) { for (auto& device : devices) { - cout << "Platform: " << info->PlatformName(device.first) << endl; - cout << "Device: " << info->DeviceName(device.first, device.second) << endl; + cout << "Platform: " << info->PlatformName(device.first) << "\n"; + cout << "Device: " << info->DeviceName(device.first, device.second) << "\n"; } } if (opt.ThreadCount() > 1) - cout << "Cannot specify threads with OpenCL, using 1 thread." << endl; + cout << "Cannot specify threads with OpenCL, using 1 thread.\n"; opt.ThreadCount(1); @@ -84,7 +84,7 @@ bool EmberAnimate(EmberOptions& opt) if (opt.BitsPerChannel() != 8) { - cout << "Bits per channel cannot be anything other than 8 with OpenCL, setting to 8." << endl; + cout << "Bits per channel cannot be anything other than 8 with OpenCL, setting to 8.\n"; opt.BitsPerChannel(8); } } @@ -98,7 +98,7 @@ bool EmberAnimate(EmberOptions& opt) if (!tempRenderer.get()) { - cout << "Renderer creation failed, exiting." << endl; + cout << "Renderer creation failed, exiting.\n"; return false; } @@ -110,12 +110,12 @@ bool EmberAnimate(EmberOptions& opt) if (opt.ThreadCount() == 0) { - cout << "Using " << Timing::ProcessorCount() << " automatically detected threads." << endl; + cout << "Using " << Timing::ProcessorCount() << " automatically detected threads.\n"; opt.ThreadCount(Timing::ProcessorCount()); } else { - cout << "Using " << opt.ThreadCount() << " manually specified threads." << endl; + cout << "Using " << opt.ThreadCount() << " manually specified threads.\n"; } tempRenderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr); @@ -125,7 +125,7 @@ bool EmberAnimate(EmberOptions& opt) if (!InitPaletteList(opt.PalettePath())) return false; - cout << "Parsing ember file " << opt.Input() << endl; + cout << "Parsing ember file " << opt.Input() << "\n"; if (!ParseEmberFile(parser, opt.Input(), embers)) return false; @@ -134,7 +134,7 @@ bool EmberAnimate(EmberOptions& opt) if (embers.size() <= 1) { - cout << "Read " << embers.size() << " embers from file. At least 2 required to animate, exiting." << endl; + cout << "Read " << embers.size() << " embers from file. At least 2 required to animate, exiting.\n"; return false; } @@ -143,37 +143,37 @@ bool EmberAnimate(EmberOptions& opt) opt.Format() != "ppm" && opt.Format() != "bmp") { - cout << "Format must be jpg, png, ppm, or bmp not " << opt.Format() << ". Setting to jpg." << endl; + cout << "Format must be jpg, png, ppm, or bmp not " << opt.Format() << ". Setting to jpg.\n"; } channels = opt.Format() == "png" ? 4 : 3; if (opt.BitsPerChannel() == 16 && opt.Format() != "png") { - cout << "Support for 16 bits per channel images is only present for the png format. Setting to 8." << endl; + cout << "Support for 16 bits per channel images is only present for the png format. Setting to 8.\n"; opt.BitsPerChannel(8); } else if (opt.BitsPerChannel() != 8 && opt.BitsPerChannel() != 16) { - cout << "Unexpected bits per channel specified " << opt.BitsPerChannel() << ". Setting to 8." << endl; + cout << "Unexpected bits per channel specified " << opt.BitsPerChannel() << ". Setting to 8.\n"; opt.BitsPerChannel(8); } if (opt.InsertPalette() && opt.BitsPerChannel() != 8) { - cout << "Inserting palette only supported with 8 bits per channel, insertion will not take place." << endl; + cout << "Inserting palette only supported with 8 bits per channel, insertion will not take place.\n"; opt.InsertPalette(false); } if (opt.AspectRatio() < 0) { - cout << "Invalid pixel aspect ratio " << opt.AspectRatio() << endl << ". Must be positive, setting to 1." << endl; + cout << "Invalid pixel aspect ratio " << opt.AspectRatio() << "\n. Must be positive, setting to 1.\n"; opt.AspectRatio(1); } if (opt.Dtime() < 1) { - cout << "Warning: dtime must be positive, not " << opt.Dtime() << ". Setting to 1." << endl; + cout << "Warning: dtime must be positive, not " << opt.Dtime() << ". Setting to 1.\n"; opt.Dtime(1); } @@ -181,13 +181,13 @@ bool EmberAnimate(EmberOptions& opt) { if (opt.Time()) { - cout << "Cannot specify both time and frame." << endl; + cout << "Cannot specify both time and frame.\n"; return false; } if (opt.FirstFrame() || opt.LastFrame()) { - cout << "Cannot specify both frame and begin or end." << endl; + cout << "Cannot specify both frame and begin or end.\n"; return false; } @@ -199,7 +199,7 @@ bool EmberAnimate(EmberOptions& opt) { if (opt.FirstFrame() || opt.LastFrame()) { - cout << "Cannot specify both time and begin or end." << endl; + cout << "Cannot specify both time and begin or end.\n"; return false; } @@ -225,7 +225,7 @@ bool EmberAnimate(EmberOptions& opt) if (i > 0 && embers[i].m_Time == embers[i - 1].m_Time) { - cout << "Image " << i << " time of " << embers[i].m_Time << " equaled previous image time of " << embers[i - 1].m_Time << ". Adjusting up by 1." << endl; + cout << "Image " << i << " time of " << embers[i].m_Time << " equaled previous image time of " << embers[i - 1].m_Time << ". Adjusting up by 1.\n"; embers[i].m_Time++; } @@ -255,14 +255,14 @@ bool EmberAnimate(EmberOptions& opt) if (imageMem > maxMem)//Ensure the max amount of memory for a process isn't exceeded. { - cout << "Image " << i << " size > " << maxMem << ". Setting to 1920 x 1080." << endl; + cout << "Image " << i << " size > " << maxMem << ". Setting to 1920 x 1080.\n"; embers[i].m_FinalRasW = 1920; embers[i].m_FinalRasH = 1080; } if (embers[i].m_FinalRasW == 0 || embers[i].m_FinalRasH == 0) { - cout << "Warning: Output image " << i << " has dimension 0: " << embers[i].m_FinalRasW << ", " << embers[i].m_FinalRasH << ". Setting to 1920 x 1080." << endl; + cout << "Warning: Output image " << i << " has dimension 0: " << embers[i].m_FinalRasW << ", " << embers[i].m_FinalRasH << ". Setting to 1920 x 1080.\n"; embers[i].m_FinalRasW = 1920; embers[i].m_FinalRasH = 1080; } @@ -271,7 +271,7 @@ bool EmberAnimate(EmberOptions& opt) (embers[i].m_FinalRasH != embers[0].m_FinalRasH)) { cout << "Warning: flame " << i << " at time " << embers[i].m_Time << " size mismatch. (" << embers[i].m_FinalRasW << ", " << embers[i].m_FinalRasH << - ") should be (" << embers[0].m_FinalRasW << ", " << embers[0].m_FinalRasH << "). Setting to " << embers[0].m_FinalRasW << ", " << embers[0].m_FinalRasH << "." << endl; + ") should be (" << embers[0].m_FinalRasW << ", " << embers[0].m_FinalRasH << "). Setting to " << embers[0].m_FinalRasW << ", " << embers[0].m_FinalRasH << ".\n"; embers[i].m_FinalRasW = embers[0].m_FinalRasW; embers[i].m_FinalRasH = embers[0].m_FinalRasH; } @@ -279,7 +279,7 @@ bool EmberAnimate(EmberOptions& opt) if (unsorted) { - cout << "Embers were unsorted by time. First out of order index was " << firstUnsortedIndex << ". Sorting." << endl; + cout << "Embers were unsorted by time. First out of order index was " << firstUnsortedIndex << ". Sorting.\n"; std::sort(embers.begin(), embers.end(), &CompareEmbers); } @@ -295,7 +295,7 @@ bool EmberAnimate(EmberOptions& opt) if (!opt.Out().empty()) { - cout << "Single output file " << opt.Out() << " specified for multiple images. They would be all overwritten and only the last image will remain, exiting." << endl; + cout << "Single output file " << opt.Out() << " specified for multiple images. They would be all overwritten and only the last image will remain, exiting.\n"; return false; } @@ -339,7 +339,7 @@ bool EmberAnimate(EmberOptions& opt) writeSuccess = WriteBmp(filename.c_str(), finalImagep, w, h); if (!writeSuccess) - cout << "Error writing " << filename << endl; + cout << "Error writing " << filename << "\n"; }; atomfTime.store(opt.FirstFrame()); std::function iterFunc = [&](size_t index) @@ -361,16 +361,15 @@ bool EmberAnimate(EmberOptions& opt) if (opt.Verbose() && ((opt.LastFrame() - opt.FirstFrame()) / opt.Dtime() >= 1)) { - verboseCs.Enter(); - cout << "Time = " << ftime << " / " << opt.LastFrame() << " / " << opt.Dtime() << endl; - verboseCs.Leave(); + rlg l(verboseCs); + cout << "Time = " << ftime << " / " << opt.LastFrame() << " / " << opt.Dtime() << "\n"; } renderer->Reset(); if ((renderer->Run(finalImages[finalImageIndex], localTime) != eRenderStatus::RENDER_OK) || renderer->Aborted() || finalImages[finalImageIndex].empty()) { - cout << "Error: image rendering failed, skipping to next image." << endl; + cout << "Error: image rendering failed, skipping to next image.\n"; renderer->DumpErrorReport();//Something went wrong, print errors. atomfTime.store(opt.LastFrame() + 1);//Abort all threads if any of them encounter an error. break; @@ -386,9 +385,8 @@ bool EmberAnimate(EmberOptions& opt) if (opt.Verbose()) { - verboseCs.Enter(); - cout << "Writing " << flameName << endl; - verboseCs.Leave(); + rlg l(verboseCs); + cout << "Writing " << flameName << "\n"; } Interpolater::Interpolate(embers, localTime, 0, centerEmber);//Get center flame. @@ -404,16 +402,15 @@ bool EmberAnimate(EmberOptions& opt) if (opt.Verbose()) { - verboseCs.Enter(); - cout << "\nIters ran/requested: " + os.str() << endl; + rlg l(verboseCs); + cout << "\nIters ran/requested: " + os.str() << "\n"; - if (!opt.EmberCL()) cout << "Bad values: " << stats.m_Badvals << endl; + if (!opt.EmberCL()) cout << "Bad values: " << stats.m_Badvals << "\n"; - cout << "Render time: " << t.Format(stats.m_RenderMs) << endl; - cout << "Pure iter time: " << t.Format(stats.m_IterMs) << endl; - cout << "Iters/sec: " << size_t(stats.m_Iters / (stats.m_IterMs / 1000.0)) << endl; - cout << "Writing " << filename << endl << endl; - verboseCs.Leave(); + cout << "Render time: " << t.Format(stats.m_RenderMs) << "\n"; + cout << "Pure iter time: " << t.Format(stats.m_IterMs) << "\n"; + cout << "Iters/sec: " << size_t(stats.m_Iters / (stats.m_IterMs / 1000.0)) << "\n"; + cout << "Writing " << filename << "\n\n"; } //Run image writing in a thread. Although doing it this way duplicates the final output memory, it saves a lot of time @@ -487,7 +484,7 @@ int _tmain(int argc, _TCHAR* argv[]) } else if (opt.Bits() == 32) { - cout << "Bits 32/int histogram no longer supported. Using bits == 33 (float)." << endl; + cout << "Bits 32/int histogram no longer supported. Using bits == 33 (float).\n"; b = EmberAnimate(opt); } } diff --git a/Source/EmberCL/FunctionMapper.cpp b/Source/EmberCL/FunctionMapper.cpp index 5c5fc17..40e35f3 100644 --- a/Source/EmberCL/FunctionMapper.cpp +++ b/Source/EmberCL/FunctionMapper.cpp @@ -3,39 +3,39 @@ namespace EmberCLns { -std::unordered_map FunctionMapper::m_GlobalMap; +std::unordered_map FunctionMapper::s_GlobalMap; FunctionMapper::FunctionMapper() { - if (m_GlobalMap.empty()) + if (s_GlobalMap.empty()) { - m_GlobalMap["LRint"] = + s_GlobalMap["LRint"] = "inline real_t LRint(real_t x)\n" "{\n" " intPrec temp = (x >= 0.0 ? (intPrec)(x + 0.5) : (intPrec)(x - 0.5));\n" " return (real_t)temp;\n" "}\n"; - m_GlobalMap["Round"] = + s_GlobalMap["Round"] = "inline real_t Round(real_t r)\n" "{\n" " return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);\n" "}\n"; - m_GlobalMap["Sign"] = + s_GlobalMap["Sign"] = "inline real_t Sign(real_t v)\n" "{\n" " return (v < 0.0) ? -1 : (v > 0.0) ? 1 : 0.0;\n" "}\n"; - m_GlobalMap["SignNz"] = + s_GlobalMap["SignNz"] = "inline real_t SignNz(real_t v)\n" "{\n" " return (v < 0.0) ? -1.0 : 1.0;\n" "}\n"; - m_GlobalMap["Sqr"] = + s_GlobalMap["Sqr"] = "inline real_t Sqr(real_t v)\n" "{\n" " return v * v;\n" "}\n"; - m_GlobalMap["SafeSqrt"] = + s_GlobalMap["SafeSqrt"] = "inline real_t SafeSqrt(real_t x)\n" "{\n" " if (x <= 0.0)\n" @@ -43,7 +43,7 @@ FunctionMapper::FunctionMapper() "\n" " return sqrt(x);\n" "}\n"; - m_GlobalMap["SafeDivInv"] = + s_GlobalMap["SafeDivInv"] = "inline real_t SafeDivInv(real_t q, real_t r)\n" "{\n" " if (r < EPS)\n" @@ -51,81 +51,81 @@ FunctionMapper::FunctionMapper() "\n" " return q / r;\n" "}\n"; - m_GlobalMap["Cube"] = + s_GlobalMap["Cube"] = "inline real_t Cube(real_t v)\n" "{\n" " return v * v * v;\n" "}\n"; - m_GlobalMap["Hypot"] = + s_GlobalMap["Hypot"] = "inline real_t Hypot(real_t x, real_t y)\n" "{\n" " return sqrt(SQR(x) + SQR(y));\n" "}\n"; - m_GlobalMap["Spread"] = + s_GlobalMap["Spread"] = "inline real_t Spread(real_t x, real_t y)\n" "{\n" " return Hypot(x, y) * ((x) > 0.0 ? 1.0 : -1.0);\n" "}\n"; - m_GlobalMap["Powq4"] = + s_GlobalMap["Powq4"] = "inline real_t Powq4(real_t x, real_t y)\n" "{\n" " return pow(fabs(x), y) * SignNz(x);\n" "}\n"; - m_GlobalMap["Powq4c"] = + s_GlobalMap["Powq4c"] = "inline real_t Powq4c(real_t x, real_t y)\n" "{\n" " return y == 1.0 ? x : Powq4(x, y);\n" "}\n"; - m_GlobalMap["Zeps"] = + s_GlobalMap["Zeps"] = "inline real_t Zeps(real_t x)\n" "{\n" " return x == 0.0 ? EPS : x;\n" "}\n"; - m_GlobalMap["Lerp"] = + s_GlobalMap["Lerp"] = "inline real_t Lerp(real_t a, real_t b, real_t p)\n" "{\n" " return a + (b - a) * p;\n" "}\n"; - m_GlobalMap["Fabsmod"] = + s_GlobalMap["Fabsmod"] = "inline real_t Fabsmod(real_t v)\n" "{\n" " real_t dummy;\n" "\n" " return modf(v, &dummy);\n" "}\n"; - m_GlobalMap["Fosc"] = + s_GlobalMap["Fosc"] = "inline real_t Fosc(real_t p, real_t amp, real_t ph)\n" "{\n" " return 0.5 - cos(p * amp + ph) * 0.5;\n" "}\n"; - m_GlobalMap["Foscn"] = + s_GlobalMap["Foscn"] = "inline real_t Foscn(real_t p, real_t ph)\n" "{\n" " return 0.5 - cos(p + ph) * 0.5;\n" "}\n"; - m_GlobalMap["LogScale"] = + s_GlobalMap["LogScale"] = "inline real_t LogScale(real_t x)\n" "{\n" " return x == 0.0 ? 0.0 : log((fabs(x) + 1) * M_E) * SignNz(x) / M_E;\n" "}\n"; - m_GlobalMap["LogMap"] = + s_GlobalMap["LogMap"] = "inline real_t LogMap(real_t x)\n" "{\n" " return x == 0.0 ? 0.0 : (M_E + log(x * M_E)) * 0.25 * SignNz(x);\n" "}\n"; - m_GlobalMap["ClampGte"] = + s_GlobalMap["ClampGte"] = "inline real_t ClampGte(real_t val, real_t gte)\n" "{\n" " return (val < gte) ? gte : val;\n" "}\n"; - m_GlobalMap["Swap"] = + s_GlobalMap["Swap"] = "inline void Swap(real_t* val1, real_t* val2)\n" "{\n" " real_t tmp = *val1;\n" " *val1 = *val2;\n" " *val2 = tmp;\n" "}\n"; - m_GlobalMap["Vratio"] = + s_GlobalMap["Vratio"] = "inline real_t Vratio(real2* p, real2* q, real2* u)\n" "{\n" " real2 pmq = *p - *q;\n" @@ -135,7 +135,7 @@ FunctionMapper::FunctionMapper() "\n" " return 2 * (((*u).x - (*q).x) * pmq.x + ((*u).y - (*q).y) * pmq.y) / Zeps(SQR(pmq.x) + SQR(pmq.y));\n" "}\n"; - m_GlobalMap["Closest"] = + s_GlobalMap["Closest"] = "inline int Closest(real2* p, int n, real2* u)\n" "{\n" " real_t d2;\n" @@ -155,7 +155,7 @@ FunctionMapper::FunctionMapper() "\n" " return j;\n" "}\n"; - m_GlobalMap["Voronoi"] = + s_GlobalMap["Voronoi"] = "inline real_t Voronoi(real2* p, int n, int q, real2* u)\n" "{\n" " real_t ratio;\n" @@ -175,7 +175,7 @@ FunctionMapper::FunctionMapper() "\n" " return ratiomax;\n" "}\n"; - m_GlobalMap["SimplexNoise3D"] = + s_GlobalMap["SimplexNoise3D"] = "inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real3* grad)\n" "{\n" " real3 c[4];\n" @@ -263,7 +263,7 @@ FunctionMapper::FunctionMapper() "\n" " return 32 * n;\n" "}\n"; - m_GlobalMap["PerlinNoise3D"] = + 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" "{\n" " int i;\n" @@ -281,11 +281,11 @@ FunctionMapper::FunctionMapper() "\n" " return n;\n" "}\n"; - m_GlobalMap["JacobiElliptic"] = + s_GlobalMap["JacobiElliptic"] = "inline void JacobiElliptic(real_t uu, real_t emmc, real_t* sn, real_t* cn, real_t* dn)\n" "{\n" " real_t CA = 0.0003;\n" - " real_t a, b, c, d, em[13], en[13];\n" + " real_t a, b, c, d = 1, em[13], en[13];\n" " int bo;\n" " int l;\n" " int ii;\n" @@ -371,11 +371,16 @@ FunctionMapper::FunctionMapper() } } +/// +/// Get a pointer to the text of the global function whose name is the passed in string. +/// +/// The function name to retrieve +/// A pointer to the function body string if found, else nullptr. const string* FunctionMapper::GetGlobalFunc(const string& func) { - const auto& text = m_GlobalMap.find(func); + const auto& text = s_GlobalMap.find(func); - if (text != m_GlobalMap.end()) + if (text != s_GlobalMap.end()) return &text->second; else return nullptr; diff --git a/Source/EmberCL/FunctionMapper.h b/Source/EmberCL/FunctionMapper.h index 8e3828a..487d40e 100644 --- a/Source/EmberCL/FunctionMapper.h +++ b/Source/EmberCL/FunctionMapper.h @@ -16,6 +16,6 @@ public: static const string* GetGlobalFunc(const string& func); private: - static std::unordered_map m_GlobalMap; + static std::unordered_map s_GlobalMap; }; } \ No newline at end of file diff --git a/Source/EmberCL/IterOpenCLKernelCreator.cpp b/Source/EmberCL/IterOpenCLKernelCreator.cpp index 084896d..317d61d 100644 --- a/Source/EmberCL/IterOpenCLKernelCreator.cpp +++ b/Source/EmberCL/IterOpenCLKernelCreator.cpp @@ -575,7 +575,7 @@ string IterOpenCLKernelCreator::GlobalFunctionsString(const Ember& ember) for (auto& funcName : funcNames) if (auto text = m_FunctionMapper.GetGlobalFunc(funcName)) - os << *text << endl; + os << *text << "\n"; return os.str(); } @@ -643,7 +643,7 @@ void IterOpenCLKernelCreator::ParVarIndexDefines(const Ember& ember, pair< if (!parVar->Params()[k].IsState()) { if (doString) - os << "#define " << ToUpper(parVar->Params()[k].Name()) << "_" << i << " " << size << endl;//Uniquely identify this param in this variation in this xform. + os << "#define " << ToUpper(parVar->Params()[k].Name()) << "_" << i << " " << size << "\n";//Uniquely identify this param in this variation in this xform. auto elements = parVar->Params()[k].Size() / sizeof(T); @@ -710,7 +710,7 @@ void IterOpenCLKernelCreator::SharedDataIndexDefines(const Ember& ember, p if (auto dataInfo = varFuncs->GetSharedData(s))///Will contain a name, pointer to data, and size of the data in units of sizeof(T). { if (doString) - os << "#define " << ToUpper(name) << " " << offset << endl; + os << "#define " << ToUpper(name) << " " << offset << "\n"; if (doVals) params.second.insert(params.second.end(), dataInfo->first, dataInfo->first + dataInfo->second); diff --git a/Source/EmberCL/IterOpenCLKernelCreator.h b/Source/EmberCL/IterOpenCLKernelCreator.h index c1c8618..f67ecdf 100644 --- a/Source/EmberCL/IterOpenCLKernelCreator.h +++ b/Source/EmberCL/IterOpenCLKernelCreator.h @@ -57,12 +57,12 @@ typedef void (*KernelFuncPointer) (size_t gridWidth, size_t gridHeight, size_t b static void OpenCLSim(size_t gridWidth, size_t gridHeight, size_t blockWidth, size_t blockHeight, KernelFuncPointer func) { - cout << "OpenCLSim(): " << endl; - cout << " Params: " << endl; - cout << " gridW: " << gridWidth << endl; - cout << " gridH: " << gridHeight << endl; - cout << " blockW: " << blockWidth << endl; - cout << " blockH: " << blockHeight << endl; + cout << "OpenCLSim(): "; + cout << "\n Params: "; + cout << "\n gridW: " << gridWidth; + cout << "\n gridH: " << gridHeight; + cout << "\n blockW: " << blockWidth; + cout << "\n blockH: " << blockHeight; for (size_t i = 0; i < gridHeight; i += blockHeight) { diff --git a/Source/EmberCL/OpenCLInfo.cpp b/Source/EmberCL/OpenCLInfo.cpp index 8e774a3..43cbf9d 100644 --- a/Source/EmberCL/OpenCLInfo.cpp +++ b/Source/EmberCL/OpenCLInfo.cpp @@ -264,35 +264,35 @@ string OpenCLInfo::DumpInfo() const for (size_t platform = 0; platform < m_Platforms.size(); platform++) { - os << "Platform " << platform << ": " << PlatformName(platform) << endl; + os << "Platform " << platform << ": " << PlatformName(platform) << "\n"; for (size_t device = 0; device < m_Devices[platform].size(); device++) { - os << "Device " << device << ": " << DeviceName(platform, device) << endl; - os << "CL_DEVICE_OPENCL_C_VERSION: " << GetInfo(platform, device, CL_DEVICE_OPENCL_C_VERSION) << endl; - os << "CL_DEVICE_LOCAL_MEM_SIZE: " << GetInfo(platform, device, CL_DEVICE_LOCAL_MEM_SIZE) << endl; - os << "CL_DEVICE_LOCAL_MEM_TYPE: " << GetInfo(platform, device, CL_DEVICE_LOCAL_MEM_TYPE) << endl; - os << "CL_DEVICE_MAX_COMPUTE_UNITS: " << GetInfo(platform, device, CL_DEVICE_MAX_COMPUTE_UNITS) << endl; - os << "CL_DEVICE_MAX_READ_IMAGE_ARGS: " << GetInfo(platform, device, CL_DEVICE_MAX_READ_IMAGE_ARGS) << endl; - os << "CL_DEVICE_MAX_WRITE_IMAGE_ARGS: " << GetInfo(platform, device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS) << endl; - os << "CL_DEVICE_MAX_MEM_ALLOC_SIZE: " << GetInfo(platform, device, CL_DEVICE_MAX_MEM_ALLOC_SIZE) << endl; - os << "CL_DEVICE_ADDRESS_BITS: " << GetInfo(platform, device, CL_DEVICE_ADDRESS_BITS) << endl; - os << "CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: " << GetInfo(platform, device, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE) << endl; - os << "CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: " << GetInfo(platform, device, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE) << endl; - os << "CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: " << GetInfo(platform, device, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE) << endl; - os << "CL_DEVICE_GLOBAL_MEM_SIZE: " << GetInfo(platform, device, CL_DEVICE_GLOBAL_MEM_SIZE) << endl; - os << "CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: " << GetInfo(platform, device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE) << endl; - os << "CL_DEVICE_MAX_CONSTANT_ARGS: " << GetInfo(platform, device, CL_DEVICE_MAX_CONSTANT_ARGS) << endl; - os << "CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: " << GetInfo(platform, device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS) << endl; - os << "CL_DEVICE_MAX_WORK_GROUP_SIZE: " << GetInfo(platform, device, CL_DEVICE_MAX_WORK_GROUP_SIZE) << endl; + os << "Device " << device << ": " << DeviceName(platform, device); + os << "\nCL_DEVICE_OPENCL_C_VERSION: " << GetInfo(platform, device, CL_DEVICE_OPENCL_C_VERSION); + os << "\nCL_DEVICE_LOCAL_MEM_SIZE: " << GetInfo(platform, device, CL_DEVICE_LOCAL_MEM_SIZE); + os << "\nCL_DEVICE_LOCAL_MEM_TYPE: " << GetInfo(platform, device, CL_DEVICE_LOCAL_MEM_TYPE); + os << "\nCL_DEVICE_MAX_COMPUTE_UNITS: " << GetInfo(platform, device, CL_DEVICE_MAX_COMPUTE_UNITS); + os << "\nCL_DEVICE_MAX_READ_IMAGE_ARGS: " << GetInfo(platform, device, CL_DEVICE_MAX_READ_IMAGE_ARGS); + os << "\nCL_DEVICE_MAX_WRITE_IMAGE_ARGS: " << GetInfo(platform, device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS); + os << "\nCL_DEVICE_MAX_MEM_ALLOC_SIZE: " << GetInfo(platform, device, CL_DEVICE_MAX_MEM_ALLOC_SIZE); + os << "\nCL_DEVICE_ADDRESS_BITS: " << GetInfo(platform, device, CL_DEVICE_ADDRESS_BITS); + os << "\nCL_DEVICE_GLOBAL_MEM_CACHE_TYPE: " << GetInfo(platform, device, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE); + os << "\nCL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: " << GetInfo(platform, device, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE); + os << "\nCL_DEVICE_GLOBAL_MEM_CACHE_SIZE: " << GetInfo(platform, device, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE); + os << "\nCL_DEVICE_GLOBAL_MEM_SIZE: " << GetInfo(platform, device, CL_DEVICE_GLOBAL_MEM_SIZE); + os << "\nCL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: " << GetInfo(platform, device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE); + os << "\nCL_DEVICE_MAX_CONSTANT_ARGS: " << GetInfo(platform, device, CL_DEVICE_MAX_CONSTANT_ARGS); + os << "\nCL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: " << GetInfo(platform, device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS); + os << "\nCL_DEVICE_MAX_WORK_GROUP_SIZE: " << GetInfo(platform, device, CL_DEVICE_MAX_WORK_GROUP_SIZE); sizes = GetInfo>(platform, device, CL_DEVICE_MAX_WORK_ITEM_SIZES); - os << "CL_DEVICE_MAX_WORK_ITEM_SIZES: " << sizes[0] << ", " << sizes[1] << ", " << sizes[2] << endl << endl; + os << "\nCL_DEVICE_MAX_WORK_ITEM_SIZES: " << sizes[0] << ", " << sizes[1] << ", " << sizes[2] << "\n" << "\n"; if (device != m_Devices[platform].size() - 1 && platform != m_Platforms.size() - 1) - os << endl; + os << "\n"; } - os << endl; + os << "\n"; } return os.str(); @@ -309,7 +309,7 @@ bool OpenCLInfo::CheckCL(cl_int err, const char* name) if (err != CL_SUCCESS) { ostringstream ss; - ss << "ERROR: " << ErrorToStringCL(err) << " in " << name << "." << endl; + ss << "ERROR: " << ErrorToStringCL(err) << " in " << name << ".\n"; AddToReport(ss.str()); } diff --git a/Source/EmberCL/OpenCLWrapper.cpp b/Source/EmberCL/OpenCLWrapper.cpp index 05e8cd9..c16701c 100644 --- a/Source/EmberCL/OpenCLWrapper.cpp +++ b/Source/EmberCL/OpenCLWrapper.cpp @@ -332,7 +332,7 @@ bool OpenCLWrapper::AddAndWriteImage(const string& name, cl_mem_flags flags, con if (shared) { //::wglMakeCurrent(wglGetCurrentDC(), wglGetCurrentContext()); - IMAGEGL2D imageGL(m_Context, flags, GL_TEXTURE_2D, 0, texName, &err); + cl::ImageGL imageGL(m_Context, flags, GL_TEXTURE_2D, 0, texName, &err); NamedImage2DGL namedImageGL(imageGL, name); if (m_Info->CheckCL(err, "cl::ImageGL()")) @@ -360,11 +360,11 @@ bool OpenCLWrapper::AddAndWriteImage(const string& name, cl_mem_flags flags, con { if (shared) { - IMAGEGL2D imageGL = m_GLImages[imageIndex].m_Image; + cl::ImageGL imageGL = m_GLImages[imageIndex].m_Image; if (!CompareImageParams(imageGL, flags, format, width, height, row_pitch)) { - NamedImage2DGL namedImageGL(IMAGEGL2D(m_Context, flags, GL_TEXTURE_2D, 0, texName, &err), name);//Sizes are different, so create new. + NamedImage2DGL namedImageGL(cl::ImageGL(m_Context, flags, GL_TEXTURE_2D, 0, texName, &err), name);//Sizes are different, so create new. if (m_Info->CheckCL(err, "cl::ImageGL()")) { @@ -430,7 +430,7 @@ bool OpenCLWrapper::WriteImage2D(size_t index, bool shared, ::size_t width, ::si if (shared && index < m_GLImages.size()) { - IMAGEGL2D imageGL = m_GLImages[index].m_Image; + cl::ImageGL imageGL = m_GLImages[index].m_Image; if (EnqueueAcquireGLObjects(imageGL)) { @@ -502,7 +502,7 @@ bool OpenCLWrapper::ReadImage(size_t imageIndex, ::size_t width, ::size_t height if (shared && imageIndex < m_GLImages.size()) { - IMAGEGL2D imageGL = m_GLImages[imageIndex].m_Image; + cl::ImageGL imageGL = m_GLImages[imageIndex].m_Image; if (EnqueueAcquireGLObjects(imageGL)) { @@ -573,7 +573,7 @@ size_t OpenCLWrapper::GetImageSize(size_t imageIndex, bool shared) { vector images; images.push_back(m_GLImages[imageIndex].m_Image); - IMAGEGL2D image = m_GLImages[imageIndex].m_Image; + cl::ImageGL image = m_GLImages[imageIndex].m_Image; if (EnqueueAcquireGLObjects(&images)) size = image.getImageInfo(nullptr) * image.getImageInfo(nullptr) * image.getImageInfo(nullptr);//Should pitch be checked here? @@ -662,17 +662,17 @@ bool OpenCLWrapper::CreateImage2D(cl::Image2D& image2D, cl_mem_flags flags, cl:: /// The mip map level /// The texture ID of the shared OpenGL texture /// True if success, else false. -bool OpenCLWrapper::CreateImage2DGL(IMAGEGL2D& image2DGL, cl_mem_flags flags, GLenum target, GLint miplevel, GLuint texobj) +bool OpenCLWrapper::CreateImage2DGL(cl::ImageGL& image2DGL, cl_mem_flags flags, GLenum target, GLint miplevel, GLuint texobj) { if (m_Init) { cl_int err; - image2DGL = IMAGEGL2D(m_Context, - flags, - target, - miplevel, - texobj, - &err); + image2DGL = cl::ImageGL(m_Context, + flags, + target, + miplevel, + texobj, + &err); return m_Info->CheckCL(err, "cl::ImageGL()"); } @@ -699,7 +699,7 @@ bool OpenCLWrapper::EnqueueAcquireGLObjects(const string& name) /// /// The image to acquire /// True if success, else false. -bool OpenCLWrapper::EnqueueAcquireGLObjects(IMAGEGL2D& image) +bool OpenCLWrapper::EnqueueAcquireGLObjects(cl::ImageGL& image) { if (m_Init && m_Shared) { @@ -733,7 +733,7 @@ bool OpenCLWrapper::EnqueueReleaseGLObjects(const string& name) /// /// The image to release /// True if success, else false. -bool OpenCLWrapper::EnqueueReleaseGLObjects(IMAGEGL2D& image) +bool OpenCLWrapper::EnqueueReleaseGLObjects(cl::ImageGL& image) { if (m_Init && m_Shared) { diff --git a/Source/EmberCL/OpenCLWrapper.h b/Source/EmberCL/OpenCLWrapper.h index f1a4101..6360e53 100644 --- a/Source/EmberCL/OpenCLWrapper.h +++ b/Source/EmberCL/OpenCLWrapper.h @@ -9,8 +9,6 @@ namespace EmberCLns { -#define IMAGEGL2D cl::ImageGL - /// /// Class to contain all of the things needed to store an OpenCL program. /// The name of it, the source, the compiled program object and the kernel. @@ -75,13 +73,13 @@ public: { } - NamedImage2DGL(const IMAGEGL2D& image, const string& name) + NamedImage2DGL(const cl::ImageGL& image, const string& name) { m_Image = image; m_Name = name; } - IMAGEGL2D m_Image; + cl::ImageGL m_Image; string m_Name; }; @@ -129,11 +127,11 @@ public: bool CompareImageParams(cl::Image& image, cl_mem_flags flags, const cl::ImageFormat& format, ::size_t width, ::size_t height, ::size_t row_pitch); void ClearImages(bool shared); bool CreateImage2D(cl::Image2D& image2D, cl_mem_flags flags, cl::ImageFormat format, ::size_t width, ::size_t height, ::size_t row_pitch = 0, void* data = NULL); - bool CreateImage2DGL(IMAGEGL2D& image2DGL, cl_mem_flags flags, GLenum target, GLint miplevel, GLuint texobj); + bool CreateImage2DGL(cl::ImageGL& image2DGL, cl_mem_flags flags, GLenum target, GLint miplevel, GLuint texobj); bool EnqueueAcquireGLObjects(const string& name); - bool EnqueueAcquireGLObjects(IMAGEGL2D& image); + bool EnqueueAcquireGLObjects(cl::ImageGL& image); bool EnqueueReleaseGLObjects(const string& name); - bool EnqueueReleaseGLObjects(IMAGEGL2D& image); + bool EnqueueReleaseGLObjects(cl::ImageGL& image); bool EnqueueAcquireGLObjects(const VECTOR_CLASS* memObjects = NULL); bool EnqueueReleaseGLObjects(const VECTOR_CLASS* memObjects = NULL); bool CreateSampler(cl::Sampler& sampler, cl_bool normalizedCoords, cl_addressing_mode addressingMode, cl_filter_mode filterMode); diff --git a/Source/EmberCL/RendererCL.cpp b/Source/EmberCL/RendererCL.cpp index 03030e8..ffb4b89 100644 --- a/Source/EmberCL/RendererCL.cpp +++ b/Source/EmberCL/RendererCL.cpp @@ -895,25 +895,23 @@ bool RendererCL::BuildIterProgramForEmber(bool doAccum) if (b) { m_IterKernel = m_IterOpenCLKernelCreator.CreateIterKernelString(m_Ember, m_Params.first, m_GlobalShared.first, m_LockAccum, doAccum); - //cout << "Building: " << endl << iterProgram << endl; + //cout << "Building: " << "\n" << iterProgram << "\n"; vector threads; std::function func = [&](RendererClDevice * dev) { if (!dev->m_Wrapper.AddProgram(m_IterOpenCLKernelCreator.IterEntryPoint(), m_IterKernel, m_IterOpenCLKernelCreator.IterEntryPoint(), m_DoublePrecision)) { - m_ResizeCs.Enter();//Just use the resize CS for lack of a better one. + rlg l(m_ResizeCs);//Just use the resize CS for lack of a better one. b = false; AddToReport(string(loc) + "()\n" + dev->m_Wrapper.DeviceName() + ":\nBuilding the following program failed: \n" + m_IterKernel + "\n"); - m_ResizeCs.Leave(); } else if (!m_GlobalShared.second.empty()) { if (!dev->m_Wrapper.AddAndWriteBuffer(m_GlobalSharedBufferName, m_GlobalShared.second.data(), m_GlobalShared.second.size() * sizeof(m_GlobalShared.second[0]))) { - m_ResizeCs.Enter();//Just use the resize CS for lack of a better one. + rlg l(m_ResizeCs);//Just use the resize CS for lack of a better one. b = false; AddToReport(string(loc) + "()\n" + dev->m_Wrapper.DeviceName() + ":\nAdding global shared buffer failed.\n"); - m_ResizeCs.Leave(); } } }; @@ -934,7 +932,7 @@ bool RendererCL::BuildIterProgramForEmber(bool doAccum) if (b) { //t.Toc(__FUNCTION__ " program build"); - //cout << string(loc) << "():\nBuilding the following program succeeded: \n" << iterProgram << endl; + //cout << string(loc) << "():\nBuilding the following program succeeded: \n" << iterProgram << "\n"; m_LastBuiltEmber = m_Ember; } } @@ -988,7 +986,7 @@ bool RendererCL::RunIter(size_t iterCount, size_t temporalSample, si { bool b = true; auto& wrapper = m_Devices[dev]->m_Wrapper; - intmax_t itersRemaining; + intmax_t itersRemaining = 0; while (atomLaunchesRan.fetch_add(1), (b && (atomLaunchesRan.load() <= launches) && ((itersRemaining = atomItersRemaining.load()) > 0) && !m_Abort)) { @@ -1002,7 +1000,7 @@ bool RendererCL::RunIter(size_t iterCount, size_t temporalSample, si //The number of iters per thread must be adjusted if they've requested less iters than is normally ran in a grid (256 * 256 * 64 * 2 = 32,768). uint iterCountPerKernel = std::min(uint(adjustedIterCountPerKernel), uint(ceil(double(itersRemaining) / IterGridKernelCount()))); size_t iterCountThisLaunch = iterCountPerKernel * IterGridKernelWidth() * IterGridKernelHeight(); - //cout << "itersRemaining " << itersRemaining << ", iterCountPerKernel " << iterCountPerKernel << ", iterCountThisLaunch " << iterCountThisLaunch << endl; + //cout << "itersRemaining " << itersRemaining << ", iterCountPerKernel " << iterCountPerKernel << ", iterCountThisLaunch " << iterCountThisLaunch << "\n"; if (b && !(b = wrapper.SetArg (kernelIndex, argIndex++, iterCountPerKernel))) { AddToReport(loc); }//Number of iters for each thread to run. diff --git a/Source/EmberCL/RendererCL.h b/Source/EmberCL/RendererCL.h index e8461d0..6f674a7 100644 --- a/Source/EmberCL/RendererCL.h +++ b/Source/EmberCL/RendererCL.h @@ -222,7 +222,7 @@ private: cl::ImageFormat m_PaletteFormat; cl::ImageFormat m_FinalFormat; cl::Image2D m_Palette; - IMAGEGL2D m_AccumImage; + cl::ImageGL m_AccumImage; GLuint m_OutputTexID; EmberCL m_EmberCL; vector> m_XformsCL; diff --git a/Source/EmberCommon/EmberOptions.h b/Source/EmberCommon/EmberOptions.h index ff650a1..2adaedd 100644 --- a/Source/EmberCommon/EmberOptions.h +++ b/Source/EmberCommon/EmberOptions.h @@ -439,7 +439,7 @@ public: case eOptionIDs::OPT_VERSION: { - cout << EmberVersion() << endl; + cout << EmberVersion() << "\n"; return true; } @@ -540,8 +540,8 @@ public: } else { - cout << "Invalid argument: " << args.OptionText() << endl; - cout << "\tReason: " << GetLastErrorText(errorCode) << endl; + cout << "Invalid argument: " << args.OptionText() << "\n"; + cout << "\tReason: " << GetLastErrorText(errorCode) << "\n"; } } @@ -608,15 +608,15 @@ public: { ostringstream os; - for (auto entry : m_BoolArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << endl; + for (auto entry : m_BoolArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << "\n"; - for (auto entry : m_IntArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << endl; + for (auto entry : m_IntArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << "\n"; - for (auto entry : m_UintArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << endl; + for (auto entry : m_UintArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << "\n"; - for (auto entry : m_DoubleArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << endl; + for (auto entry : m_DoubleArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << "\n"; - for (auto entry : m_StringArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << endl; + for (auto entry : m_StringArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_DocString << "\n"; return os.str(); } @@ -631,15 +631,15 @@ public: ostringstream os; os << std::boolalpha; - for (auto entry : m_BoolArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; + for (auto entry : m_BoolArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << "\n"; - for (auto entry : m_IntArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; + for (auto entry : m_IntArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << "\n"; - for (auto entry : m_UintArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; + for (auto entry : m_UintArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << "\n"; - for (auto entry : m_DoubleArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; + for (auto entry : m_DoubleArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << "\n"; - for (auto entry : m_StringArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << endl; + for (auto entry : m_StringArgs) if (et(entry->m_OptionUse) & et(optUsage)) os << entry->m_NameWithoutDashes << ": " << (*entry)() << "\n"; return os.str(); } @@ -650,25 +650,25 @@ public: /// The specified program usage void ShowUsage(eOptionUse optUsage) { - cout << DescriptionString << " version " << EmberVersion() << endl << endl; + cout << DescriptionString << " version " << EmberVersion() << "\n\n"; if (optUsage == eOptionUse::OPT_USE_RENDER) { cout << "Usage:\n" - "\tEmberRender.exe --in=test.flam3 [--out=outfile --format=png --verbose --progress --opencl]\n" << endl; + "\tEmberRender.exe --in=test.flam3 [--out=outfile --format=png --verbose --progress --opencl]\n\n"; } else if (optUsage == eOptionUse::OPT_USE_ANIMATE) { cout << "Usage:\n" - "\tEmberAnimate.exe --in=sequence.flam3 [--format=png --verbose --progress --opencl]\n" << endl; + "\tEmberAnimate.exe --in=sequence.flam3 [--format=png --verbose --progress --opencl]\n\n"; } else if (optUsage == eOptionUse::OPT_USE_GENOME) { cout << "Usage:\n" - "\tEmberGenome.exe --sequence=test.flam3 > sequenceout.flam3\n" << endl; + "\tEmberGenome.exe --sequence=test.flam3 > sequenceout.flam3\n\n"; } - cout << GetUsage(optUsage) << endl; + cout << GetUsage(optUsage) << "\n"; } /// diff --git a/Source/EmberGenome/EmberGenome.cpp b/Source/EmberGenome/EmberGenome.cpp index b52a819..7b3b866 100644 --- a/Source/EmberGenome/EmberGenome.cpp +++ b/Source/EmberGenome/EmberGenome.cpp @@ -55,11 +55,11 @@ bool EmberGenome(EmberOptions& opt) std::cout.imbue(std::locale("")); if (opt.DumpArgs()) - cerr << opt.GetValues(eOptionUse::OPT_USE_GENOME) << endl; + cerr << opt.GetValues(eOptionUse::OPT_USE_GENOME) << "\n"; if (opt.OpenCLInfo()) { - cerr << "\nOpenCL Info: " << endl; + cerr << "\nOpenCL Info: \n"; cerr << info->DumpInfo(); return true; } @@ -98,7 +98,7 @@ bool EmberGenome(EmberOptions& opt) if (!renderer.get()) { - cerr << "Renderer creation failed, exiting." << endl; + cerr << "Renderer creation failed, exiting.\n"; return false; } @@ -112,14 +112,14 @@ bool EmberGenome(EmberOptions& opt) } else { - cerr << "Using OpenCL to render." << endl; + cerr << "Using OpenCL to render.\n"; if (opt.Verbose()) { for (auto& device : devices) { - cerr << "Platform: " << info->PlatformName(device.first) << endl; - cerr << "Device: " << info->DeviceName(device.first, device.second) << endl; + cerr << "Platform: " << info->PlatformName(device.first) << "\n"; + cerr << "Device: " << info->DeviceName(device.first, device.second) << "\n"; } } } @@ -139,7 +139,7 @@ bool EmberGenome(EmberOptions& opt) if (opt.UseVars() != "" && opt.DontUseVars() != "") { - cerr << "use_vars and dont_use_vars cannot both be specified. Returning without executing." << endl; + cerr << "use_vars and dont_use_vars cannot both be specified. Returning without executing.\n"; return false; } @@ -231,19 +231,19 @@ bool EmberGenome(EmberOptions& opt) if (count > 1) { - cerr << "Can only specify one of mutate, clone, cross, rotate, strip, or inter. Returning without executing." << endl; + cerr << "Can only specify one of mutate, clone, cross, rotate, strip, or inter. Returning without executing.\n"; return false; } if (doCross0 != doCross1)//Must both be either true or false. { - cerr << "Must specify both crossover arguments. Returning without executing." << endl; + cerr << "Must specify both crossover arguments. Returning without executing.\n"; return false; } if (opt.Method() != "" && (!doCross0 && !doMutate)) { - cerr << "Cannot specify method unless doing crossover or mutate. Returning without executing." << endl; + cerr << "Cannot specify method unless doing crossover or mutate. Returning without executing.\n"; return false; } @@ -253,7 +253,7 @@ bool EmberGenome(EmberOptions& opt) return false; if (templateEmbers.size() > 1) - cerr << "More than one control point in template, ignoring all but first." << endl; + cerr << "More than one control point in template, ignoring all but first.\n"; pTemplate = &templateEmbers[0]; } @@ -297,7 +297,7 @@ bool EmberGenome(EmberOptions& opt) if (opt.CloneAll() != "") { - cout << "" << endl; + cout << "\n"; for (i = 0; i < embers.size(); i++) { @@ -308,7 +308,7 @@ bool EmberGenome(EmberOptions& opt) cout << emberToXml.ToString(embers[i], opt.Extras(), opt.PrintEditDepth(), !opt.NoEdits(), false, opt.HexPalette()); } - cout << "" << endl; + cout << "\n"; return true; } @@ -318,7 +318,7 @@ bool EmberGenome(EmberOptions& opt) { if (i > 0 && embers[i].m_Time <= embers[i - 1].m_Time) { - cerr << "Error: control points must be sorted by time, but " << embers[i].m_Time << " <= " << embers[i - 1].m_Time << ", index " << i << "." << endl; + cerr << "Error: control points must be sorted by time, but " << embers[i].m_Time << " <= " << embers[i - 1].m_Time << ", index " << i << ".\n"; return false; } @@ -331,7 +331,7 @@ bool EmberGenome(EmberOptions& opt) if (lastFrame < firstFrame) lastFrame = firstFrame; - cout << "" << endl; + cout << "\n"; for (ftime = firstFrame; ftime <= lastFrame; ftime++) { @@ -370,7 +370,7 @@ bool EmberGenome(EmberOptions& opt) cout << emberToXml.ToString(interpolated, opt.Extras(), opt.PrintEditDepth(), !opt.NoEdits(), false, opt.HexPalette()); } - cout << "" << endl; + cout << "\n"; return true; } @@ -380,12 +380,12 @@ bool EmberGenome(EmberOptions& opt) if (opt.Frames() == 0) { - cerr << "nframes must be positive and non-zero, not " << opt.Frames() << "." << endl; + cerr << "nframes must be positive and non-zero, not " << opt.Frames() << ".\n"; return false; } if (opt.Enclosed()) - cout << "" << endl; + cout << "\n"; spread = 1 / T(opt.Frames()); frameCount = 0; @@ -437,7 +437,7 @@ bool EmberGenome(EmberOptions& opt) cout << emberToXml.ToString(result, opt.Extras(), opt.PrintEditDepth(), !opt.NoEdits(), false, opt.HexPalette()); if (opt.Enclosed()) - cout << "" << endl; + cout << "\n"; return true; } @@ -448,7 +448,7 @@ bool EmberGenome(EmberOptions& opt) if (opt.Frames() == 0) { - cerr << "nframes must be positive and non-zero, not " << opt.Frames() << "." << endl; + cerr << "nframes must be positive and non-zero, not " << opt.Frames() << ".\n"; return false; } @@ -456,13 +456,13 @@ bool EmberGenome(EmberOptions& opt) spread = 1 / T(opt.Frames()); if (opt.Enclosed()) - cout << "" << endl; + cout << "\n"; if (doRotate) { if (embers.size() != 1) { - cerr << "rotation requires one control point, not " << embers.size() << "." << endl; + cerr << "rotation requires one control point, not " << embers.size() << ".\n"; return false; } @@ -477,7 +477,7 @@ bool EmberGenome(EmberOptions& opt) { if (embers.size() != 2) { - cerr << "interpolation requires two control points, not " << embers.size() << "." << endl; + cerr << "interpolation requires two control points, not " << embers.size() << ".\n"; return false; } @@ -490,7 +490,7 @@ bool EmberGenome(EmberOptions& opt) } if (opt.Enclosed()) - cout << "" << endl; + cout << "\n"; return true; } @@ -498,7 +498,7 @@ bool EmberGenome(EmberOptions& opt) if (doStrip) { if (opt.Enclosed()) - cout << "" << endl; + cout << "\n"; for (i = 0; i < embers.size(); i++) { @@ -520,7 +520,7 @@ bool EmberGenome(EmberOptions& opt) } if (opt.Enclosed()) - cout << "" << endl; + cout << "\n"; return true; } @@ -534,12 +534,12 @@ bool EmberGenome(EmberOptions& opt) if (opt.Repeat() == 0) { - cerr << "Repeat must be positive, not " << opt.Repeat() << endl; + cerr << "Repeat must be positive, not " << opt.Repeat() << "\n"; return false; } if (opt.Enclosed()) - cout << "" << endl; + cout << "\n"; for (rep = 0; rep < opt.Repeat(); rep++) { @@ -596,7 +596,7 @@ bool EmberGenome(EmberOptions& opt) mutMeth = eMutateMode::MUTATE_ALL_COEFS; else { - cerr << "method " << opt.Method() << " not defined for mutate. Defaulting to random." << endl; + cerr << "method " << opt.Method() << " not defined for mutate. Defaulting to random.\n"; mutMeth = eMutateMode::MUTATE_NOT_SPECIFIED; } @@ -632,7 +632,7 @@ bool EmberGenome(EmberOptions& opt) crossMeth = eCrossMode::CROSS_ALTERNATE; else { - cerr << "method '" << opt.Method() << "' not defined for cross. Defaulting to random." << endl; + cerr << "method '" << opt.Method() << "' not defined for cross. Defaulting to random.\n"; crossMeth = eCrossMode::CROSS_NOT_SPECIFIED; } @@ -699,7 +699,7 @@ bool EmberGenome(EmberOptions& opt) if (!didColor && rand.RandBit()) { if (opt.Debug()) - cerr << "improving colors..." << endl; + cerr << "improving colors...\n"; tools.ImproveColors(orig, 100, false, 10); os << " improved colors"; @@ -712,7 +712,7 @@ bool EmberGenome(EmberOptions& opt) if (renderer->Run(finalImage) != eRenderStatus::RENDER_OK) { - cerr << "Error: test image rendering failed, aborting." << endl; + cerr << "Error: test image rendering failed, aborting.\n"; return false; } @@ -733,7 +733,7 @@ bool EmberGenome(EmberOptions& opt) fractionWhite = totw / T(n); if (opt.Debug()) - cerr << "avgPix = " << avgPix << " fractionBlack = " << fractionBlack << " fractionWhite = " << fractionWhite << " n = " << n << endl; + cerr << "avgPix = " << avgPix << " fractionBlack = " << fractionBlack << " fractionWhite = " << fractionWhite << " n = " << n << "\n"; orig.Clear(); count++; @@ -744,7 +744,7 @@ bool EmberGenome(EmberOptions& opt) count < opt.Tries()); if (count == opt.Tries()) - cerr << "Warning: reached maximum attempts, giving up." << endl; + cerr << "Warning: reached maximum attempts, giving up.\n"; } if (pTemplate) @@ -806,7 +806,7 @@ int _tmain(int argc, _TCHAR* argv[]) } else if (opt.Bits() == 32) { - cerr << "Bits 32/int histogram no longer supported. Using bits == 33 (float)." << endl; + cerr << "Bits 32/int histogram no longer supported. Using bits == 33 (float).\n"; b = EmberGenome(opt); } } diff --git a/Source/EmberRender/EmberRender.cpp b/Source/EmberRender/EmberRender.cpp index 5a9ccfa..60db9b6 100644 --- a/Source/EmberRender/EmberRender.cpp +++ b/Source/EmberRender/EmberRender.cpp @@ -17,11 +17,11 @@ bool EmberRender(EmberOptions& opt) std::cout.imbue(std::locale("")); if (opt.DumpArgs()) - cout << opt.GetValues(eOptionUse::OPT_USE_RENDER) << endl; + cout << opt.GetValues(eOptionUse::OPT_USE_RENDER) << "\n"; if (opt.OpenCLInfo()) { - cout << "\nOpenCL Info: " << endl; + cout << "\nOpenCL Info: \n"; cout << info->DumpInfo(); return true; } @@ -55,7 +55,7 @@ bool EmberRender(EmberOptions& opt) if (!renderer.get()) { - cout << "Renderer creation failed, exiting." << endl; + cout << "Renderer creation failed, exiting.\n" ; return false; } @@ -72,38 +72,38 @@ bool EmberRender(EmberOptions& opt) { if (opt.ThreadCount() == 0) { - cout << "Using " << Timing::ProcessorCount() << " automatically detected threads." << endl; + cout << "Using " << Timing::ProcessorCount() << " automatically detected threads.\n"; opt.ThreadCount(Timing::ProcessorCount()); } else { - cout << "Using " << opt.ThreadCount() << " manually specified threads." << endl; + cout << "Using " << opt.ThreadCount() << " manually specified threads.\n"; } renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr); } else { - cout << "Using OpenCL to render." << endl; + cout << "Using OpenCL to render.\n"; if (opt.Verbose()) { for (auto& device : devices) { - cout << "Platform: " << info->PlatformName(device.first) << endl; - cout << "Device: " << info->DeviceName(device.first, device.second) << endl; + cout << "Platform: " << info->PlatformName(device.first) << "\n"; + cout << "Device: " << info->DeviceName(device.first, device.second) << "\n"; } } if (opt.ThreadCount() > 1) - cout << "Cannot specify threads with OpenCL, using 1 thread." << endl; + cout << "Cannot specify threads with OpenCL, using 1 thread.\n"; opt.ThreadCount(1); renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr); if (opt.BitsPerChannel() != 8) { - cout << "Bits per channel cannot be anything other than 8 with OpenCL, setting to 8." << endl; + cout << "Bits per channel cannot be anything other than 8 with OpenCL, setting to 8.\n"; opt.BitsPerChannel(8); } } @@ -113,37 +113,37 @@ bool EmberRender(EmberOptions& opt) opt.Format() != "ppm" && opt.Format() != "bmp") { - cout << "Format must be jpg, png, ppm, or bmp not " << opt.Format() << ". Setting to jpg." << endl; + cout << "Format must be jpg, png, ppm, or bmp not " << opt.Format() << ". Setting to jpg.\n"; } channels = opt.Format() == "png" ? 4 : 3; if (opt.BitsPerChannel() == 16 && opt.Format() != "png") { - cout << "Support for 16 bits per channel images is only present for the png format. Setting to 8." << endl; + cout << "Support for 16 bits per channel images is only present for the png format. Setting to 8.\n"; opt.BitsPerChannel(8); } else if (opt.BitsPerChannel() != 8 && opt.BitsPerChannel() != 16) { - cout << "Unexpected bits per channel specified " << opt.BitsPerChannel() << ". Setting to 8." << endl; + cout << "Unexpected bits per channel specified " << opt.BitsPerChannel() << ". Setting to 8.\n"; opt.BitsPerChannel(8); } if (opt.InsertPalette() && opt.BitsPerChannel() != 8) { - cout << "Inserting palette only supported with 8 bits per channel, insertion will not take place." << endl; + cout << "Inserting palette only supported with 8 bits per channel, insertion will not take place.\n"; opt.InsertPalette(false); } if (opt.AspectRatio() < 0) { - cout << "Invalid pixel aspect ratio " << opt.AspectRatio() << endl << ". Must be positive, setting to 1." << endl; + cout << "Invalid pixel aspect ratio " << opt.AspectRatio() << "\n. Must be positive, setting to 1.\n"; opt.AspectRatio(1); } if (!opt.Out().empty() && (embers.size() > 1)) { - cout << "Single output file " << opt.Out() << " specified for multiple images. Changing to use prefix of badname-changethis instead. Always specify prefixes when reading a file with multiple embers." << endl; + cout << "Single output file " << opt.Out() << " specified for multiple images. Changing to use prefix of badname-changethis instead. Always specify prefixes when reading a file with multiple embers.\n"; opt.Out(""); opt.Prefix("badname-changethis"); } @@ -165,9 +165,9 @@ bool EmberRender(EmberOptions& opt) for (i = 0; i < embers.size(); i++) { if (opt.Verbose() && embers.size() > 1) - cout << "\nFlame = " << i + 1 << "/" << embers.size() << endl; + cout << "\nFlame = " << i + 1 << "/" << embers.size() << "\n"; else if (embers.size() > 1) - VerbosePrint(endl); + VerbosePrint("\n"); if (opt.Supersample() > 0) embers[i].m_Supersample = opt.Supersample(); @@ -192,7 +192,7 @@ bool EmberRender(EmberOptions& opt) if (embers[i].m_FinalRasW == 0 || embers[i].m_FinalRasH == 0) { - cout << "Output image " << i << " has dimension 0: " << embers[i].m_FinalRasW << ", " << embers[i].m_FinalRasH << ". Setting to 1920 x 1080." << endl; + cout << "Output image " << i << " has dimension 0: " << embers[i].m_FinalRasW << ", " << embers[i].m_FinalRasH << ". Setting to 1920 x 1080.\n"; embers[i].m_FinalRasW = 1920; embers[i].m_FinalRasH = 1080; } @@ -204,7 +204,7 @@ bool EmberRender(EmberOptions& opt) if (imageMem > maxMem)//Ensure the max amount of memory for a process is not exceeded. { - cout << "Image " << i << " size > " << maxMem << ". Setting to 1920 x 1080." << endl; + cout << "Image " << i << " size > " << maxMem << ". Setting to 1920 x 1080.\n"; embers[i].m_FinalRasW = 1920; embers[i].m_FinalRasH = 1080; } @@ -227,9 +227,9 @@ bool EmberRender(EmberOptions& opt) } strips = VerifyStrips(embers[i].m_FinalRasH, strips, - [&](const string & s) { cout << s << endl; }, //Greater than height. - [&](const string & s) { cout << s << endl; }, //Mod height != 0. - [&](const string & s) { cout << s << endl; }); //Final strips value to be set. + [&](const string & s) { cout << s << "\n"; }, //Greater than height. + [&](const string & s) { cout << s << "\n"; }, //Mod height != 0. + [&](const string & s) { cout << s << "\n"; }); //Final strips value to be set. //For testing incremental renderer. //int sb = 1; //bool resume = false, success = false; @@ -244,7 +244,7 @@ bool EmberRender(EmberOptions& opt) [&](size_t strip)//Pre strip. { if (opt.Verbose() && (strips > 1) && strip > 0) - cout << endl; + cout << "\n"; if (strips > 1) VerbosePrint("Strip = " << (strip + 1) << "/" << strips); @@ -256,7 +256,7 @@ bool EmberRender(EmberOptions& opt) }, [&](size_t strip)//Error. { - cout << "Error: image rendering failed, skipping to next image." << endl; + cout << "Error: image rendering failed, skipping to next image.\n"; renderer->DumpErrorReport();//Something went wrong, print errors. }, //Final strip. @@ -291,7 +291,7 @@ bool EmberRender(EmberOptions& opt) VerbosePrint("Render time: " + t.Format(stats.m_RenderMs)); VerbosePrint("Pure iter time: " + t.Format(stats.m_IterMs)); - VerbosePrint("Iters/sec: " << size_t(stats.m_Iters / (stats.m_IterMs / 1000.0)) << endl); + VerbosePrint("Iters/sec: " << size_t(stats.m_Iters / (stats.m_IterMs / 1000.0)) << "\n"); VerbosePrint("Writing " + filename); if ((opt.Format() == "jpg" || opt.Format() == "bmp") && renderer->NumChannels() == 4) @@ -310,7 +310,7 @@ bool EmberRender(EmberOptions& opt) writeSuccess = WriteBmp(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH); if (!writeSuccess) - cout << "Error writing " << filename << endl; + cout << "Error writing " << filename << "\n"; }); if (opt.EmberCL() && opt.DumpKernel()) @@ -322,7 +322,7 @@ bool EmberRender(EmberOptions& opt) "Density filter kernel:\n" << rendererCL->DEKernel() << "\n\n" << "Final accumulation kernel:\n" << - rendererCL->FinalAccumKernel() << endl; + rendererCL->FinalAccumKernel() << "\n"; } } @@ -368,7 +368,7 @@ int _tmain(int argc, _TCHAR* argv[]) } else if (opt.Bits() == 32) { - cout << "Bits 32/int histogram no longer supported. Using bits == 33 (float)." << endl; + cout << "Bits 32/int histogram no longer supported. Using bits == 33 (float).\n"; b = EmberRender(opt); } } diff --git a/Source/EmberTester/EmberTester.cpp b/Source/EmberTester/EmberTester.cpp index 4662b4c..8aa2940 100644 --- a/Source/EmberTester/EmberTester.cpp +++ b/Source/EmberTester/EmberTester.cpp @@ -1962,6 +1962,28 @@ void DistribTester() } } +template +void TestAffine() +{ + v2T x(1, 0), y(0, 1), t(1, 0); + Affine2D af(x, y, t); + auto af2 = af; + cout << af.ToString() << "\n\n"; + af.RotateTrans(90); + cout << af.ToString() << "\n\n"; + af2.RotateTrans(-90); + cout << af2.ToString() << "\n\n"; +} + +template +void TestRotate() +{ + T angle = 45; + v3T x(1, 0, 0), y(0, 1, 0), xy(1, 1, 0); + auto xtrans = glm::translate(m4T(1), xy); + auto xrot = glm::rotate(xtrans, angle * DEG_2_RAD_T, v3T(0, 0, 1)); +} + #define DO_NVIDIA 1 int _tmain(int argc, _TCHAR* argv[]) @@ -1971,7 +1993,12 @@ int _tmain(int argc, _TCHAR* argv[]) Timing t(4); QTIsaac rand(1, 2, 3); mt19937 meow(1729); - /* MakeTestAllVarsRegPrePostComboFile("testallvarsout.flame"); + /* TestAffine(); + TestAffine();*/ + /* TestRotate(); + TestRotate(); + return 1; + MakeTestAllVarsRegPrePostComboFile("testallvarsout.flame"); return 0; @@ -2175,28 +2202,28 @@ int _tmain(int argc, _TCHAR* argv[]) #endif } -#ifdef DO_DOUBLE - - //t.Tic(); - //TestCpuGpuResults(); - //t.Toc("TestCpuGpuResults()"); - if (b) - { - t.Tic(); - TestAllVarsCLBuild(0, 0, true); - t.Toc("TestAllVarsCLBuild()"); - - if (b) - { -#ifdef DO_NVIDIA - t.Tic(); - TestAllVarsCLBuild(1, 0, true); - t.Toc("TestAllVarsCLBuild()"); -#endif - } - } - -#endif +//#ifdef DO_DOUBLE +// +// //t.Tic(); +// //TestCpuGpuResults(); +// //t.Toc("TestCpuGpuResults()"); +// if (b) +// { +// t.Tic(); +// TestAllVarsCLBuild(0, 0, true); +// t.Toc("TestAllVarsCLBuild()"); +// +// if (b) +// { +//#ifdef DO_NVIDIA +// t.Tic(); +// TestAllVarsCLBuild(1, 0, true); +// t.Toc("TestAllVarsCLBuild()"); +//#endif +// } +// } +// +//#endif #endif //PrintAllVars(); //_CrtDumpMemoryLeaks(); diff --git a/Source/Fractorium/DoubleSpinBox.cpp b/Source/Fractorium/DoubleSpinBox.cpp index d9fe1f1..5920b3d 100644 --- a/Source/Fractorium/DoubleSpinBox.cpp +++ b/Source/Fractorium/DoubleSpinBox.cpp @@ -1,7 +1,7 @@ #include "FractoriumPch.h" #include "DoubleSpinBox.h" -QTimer DoubleSpinBox::m_Timer; +QTimer DoubleSpinBox::s_Timer; /// /// Constructor that passes parent to the base and sets up height and step. @@ -144,17 +144,16 @@ void DoubleSpinBox::OnTimeout() //qDebug() << "Shift pressed"; scale = 0.0001; } - /*else if (ctrl) - { + /* else if (ctrl) + { qDebug() << "Control pressed"; scale = 0.01; - }*/ + }*/ else scale = 0.001; val = d + (distance * amount * scale); setValue(val); - //qDebug() << "Timer on, orig val: " << d << ", new val: " << val << ", distance " << distance; } @@ -169,47 +168,47 @@ bool DoubleSpinBox::eventFilter(QObject* o, QEvent* e) QMouseEvent* me = dynamic_cast(e); if (isEnabled() && - me && - me->type() == QMouseEvent::MouseButtonPress && - me->button() == Qt::RightButton) + me && + me->type() == QMouseEvent::MouseButtonPress && + me->button() == Qt::RightButton) { m_MouseDownPoint = m_MouseMovePoint = me->pos(); StartTimer(); //qDebug() << "Right mouse down"; - // QPoint pt; - // - // if (QMouseEvent* me = (QMouseEvent*)e) - // pt = me->localPos().toPoint(); - // - // int pos = lineEdit()->cursorPositionAt(pt); - // - // if (lineEdit()->selectedText() != "") - // { - // lineEdit()->deselect(); - // lineEdit()->setCursorPosition(pos); - // return true; - // } - // else if (m_Select) - // { - // lineEdit()->setCursorPosition(pos); - // selectAll(); - // m_Select = false; - // return true; - // } + // QPoint pt; + // + // if (QMouseEvent* me = (QMouseEvent*)e) + // pt = me->localPos().toPoint(); + // + // int pos = lineEdit()->cursorPositionAt(pt); + // + // if (lineEdit()->selectedText() != "") + // { + // lineEdit()->deselect(); + // lineEdit()->setCursorPosition(pos); + // return true; + // } + // else if (m_Select) + // { + // lineEdit()->setCursorPosition(pos); + // selectAll(); + // m_Select = false; + // return true; + // } } else if (isEnabled() && - me && - me->type() == QMouseEvent::MouseButtonRelease && - me->button() == Qt::RightButton) + me && + me->type() == QMouseEvent::MouseButtonRelease && + me->button() == Qt::RightButton) { StopTimer(); m_MouseDownPoint = m_MouseMovePoint = me->pos(); //qDebug() << "Right mouse up"; } else if (isEnabled() && - me && - me->type() == QMouseEvent::MouseMove && - QGuiApplication::mouseButtons() & Qt::RightButton) + me && + me->type() == QMouseEvent::MouseMove && + QGuiApplication::mouseButtons() & Qt::RightButton) { m_MouseMovePoint = me->pos(); qDebug() << "Mouse move while right down. Pt = " << me->pos() << ", global: " << mapToGlobal(me->pos()); @@ -262,8 +261,8 @@ void DoubleSpinBox::focusInEvent(QFocusEvent* e) /// The event void DoubleSpinBox::focusOutEvent(QFocusEvent* e) { - //lineEdit()->deselect();//Clear selection when leaving. - //lineEdit()->setReadOnly(true);//Clever hack to clear the cursor when leaving. + //lineEdit()->deselect();//Clear selection when leaving. + //lineEdit()->setReadOnly(true);//Clever hack to clear the cursor when leaving. StopTimer(); QDoubleSpinBox::focusOutEvent(e); } @@ -299,9 +298,9 @@ void DoubleSpinBox::leaveEvent(QEvent* e) /// void DoubleSpinBox::StartTimer() { - m_Timer.stop(); - connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); - m_Timer.start(300); + s_Timer.stop(); + connect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); + s_Timer.start(300); } /// @@ -309,6 +308,6 @@ void DoubleSpinBox::StartTimer() /// void DoubleSpinBox::StopTimer() { - m_Timer.stop(); - disconnect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); + s_Timer.stop(); + disconnect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); } \ No newline at end of file diff --git a/Source/Fractorium/DoubleSpinBox.h b/Source/Fractorium/DoubleSpinBox.h index 15d4ac2..0af59a7 100644 --- a/Source/Fractorium/DoubleSpinBox.h +++ b/Source/Fractorium/DoubleSpinBox.h @@ -51,7 +51,7 @@ private: double m_SmallStep; QPoint m_MouseDownPoint; QPoint m_MouseMovePoint; - static QTimer m_Timer; + static QTimer s_Timer; }; /// diff --git a/Source/Fractorium/FinalRenderDialog.cpp b/Source/Fractorium/FinalRenderDialog.cpp index 227259e..0151416 100644 --- a/Source/Fractorium/FinalRenderDialog.cpp +++ b/Source/Fractorium/FinalRenderDialog.cpp @@ -15,7 +15,6 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set { ui.setupUi(this); int row = 0, spinHeight = 20; - uint i; double dmax = numeric_limits::max(); QTableWidget* table = ui.FinalRenderParamsTable; QTableWidgetItem* item = nullptr; diff --git a/Source/Fractorium/FinalRenderEmberController.cpp b/Source/Fractorium/FinalRenderEmberController.cpp index 44162a9..73fd1ae 100644 --- a/Source/Fractorium/FinalRenderEmberController.cpp +++ b/Source/Fractorium/FinalRenderEmberController.cpp @@ -110,7 +110,7 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD m_FinalPreviewRenderer->NumChannels(4); m_FinalPreviewRenderFunc = [&]() { - m_PreviewCs.Enter();//Thread prep. + rlg l(m_PreviewCs);//Thread prep. m_PreviewRun = true; m_FinalPreviewRenderer->Abort(); T scalePercentage; @@ -144,11 +144,10 @@ FinalRenderEmberController::FinalRenderEmberController(FractoriumFinalRenderD { QImage image(finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, QImage::Format_RGBA8888);//The label wants RGBA. memcpy(image.scanLine(0), m_PreviewFinalImage.data(), finalEmber.m_FinalRasW * finalEmber.m_FinalRasH * 4);//Memcpy the data in. - QPixmap pixmap = QPixmap::fromImage(image); + QPixmap pixmap(QPixmap::fromImage(image)); QMetaObject::invokeMethod(widget, "setPixmap", Qt::QueuedConnection, Q_ARG(QPixmap, pixmap)); }); m_PreviewRun = false; - m_PreviewCs.Leave(); }; //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. @@ -837,7 +836,7 @@ void FinalRenderEmberController::HandleFinishedProgress() template void FinalRenderEmberController::RenderComplete(Ember& ember, const EmberStats& stats, Timing& renderTimer) { - m_ProgressCs.Enter(); + rlg l(m_ProgressCs); string renderTimeString = renderTimer.Format(renderTimer.Toc()), totalTimeString; QString status, filename = ComposePath(QString::fromStdString(ember.m_Name)); QString itersString = ToString(stats.m_Iters); @@ -885,7 +884,6 @@ void FinalRenderEmberController::RenderComplete(Ember& ember, const EmberS } QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTextOutput, "update", Qt::QueuedConnection); - m_ProgressCs.Leave(); } /// diff --git a/Source/Fractorium/FinalRenderEmberController.h b/Source/Fractorium/FinalRenderEmberController.h index 7cacf24..5b384f5 100644 --- a/Source/Fractorium/FinalRenderEmberController.h +++ b/Source/Fractorium/FinalRenderEmberController.h @@ -82,11 +82,11 @@ protected: QFuture m_FinalPreviewResult; std::function m_FinalRenderFunc; std::function m_FinalPreviewRenderFunc; - + FractoriumSettings* m_Settings; FractoriumFinalRenderDialog* m_FinalRenderDialog; FinalRenderGuiState m_GuiState; - CriticalSection m_PreviewCs, m_ProgressCs; + std::recursive_mutex m_PreviewCs, m_ProgressCs; Timing m_RenderTimer; Timing m_TotalTimer; }; diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui index bffb2cd..d2a4e19 100644 --- a/Source/Fractorium/Fractorium.ui +++ b/Source/Fractorium/Fractorium.ui @@ -2780,7 +2780,7 @@ QTabWidget::Triangular - 1 + 2 @@ -3470,8 +3470,8 @@ 0 0 - 263 - 700 + 118 + 618 @@ -5485,8 +5485,8 @@ 0 0 - 259 - 652 + 133 + 52 @@ -6768,6 +6768,9 @@ Clear any existing flames and create a new file with 10 random flames in it + + Ctrl+N + @@ -6777,6 +6780,9 @@ &Open + + Ctrl+O + @@ -6798,6 +6804,9 @@ <html><body><p>Save the currently displayed flame back to the opened file in memory.</p><p>This overwrites the original flame but does not store the file back to disk.</p></body></html> + + Ctrl+B + @@ -6810,6 +6819,9 @@ Save the current flame as an xml file + + Ctrl+S + @@ -6861,6 +6873,9 @@ Add a new random flame to the end of the current file + + Ctrl+R + @@ -6876,6 +6891,9 @@ Save all flames as a single xml file + + Ctrl+Shift+S + @@ -6920,6 +6938,9 @@ Add a new empty flame to the end of the current file + + Ctrl+E + @@ -6927,7 +6948,7 @@ :/Fractorium/Icons/layers.png:/Fractorium/Icons/layers.png - Co&py Flame + Add Co&py of Flame Add a copy of the current flame to the end of the current file @@ -7069,11 +7090,6 @@ Remove the flatten variation from each xform - - - Fl&ip - - Copy Selected &Xforms @@ -7082,7 +7098,7 @@ Copy selected xforms to the clipboard - Ctrl+D + Ctrl+C, X @@ -7093,7 +7109,7 @@ Paste copied xforms into the current flame - Ctrl+S + Ctrl+V, X @@ -7192,7 +7208,7 @@ Stop Renderer - Ctrl+R + Ctrl+P diff --git a/Source/Fractorium/FractoriumEmberController.cpp b/Source/Fractorium/FractoriumEmberController.cpp index b114130..d1f1bab 100644 --- a/Source/Fractorium/FractoriumEmberController.cpp +++ b/Source/Fractorium/FractoriumEmberController.cpp @@ -20,15 +20,13 @@ FractoriumEmberControllerBase::FractoriumEmberControllerBase(Fractorium* fractor m_OutputTexID = 0; m_SubBatchCount = 1;//Will be ovewritten by the options on first render. m_Fractorium = fractorium; - m_RenderTimer = nullptr; - m_RenderRestartTimer = nullptr; m_Info = OpenCLInfo::Instance(); m_Rand = QTIsaac(ISAAC_INT(t.Tic()), ISAAC_INT(t.Tic() * 2), ISAAC_INT(t.Tic() * 3));//Ensure a different rand seed on each instance. - m_RenderTimer = new QTimer(m_Fractorium); + m_RenderTimer = std::unique_ptr(new QTimer(m_Fractorium)); m_RenderTimer->setInterval(0); - m_Fractorium->connect(m_RenderTimer, SIGNAL(timeout()), SLOT(IdleTimer())); - m_RenderRestartTimer = new QTimer(m_Fractorium); - m_Fractorium->connect(m_RenderRestartTimer, SIGNAL(timeout()), SLOT(StartRenderTimer())); + m_Fractorium->connect(m_RenderTimer.get(), SIGNAL(timeout()), SLOT(IdleTimer())); + m_RenderRestartTimer = std::unique_ptr(new QTimer(m_Fractorium)); + m_Fractorium->connect(m_RenderRestartTimer.get(), SIGNAL(timeout()), SLOT(StartRenderTimer())); } /// @@ -38,20 +36,8 @@ FractoriumEmberControllerBase::FractoriumEmberControllerBase(Fractorium* fractor FractoriumEmberControllerBase::~FractoriumEmberControllerBase() { StopRenderTimer(true); - - if (m_RenderTimer) - { - m_RenderTimer->stop(); - delete m_RenderTimer; - m_RenderTimer = nullptr; - } - - if (m_RenderRestartTimer) - { - m_RenderRestartTimer->stop(); - delete m_RenderRestartTimer; - m_RenderRestartTimer = nullptr; - } + m_RenderTimer->stop(); + m_RenderRestartTimer->stop(); } /// @@ -64,26 +50,35 @@ template FractoriumEmberController::FractoriumEmberController(Fractorium* fractorium) : FractoriumEmberControllerBase(fractorium) { + bool b = false; m_PreviewRun = false; m_PreviewRunning = false; - m_SheepTools = unique_ptr>(new SheepTools( - QString(QApplication::applicationDirPath() + "flam3-palettes.xml").toLocal8Bit().data(), - new EmberNs::Renderer())); m_GLController = unique_ptr>(new GLEmberController(fractorium, fractorium->ui.GLDisplay, this)); m_PreviewRenderer = unique_ptr>(new EmberNs::Renderer()); - //Initial combo change event to fill the palette table will be called automatically later. - //Look hard for a palette. - if (!(InitPaletteList(QDir::currentPath().toLocal8Bit().data()) || - InitPaletteList(QDir::homePath().toLocal8Bit().data()) || - InitPaletteList(QCoreApplication::applicationDirPath().toLocal8Bit().data()) || - InitPaletteList(QString("/usr/local/share/fractorium").toLocal8Bit().data()) || - InitPaletteList(QString("/usr/share/fractorium").toLocal8Bit().data())) ) + static vector paths = { - throw "No palettes found, exiting."; + QDir::currentPath().toLocal8Bit().data(), + QDir::homePath().toLocal8Bit().data(), + QCoreApplication::applicationDirPath().toLocal8Bit().data(), + QString("/usr/local/share/fractorium").toLocal8Bit().data(), + QString("/usr/share/fractorium").toLocal8Bit().data() + }; + + for (auto& path : paths) + { + if (b = InitPaletteList(path)) + { + m_SheepTools = unique_ptr>(new SheepTools( + m_PaletteList.Name(0), new EmberNs::Renderer())); + break; + } } + if (!b) + throw "No palettes found, exiting."; + BackgroundChanged(QColor(0, 0, 0));//Default to black. ClearUndo(); m_PreviewRenderer->Callback(nullptr); @@ -101,9 +96,9 @@ FractoriumEmberController::FractoriumEmberController(Fractorium* fractorium) m_PreviewRun = true; m_PreviewRunning = true; m_PreviewRenderer->ThreadCount(std::max(1u, Timing::ProcessorCount() - 1));//Leave one processor free so the GUI can breathe. - QTreeWidget* tree = m_Fractorium->ui.LibraryTree; + auto tree = m_Fractorium->ui.LibraryTree; - if (QTreeWidgetItem* top = tree->topLevelItem(0)) + if (auto top = tree->topLevelItem(0)) { for (size_t i = start; m_PreviewRun && i < end && i < m_EmberFile.Size(); i++) { @@ -117,7 +112,7 @@ FractoriumEmberController::FractoriumEmberController(Fractorium* fractorium) if (m_PreviewRenderer->Run(m_PreviewFinalImage) == eRenderStatus::RENDER_OK) { - if (EmberTreeWidgetItem* treeItem = dynamic_cast*>(top->child(i))) + if (auto treeItem = dynamic_cast*>(top->child(i))) { //It is critical that Qt::BlockingQueuedConnection is passed because this is running on a different thread than the UI. //This ensures the events are processed in order as each preview is updated, and that control does not return here @@ -193,11 +188,11 @@ void FractoriumEmberController::SetEmber(size_t index) { if (index < m_EmberFile.Size()) { - if (QTreeWidgetItem* top = m_Fractorium->ui.LibraryTree->topLevelItem(0)) + if (auto top = m_Fractorium->ui.LibraryTree->topLevelItem(0)) { for (uint i = 0; i < top->childCount(); i++) { - if (EmberTreeWidgetItem* emberItem = dynamic_cast*>(top->child(i))) + if (auto emberItem = dynamic_cast*>(top->child(i))) emberItem->setSelected(i == index); } } diff --git a/Source/Fractorium/FractoriumEmberController.h b/Source/Fractorium/FractoriumEmberController.h index 684d32f..e8a54e5 100644 --- a/Source/Fractorium/FractoriumEmberController.h +++ b/Source/Fractorium/FractoriumEmberController.h @@ -194,7 +194,6 @@ public: //Xaos. virtual void FillXaos() { } - virtual QString MakeXaosNameString(uint i) { return ""; } virtual void XaosChanged(int x, int y, double val) { } virtual void ClearXaos() { } virtual void RandomXaos() { } @@ -254,7 +253,7 @@ protected: QString m_LastSaveAll; QString m_LastSaveCurrent; string m_CurrentPaletteFilePath; - CriticalSection m_Cs; + std::recursive_mutex m_Cs; std::thread m_WriteThread; vector m_FinalImage; vector m_PreviewFinalImage; @@ -263,8 +262,8 @@ protected: unique_ptr m_Renderer; QTIsaac m_Rand; Fractorium* m_Fractorium; - QTimer* m_RenderTimer; - QTimer* m_RenderRestartTimer; + std::unique_ptr m_RenderTimer; + std::unique_ptr m_RenderRestartTimer; shared_ptr m_Info; }; @@ -439,7 +438,6 @@ public: //Xforms Xaos. virtual void FillXaos() override; - virtual QString MakeXaosNameString(uint i) override; virtual void XaosChanged(int x, int y, double val) override; virtual void ClearXaos() override; virtual void RandomXaos() override; @@ -475,7 +473,6 @@ private: bool IsFinal(Xform* xform); //Xforms Color. - void SetCurrentXformColorIndex(double d, bool updateRender); void FillCurvesControl(); //Xforms Selection. diff --git a/Source/Fractorium/FractoriumInfo.cpp b/Source/Fractorium/FractoriumInfo.cpp index eef2cf6..e59dd02 100644 --- a/Source/Fractorium/FractoriumInfo.cpp +++ b/Source/Fractorium/FractoriumInfo.cpp @@ -32,7 +32,7 @@ void Fractorium::InitInfoUI() /// Ignored void Fractorium::OnSummaryTableHeaderResized(int logicalIndex, int oldSize, int newSize) { - QPixmap pixmap = QPixmap::fromImage(m_Controller->FinalPaletteImage());//Create a QPixmap out of the QImage, will be empty on startup. + QPixmap pixmap(QPixmap::fromImage(m_Controller->FinalPaletteImage()));//Create a QPixmap out of the QImage, will be empty on startup. SetPaletteTableItem(&pixmap, ui.SummaryTable, m_InfoPaletteItem, 1, 0); } @@ -57,7 +57,7 @@ void Fractorium::OnSummaryTreeHeaderSectionClicked(int logicalIndex) /// values from the ember. /// It's also meant to be used in a fire-and-forget way. Once the tree is filled /// individual nodes are never referenced again. -/// The entire tree is cleared and refilled for every field change. +/// The entire tree is cleared and refilled whenever a render is completed. /// This would seem inefficient, but it appears to update with no flicker. /// If this ever presents a problem in the future, revisit with a more /// intelligent design. @@ -74,17 +74,6 @@ void FractoriumEmberController::FillSummary() QColor color; auto table = m_Fractorium->ui.SummaryTable; auto tree = m_Fractorium->ui.SummaryTree; - QVariantList states; - QTreeWidgetItemIterator it(tree); - - while (*it) - { - if (!(*it)->parent())//Top level only. - states += (*it)->isExpanded(); - - ++it; - } - tree->blockSignals(true); tree->clear(); m_Fractorium->m_InfoNameItem->setText(m_Ember.m_Name.c_str()); @@ -92,7 +81,7 @@ void FractoriumEmberController::FillSummary() m_Fractorium->m_InfoXaosItem->setText(m_Ember.XaosPresent() ? "Yes" : "No"); m_Fractorium->m_InfoXformCountItem->setText(QString::number(m_Ember.XformCount())); m_Fractorium->m_InfoFinalXformItem->setText(m_Ember.UseFinalXform() ? "Yes" : "No"); - QPixmap pixmap = QPixmap::fromImage(m_FinalPaletteImage);//Create a QPixmap out of the QImage. + QPixmap pixmap(QPixmap::fromImage(m_FinalPaletteImage));//Create a QPixmap out of the QImage. QSize size(table->columnWidth(0), table->rowHeight(1) + 1); m_Fractorium->m_InfoPaletteItem->setData(Qt::DecorationRole, pixmap.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); @@ -178,26 +167,7 @@ void FractoriumEmberController::FillSummary() auto item2 = new QTreeWidgetItem(tree);//Empty item in between xforms. } - QTreeWidgetItemIterator it2(tree); - - if (!states.isEmpty()) - { - while (*it2) - { - if (!(*it2)->parent())//Top level only. - { - if (!states.isEmpty()) - (*it2)->setExpanded(states.takeFirst().toBool()); - else - (*it2)->setExpanded(true);//Expand any remainder when going from lesser to greater number of xforms. - } - - ++it2; - } - } - else - tree->expandAll(); - + tree->expandAll(); tree->blockSignals(false); } diff --git a/Source/Fractorium/FractoriumLibrary.cpp b/Source/Fractorium/FractoriumLibrary.cpp index 003a9a7..fe27f7c 100644 --- a/Source/Fractorium/FractoriumLibrary.cpp +++ b/Source/Fractorium/FractoriumLibrary.cpp @@ -20,9 +20,9 @@ pair Fractorium::GetCurrentEmberIndex() { size_t index = 0; QTreeWidgetItem* item = nullptr; - QTreeWidget* tree = ui.LibraryTree; + auto tree = ui.LibraryTree; - if (QTreeWidgetItem* top = tree->topLevelItem(0)) + if (auto top = tree->topLevelItem(0)) { for (int i = 0; i < top->childCount(); i++)//Iterate through all of the children, which will represent the open embers. { @@ -35,7 +35,7 @@ pair Fractorium::GetCurrentEmberIndex() } } - return pair(index, item); + return make_pair(index, item); } /// @@ -57,11 +57,10 @@ template void FractoriumEmberController::SyncNames() { EmberTreeWidgetItem* item; - QTreeWidget* tree = m_Fractorium->ui.LibraryTree; - + auto tree = m_Fractorium->ui.LibraryTree; tree->blockSignals(true); - if (QTreeWidgetItem* top = tree->topLevelItem(0)) + if (auto top = tree->topLevelItem(0)) { for (int i = 0; i < top->childCount(); i++)//Iterate through all of the children, which will represent the open embers. { @@ -80,11 +79,10 @@ template void FractoriumEmberController::SyncPointers() { EmberTreeWidgetItem* item; - QTreeWidget* tree = m_Fractorium->ui.LibraryTree; - + auto tree = m_Fractorium->ui.LibraryTree; tree->blockSignals(true); - if (QTreeWidgetItem* top = tree->topLevelItem(0)) + if (auto top = tree->topLevelItem(0)) { size_t childCount = top->childCount(); @@ -107,28 +105,23 @@ void FractoriumEmberController::SyncPointers() template void FractoriumEmberController::FillLibraryTree(int selectIndex) { - uint i, j, size = 64; - QTreeWidget* tree = m_Fractorium->ui.LibraryTree; + uint j, size = 64; + auto tree = m_Fractorium->ui.LibraryTree; vector v(size * size * 4); - StopPreviewRender(); tree->clear(); QCoreApplication::flush(); - tree->blockSignals(true); - - QTreeWidgetItem* fileItem = new QTreeWidgetItem(tree); + auto fileItem = new QTreeWidgetItem(tree); QFileInfo info(m_EmberFile.m_Filename); - fileItem->setText(0, info.fileName()); fileItem->setToolTip(0, m_EmberFile.m_Filename); fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable); for (j = 0; j < m_EmberFile.Size(); j++) { - Ember* ember = &m_EmberFile.m_Embers[j]; - EmberTreeWidgetItem* emberItem = new EmberTreeWidgetItem(ember, fileItem); - + auto ember = &m_EmberFile.m_Embers[j]; + auto emberItem = new EmberTreeWidgetItem(ember, fileItem); emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable); if (ember->m_Name.empty()) @@ -143,13 +136,13 @@ void FractoriumEmberController::FillLibraryTree(int selectIndex) tree->blockSignals(false); if (selectIndex != -1) - if (QTreeWidgetItem* top = tree->topLevelItem(0)) - if (EmberTreeWidgetItem* emberItem = dynamic_cast*>(top->child(selectIndex))) + if (auto top = tree->topLevelItem(0)) + if (auto emberItem = dynamic_cast*>(top->child(selectIndex))) emberItem->setSelected(true); QCoreApplication::flush(); RenderPreviews(0, m_EmberFile.Size()); - tree->expandAll(); + tree->expandAll(); } /// @@ -160,20 +153,18 @@ template void FractoriumEmberController::UpdateLibraryTree() { uint i, size = 64; - QTreeWidget* tree = m_Fractorium->ui.LibraryTree; + auto tree = m_Fractorium->ui.LibraryTree; vector v(size * size * 4); - if (QTreeWidgetItem* top = tree->topLevelItem(0)) + if (auto top = tree->topLevelItem(0)) { int childCount = top->childCount(); - tree->blockSignals(true); for (i = childCount; i < m_EmberFile.Size(); i++) { Ember* ember = &m_EmberFile.m_Embers[i]; - EmberTreeWidgetItem* emberItem = new EmberTreeWidgetItem(ember, top); - + auto emberItem = new EmberTreeWidgetItem(ember, top); emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable); if (ember->m_Name.empty()) @@ -208,9 +199,9 @@ void FractoriumEmberController::EmberTreeItemChanged(QTreeWidgetItem* item, i { try { - QTreeWidget* tree = m_Fractorium->ui.LibraryTree; - EmberTreeWidgetItem* emberItem = dynamic_cast*>(item); - + auto tree = m_Fractorium->ui.LibraryTree; + auto emberItem = dynamic_cast*>(item); + if (emberItem) { if (emberItem->text(0).isEmpty())//Prevent empty string. @@ -220,7 +211,6 @@ void FractoriumEmberController::EmberTreeItemChanged(QTreeWidgetItem* item, i } string oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name. - tree->blockSignals(true); emberItem->UpdateEmberName();//Copy edit text to the ember's name variable. m_EmberFile.MakeNamesUnique();//Ensure all names remain unique. @@ -246,7 +236,7 @@ void FractoriumEmberController::EmberTreeItemChanged(QTreeWidgetItem* item, i } } } - catch(const std::exception& e) + catch (const std::exception& e) { qDebug() << "FractoriumEmberController::EmberTreeItemChanged() : Exception thrown: " << e.what(); } @@ -267,7 +257,7 @@ void Fractorium::OnEmberTreeItemChanged(QTreeWidgetItem* item, int col) { m_Cont template void FractoriumEmberController::EmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col) { - if (EmberTreeWidgetItem* emberItem = dynamic_cast*>(item)) + if (auto emberItem = dynamic_cast*>(item)) { ClearUndo(); SetEmber(*emberItem->GetEmber()); @@ -285,8 +275,7 @@ void Fractorium::OnEmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col) { template void FractoriumEmberController::Delete(const pair& p) { - QTreeWidget* tree = m_Fractorium->ui.LibraryTree; - + auto tree = m_Fractorium->ui.LibraryTree; tree->blockSignals(true); if (m_EmberFile.Delete(p.first)) @@ -298,7 +287,7 @@ void FractoriumEmberController::Delete(const pair& tree->blockSignals(false); //If there is now only one item left and it wasn't selected, select it. - if (QTreeWidgetItem* top = tree->topLevelItem(0)) + if (auto top = tree->topLevelItem(0)) { if (top->childCount() == 1) if (auto item = dynamic_cast*>(top->child(0))) @@ -331,17 +320,16 @@ void FractoriumEmberController::RenderPreviews(uint start, uint end) if (start == UINT_MAX && end == UINT_MAX) { - QTreeWidget* tree = m_Fractorium->ui.LibraryTree; - + auto tree = m_Fractorium->ui.LibraryTree; tree->blockSignals(true); - if (QTreeWidgetItem* top = tree->topLevelItem(0)) + if (auto top = tree->topLevelItem(0)) { int childCount = top->childCount(); vector emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 3); for (int i = 0; i < childCount; i++) - if (EmberTreeWidgetItem* treeItem = dynamic_cast*>(top->child(i))) + if (auto treeItem = dynamic_cast*>(top->child(i))) treeItem->SetImage(emptyPreview, PREVIEW_SIZE, PREVIEW_SIZE); } @@ -359,10 +347,11 @@ template void FractoriumEmberController::StopPreviewRender() { m_PreviewRun = false; + m_PreviewRenderer->Abort(); while (m_PreviewRunning) QApplication::processEvents(); - + m_PreviewResult.cancel(); while (m_PreviewResult.isRunning()) @@ -375,5 +364,5 @@ void FractoriumEmberController::StopPreviewRender() template class FractoriumEmberController; #ifdef DO_DOUBLE - template class FractoriumEmberController; +template class FractoriumEmberController; #endif diff --git a/Source/Fractorium/FractoriumMenus.cpp b/Source/Fractorium/FractoriumMenus.cpp index 3c7d67e..9039b38 100644 --- a/Source/Fractorium/FractoriumMenus.cpp +++ b/Source/Fractorium/FractoriumMenus.cpp @@ -139,7 +139,7 @@ void Fractorium::OnActionNewRandomFlameInCurrentFile(bool checked) { m_Controlle template void FractoriumEmberController::CopyFlameInCurrentFile() { - Ember ember = m_Ember; + auto ember = m_Ember; StopPreviewRender(); ember.m_Name = EmberFile::DefaultEmberName(m_EmberFile.Size() + 1).toStdString(); ember.m_Index = m_EmberFile.Size(); @@ -199,7 +199,7 @@ void FractoriumEmberController::OpenAndPrepFiles(const QStringList& filenames } else { - vector errors = parser.ErrorReport(); + auto errors = parser.ErrorReport(); m_Fractorium->ErrorReportToQTextEdit(errors, m_Fractorium->ui.InfoFileOpeningTextEdit); m_Fractorium->ShowCritical("Open Failed", "Could not open file, see info tab for details."); } @@ -246,7 +246,7 @@ template void FractoriumEmberController::SaveCurrentAsXml() { QString filename; - FractoriumSettings* s = m_Fractorium->m_Settings; + auto s = m_Fractorium->m_Settings; if (s->SaveAutoUnique() && m_LastSaveCurrent != "") { @@ -266,10 +266,10 @@ void FractoriumEmberController::SaveCurrentAsXml() if (filename != "") { - Ember ember = m_Ember; + auto ember = m_Ember; EmberToXml writer; QFileInfo fileInfo(filename); - xmlDocPtr tempEdit = ember.m_Edits; + auto tempEdit = ember.m_Edits; SaveCurrentToOpenedFile();//Save the current ember back to the opened file before writing to disk. ApplyXmlSavingTemplate(ember); ember.m_Edits = writer.CreateNewEditdoc(&ember, nullptr, "edit", s->Nick().toStdString(), s->Url().toStdString(), s->Id().toStdString(), "", 0, 0); @@ -300,7 +300,7 @@ template void FractoriumEmberController::SaveEntireFileAsXml() { QString filename; - FractoriumSettings* s = m_Fractorium->m_Settings; + auto s = m_Fractorium->m_Settings; if (s->SaveAutoUnique() && m_LastSaveAll != "") filename = EmberFile::UniqueFilename(m_LastSaveAll); @@ -340,12 +340,12 @@ void Fractorium::OnActionSaveEntireFileAsXml(bool checked) { m_Controller->SaveE /// Ignored void Fractorium::OnActionSaveCurrentScreen(bool checked) { - QString filename = SetupSaveImageDialog(m_Controller->Name()); + auto filename = SetupSaveImageDialog(m_Controller->Name()); auto renderer = m_Controller->Renderer(); auto& pixels = *m_Controller->FinalImage(); - RendererCLBase* rendererCL = dynamic_cast(m_Controller->Renderer()); + auto rendererCL = dynamic_cast(m_Controller->Renderer()); auto stats = m_Controller->Stats(); - EmberImageComments comments = renderer->ImageComments(stats, 0, false, true); + auto comments = renderer->ImageComments(stats, 0, false, true); if (rendererCL && renderer->PrepFinalAccumVector(pixels)) { @@ -460,9 +460,9 @@ void Fractorium::OnActionRedo(bool checked) { m_Controller->Redo(); } template void FractoriumEmberController::CopyXml() { - Ember ember = m_Ember; + auto ember = m_Ember; EmberToXml emberToXml; - FractoriumSettings* settings = m_Fractorium->m_Settings; + auto settings = m_Fractorium->m_Settings; ember.m_Quality = settings->XmlQuality(); ember.m_Supersample = settings->XmlSupersample(); ember.m_TemporalSamples = settings->XmlTemporalSamples(); @@ -480,7 +480,7 @@ void FractoriumEmberController::CopyAllXml() { ostringstream os; EmberToXml emberToXml; - FractoriumSettings* settings = m_Fractorium->m_Settings; + auto settings = m_Fractorium->m_Settings; os << "\n"; for (auto& e : m_EmberFile.m_Embers) @@ -510,8 +510,8 @@ void FractoriumEmberController::PasteXmlAppend() string s, errors; XmlToEmber parser; vector> embers; - QTextCodec* codec = QTextCodec::codecForName("UTF-8"); - QByteArray b = codec->fromUnicode(QApplication::clipboard()->text()); + auto codec = QTextCodec::codecForName("UTF-8"); + auto b = codec->fromUnicode(QApplication::clipboard()->text()); s.reserve(b.size()); for (i = 0; i < b.size(); i++) @@ -563,9 +563,9 @@ void FractoriumEmberController::PasteXmlOver() uint i; string s, errors; XmlToEmber parser; - Ember backupEmber = m_EmberFile.m_Embers[0]; - QTextCodec* codec = QTextCodec::codecForName("UTF-8"); - QByteArray b = codec->fromUnicode(QApplication::clipboard()->text()); + auto backupEmber = m_EmberFile.m_Embers[0]; + auto codec = QTextCodec::codecForName("UTF-8"); + auto b = codec->fromUnicode(QApplication::clipboard()->text()); s.reserve(b.size()); for (i = 0; i < b.size(); i++) @@ -810,6 +810,7 @@ void Fractorium::OnActionFinalRender(bool checked) { //First completely stop what the current rendering process is doing. m_Controller->DeleteRenderer();//Delete the renderer, but not the controller. + m_Controller->StopPreviewRender(); OnActionSaveCurrentToOpenedFile(true);//Save whatever was edited back to the current open file. m_RenderStatusLabel->setText("Renderer stopped."); m_FinalRenderDialog->show(); diff --git a/Source/Fractorium/FractoriumPalette.cpp b/Source/Fractorium/FractoriumPalette.cpp index 65ea4ce..6609953 100644 --- a/Source/Fractorium/FractoriumPalette.cpp +++ b/Source/Fractorium/FractoriumPalette.cpp @@ -139,7 +139,7 @@ void Fractorium::OnPaletteFilenameComboChanged(const QString& text) template void FractoriumEmberController::ApplyPaletteToEmber() { - int i, rot = 0; + int rot = 0; uint blur = m_Fractorium->m_PaletteBlurSpin->value(); uint freq = m_Fractorium->m_PaletteFrequencySpin->value(); double sat = double(m_Fractorium->m_PaletteSaturationSpin->value() / 100.0); @@ -170,7 +170,7 @@ void FractoriumEmberController::UpdateAdjustedPaletteGUI(Palette& palette) vector v = palette.MakeRgbPaletteBlock(PALETTE_CELL_HEIGHT);//Make the palette repeat for PALETTE_CELL_HEIGHT rows. m_FinalPaletteImage = QImage(palette.Size(), PALETTE_CELL_HEIGHT, QImage::Format_RGB888);//Create a QImage out of it. memcpy(m_FinalPaletteImage.scanLine(0), v.data(), v.size() * sizeof(v[0]));//Memcpy the data in. - auto pixmap = QPixmap::fromImage(m_FinalPaletteImage);//Create a QPixmap out of the QImage. + QPixmap pixmap(QPixmap::fromImage(m_FinalPaletteImage));//Create a QPixmap out of the QImage. previewPaletteItem->setData(Qt::DecorationRole, pixmap.scaled(QSize(pixmap.width(), palettePreviewTable->rowHeight(0) + 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));//Set the pixmap on the palette tab. m_Fractorium->SetPaletteTableItem(&pixmap, m_Fractorium->ui.XformPaletteRefTable, m_Fractorium->m_PaletteRefItem, 0, 0);//Set the palette ref table on the xforms | color tab. auto previewNameItem = palettePreviewTable->item(0, 0); @@ -287,7 +287,7 @@ void Fractorium::OnPaletteRandomSelectButtonClicked(bool checked) /// void Fractorium::OnPaletteRandomAdjustButtonClicked(bool checked) { - QTIsaac* gRand = QTIsaac::GlobalRand.get(); + auto gRand = QTIsaac::GlobalRand.get(); m_PaletteHueSpin->setValue(-180 + gRand->Rand(361)); m_PaletteSaturationSpin->setValue(-50 + gRand->Rand(101));//Full range of these leads to bad palettes, so clamp range. m_PaletteBrightnessSpin->setValue(-50 + gRand->Rand(101)); diff --git a/Source/Fractorium/FractoriumParams.cpp b/Source/Fractorium/FractoriumParams.cpp index 891e96e..f3e3d3f 100644 --- a/Source/Fractorium/FractoriumParams.cpp +++ b/Source/Fractorium/FractoriumParams.cpp @@ -565,7 +565,7 @@ void FractoriumEmberController::FillParamTablesAndPalette() template void FractoriumEmberController::ParamsToEmber(Ember& ember) { - QColor color = m_Fractorium->ui.ColorTable->item(5, 1)->backgroundColor(); + auto color = m_Fractorium->ui.ColorTable->item(5, 1)->backgroundColor(); ember.m_Brightness = m_Fractorium->m_BrightnessSpin->value();//Color. ember.m_Gamma = m_Fractorium->m_GammaSpin->value(); ember.m_GammaThresh = m_Fractorium->m_GammaThresholdSpin->value(); diff --git a/Source/Fractorium/FractoriumRender.cpp b/Source/Fractorium/FractoriumRender.cpp index 2f8e52b..f919c06 100644 --- a/Source/Fractorium/FractoriumRender.cpp +++ b/Source/Fractorium/FractoriumRender.cpp @@ -7,7 +7,7 @@ /// True if running, else false. bool FractoriumEmberControllerBase::RenderTimerRunning() { - return m_RenderTimer && m_RenderTimer->isActive(); + return m_RenderTimer->isActive(); } /// @@ -16,12 +16,9 @@ bool FractoriumEmberControllerBase::RenderTimerRunning() /// void FractoriumEmberControllerBase::StartRenderTimer() { - if (m_RenderTimer) - { - UpdateRender(); - m_RenderTimer->start(); - m_RenderElapsedTimer.Tic(); - } + UpdateRender(); + m_RenderTimer->start(); + m_RenderElapsedTimer.Tic(); } /// @@ -33,12 +30,8 @@ void FractoriumEmberControllerBase::StartRenderTimer() void FractoriumEmberControllerBase::DelayedStartRenderTimer() { DeleteRenderer(); - - if (m_RenderRestartTimer) - { - m_RenderRestartTimer->setSingleShot(true); - m_RenderRestartTimer->start(300);//Will stop the timer if it's already running, and start again. - } + m_RenderRestartTimer->setSingleShot(true); + m_RenderRestartTimer->start(300);//Will stop the timer if it's already running, and start again. } /// @@ -48,8 +41,7 @@ void FractoriumEmberControllerBase::DelayedStartRenderTimer() /// True to block, else false. void FractoriumEmberControllerBase::StopRenderTimer(bool wait) { - if (m_RenderTimer) - m_RenderTimer->stop(); + m_RenderTimer->stop(); if (m_Renderer.get()) m_Renderer->Abort(); @@ -130,12 +122,11 @@ void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, c if (filename != "") { bool b = false; - uint i, j; byte* data = nullptr; vector vecRgb; QFileInfo fileInfo(filename); QString suffix = fileInfo.suffix(); - FractoriumSettings* settings = m_Fractorium->m_Settings; + auto settings = m_Fractorium->m_Settings; //Ensure dimensions are valid. if (pixels.size() < (width * height * channels * bpc)) @@ -183,13 +174,11 @@ void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, c /// The action for the renderer to take void FractoriumEmberControllerBase::AddProcessAction(eProcessAction action) { - m_Cs.Enter(); + rlg l(m_Cs); m_ProcessActions.push_back(action); if (m_Renderer.get()) m_Renderer->Abort(); - - m_Cs.Leave(); } /// @@ -200,7 +189,7 @@ void FractoriumEmberControllerBase::AddProcessAction(eProcessAction action) /// The most significant processing action desired eProcessAction FractoriumEmberControllerBase::CondenseAndClearProcessActions() { - m_Cs.Enter(); + rlg l(m_Cs); auto action = eProcessAction::NOTHING; for (auto a : m_ProcessActions) @@ -208,7 +197,6 @@ eProcessAction FractoriumEmberControllerBase::CondenseAndClearProcessActions() action = a; m_ProcessActions.clear(); - m_Cs.Leave(); return action; } @@ -266,7 +254,7 @@ template bool FractoriumEmberController::SyncSizes() { bool changed = false; - GLWidget* gl = m_Fractorium->ui.GLDisplay; + auto gl = m_Fractorium->ui.GLDisplay; RendererCL* rendererCL = nullptr; if (!m_GLController->SizesMatch()) @@ -296,7 +284,7 @@ bool FractoriumEmberController::Render() { m_Rendering = true; bool success = true; - GLWidget* gl = m_Fractorium->ui.GLDisplay; + auto gl = m_Fractorium->ui.GLDisplay; RendererCL* rendererCL = nullptr; eProcessAction qualityAction, action; //Quality is the only parameter we update inside the timer. @@ -403,10 +391,10 @@ bool FractoriumEmberController::Render() //Rendering has finished, update final stats. if (ProcessState() == eProcessState::ACCUM_DONE) { - EmberStats stats = m_Renderer->Stats(); - QString iters = ToString(stats.m_Iters); - QString scaledQuality = ToString(uint(m_Renderer->ScaledQuality())); - string renderTime = m_RenderElapsedTimer.Format(m_RenderElapsedTimer.Toc()); + auto stats = m_Renderer->Stats(); + auto iters = ToString(stats.m_Iters); + auto scaledQuality = ToString(uint(m_Renderer->ScaledQuality())); + auto renderTime = m_RenderElapsedTimer.Format(m_RenderElapsedTimer.Toc()); m_Fractorium->m_ProgressBar->setValue(100); //Only certain stats can be reported with OpenCL. @@ -417,8 +405,8 @@ bool FractoriumEmberController::Render() else { double percent = double(stats.m_Badvals) / double(stats.m_Iters); - QString badVals = ToString(stats.m_Badvals); - QString badPercent = QLocale::system().toString(percent * 100, 'f', 2); + auto badVals = ToString(stats.m_Badvals); + auto badPercent = QLocale::system().toString(percent * 100, 'f', 2); m_Fractorium->m_RenderStatusLabel->setText("Iters: " + iters + ". Scaled quality: " + scaledQuality + ". Bad values: " + badVals + " (" + badPercent + "%). Total time: " + QString::fromStdString(renderTime) + "."); } @@ -428,13 +416,18 @@ bool FractoriumEmberController::Render() } else if (m_EditState == eEditUndoState::REGULAR_EDIT)//Regular edit, just add to the end of the undo list. { - m_UndoList.push_back(m_Ember); - m_UndoIndex = m_UndoList.size() - 1; - m_Fractorium->ui.ActionUndo->setEnabled(m_UndoList.size() > 1); - m_Fractorium->ui.ActionRedo->setEnabled(false); + auto btn = QApplication::mouseButtons(); - if (m_UndoList.size() >= UNDO_SIZE) - m_UndoList.pop_front(); + if (!btn.testFlag(Qt::LeftButton) && !btn.testFlag(Qt::RightButton) && !btn.testFlag(Qt::MiddleButton)) + { + m_UndoList.push_back(m_Ember); + m_UndoIndex = m_UndoList.size() - 1; + m_Fractorium->ui.ActionUndo->setEnabled(m_UndoList.size() > 1); + m_Fractorium->ui.ActionRedo->setEnabled(false); + + if (m_UndoList.size() >= UNDO_SIZE) + m_UndoList.pop_front(); + } } else if (!m_LastEditWasUndoRedo && m_UndoIndex < m_UndoList.size() - 1)//They were anywhere but the end of the undo list, then did a manual edit, so clear the undo list. { @@ -459,9 +452,6 @@ bool FractoriumEmberController::Render() if (m_FinalImage.size() == m_Renderer->FinalBufferSize())//Make absolutely sure the correct amount of data is passed. gl->update(); - //gl->repaint(); - //m_Fractorium->update(); - //m_Fractorium->ui.GLParentScrollArea->update(); //Uncomment for debugging kernel build and execution errors. //m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo())); //if (rendererCL) @@ -474,7 +464,7 @@ bool FractoriumEmberController::Render() } else//Something went very wrong, show error report. { - vector errors = m_Renderer->ErrorReport(); + auto errors = m_Renderer->ErrorReport(); success = false; m_FailedRenders++; m_Fractorium->m_RenderStatusLabel->setText("Rendering failed, see info tab. Try changing parameters."); @@ -503,7 +493,6 @@ bool FractoriumEmberController::Render() if (ProcessState() == eProcessState::ACCUM_DONE) QThread::msleep(1); - //QApplication::processEvents(); m_Rendering = false; return success; } @@ -520,8 +509,8 @@ template bool FractoriumEmberController::CreateRenderer(eRendererType renderType, const vector>& devices, bool shared) { bool ok = true; - FractoriumSettings* s = m_Fractorium->m_Settings; - GLWidget* gl = m_Fractorium->ui.GLDisplay; + auto s = m_Fractorium->m_Settings; + auto gl = m_Fractorium->ui.GLDisplay; if (!m_Renderer.get() || (m_Renderer->RendererType() != renderType) || !Equal(m_Devices, devices)) { @@ -691,6 +680,7 @@ bool Fractorium::CreateControllerFromOptions() //First check if a controller has already been created, and if so, save its embers and gracefully shut it down. if (m_Controller.get()) { + 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 //m_Controller->CopyEmber(ed); diff --git a/Source/Fractorium/FractoriumXaos.cpp b/Source/Fractorium/FractoriumXaos.cpp index 859f32b..3bb724b 100644 --- a/Source/Fractorium/FractoriumXaos.cpp +++ b/Source/Fractorium/FractoriumXaos.cpp @@ -48,35 +48,6 @@ void FractoriumEmberController::FillXaos() m_Fractorium->ui.XaosTableView->resizeColumnsToContents(); } -/// -/// Create and return a xaos name string. -/// -/// The index of the xform whose xaos will be used -/// The xaos name string -template -QString FractoriumEmberController::MakeXaosNameString(uint i) -{ - auto xform = m_Ember.GetXform(i); - QString name; - //if (xform) - //{ - // int indexPlus1 = m_Ember.GetXformIndex(xform) + 1;//GUI is 1 indexed to avoid confusing the user. - // int curr = m_Fractorium->ui.CurrentXformCombo->currentIndex() + 1; - // - // if (indexPlus1 != -1) - // { - // if (m_Fractorium->ui.XaosToRadio->isChecked()) - // name = QString("From ") + ToString(curr) + QString(" To ") + ToString(indexPlus1); - // else - // name = QString("From ") + ToString(indexPlus1) + QString(" To ") + ToString(curr); - // - // //if (xform->m_Name != "") - // // name = name + " (" + QString::fromStdString(xform->m_Name) + ")"; - // } - //} - return name; -} - /// /// Set the xaos value. /// Called when any xaos spinner is changed. @@ -93,13 +64,13 @@ void FractoriumEmberController::XaosChanged(int x, int y, double val) auto newVal = TruncPrecision(val, XAOS_PREC);//Sometimes 0 comes in as a very small number, so round. if (auto xform = m_Ember.GetXform(x)) - if (!IsClose(newVal, xform->Xaos(y), 1e-7)) + if (!IsClose(newVal, xform->Xaos(y), T(1e-7))) Update([&] { xform->SetXaos(y, newVal); }); } void Fractorium::OnXaosChanged(double d) { - if (auto* senderSpinBox = qobject_cast(this->sender())) + if (auto senderSpinBox = qobject_cast(this->sender())) { auto p = senderSpinBox->property("tableindex").toPoint(); m_Controller->XaosChanged(p.x(), p.y(), d); diff --git a/Source/Fractorium/FractoriumXformsAffine.cpp b/Source/Fractorium/FractoriumXformsAffine.cpp index ab131cb..f13cc1f 100644 --- a/Source/Fractorium/FractoriumXformsAffine.cpp +++ b/Source/Fractorium/FractoriumXformsAffine.cpp @@ -364,7 +364,7 @@ void FractoriumEmberController::RotateXformsByAngle(double angle, bool pre) UpdateXform([&] (Xform* xform) { auto affine = pre ? &xform->m_Affine : &xform->m_Post; - affine->Rotate(angle); + affine->Rotate(angle * DEG_2_RAD_T); }, eXformUpdate::UPDATE_SELECTED); FillAffineWithXform(CurrentXform(), pre); } @@ -595,7 +595,7 @@ template void FractoriumEmberController::FillAffineWithXform(Xform* xform, bool pre) { DoubleSpinBox** spinners = pre ? m_Fractorium->m_PreSpins : m_Fractorium->m_PostSpins; - const Affine2D& affine = pre ? xform->m_Affine : xform->m_Post; + auto& affine = pre ? xform->m_Affine : xform->m_Post; if (m_Fractorium->ui.PolarAffineCheckBox->isChecked()) { diff --git a/Source/Fractorium/FractoriumXformsColor.cpp b/Source/Fractorium/FractoriumXformsColor.cpp index b9f4f80..92a61ff 100644 --- a/Source/Fractorium/FractoriumXformsColor.cpp +++ b/Source/Fractorium/FractoriumXformsColor.cpp @@ -47,7 +47,15 @@ void FractoriumEmberController::XformColorIndexChanged(double d, bool updateR scroll->blockSignals(true); scroll->setValue(scrollVal); scroll->blockSignals(false); - SetCurrentXformColorIndex(d, updateRender); + m_Fractorium->ui.XformColorIndexTable->item(0, 0)->setBackgroundColor(ColorIndexToQColor(d));//Grab the current color from the index and assign it to the first cell of the first table. + + if (updateRender)//False when just updating GUI, true when in response to a GUI change so update values and reset renderer. + { + UpdateXform([&](Xform* xform) + { + xform->m_ColorX = Clamp(d, 0, 1); + }, eXformUpdate::UPDATE_SELECTED, updateRender); + } } void Fractorium::OnXformColorIndexChanged(double d) { OnXformColorIndexChanged(d, true); } @@ -135,7 +143,7 @@ void Fractorium::OnSoloXformCheckBoxStateChanged(int state) /// Ignored void Fractorium::OnXformRefPaletteResized(int logicalIndex, int oldSize, int newSize) { - QPixmap pixmap = QPixmap::fromImage(m_Controller->FinalPaletteImage()); + QPixmap pixmap(QPixmap::fromImage(m_Controller->FinalPaletteImage())); SetPaletteTableItem(&pixmap, ui.XformPaletteRefTable, m_PaletteRefItem, 0, 0); } @@ -204,22 +212,6 @@ QColor FractoriumEmberController::ColorIndexToQColor(double d) return QColor::fromRgb(rgb); } -/// -/// Set the selected xforms color index to the passed in value. -/// Set the color cell in the palette ref table. -/// -/// The index value to set, 0-1. -template -void FractoriumEmberController::SetCurrentXformColorIndex(double d, bool updateRender) -{ - UpdateXform([&] (Xform* xform) - { - xform->m_ColorX = Clamp(d, 0, 1); - //Grab the current color from the index and assign it to the first cell of the first table. - m_Fractorium->ui.XformColorIndexTable->item(0, 0)->setBackgroundColor(ColorIndexToQColor(xform->m_ColorX)/*QColor::fromRgb(rgb)*/); - }, eXformUpdate::UPDATE_SELECTED, updateRender); -} - /// /// Set the points in the curves control to the values of the curve points in the current ember. /// diff --git a/Source/Fractorium/FractoriumXformsSelect.cpp b/Source/Fractorium/FractoriumXformsSelect.cpp index 1072e53..ae2d9ef 100644 --- a/Source/Fractorium/FractoriumXformsSelect.cpp +++ b/Source/Fractorium/FractoriumXformsSelect.cpp @@ -9,7 +9,6 @@ void Fractorium::InitXformsSelectUI() m_XformsSelectionLayout = (QFormLayout*)ui.XformsSelectGroupBoxScrollAreaWidget->layout(); connect(ui.XformsSelectAllButton, SIGNAL(clicked(bool)), this, SLOT(OnXformsSelectAllButtonClicked(bool)), Qt::QueuedConnection); connect(ui.XformsSelectNoneButton, SIGNAL(clicked(bool)), this, SLOT(OnXformsSelectNoneButtonClicked(bool)), Qt::QueuedConnection); - ClearXformsSelections(); } @@ -17,13 +16,13 @@ void Fractorium::InitXformsSelectUI() /// Check all of the xform selection checkboxes. /// /// Ignored -void Fractorium::OnXformsSelectAllButtonClicked(bool checked) { ForEachXformCheckbox([&](int i, QCheckBox* w) { w->setChecked(true); }); } +void Fractorium::OnXformsSelectAllButtonClicked(bool checked) { ForEachXformCheckbox([&](int i, QCheckBox * w) { w->setChecked(true); }); } /// /// Uncheck all of the xform selection checkboxes. /// /// Ignored -void Fractorium::OnXformsSelectNoneButtonClicked(bool checked) { ForEachXformCheckbox([&](int i, QCheckBox* w) { w->setChecked(false); }); } +void Fractorium::OnXformsSelectNoneButtonClicked(bool checked) { ForEachXformCheckbox([&](int i, QCheckBox * w) { w->setChecked(false); }); } /// /// Clear all of the dynamically created xform checkboxes. @@ -31,7 +30,6 @@ void Fractorium::OnXformsSelectNoneButtonClicked(bool checked) { ForEachXformChe void Fractorium::ClearXformsSelections() { QLayoutItem* child = nullptr; - m_XformSelections.clear(); m_XformsSelectionLayout->blockSignals(true); @@ -95,9 +93,9 @@ void Fractorium::ForEachXformCheckbox(std::function func) template bool FractoriumEmberController::XformCheckboxAt(int i, std::function func) { - if (QLayoutItem* child = m_Fractorium->m_XformsSelectionLayout->itemAt(i)) + if (auto child = m_Fractorium->m_XformsSelectionLayout->itemAt(i)) { - if (auto* w = qobject_cast(child->widget())) + if (auto w = qobject_cast(child->widget())) { func(w); return true; diff --git a/Source/Fractorium/FractoriumXformsVariations.cpp b/Source/Fractorium/FractoriumXformsVariations.cpp index b759417..8a9493e 100644 --- a/Source/Fractorium/FractoriumXformsVariations.cpp +++ b/Source/Fractorium/FractoriumXformsVariations.cpp @@ -171,11 +171,11 @@ void FractoriumEmberController::SetupVariationTree() template void FractoriumEmberController::ClearVariationsTree() { - QTreeWidget* tree = m_Fractorium->ui.VariationsTree; + auto tree = m_Fractorium->ui.VariationsTree; for (int i = 0; i < tree->topLevelItemCount(); i++) { - QTreeWidgetItem* item = tree->topLevelItem(i); + auto item = tree->topLevelItem(i); auto* spinBox = dynamic_cast(tree->itemWidget(item, 1)); spinBox->SetValueStealth(0); @@ -189,7 +189,7 @@ void FractoriumEmberController::ClearVariationsTree() /// /// Copy the value of a variation or param spinner to its corresponding value -/// in the currently selected xform. +/// in the selected xforms. /// Called when any spinner in the variations tree is changed. /// Resets the rendering process. /// @@ -197,79 +197,82 @@ void FractoriumEmberController::ClearVariationsTree() template void FractoriumEmberController::VariationSpinBoxValueChanged(double d)//Would be awesome to make this work for all.//TODO { + bool update = false; auto objSender = m_Fractorium->sender(); auto tree = m_Fractorium->ui.VariationsTree; auto sender = dynamic_cast(objSender); auto xform = m_Ember.GetTotalXform(m_Fractorium->ui.CurrentXformCombo->currentIndex());//Will retrieve normal xform or final if needed. - if (sender && xform) + if (sender) { - auto var = m_VariationList.GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only. - auto parVar = dynamic_cast*>(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(); - bool isParam = parVar && sender->IsParam(); - - if (isParam) + UpdateXform([&](Xform* xform) { - //Do not take action if the xform doesn't contain the variation which this param is part of. - if (ParametricVariation* xformParVar = dynamic_cast*>(xformVar))//The parametric cast of the xform's variation. - { - if (xformParVar->SetParamVal(sender->ParamName().c_str(), d)) - { - UpdateRender(); - } - } - } - else - { - //If they spun down to zero, and it wasn't a parameter item, - //and the current xform contained the variation, then remove the variation. - if (IsNearZero(d)) - { - if (xformVar) - xform->DeleteVariationById(var->VariationId()); + auto var = m_VariationList.GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only. + auto parVar = dynamic_cast*>(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(); + bool isParam = parVar && sender->IsParam(); - widgetItem->setBackgroundColor(0, QColor(255, 255, 255));//Ensure background is always white if weight goes to zero. + if (isParam) + { + //Do not take action if the xform doesn't contain the variation which this param is part of. + if (ParametricVariation* xformParVar = dynamic_cast*>(xformVar))//The parametric cast of the xform's variation. + if (xformParVar->SetParamVal(sender->ParamName().c_str(), d)) + update = true; } else { - if (xformVar)//The xform already contained this variation, which means they just went from a non-zero weight to another non-zero weight (the simple case). + //If they spun down to zero, and it wasn't a parameter item, + //and the current xform contained the variation, then remove the variation. + if (IsNearZero(d)) { - xformVar->m_Weight = d; + if (xformVar) + xform->DeleteVariationById(var->VariationId()); + + widgetItem->setBackgroundColor(0, QColor(255, 255, 255));//Ensure background is always white if weight goes to zero. } else { - //If the item wasn't a param and the xform did not contain this variation, - //it means they went from zero to a non-zero weight, so add a new copy of this xform. - auto newVar = var->Copy();//Create a new one with default values. - newVar->m_Weight = d; - xform->AddVariation(newVar); - widgetItem->setBackgroundColor(0, QColor(200, 200, 200));//Set background to gray when a variation has non-zero weight in this xform. - - //If they've added a new parametric variation, then grab the values currently in the spinners - //for the child parameters and assign them to the newly added variation. - if (parVar) + if (xformVar)//The xform already contained this variation, which means they just went from a non-zero weight to another non-zero weight (the simple case). { - auto newParVar = dynamic_cast*>(newVar); + xformVar->m_Weight = d; + } + else + { + //If the item wasn't a param and the xform did not contain this variation, + //it means they went from zero to a non-zero weight, so add a new copy of this xform. + auto newVar = var->Copy();//Create a new one with default values. + newVar->m_Weight = d; + xform->AddVariation(newVar); + widgetItem->setBackgroundColor(0, QColor(200, 200, 200));//Set background to gray when a variation has non-zero weight in this xform. - for (int i = 0; i < widgetItem->childCount(); i++)//Iterate through all of the children, which will be the params. + //If they've added a new parametric variation, then grab the values currently in the spinners + //for the child parameters and assign them to the newly added variation. + if (parVar) { - auto childItem = widgetItem->child(i);//Get the child. - auto itemWidget = tree->itemWidget(childItem, 1);//Get the widget for the child. + auto newParVar = dynamic_cast*>(newVar); - if (auto spinBox = dynamic_cast(itemWidget))//Cast the widget to the VariationTreeDoubleSpinBox type. + for (int i = 0; i < widgetItem->childCount(); i++)//Iterate through all of the children, which will be the params. { - string s = childItem->text(0).toStdString();//Use the name of the child, and the value of the spinner widget to assign the param. - newParVar->SetParamVal(s.c_str(), spinBox->value()); + auto childItem = widgetItem->child(i);//Get the child. + auto itemWidget = tree->itemWidget(childItem, 1);//Get the widget for the child. + + if (auto spinBox = dynamic_cast(itemWidget))//Cast the widget to the VariationTreeDoubleSpinBox type. + { + string s = childItem->text(0).toStdString();//Use the name of the child, and the value of the spinner widget to assign the param. + newParVar->SetParamVal(s.c_str(), spinBox->value()); + } } } } } - } + update = true; + } + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false); + + if (update) UpdateRender(); - } } } diff --git a/Source/Fractorium/GLEmberController.cpp b/Source/Fractorium/GLEmberController.cpp index 71efbcf..4a0ff1c 100644 --- a/Source/Fractorium/GLEmberController.cpp +++ b/Source/Fractorium/GLEmberController.cpp @@ -103,6 +103,20 @@ T GLEmberController::CalcRotation() return rotStart - rot; } +/// +/// Snap the passed in world cartesian coordinate to the grid for rotation, scale or translation. +/// +/// The world cartesian coordinate to be snapped +/// The snapped world cartesian coordinate +template +typename v2T GLEmberController::SnapToGrid(v2T& vec) +{ + v2T ret; + ret.x = glm::round(vec.x / GridStep) * GridStep; + ret.y = glm::round(vec.y / GridStep) * GridStep; + return ret; +} + /// /// Snap the passed in world cartesian coordinate to the grid for rotation, scale or translation. /// @@ -135,8 +149,8 @@ typename v3T GLEmberController::SnapToNormalizedAngle(v3T& vec, uint division for (uint i = 0; i < divisions; i++) { theta = 2.0 * M_PI * T(i) / T(divisions); - c.x = cos(theta); - c.y = sin(theta); + c.x = std::cos(theta); + c.y = std::sin(theta); rsq = glm::distance(vec, c); if (rsq < bestRsq) @@ -220,7 +234,7 @@ void GLEmberController::MultMatrix(tmat4x4& mat) template void GLEmberController::QueryMatrices(bool print) { - RendererBase* renderer = m_FractoriumEmberController->Renderer(); + auto renderer = m_FractoriumEmberController->Renderer(); if (renderer) { @@ -242,13 +256,13 @@ void GLEmberController::QueryMatrices(bool print) if (print) { for (size_t i = 0; i < 4; i++) - qDebug() << "Viewport[" << i << "] = " << m_Viewport[i] << endl; + qDebug() << "Viewport[" << i << "] = " << m_Viewport[i] << "\n"; for (size_t i = 0; i < 16; i++) - qDebug() << "Modelview[" << i << "] = " << glm::value_ptr(m_Modelview)[i] << endl; + qDebug() << "Modelview[" << i << "] = " << glm::value_ptr(m_Modelview)[i] << "\n"; for (size_t i = 0; i < 16; i++) - qDebug() << "Projection[" << i << "] = " << glm::value_ptr(m_Projection)[i] << endl; + qDebug() << "Projection[" << i << "] = " << glm::value_ptr(m_Projection)[i] << "\n"; } } } diff --git a/Source/Fractorium/GLEmberController.h b/Source/Fractorium/GLEmberController.h index ef38353..3ab0537 100644 --- a/Source/Fractorium/GLEmberController.h +++ b/Source/Fractorium/GLEmberController.h @@ -109,9 +109,9 @@ public: T CalcScale(); T CalcRotation(); - Affine2D CalcDragXAxis(); - Affine2D CalcDragYAxis(); - Affine2D CalcDragTranslation(); + void CalcDragXAxis(); + void CalcDragYAxis(); + void CalcDragTranslation(); void SetEmber(Ember* ember); void SetSelectedXform(Xform* xform); @@ -120,6 +120,7 @@ public: bool CheckXformHover(Xform* xform, v3T& glCoords, T& bestDist, bool pre, bool post); private: + v2T SnapToGrid(v2T& vec); v3T SnapToGrid(v3T& vec); v3T SnapToNormalizedAngle(v3T& vec, uint divisions); v3T WindowToWorld(v3T& v, bool flip); diff --git a/Source/Fractorium/GLWidget.cpp b/Source/Fractorium/GLWidget.cpp index f220d51..448422a 100644 --- a/Source/Fractorium/GLWidget.cpp +++ b/Source/Fractorium/GLWidget.cpp @@ -63,8 +63,8 @@ void GLWidget::DrawQuad() glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - RendererBase* renderer = m_Fractorium->m_Controller->Renderer(); - vector* finalImage = m_Fractorium->m_Controller->FinalImage(); + auto renderer = m_Fractorium->m_Controller->Renderer(); + auto finalImage = m_Fractorium->m_Controller->FinalImage(); //Ensure all allocation has taken place first. if (m_OutputTexID != 0 && finalImage && !finalImage->empty()) @@ -123,14 +123,14 @@ bool GLEmberControllerBase::Allocate(bool force) { return m_GL->Allocate(force); /// Helpers to set/get/clear which keys are pressed while dragging. /// /// bool -bool GLEmberControllerBase::GetAlt() { return (m_DragModifier & et(eDragModifier::DragModAlt)) == et(eDragModifier::DragModAlt); } -bool GLEmberControllerBase::GetShift() { return (m_DragModifier & et(eDragModifier::DragModShift)) == et(eDragModifier::DragModShift); } -bool GLEmberControllerBase::GetControl() { return (m_DragModifier & et(eDragModifier::DragModControl)) == et(eDragModifier::DragModControl); } -void GLEmberControllerBase::SetAlt() { m_DragModifier |= et(eDragModifier::DragModAlt); } -void GLEmberControllerBase::SetShift() { m_DragModifier |= et(eDragModifier::DragModShift); } -void GLEmberControllerBase::SetControl() { m_DragModifier |= et(eDragModifier::DragModControl); } -void GLEmberControllerBase::ClearAlt() { m_DragModifier &= ~et(eDragModifier::DragModAlt); } -void GLEmberControllerBase::ClearShift() { m_DragModifier &= ~et(eDragModifier::DragModShift); } +bool GLEmberControllerBase::GetAlt() { return (m_DragModifier & et(eDragModifier::DragModAlt)) == et(eDragModifier::DragModAlt); } +bool GLEmberControllerBase::GetShift() { return (m_DragModifier & et(eDragModifier::DragModShift)) == et(eDragModifier::DragModShift); } +bool GLEmberControllerBase::GetControl() { return (m_DragModifier & et(eDragModifier::DragModControl)) == et(eDragModifier::DragModControl); } +void GLEmberControllerBase::SetAlt() { m_DragModifier |= et(eDragModifier::DragModAlt); } +void GLEmberControllerBase::SetShift() { m_DragModifier |= et(eDragModifier::DragModShift); } +void GLEmberControllerBase::SetControl() { m_DragModifier |= et(eDragModifier::DragModControl); } +void GLEmberControllerBase::ClearAlt() { m_DragModifier &= ~et(eDragModifier::DragModAlt); } +void GLEmberControllerBase::ClearShift() { m_DragModifier &= ~et(eDragModifier::DragModShift); } void GLEmberControllerBase::ClearControl() { m_DragModifier &= ~et(eDragModifier::DragModControl); } /// @@ -214,9 +214,9 @@ void GLWidget::paintGL() //Ensure there is a renderer and that it's supposed to be drawing, signified by the running timer. if (controller && controller->Renderer()) { - RendererBase* renderer = controller->Renderer(); + auto renderer = controller->Renderer(); m_Drawing = true; - controller->GLController()->DrawImage(); + GLController()->DrawImage(); //Affine drawing. bool pre = m_Fractorium->ui.PreAffineGroupBox->isChecked(); bool post = m_Fractorium->ui.PostAffineGroupBox->isChecked(); @@ -431,7 +431,7 @@ void GLEmberController::MousePress(QMouseEvent* e) m_BoundsDown.x = renderer->LowerLeftY(false); m_BoundsDown.y = renderer->UpperRightX(false); m_BoundsDown.z = renderer->UpperRightY(false); - Qt::KeyboardModifiers mod = e->modifiers(); + auto mod = e->modifiers(); if (mod.testFlag(Qt::ShiftModifier)) SetShift(); @@ -455,11 +455,11 @@ void GLEmberController::MousePress(QMouseEvent* e) m_DragSrcTransform = Affine2D(m_AffineType == eAffineType::AffinePre ? m_SelectedXform->m_Affine : m_SelectedXform->m_Post);//Copy the affine of the xform that was selected. //The user has selected an xform by clicking on it, so update the main GUI by selecting this xform in the combo box. m_Fractorium->CurrentXform(xformIndex);//Must do this first so UpdateXform() below properly grabs the current plus any selected. - //m_DragSrcTransforms.clear(); - //m_FractoriumEmberController->UpdateXform([&](Xform* xform) - //{ - // m_DragSrcTransforms.push_back(m_AffineType == eAffineType::AffinePre ? xform->m_Affine : xform->m_Post); - //}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Don't update renderer here. + m_DragSrcTransforms.clear(); + m_FractoriumEmberController->UpdateXform([&](Xform* xform) + { + m_DragSrcTransforms.push_back(m_AffineType == eAffineType::AffinePre ? xform->m_Affine : xform->m_Post); + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Don't update renderer here. m_DragHandlePos = m_HoverHandlePos;//The location in local coordinates of the point selected on the spinner, x, y or center. m_DragHandleOffset = m_DragHandlePos - m_MouseWorldPos;//The distance in world coordinates from the point selected to the center of the spinner. m_DragState = eDragState::DragDragging; @@ -505,7 +505,7 @@ void GLWidget::mousePressEvent(QMouseEvent* e) { setFocus();//Must do this so that this window gets keyboard events. - if (GLEmberControllerBase* controller = GLController()) + if (auto controller = GLController()) controller->MousePress(e); QOpenGLWidget::mousePressEvent(e); @@ -538,7 +538,7 @@ void GLWidget::mouseReleaseEvent(QMouseEvent* e) { setFocus();//Must do this so that this window gets keyboard events. - if (GLEmberControllerBase* controller = GLController()) + if (auto controller = GLController()) controller->MouseRelease(e); QOpenGLWidget::mouseReleaseEvent(e); @@ -571,22 +571,13 @@ void GLEmberController::MouseMove(QMouseEvent* e) if (m_SelectedXform && m_DragState == eDragState::DragDragging)//Dragging and affine. { bool pre = m_AffineType == eAffineType::AffinePre; - Affine2D* affine = pre ? &m_SelectedXform->m_Affine : &m_SelectedXform->m_Post;//Determine pre or post affine. if (m_HoverType == eHoverType::HoverTranslation) - { - //m_FractoriumEmberController->UpdateXform([&](Xform* xform) - //{ - // affine = pre ? &xform->m_Affine : &xform->m_Post;//Determine pre or post affine. - // *affine = CalcDragTranslation(); - //}, eXformUpdate::UPDATE_ALL, false);//Don't need to update render for every xform, just do it once below. - *affine = CalcDragTranslation(); - //CalcDragTranslation(); - } + CalcDragTranslation(); else if (m_HoverType == eHoverType::HoverXAxis) - *affine = CalcDragXAxis(); + CalcDragXAxis(); else if (m_HoverType == eHoverType::HoverYAxis) - *affine = CalcDragYAxis(); + CalcDragYAxis(); m_FractoriumEmberController->FillAffineWithXform(m_SelectedXform, pre);//Update the spinners in the affine tab of the main window. m_FractoriumEmberController->UpdateRender();//Restart the rendering process. @@ -598,7 +589,7 @@ void GLEmberController::MouseMove(QMouseEvent* e) Affine2D rotMat; rotMat.C(m_CenterDownX); rotMat.F(m_CenterDownY); - rotMat.Rotate(ember->m_Rotate); + rotMat.Rotate(ember->m_Rotate * DEG_2_RAD_T); v2T v1(x, y); v2T v2 = rotMat.TransformVector(v1); ember->m_CenterX = v2.x; @@ -611,8 +602,7 @@ void GLEmberController::MouseMove(QMouseEvent* e) T scale = CalcScale(); ember->m_Rotate = NormalizeDeg180(m_RotationDown + rot); m_Fractorium->SetRotation(ember->m_Rotate, true); - ember->m_PixelsPerUnit = m_ScaleDown + scale; - m_Fractorium->SetScale(ember->m_PixelsPerUnit);//Will restart the rendering process. + m_Fractorium->SetScale(m_ScaleDown + scale);//Will restart the rendering process. } else { @@ -625,22 +615,12 @@ void GLEmberController::MouseMove(QMouseEvent* e) //In that case, nothing needs to be done. if (UpdateHover(mouseFlipped) == -1) draw = false; - - //auto previousHover = m_HoverXform; - // - //if (UpdateHover(mouseFlipped) == -1) - // m_HoverXform = m_SelectedXform; - // - //if (m_HoverXform == previousHover) - // draw = false; } //Only update if the user was dragging or hovered over a point. //Use repaint() to update immediately for a more responsive feel. if ((m_DragState != eDragState::DragNone) || draw) m_GL->update(); - - //m_GL->repaint(); } /// @@ -651,7 +631,7 @@ void GLWidget::mouseMoveEvent(QMouseEvent* e) { setFocus();//Must do this so that this window gets keyboard events. - if (GLEmberControllerBase* controller = GLController()) + if (auto controller = GLController()) controller->MouseMove(e); QOpenGLWidget::mouseMoveEvent(e); @@ -679,28 +659,12 @@ void GLEmberController::Wheel(QWheelEvent* e) /// The event void GLWidget::wheelEvent(QWheelEvent* e) { - if (GLEmberControllerBase* controller = GLController()) + if (auto controller = GLController()) controller->Wheel(e); //Do not call QOpenGLWidget::wheelEvent(e) because this should only affect the scale and not the position of the scroll bars. } -/// -/// Respond to a resize event which will set the double click default value -/// in the width and height spinners. -/// Note, this does not change the size of the ember being rendered or -/// the OpenGL texture it's being drawn on. -/// -/// The event -//void GLWidget::resizeEvent(QResizeEvent* e) -//{ -// if (m_Fractorium) -// { -// } -// -// QOpenGLWidget::resizeEvent(e); -//} - /// /// Set the dimensions of the drawing area. /// This will be called from the main window's SyncSizes() function. @@ -710,8 +674,6 @@ void GLWidget::wheelEvent(QWheelEvent* e) void GLWidget::SetDimensions(int w, int h) { setFixedSize(w, h); - //resize(w, h); - //m_Fractorium->ui.GLParentScrollAreaContents->setFixedSize(w, h); } /// @@ -817,7 +779,7 @@ bool GLEmberController::SizesMatch() /// A value to scale by, used when locking the affine scale void GLWidget::DrawGrid(double scale) { - RendererBase* renderer = m_Fractorium->m_Controller->Renderer(); + auto renderer = m_Fractorium->m_Controller->Renderer(); float unitX = std::abs(renderer->UpperRightX(false) - renderer->LowerLeftX(false)) / 2.0f; float unitY = std::abs(renderer->UpperRightY(false) - renderer->LowerLeftY(false)) / 2.0f; float rad = std::max(unitX * scale, unitY * scale); @@ -916,10 +878,10 @@ template void GLEmberController::DrawAffine(Xform* xform, bool pre, bool selected) { auto ember = m_FractoriumEmberController->CurrentEmber(); - bool final = ember->IsFinalXform(xform); - int index = ember->GetXformIndex(xform); - size_t size = ember->m_Palette.m_Entries.size(); - v4T color = ember->m_Palette.m_Entries[Clamp(xform->m_ColorX * size, 0, size - 1)]; + auto final = ember->IsFinalXform(xform); + auto index = ember->GetXformIndex(xform); + auto size = ember->m_Palette.m_Entries.size(); + auto color = ember->m_Palette.m_Entries[Clamp(xform->m_ColorX * size, 0, size - 1)]; auto affine = pre ? &xform->m_Affine : &xform->m_Post; //For some incredibly strange reason, even though glm and OpenGL use matrices with a column-major //data layout, nothing will work here unless they are flipped to row major order. This is how it was @@ -968,7 +930,7 @@ void GLWidget::DrawAffineHelper(int index, bool selected, bool pre, bool final, { float px = 1.0f; float py = 0.0f; - QColor col = final ? m_Fractorium->m_FinalXformComboColor : m_Fractorium->m_XformComboColors[index % XFORM_COLOR_COUNT]; + auto col = final ? m_Fractorium->m_FinalXformComboColor : m_Fractorium->m_XformComboColors[index % XFORM_COLOR_COUNT]; glBegin(GL_LINES); //Circle part. @@ -986,8 +948,8 @@ void GLWidget::DrawAffineHelper(int index, bool selected, bool pre, bool final, for (size_t i = 1; i <= 64; i++)//The circle. { float theta = float(M_PI) * 2.0f * float(i % 64) / 64.0f; - float fx = float(cos(theta)); - float fy = float(sin(theta)); + float fx = std::cos(theta); + float fy = std::sin(theta); glVertex2f(px, py); glVertex2f(fx, fy); px = fx; @@ -1214,56 +1176,73 @@ bool GLEmberController::CheckXformHover(Xform* xform, v3T& glCoords, T& be /// /// The new affine transform to be assigned to the selected xform template -Affine2D GLEmberController::CalcDragXAxis() +void GLEmberController::CalcDragXAxis() { - v3T t3, newAxis, newPos; + size_t index = 0; auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent(); - auto result = m_DragSrcTransform; + auto scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked(); + bool pre = m_AffineType == eAffineType::AffinePre; bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt(); - if (worldPivotShiftAlt) - t3 = v3T(0, 0, 0); - else - t3 = v3T(m_DragSrcTransform.O(), 0); - if (GetShift()) { - v3T targetAxis = (m_MouseWorldPos * scale) - t3; - v3T norm = glm::normalize(targetAxis); + v3T snapped = GetControl() ? SnapToNormalizedAngle(m_MouseWorldPos + m_DragHandleOffset, 24) : m_MouseWorldPos + m_DragHandleOffset; + auto startDiff = (v2T(m_MouseDownWorldPos) * scale) - m_DragSrcTransform.O(); + auto endDiff = (v2T(snapped) * scale) - m_DragSrcTransform.O(); + T startAngle = std::atan2(startDiff.y, startDiff.x); + T endAngle = std::atan2(endDiff.y, endDiff.x); + T angle = startAngle - endAngle; + m_FractoriumEmberController->UpdateXform([&](Xform* xform) + { + auto affine = pre ? &xform->m_Affine : &xform->m_Post; + auto srcRotated = m_DragSrcTransforms[index++]; - if (GetControl()) - norm = SnapToNormalizedAngle(norm, 24); + if (worldPivotShiftAlt) + { + srcRotated.X(srcRotated.O() + srcRotated.X()); + srcRotated.O(v2T(0)); + srcRotated.Rotate(angle); + affine->X(srcRotated.X() - affine->O()); + } + else if (GetAlt()) + { + srcRotated.Rotate(angle); + affine->X(srcRotated.X()); + } + else + { + srcRotated.Rotate(angle); + *affine = srcRotated; + } - if (worldPivotShiftAlt) - newAxis = norm * glm::length(m_DragSrcTransform.O() + m_DragSrcTransform.X()); - else - newAxis = norm * glm::length(m_DragSrcTransform.X()); + if (xform == m_FractoriumEmberController->CurrentXform()) + m_DragHandlePos = v3T((affine->O() + affine->X()) * scaleBack, 0); + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Calling code will update renderer. } else { + v3T diff; + if (GetControl()) - newPos = SnapToGrid(m_MouseWorldPos); + diff = SnapToGrid(m_MouseWorldPos + m_DragHandleOffset) - m_MouseDownWorldPos; else - newPos = m_MouseWorldPos + m_DragHandleOffset; + diff = (m_MouseWorldPos + m_DragHandleOffset) - m_MouseDownWorldPos; - newAxis = (newPos * scale) - t3; - } + auto origXPlusOff = v3T(m_DragSrcTransform.X(), 0) + (diff * scale); + m_FractoriumEmberController->UpdateXform([&](Xform* xform) + { + auto affine = pre ? &xform->m_Affine : &xform->m_Post; + auto axis = v3T(m_DragSrcTransforms[index++].X(), 0) + (diff * scale); - if (GetAlt()) - { - if (worldPivotShiftAlt) - result.X(v2T(newAxis) - m_DragSrcTransform.O()); - else - result.X(v2T(newAxis)); - } - else - { - result.RotateScaleXTo(v2T(newAxis)); - } + if (GetAlt()) + affine->X(v2T(origXPlusOff));//Absolute, not ratio. + else + affine->RotateScaleXTo(v2T(axis)); - T scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked(); - m_DragHandlePos = v3T((result.O() + result.X()) * scaleBack, 0); - return result; + if (xform == m_FractoriumEmberController->CurrentXform()) + m_DragHandlePos = v3T((affine->O() + affine->X()) * scaleBack, 0); + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false); + } } /// @@ -1285,56 +1264,73 @@ Affine2D GLEmberController::CalcDragXAxis() /// /// The new affine transform to be assigned to the selected xform template -Affine2D GLEmberController::CalcDragYAxis() +void GLEmberController::CalcDragYAxis() { - v3T t3, newAxis, newPos; + size_t index = 0; auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent(); - auto result = m_DragSrcTransform; + auto scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked(); + bool pre = m_AffineType == eAffineType::AffinePre; bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt(); - if (worldPivotShiftAlt) - t3 = v3T(0, 0, 0); - else - t3 = v3T(m_DragSrcTransform.O(), 0); - if (GetShift()) { - v3T targetAxis = (m_MouseWorldPos * scale) - t3; - v3T norm = glm::normalize(targetAxis); + v3T snapped = GetControl() ? SnapToNormalizedAngle(m_MouseWorldPos + m_DragHandleOffset, 24) : m_MouseWorldPos + m_DragHandleOffset; + auto startDiff = (v2T(m_MouseDownWorldPos) * scale) - m_DragSrcTransform.O(); + auto endDiff = (v2T(snapped) * scale) - m_DragSrcTransform.O(); + T startAngle = std::atan2(startDiff.y, startDiff.x); + T endAngle = std::atan2(endDiff.y, endDiff.x); + T angle = startAngle - endAngle; + m_FractoriumEmberController->UpdateXform([&](Xform* xform) + { + auto affine = pre ? &xform->m_Affine : &xform->m_Post; + auto srcRotated = m_DragSrcTransforms[index++]; - if (GetControl()) - norm = SnapToNormalizedAngle(norm, 24); + if (worldPivotShiftAlt) + { + srcRotated.Y(srcRotated.O() + srcRotated.Y()); + srcRotated.O(v2T(0)); + srcRotated.Rotate(angle); + affine->Y(srcRotated.Y() - affine->O()); + } + else if (GetAlt()) + { + srcRotated.Rotate(angle); + affine->Y(srcRotated.Y()); + } + else + { + srcRotated.Rotate(angle); + *affine = srcRotated; + } - if (worldPivotShiftAlt) - newAxis = norm * glm::length(m_DragSrcTransform.O() + m_DragSrcTransform.Y()); - else - newAxis = norm * glm::length(m_DragSrcTransform.Y()); + if (xform == m_FractoriumEmberController->CurrentXform()) + m_DragHandlePos = v3T((affine->O() + affine->Y()) * scaleBack, 0); + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Calling code will update renderer. } else { + v3T diff; + if (GetControl()) - newPos = SnapToGrid(m_MouseWorldPos); + diff = SnapToGrid(m_MouseWorldPos + m_DragHandleOffset) - m_MouseDownWorldPos; else - newPos = m_MouseWorldPos + m_DragHandleOffset; + diff = (m_MouseWorldPos + m_DragHandleOffset) - m_MouseDownWorldPos; - newAxis = (newPos * scale) - t3; - } + auto origXPlusOff = v3T(m_DragSrcTransform.Y(), 0) + (diff * scale); + m_FractoriumEmberController->UpdateXform([&](Xform* xform) + { + auto affine = pre ? &xform->m_Affine : &xform->m_Post; + auto axis = v3T(m_DragSrcTransforms[index++].Y(), 0) + (diff * scale); - if (GetAlt()) - { - if (worldPivotShiftAlt) - result.Y(v2T(newAxis) - m_DragSrcTransform.O()); - else - result.Y(v2T(newAxis)); - } - else - { - result.RotateScaleYTo(v2T(newAxis)); - } + if (GetAlt()) + affine->Y(v2T(origXPlusOff));//Absolute, not ratio. + else + affine->RotateScaleYTo(v2T(axis)); - T scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked(); - m_DragHandlePos = v3T((result.O() + result.Y()) * scaleBack, 0); - return result; + if (xform == m_FractoriumEmberController->CurrentXform()) + m_DragHandlePos = v3T((affine->O() + affine->Y()) * scaleBack, 0); + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false); + } } /// @@ -1350,58 +1346,65 @@ Affine2D GLEmberController::CalcDragYAxis() /// Control + Shift: Rotate about world center, rotating orientation, snapping to grid. /// All others are the same as local pivot. /// -/// The new affine transform to be assigned to the selected xform template -Affine2D GLEmberController::CalcDragTranslation() +void GLEmberController::CalcDragTranslation() { - v3T newPos; + size_t index = 0; auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent(); - auto result = m_DragSrcTransform; + auto scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked(); bool worldPivotShift = !m_Fractorium->LocalPivot() && GetShift(); + bool pre = m_AffineType == eAffineType::AffinePre; if (GetShift()) { - v3T norm = glm::normalize(m_MouseWorldPos); - - if (GetControl()) - norm = SnapToNormalizedAngle(norm, 12); - - newPos = glm::length(m_DragSrcTransform.O()) * norm; - - if (worldPivotShift) + v3T snapped = GetControl() ? SnapToNormalizedAngle(m_MouseWorldPos, 24) : m_MouseWorldPos; + T startAngle = std::atan2(m_DragSrcTransform.O().y, m_DragSrcTransform.O().x); + T endAngle = std::atan2(snapped.y, snapped.x); + T angle = startAngle - endAngle; + m_FractoriumEmberController->UpdateXform([&](Xform* xform) { - T startAngle = atan2(m_DragSrcTransform.O().y, m_DragSrcTransform.O().x); - T endAngle = atan2(newPos.y, newPos.x); - T angle = startAngle - endAngle; - result.Rotate(angle * RAD_2_DEG); - //RotateXformsByAngle - } + auto affine = pre ? &xform->m_Affine : &xform->m_Post; + auto srcRotated = m_DragSrcTransforms[index++]; + srcRotated.RotateTrans(angle); + + if (worldPivotShift) + { + srcRotated.Rotate(angle); + affine->X(srcRotated.X()); + affine->Y(srcRotated.Y()); + } + + affine->O(srcRotated.O()); + + if (xform == m_FractoriumEmberController->CurrentXform()) + m_DragHandlePos = v3T(srcRotated.O(), 0) * scaleBack; + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Calling code will update renderer. } else { + auto diff = m_MouseWorldPos - m_MouseDownWorldPos; + if (GetControl()) { - newPos = SnapToGrid(m_MouseWorldPos); + m_FractoriumEmberController->UpdateXform([&](Xform* xform) + { + auto affine = pre ? &xform->m_Affine : &xform->m_Post; + auto offset = m_DragSrcTransforms[index++].O() + (scale * v2T(diff)); + auto snapped = SnapToGrid(offset); + affine->O(v2T(snapped.x, snapped.y)); + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false); + m_DragHandlePos = SnapToGrid(m_MouseWorldPos); } else { - newPos = m_MouseWorldPos + m_DragHandleOffset; - //bool pre = m_AffineType == eAffineType::AffinePre; - //size_t index = 0; - //newPos = m_MouseWorldPos; - //auto diff = m_MouseWorldPos - m_MouseDownWorldPos; - //m_FractoriumEmberController->UpdateXform([&](Xform* xform) - //{ - // auto affine = pre ? &xform->m_Affine : &xform->m_Post;//Determine pre or post affine. - // affine->O(m_DragSrcTransforms[index++].O() + v2T(diff)); - //}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Don't need to update render for every xform, just do it once below. + m_FractoriumEmberController->UpdateXform([&](Xform* xform) + { + auto affine = pre ? &xform->m_Affine : &xform->m_Post; + affine->O(m_DragSrcTransforms[index++].O() + (scale * v2T(diff))); + }, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false); + m_DragHandlePos = m_MouseWorldPos; } } - - T scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked(); - result.O(v2T(newPos * scale)); - m_DragHandlePos = newPos; - return result; } /// diff --git a/Source/Fractorium/GLWidget.h b/Source/Fractorium/GLWidget.h index ef59552..f412669 100644 --- a/Source/Fractorium/GLWidget.h +++ b/Source/Fractorium/GLWidget.h @@ -62,7 +62,6 @@ protected: virtual void mouseReleaseEvent(QMouseEvent* e) override; virtual void mouseMoveEvent(QMouseEvent* e) override; virtual void wheelEvent(QWheelEvent* e) override; - //virtual void resizeEvent(QResizeEvent* e) override; private: void SetDimensions(int w, int h); diff --git a/Source/Fractorium/SpinBox.cpp b/Source/Fractorium/SpinBox.cpp index 13d05a4..7adb580 100644 --- a/Source/Fractorium/SpinBox.cpp +++ b/Source/Fractorium/SpinBox.cpp @@ -1,7 +1,7 @@ #include "FractoriumPch.h" #include "SpinBox.h" -QTimer SpinBox::m_Timer; +QTimer SpinBox::s_Timer; /// /// Constructor that passes parent to the base and sets up height and step. @@ -118,17 +118,16 @@ void SpinBox::OnTimeout() //qDebug() << "Shift pressed"; scale = 0.001; } - /*else if (ctrl) - { - qDebug() << "Control pressed"; - scale = 0.01; - }*/ + /* else if (ctrl) + { + qDebug() << "Control pressed"; + scale = 0.01; + }*/ else scale = 0.01; val = d + (distance * amount * scale); setValue(int(val)); - //qDebug() << "Timer on, orig val: " << d << ", new val: " << val << ", distance " << distance; } @@ -143,9 +142,9 @@ bool SpinBox::eventFilter(QObject* o, QEvent* e) QMouseEvent* me = dynamic_cast(e); if (isEnabled() && - me && - me->type() == QMouseEvent::MouseButtonPress && - me->button() == Qt::RightButton) + me && + me->type() == QMouseEvent::MouseButtonPress && + me->button() == Qt::RightButton) { m_MouseDownPoint = m_MouseMovePoint = me->pos(); StartTimer(); @@ -172,18 +171,18 @@ bool SpinBox::eventFilter(QObject* o, QEvent* e) // } } else if (isEnabled() && - me && - me->type() == QMouseEvent::MouseButtonRelease && - me->button() == Qt::RightButton) + me && + me->type() == QMouseEvent::MouseButtonRelease && + me->button() == Qt::RightButton) { StopTimer(); m_MouseDownPoint = m_MouseMovePoint = me->pos(); //qDebug() << "Right mouse up"; } else if (isEnabled() && - me && - me->type() == QMouseEvent::MouseMove && - QGuiApplication::mouseButtons() & Qt::RightButton) + me && + me->type() == QMouseEvent::MouseMove && + QGuiApplication::mouseButtons() & Qt::RightButton) { m_MouseMovePoint = me->pos(); qDebug() << "Mouse move while right down. Pt = " << me->pos() << ", global: " << mapToGlobal(me->pos()); @@ -236,8 +235,8 @@ void SpinBox::focusInEvent(QFocusEvent* e) /// The event void SpinBox::focusOutEvent(QFocusEvent* e) { - //lineEdit()->deselect();//Clear selection when leaving. - //lineEdit()->setReadOnly(true);//Clever hack to clear the cursor when leaving. + //lineEdit()->deselect();//Clear selection when leaving. + //lineEdit()->setReadOnly(true);//Clever hack to clear the cursor when leaving. StopTimer(); QSpinBox::focusOutEvent(e); } @@ -273,9 +272,9 @@ void SpinBox::leaveEvent(QEvent* e) /// void SpinBox::StartTimer() { - m_Timer.stop(); - connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); - m_Timer.start(300); + s_Timer.stop(); + connect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); + s_Timer.start(300); } /// @@ -283,6 +282,6 @@ void SpinBox::StartTimer() /// void SpinBox::StopTimer() { - m_Timer.stop(); - disconnect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); + s_Timer.stop(); + disconnect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); } diff --git a/Source/Fractorium/SpinBox.h b/Source/Fractorium/SpinBox.h index 140ea64..ee3e72a 100644 --- a/Source/Fractorium/SpinBox.h +++ b/Source/Fractorium/SpinBox.h @@ -48,5 +48,5 @@ private: int m_SmallStep; QPoint m_MouseDownPoint; QPoint m_MouseMovePoint; - static QTimer m_Timer; + static QTimer s_Timer; }; diff --git a/Source/Fractorium/VariationTreeWidgetItem.h b/Source/Fractorium/VariationTreeWidgetItem.h index e84c48e..522fffc 100644 --- a/Source/Fractorium/VariationTreeWidgetItem.h +++ b/Source/Fractorium/VariationTreeWidgetItem.h @@ -53,25 +53,21 @@ private: bool operator < (const QTreeWidgetItem& other) const { int column = treeWidget()->sortColumn(); - eVariationId index1, index2; - double weight1 = 0, weight2 = 0; - VariationTreeWidgetItem* varItemWidget; - VariationTreeDoubleSpinBox* spinBox1, *spinBox2; auto itemWidget1 = treeWidget()->itemWidget(const_cast(this), 1);//Get the widget for the second column. - if ((spinBox1 = dynamic_cast(itemWidget1)))//Cast the widget to the VariationTreeDoubleSpinBox type. + if (auto spinBox1 = dynamic_cast(itemWidget1))//Cast the widget to the VariationTreeDoubleSpinBox type. { auto itemWidget2 = treeWidget()->itemWidget(const_cast(&other), 1);//Get the widget for the second column of the widget item passed in. - if ((spinBox2 = dynamic_cast(itemWidget2)))//Cast the widget to the VariationTreeDoubleSpinBox type. + if (auto spinBox2 = dynamic_cast(itemWidget2))//Cast the widget to the VariationTreeDoubleSpinBox type. { if (spinBox1->IsParam() || spinBox2->IsParam())//Do not sort params, their order will always remain the same. return false; - weight1 = spinBox1->value(); - weight2 = spinBox2->value(); - index1 = spinBox1->GetVariationId(); - index2 = spinBox2->GetVariationId(); + auto weight1 = spinBox1->value(); + auto weight2 = spinBox2->value(); + auto index1 = spinBox1->GetVariationId(); + auto index2 = spinBox2->GetVariationId(); if (column == 0)//First column clicked, sort by variation index. {