mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-02-23 05:21:33 -05:00
--User changes
-Add variations changes to the list of functionality that can be applied to all xforms using the Select tab. -Allow for graphical affine adjustments to apply to multiple selected xforms. -Slight optimization of the pie variation. -Undo state is only saved when the render completes and the mouse buttons are released. This helps avoid intermediate steps for quickly completing renders while dragging. -Add some keyboard shortcuts for toolbar and menu items. -Make info tab tree always expanded. --Bug fixes -Make precalcs for all hypertile variations safer by using Zeps() for denominators. -Changing the current xform with more than one selected would set all xform's color index value that of the current one. -Use hard found palette path information for randoms as well. -OpenCL build and assignment errors for Z value in epispiral variation. -Unitialized local variables in hexaplay3D, crob, pRose3D. --Code changes -Change static member variables from m_ to s_. -Get rid of excessive endl and replace with "\n". -Remove old IMAGEGL2D define from before Nvidia supported OpenCL 1.2. -Remove old CriticalSection code and use std::recursive_mutex. -Make Affine2D Rotate() and RotateTrans() take radians instead of angles. -More C++11 work. -General cleanup.
This commit is contained in:
parent
a345e2d5e1
commit
a800b08b67
@ -208,16 +208,25 @@ void Affine2D<T>::Scale(T amount)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="angle">The angle to rotate by</param>
|
/// <param name="angle">The angle to rotate by</param>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Affine2D<T>::Rotate(T angle)
|
void Affine2D<T>::Rotate(T rad)
|
||||||
{
|
{
|
||||||
m4T origMat4 = ToMat4ColMajor(true);//Must center and use column major for glm to work.
|
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.
|
A(newMat4[0][0]);//Use direct assignments instead of constructor to skip assigning C and F.
|
||||||
B(newMat4[0][1]);
|
B(newMat4[0][1]);
|
||||||
D(newMat4[1][0]);
|
D(newMat4[1][0]);
|
||||||
E(newMat4[1][1]);
|
E(newMat4[1][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Affine2D<T>::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]);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Move by v.
|
/// Move by v.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -341,6 +350,16 @@ typename m4T Affine2D<T>::ToMat4RowMajor(bool center) const
|
|||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename m4T Affine2D<T>::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;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Accessors.
|
/// Accessors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -366,6 +385,19 @@ template <typename T> void Affine2D<T>::X(const v2T& x) { A(x.x); D(x.y); }//X A
|
|||||||
template <typename T> void Affine2D<T>::Y(const v2T& y) { B(y.x); E(y.y); }//Y Axis.
|
template <typename T> void Affine2D<T>::Y(const v2T& y) { B(y.x); E(y.y); }//Y Axis.
|
||||||
template <typename T> void Affine2D<T>::O(const v2T& t) { C(t.x); F(t.y); }//Translation.
|
template <typename T> void Affine2D<T>::O(const v2T& t) { C(t.x); F(t.y); }//Translation.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
string Affine2D<T>::ToString() const
|
||||||
|
{
|
||||||
|
ostringstream ss;
|
||||||
|
ss << "A: " << A() << " "
|
||||||
|
<< "B: " << B() << " "
|
||||||
|
<< "C: " << C()
|
||||||
|
<< "\nD: " << D() << " "
|
||||||
|
<< "E: " << E() << " "
|
||||||
|
<< "F: " << F();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotate and scale this affine transform and return as a copy. Orginal is unchanged.
|
/// Rotate and scale this affine transform and return as a copy. Orginal is unchanged.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -77,7 +77,8 @@ public:
|
|||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
void Scale(T amount);
|
void Scale(T amount);
|
||||||
Affine2D<T> ScaleCopy(T amount);
|
Affine2D<T> ScaleCopy(T amount);
|
||||||
void Rotate(T angle);
|
void Rotate(T rad);
|
||||||
|
void RotateTrans(T rad);
|
||||||
void Translate(const v2T& v);
|
void Translate(const v2T& v);
|
||||||
void RotateScaleXTo(const v2T& v);
|
void RotateScaleXTo(const v2T& v);
|
||||||
void RotateScaleYTo(const v2T& v);
|
void RotateScaleYTo(const v2T& v);
|
||||||
@ -88,6 +89,7 @@ public:
|
|||||||
m2T ToMat2RowMajor() const;
|
m2T ToMat2RowMajor() const;
|
||||||
m4T ToMat4ColMajor(bool center = false) const;
|
m4T ToMat4ColMajor(bool center = false) const;
|
||||||
m4T ToMat4RowMajor(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&.
|
//Note that returning a copy is actually faster than a const ref&.
|
||||||
T A() const;
|
T A() const;
|
||||||
@ -112,6 +114,8 @@ public:
|
|||||||
void Y(const v2T& y);
|
void Y(const v2T& y);
|
||||||
void O(const v2T& t);
|
void O(const v2T& t);
|
||||||
|
|
||||||
|
string ToString() const;
|
||||||
|
|
||||||
static Affine2D CalcRotateScale(const v2T& from, const v2T& to);
|
static Affine2D CalcRotateScale(const v2T& from, const v2T& to);
|
||||||
static void CalcRSAC(const v2T& from, const v2T& to, T& a, T& c);
|
static void CalcRSAC(const v2T& from, const v2T& to, T& a, T& c);
|
||||||
|
|
||||||
|
@ -99,7 +99,6 @@ public:
|
|||||||
m_PadCarLlY = T(carToRas.PadCarLlY());
|
m_PadCarLlY = T(carToRas.PadCarLlY());
|
||||||
m_PadCarUrX = T(carToRas.PadCarUrX());
|
m_PadCarUrX = T(carToRas.PadCarUrX());
|
||||||
m_PadCarUrY = T(carToRas.PadCarUrY());
|
m_PadCarUrY = T(carToRas.PadCarUrY());
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,29 +116,22 @@ public:
|
|||||||
{
|
{
|
||||||
m_RasWidth = rasW;
|
m_RasWidth = rasW;
|
||||||
m_RasHeight = rasH;
|
m_RasHeight = rasH;
|
||||||
|
|
||||||
m_CarLlX = carLlX;
|
m_CarLlX = carLlX;
|
||||||
m_CarLlY = carLlY;
|
m_CarLlY = carLlY;
|
||||||
m_CarUrX = carUrX;
|
m_CarUrX = carUrX;
|
||||||
m_CarUrY = carUrY;
|
m_CarUrY = carUrY;
|
||||||
|
|
||||||
T carW = m_CarUrX - m_CarLlX;//Right minus left.
|
T carW = m_CarUrX - m_CarLlX;//Right minus left.
|
||||||
T carH = m_CarUrY - m_CarLlY;//Top minus bottom.
|
T carH = m_CarUrY - m_CarLlY;//Top minus bottom.
|
||||||
T invSizeW = T(1.0) / carW;
|
T invSizeW = T(1.0) / carW;
|
||||||
T invSizeH = T(1.0) / carH;
|
T invSizeH = T(1.0) / carH;
|
||||||
|
|
||||||
m_PixPerImageUnitW = static_cast<T>(rasW) * invSizeW;
|
m_PixPerImageUnitW = static_cast<T>(rasW) * invSizeW;
|
||||||
m_RasLlX = m_PixPerImageUnitW * carLlX;
|
m_RasLlX = m_PixPerImageUnitW * carLlX;
|
||||||
|
|
||||||
m_PixPerImageUnitH = static_cast<T>(rasH) * invSizeH;
|
m_PixPerImageUnitH = static_cast<T>(rasH) * invSizeH;
|
||||||
m_RasLlY = m_PixPerImageUnitH * carLlY;
|
m_RasLlY = m_PixPerImageUnitH * carLlY;
|
||||||
|
|
||||||
m_OneRow = abs(m_CarUrY - m_CarLlY) / m_RasHeight;
|
m_OneRow = abs(m_CarUrY - m_CarLlY) / m_RasHeight;
|
||||||
m_OneCol = abs(m_CarUrX - m_CarLlX) / m_RasWidth;
|
m_OneCol = abs(m_CarUrX - m_CarLlX) / m_RasWidth;
|
||||||
|
|
||||||
m_PadCarLlX = m_CarLlX + m_OneCol;
|
m_PadCarLlX = m_CarLlX + m_OneCol;
|
||||||
m_PadCarUrX = m_CarUrX - m_OneCol;
|
m_PadCarUrX = m_CarUrX - m_OneCol;
|
||||||
|
|
||||||
m_PadCarLlY = m_CarLlY + m_OneRow;
|
m_PadCarLlY = m_CarLlY + m_OneRow;
|
||||||
m_PadCarUrY = m_CarUrY - 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...
|
//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.
|
// 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 &&
|
return point.m_X >= m_CarLlX &&
|
||||||
point.m_X < m_CarUrX &&
|
point.m_X < m_CarUrX &&
|
||||||
point.m_Y < m_CarUrY &&
|
point.m_Y < m_CarUrY &&
|
||||||
|
@ -115,10 +115,8 @@ public:
|
|||||||
T finalMinRad = m_MinRad * m_Supersample + 1;//Should scale the filter width by the oversample.
|
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.
|
T finalMaxRad = m_MaxRad * m_Supersample + 1;//The '+1' comes from the assumed distance to the first pixel.
|
||||||
GaussianFilter<T> gaussianFilter(m_MaxRad, m_Supersample);
|
GaussianFilter<T> gaussianFilter(m_MaxRad, m_Supersample);
|
||||||
|
|
||||||
m_KernelSize = 0;
|
m_KernelSize = 0;
|
||||||
m_MaxFilterIndex = 0;
|
m_MaxFilterIndex = 0;
|
||||||
|
|
||||||
//Calculate how many filter kernels are needed based on the decay function
|
//Calculate how many filter kernels are needed based on the decay function
|
||||||
//
|
//
|
||||||
// num filters = (de_max_width / de_min_width)^(1 / estimator_curve)
|
// num filters = (de_max_width / de_min_width)^(1 / estimator_curve)
|
||||||
@ -146,7 +144,6 @@ public:
|
|||||||
rowSize = static_cast<int>(2 * ceil(finalMaxRad) - 1);
|
rowSize = static_cast<int>(2 * ceil(finalMaxRad) - 1);
|
||||||
m_FilterWidth = (rowSize - 1) / 2;
|
m_FilterWidth = (rowSize - 1) / 2;
|
||||||
m_KernelSize = (m_FilterWidth + 1) * (2 + m_FilterWidth) / 2;
|
m_KernelSize = (m_FilterWidth + 1) * (2 + m_FilterWidth) / 2;
|
||||||
|
|
||||||
m_Coefs.resize(maxIndex * m_KernelSize);
|
m_Coefs.resize(maxIndex * m_KernelSize);
|
||||||
m_Widths.resize(maxIndex);
|
m_Widths.resize(maxIndex);
|
||||||
|
|
||||||
@ -261,7 +258,6 @@ public:
|
|||||||
{
|
{
|
||||||
T finalMaxRad = m_MaxRad * m_Supersample + 1;
|
T finalMaxRad = m_MaxRad * m_Supersample + 1;
|
||||||
T finalMinRad = m_MinRad * m_Supersample + 1;
|
T finalMinRad = m_MinRad * m_Supersample + 1;
|
||||||
|
|
||||||
return std::pow(finalMaxRad / finalMinRad, T(1.0) / m_Curve) <= 1e7;
|
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;
|
size_t i, j, coefIndex = 0, w = m_FilterWidth + 1;
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
|
|
||||||
ss
|
ss
|
||||||
<< "Density Filter:" << endl
|
<< "Density Filter:"
|
||||||
<< " Min radius: " << MinRad() << endl
|
<< "\n Min radius: " << MinRad()
|
||||||
<< " Max radius: " << MaxRad() << endl
|
<< "\n Max radius: " << MaxRad()
|
||||||
<< " Curve: " << Curve() << endl
|
<< "\n Curve: " << Curve()
|
||||||
<< " Kernel size: " << KernelSize() << endl
|
<< "\n Kernel size: " << KernelSize()
|
||||||
<< " Max filter index: " << MaxFilterIndex() << endl
|
<< "\n Max filter index: " << MaxFilterIndex()
|
||||||
<< "Max Filtered counts: " << MaxFilteredCounts() << endl
|
<< "\nMax Filtered counts: " << MaxFilteredCounts()
|
||||||
<< " Filter width: " << FilterWidth() << endl;
|
<< "\n Filter width: " << FilterWidth();
|
||||||
|
ss << "\nCoefficients: \n";
|
||||||
ss << "Coefficients: " << endl;
|
|
||||||
|
|
||||||
for (i = 0; i < m_Widths.size(); i++)
|
for (i = 0; i < m_Widths.size(); i++)
|
||||||
{
|
{
|
||||||
for (coefIndex = 0; coefIndex < m_KernelSize; coefIndex++)
|
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++)
|
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++)
|
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 << std::setw(2) << std::setfill('0') << m_CoefIndices[i * w + j] << "\t";
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << endl;
|
cout << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
namespace EmberNs
|
namespace EmberNs
|
||||||
{
|
{
|
||||||
template<> unique_ptr<QTIsaac<ISAAC_SIZE, ISAAC_INT>> QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand = unique_ptr<QTIsaac<ISAAC_SIZE, ISAAC_INT>>(new QTIsaac<ISAAC_SIZE, ISAAC_INT>());
|
template<> unique_ptr<QTIsaac<ISAAC_SIZE, ISAAC_INT>> QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand = unique_ptr<QTIsaac<ISAAC_SIZE, ISAAC_INT>>(new QTIsaac<ISAAC_SIZE, ISAAC_INT>());
|
||||||
template<> CriticalSection QTIsaac<ISAAC_SIZE, ISAAC_INT>::m_CS = CriticalSection();
|
template<> std::recursive_mutex QTIsaac<ISAAC_SIZE, ISAAC_INT>::s_CS = std::recursive_mutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Curves.h"
|
#include "Curves.h"
|
||||||
@ -56,7 +56,7 @@ uint Timing::m_ProcessorCount;
|
|||||||
|
|
||||||
#define EXPORT_SINGLE_TYPE_EMBER(T) \
|
#define EXPORT_SINGLE_TYPE_EMBER(T) \
|
||||||
template<> const char* PaletteList<T>::m_DefaultFilename = "flam3-palettes.xml"; \
|
template<> const char* PaletteList<T>::m_DefaultFilename = "flam3-palettes.xml"; \
|
||||||
template<> map<string, vector<Palette<T>>> PaletteList<T>::m_Palettes = map<string, vector<Palette<T>>>(); \
|
template<> map<string, vector<Palette<T>>> PaletteList<T>::s_Palettes = map<string, vector<Palette<T>>>(); \
|
||||||
template<> bool XmlToEmber<T>::m_Init = false; \
|
template<> bool XmlToEmber<T>::m_Init = false; \
|
||||||
template<> vector<string> XmlToEmber<T>::m_FlattenNames = vector<string>(); \
|
template<> vector<string> XmlToEmber<T>::m_FlattenNames = vector<string>(); \
|
||||||
template<> unordered_map<string, string> XmlToEmber<T>::m_BadParamNames = unordered_map<string, string>(); \
|
template<> unordered_map<string, string> XmlToEmber<T>::m_BadParamNames = unordered_map<string, string>(); \
|
||||||
|
@ -1034,7 +1034,7 @@ public:
|
|||||||
if (m_Xforms[i].Empty() && m_AffineInterp != eAffineInterp::AFFINE_INTERP_LOG)
|
if (m_Xforms[i].Empty() && m_AffineInterp != eAffineInterp::AFFINE_INTERP_LOG)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_Xforms[i].m_Affine.Rotate(angle);
|
m_Xforms[i].m_Affine.Rotate(angle * DEG_2_RAD_T);
|
||||||
//Don't rotate post.
|
//Don't rotate post.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ namespace EmberNs
|
|||||||
#define EMPTYFIELD -9999
|
#define EMPTYFIELD -9999
|
||||||
typedef std::chrono::high_resolution_clock Clock;
|
typedef std::chrono::high_resolution_clock Clock;
|
||||||
typedef uint et;
|
typedef uint et;
|
||||||
|
typedef std::lock_guard <std::recursive_mutex> rlg;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thin wrapper around getting the current time in milliseconds.
|
/// Thin wrapper around getting the current time in milliseconds.
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -116,18 +116,18 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Error: Writing flame " << filename << " failed." << endl;
|
cout << "Error: Writing flame " << filename << " failed.\n";
|
||||||
b = false;
|
b = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
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;
|
b = false;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
cout << "Error: Writing flame " << filename << " failed." << endl;
|
cout << "Error: Writing flame " << filename << " failed.\n";
|
||||||
b = false;
|
b = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ public:
|
|||||||
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][2] * 255));
|
os << hex << setw(2) << setfill('0') << int(std::rint(ember.m_Palette[idx][2] * 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
os << endl;
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
os << " </palette>\n";
|
os << " </palette>\n";
|
||||||
@ -472,7 +472,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Failed to parse comment into Xml." << endl;
|
cout << "Failed to parse comment into Xml.\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +639,7 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
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
|
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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
#ifndef __ISAAC64
|
#ifndef __ISAAC64
|
||||||
typedef uint ISAAC_INT;
|
typedef uint ISAAC_INT;
|
||||||
const ISAAC_INT GOLDEN_RATIO = ISAAC_INT(0x9e3779b9);
|
const ISAAC_INT GOLDEN_RATIO = ISAAC_INT(0x9e3779b9);
|
||||||
#else
|
#else
|
||||||
typedef size_t ISAAC_INT;
|
typedef size_t ISAAC_INT;
|
||||||
const ISAAC_INT GOLDEN_RATIO = ISAAC_INT(0x9e3779b97f4a7c13);
|
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
|
/// 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.
|
/// use it when no other threads are.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static unique_ptr<QTIsaac<ALPHA, ISAAC_INT> > GlobalRand;
|
static unique_ptr<QTIsaac<ALPHA, ISAAC_INT>> GlobalRand;
|
||||||
|
|
||||||
static CriticalSection m_CS;
|
static std::recursive_mutex s_CS;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The structure which holds all of the random information.
|
/// The structure which holds all of the random information.
|
||||||
@ -124,9 +124,8 @@ public:
|
|||||||
/// <returns>The next random integer in the range of 0-255</returns>
|
/// <returns>The next random integer in the range of 0-255</returns>
|
||||||
static inline T LockedRandByte()
|
static inline T LockedRandByte()
|
||||||
{
|
{
|
||||||
m_CS.Enter();
|
rlg l(s_CS);
|
||||||
T t = GlobalRand->RandByte();
|
T t = GlobalRand->RandByte();
|
||||||
m_CS.Leave();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,9 +136,9 @@ public:
|
|||||||
inline T Rand()
|
inline T Rand()
|
||||||
{
|
{
|
||||||
#ifdef ISAAC_FLAM3_DEBUG
|
#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
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,9 +148,8 @@ public:
|
|||||||
/// <returns>The next random integer</returns>
|
/// <returns>The next random integer</returns>
|
||||||
static inline T LockedRand()
|
static inline T LockedRand()
|
||||||
{
|
{
|
||||||
m_CS.Enter();
|
rlg l(s_CS);
|
||||||
T t = GlobalRand->Rand();
|
T t = GlobalRand->Rand();
|
||||||
m_CS.Leave();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,9 +170,8 @@ public:
|
|||||||
/// <returns>A value between 0 and the value passed in minus 1</returns>
|
/// <returns>A value between 0 and the value passed in minus 1</returns>
|
||||||
static inline T LockedRand(T upper)
|
static inline T LockedRand(T upper)
|
||||||
{
|
{
|
||||||
m_CS.Enter();
|
rlg l(s_CS);
|
||||||
T t = GlobalRand->Rand(upper);
|
T t = GlobalRand->Rand(upper);
|
||||||
m_CS.Leave();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,9 +198,8 @@ public:
|
|||||||
template<typename floatType>
|
template<typename floatType>
|
||||||
static inline floatType LockedFrand(floatType fMin, floatType fMax)
|
static inline floatType LockedFrand(floatType fMin, floatType fMax)
|
||||||
{
|
{
|
||||||
m_CS.Enter();
|
rlg l(s_CS);
|
||||||
floatType t = GlobalRand->template Frand<floatType>(fMin, fMax);
|
floatType t = GlobalRand->template Frand<floatType>(fMin, fMax);
|
||||||
m_CS.Leave();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,9 +225,8 @@ public:
|
|||||||
template<typename floatType>
|
template<typename floatType>
|
||||||
static inline floatType LockedFrand01()
|
static inline floatType LockedFrand01()
|
||||||
{
|
{
|
||||||
m_CS.Enter();
|
rlg l(s_CS);
|
||||||
floatType t = GlobalRand->template Frand01<floatType>();
|
floatType t = GlobalRand->template Frand01<floatType>();
|
||||||
m_CS.Leave();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,9 +252,8 @@ public:
|
|||||||
template<typename floatType>
|
template<typename floatType>
|
||||||
static inline floatType LockedFrand11()
|
static inline floatType LockedFrand11()
|
||||||
{
|
{
|
||||||
m_CS.Enter();
|
rlg l(s_CS);
|
||||||
floatType t = GlobalRand->template Frand11<floatType>();
|
floatType t = GlobalRand->template Frand11<floatType>();
|
||||||
m_CS.Leave();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,9 +274,8 @@ public:
|
|||||||
template<typename floatType>
|
template<typename floatType>
|
||||||
static inline floatType LockedGoldenBit()
|
static inline floatType LockedGoldenBit()
|
||||||
{
|
{
|
||||||
m_CS.Enter();
|
rlg l(s_CS);
|
||||||
floatType t = GlobalRand->template GoldenBit<floatType>();
|
floatType t = GlobalRand->template GoldenBit<floatType>();
|
||||||
m_CS.Leave();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,9 +294,8 @@ public:
|
|||||||
/// <returns>A random 0 or 1</returns>
|
/// <returns>A random 0 or 1</returns>
|
||||||
static inline uint LockedRandBit()
|
static inline uint LockedRandBit()
|
||||||
{
|
{
|
||||||
m_CS.Enter();
|
rlg l(s_CS);
|
||||||
uint t = GlobalRand->RandBit();
|
uint t = GlobalRand->RandBit();
|
||||||
m_CS.Leave();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +321,6 @@ public:
|
|||||||
T a, b, c, d, e, f, g, h;
|
T a, b, c, d, e, f, g, h;
|
||||||
T* m = ctx->randmem;
|
T* m = ctx->randmem;
|
||||||
T* r = ctx->randrsl;
|
T* r = ctx->randrsl;
|
||||||
|
|
||||||
a = b = c = d = e = f = g = h = GOLDEN_RATIO;
|
a = b = c = d = e = f = g = h = GOLDEN_RATIO;
|
||||||
|
|
||||||
if (!useSeed)
|
if (!useSeed)
|
||||||
@ -352,9 +343,7 @@ public:
|
|||||||
{
|
{
|
||||||
a += r[i ]; b += r[i + 1]; c += r[i + 2]; d += r[i + 3];
|
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];
|
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);
|
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 ] = 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;
|
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];
|
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];
|
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);
|
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 ] = 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;
|
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.
|
//Fill in mm[] with messy stuff.
|
||||||
Shuffle(a, b, c, d, e, f, g, h);
|
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 ] = 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;
|
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
|
#ifndef ISAAC_FLAM3_DEBUG
|
||||||
|
|
||||||
if (a == 0 && b == 0 && c == 0)
|
if (a == 0 && b == 0 && c == 0)
|
||||||
{
|
{
|
||||||
m_Rc.randa = static_cast<T>(NowMs());
|
m_Rc.randa = static_cast<T>(NowMs());
|
||||||
@ -430,48 +417,45 @@ protected:
|
|||||||
/// <param name="ctx">The context to populate.</param>
|
/// <param name="ctx">The context to populate.</param>
|
||||||
void Isaac(randctx* ctx)
|
void Isaac(randctx* ctx)
|
||||||
{
|
{
|
||||||
T x,y;
|
T x, y;
|
||||||
|
|
||||||
T* mm = ctx->randmem;
|
T* mm = ctx->randmem;
|
||||||
T* r = ctx->randrsl;
|
T* r = ctx->randrsl;
|
||||||
|
|
||||||
T a = (ctx->randa);
|
T a = (ctx->randa);
|
||||||
T b = (ctx->randb + (++ctx->randc));
|
T b = (ctx->randb + (++ctx->randc));
|
||||||
|
|
||||||
T* m = mm;
|
T* m = mm;
|
||||||
T* m2 = (m + (N / 2));
|
T* m2 = (m + (N / 2));
|
||||||
T* mend = m2;
|
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 << 13), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a >> 6) , 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 << 2) , a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a >> 16), 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 << 21)), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a >> 5) , 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 << 12) , a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a >> 33) , 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;
|
m2 = mm;
|
||||||
|
|
||||||
for(; m2<mend;)
|
for (; m2 < mend;)
|
||||||
{
|
{
|
||||||
#ifndef __ISAAC64
|
#ifndef __ISAAC64
|
||||||
RngStep((a << 13), a, b, mm, m, m2, r, x, y);
|
RngStep((a << 13), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a >> 6) , 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 << 2) , a, b, mm, m, m2, r, x, y);
|
||||||
RngStep((a >> 16), 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 << 21)), a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a >> 5) , 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 << 12) , a, b, mm, m, m2, r, x, y);
|
||||||
RngStep( a ^ (a >> 33) , 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;
|
ctx->randb = b;
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
bool Add(const string& filename, bool force = false)
|
bool Add(const string& filename, bool force = false)
|
||||||
{
|
{
|
||||||
bool added = true;
|
bool added = true;
|
||||||
auto palettes = m_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
|
auto palettes = s_Palettes.insert(make_pair(filename, vector<Palette<T>>()));
|
||||||
|
|
||||||
if (force || palettes.second)
|
if (force || palettes.second)
|
||||||
{
|
{
|
||||||
@ -53,7 +53,6 @@ public:
|
|||||||
{
|
{
|
||||||
auto rootNode = xmlDocGetRootElement(doc);
|
auto rootNode = xmlDocGetRootElement(doc);
|
||||||
auto pfilename = shared_ptr<string>(new string(filename));
|
auto pfilename = shared_ptr<string>(new string(filename));
|
||||||
|
|
||||||
palettes.first->second.clear();
|
palettes.first->second.clear();
|
||||||
palettes.first->second.reserve(buf.size() / 2048);//Roughly what it takes per palette.
|
palettes.first->second.reserve(buf.size() / 2048);//Roughly what it takes per palette.
|
||||||
ParsePalettes(rootNode, pfilename, palettes.first->second);
|
ParsePalettes(rootNode, pfilename, palettes.first->second);
|
||||||
@ -62,14 +61,14 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
added = false;
|
added = false;
|
||||||
m_Palettes.erase(filename);
|
s_Palettes.erase(filename);
|
||||||
AddToReport(string(loc) + " : Couldn't load xml doc");
|
AddToReport(string(loc) + " : Couldn't load xml doc");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
added = false;
|
added = false;
|
||||||
m_Palettes.erase(filename);
|
s_Palettes.erase(filename);
|
||||||
AddToReport(string(loc) + " : Couldn't read palette file " + filename);
|
AddToReport(string(loc) + " : Couldn't read palette file " + filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,11 +81,11 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Palette<T>* GetRandomPalette()
|
Palette<T>* GetRandomPalette()
|
||||||
{
|
{
|
||||||
auto p = m_Palettes.begin();
|
auto p = s_Palettes.begin();
|
||||||
size_t i = 0, paletteFileIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand->Rand() % Size();
|
size_t i = 0, paletteFileIndex = QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand->Rand() % Size();
|
||||||
|
|
||||||
//Move p forward i elements.
|
//Move p forward i elements.
|
||||||
while (i < paletteFileIndex && p != m_Palettes.end())
|
while (i < paletteFileIndex && p != s_Palettes.end())
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
++p;
|
++p;
|
||||||
@ -111,7 +110,7 @@ public:
|
|||||||
/// <returns>A pointer to the requested palette if the index was in range, else nullptr.</returns>
|
/// <returns>A pointer to the requested palette if the index was in range, else nullptr.</returns>
|
||||||
Palette<T>* GetPalette(const string& filename, size_t i)
|
Palette<T>* GetPalette(const string& filename, size_t i)
|
||||||
{
|
{
|
||||||
auto& palettes = m_Palettes[filename];
|
auto& palettes = s_Palettes[filename];
|
||||||
|
|
||||||
if (!palettes.empty() && i < palettes.size())
|
if (!palettes.empty() && i < palettes.size())
|
||||||
return &palettes[i];
|
return &palettes[i];
|
||||||
@ -127,7 +126,7 @@ public:
|
|||||||
/// <returns>A pointer to the palette if found, else nullptr</returns>
|
/// <returns>A pointer to the palette if found, else nullptr</returns>
|
||||||
Palette<T>* GetPaletteByName(const string& filename, const string& name)
|
Palette<T>* GetPaletteByName(const string& filename, const string& name)
|
||||||
{
|
{
|
||||||
for (auto& palettes : m_Palettes)
|
for (auto& palettes : s_Palettes)
|
||||||
if (palettes.first == filename)
|
if (palettes.first == filename)
|
||||||
for (auto& palette : palettes.second)
|
for (auto& palette : palettes.second)
|
||||||
if (palette.m_Name == name)
|
if (palette.m_Name == name)
|
||||||
@ -163,7 +162,7 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
m_Palettes.clear();
|
s_Palettes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -171,7 +170,7 @@ public:
|
|||||||
/// This will be the number of files read.
|
/// This will be the number of files read.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The size of the palettes map</returns>
|
/// <returns>The size of the palettes map</returns>
|
||||||
size_t Size() { return m_Palettes.size(); }
|
size_t Size() { return s_Palettes.size(); }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the size of specified palette vector in the palettes map.
|
/// Get the size of specified palette vector in the palettes map.
|
||||||
@ -181,9 +180,9 @@ public:
|
|||||||
size_t Size(size_t index)
|
size_t Size(size_t index)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
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;
|
++i;
|
||||||
++p;
|
++p;
|
||||||
@ -199,7 +198,7 @@ public:
|
|||||||
/// <returns>The size of the palette vector at the specified index in the palettes map</returns>
|
/// <returns>The size of the palette vector at the specified index in the palettes map</returns>
|
||||||
size_t Size(const string& s)
|
size_t Size(const string& s)
|
||||||
{
|
{
|
||||||
return m_Palettes[s].size();
|
return s_Palettes[s].size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -210,9 +209,9 @@ public:
|
|||||||
const string& Name(size_t index)
|
const string& Name(size_t index)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
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;
|
++i;
|
||||||
++p;
|
++p;
|
||||||
@ -257,7 +256,7 @@ private:
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int ret = sscanf_s(static_cast<char*>(&(val[colorIndex])),"00%2x%2x%2x", &r, &g, &b);
|
int ret = sscanf_s(static_cast<char*>(&(val[colorIndex])), "00%2x%2x%2x", &r, &g, &b);
|
||||||
|
|
||||||
if (ret != 3)
|
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].r = T(r) / T(255);//Store as normalized colors in the range of 0-1.
|
||||||
palette[colorCount].g = T(g) / T(255);
|
palette[colorCount].g = T(g) / T(255);
|
||||||
palette[colorCount].b = T(b) / T(255);
|
palette[colorCount].b = T(b) / T(255);
|
||||||
|
|
||||||
colorCount++;
|
colorCount++;
|
||||||
} while (colorCount < COLORMAP_LENGTH);
|
}
|
||||||
|
while (colorCount < COLORMAP_LENGTH);
|
||||||
}
|
}
|
||||||
else if (!Compare(attr->name, "number"))
|
else if (!Compare(attr->name, "number"))
|
||||||
{
|
{
|
||||||
@ -306,6 +305,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static map<string, vector<Palette<T>>> m_Palettes;//The map of filenames to vectors that store the palettes.
|
static map<string, vector<Palette<T>>> s_Palettes;//The map of filenames to vectors that store the palettes.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ void Renderer<T, bucketT>::ComputeCamera()
|
|||||||
T carUrX = m_UpperRightX + t0;
|
T carUrX = m_UpperRightX + t0;
|
||||||
T carUrY = m_UpperRightY + t1 + shift;
|
T carUrY = m_UpperRightY + t1 + shift;
|
||||||
m_RotMat.MakeID();
|
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());
|
m_CarToRas.Init(carLlX, carLlY, carUrX, carUrY, m_SuperRasW, m_SuperRasH, PixelAspectRatio());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,8 +215,6 @@ bool Renderer<T, bucketT>::CreateDEFilter(bool& newAlloc)
|
|||||||
if (!m_DensityFilter.get()) { return false; }//Did object creation succeed?
|
if (!m_DensityFilter.get()) { return false; }//Did object creation succeed?
|
||||||
|
|
||||||
if (!m_DensityFilter->Create()) { return false; }//Object creation succeeded, did filter 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?
|
else if (!m_DensityFilter->Valid()) { return false; } //Previously created, are values ok?
|
||||||
}
|
}
|
||||||
@ -1299,7 +1297,7 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
|
|||||||
//iterationTime += t.Toc();
|
//iterationTime += t.Toc();
|
||||||
|
|
||||||
if (m_LockAccum)
|
if (m_LockAccum)
|
||||||
m_AccumCs.Enter();
|
m_AccumCs.lock();
|
||||||
|
|
||||||
//t.Tic();
|
//t.Tic();
|
||||||
//Map temp buffer samples into the histogram using the palette for color.
|
//Map temp buffer samples into the histogram using the palette for color.
|
||||||
@ -1307,7 +1305,7 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
|
|||||||
|
|
||||||
//accumulationTime += t.Toc();
|
//accumulationTime += t.Toc();
|
||||||
if (m_LockAccum)
|
if (m_LockAccum)
|
||||||
m_AccumCs.Leave();
|
m_AccumCs.unlock();
|
||||||
|
|
||||||
if (m_Callback && threadIndex == 0)
|
if (m_Callback && threadIndex == 0)
|
||||||
{
|
{
|
||||||
|
@ -263,12 +263,12 @@ size_t RendererBase::MemoryAvailable()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Warning: unable to determine physical memory." << endl;
|
cout << "Warning: unable to determine physical memory.\n";
|
||||||
memAvailable = 4e9;
|
memAvailable = 4e9;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
cout << "Warning: unable to determine physical memory." << endl;
|
cout << "Warning: unable to determine physical memory.\n";
|
||||||
memAvailable = 4e9;
|
memAvailable = 4e9;
|
||||||
#endif
|
#endif
|
||||||
return memAvailable;
|
return memAvailable;
|
||||||
@ -610,14 +610,14 @@ void RendererBase::Reset()
|
|||||||
m_ProcessAction = eProcessAction::FULL_RENDER;
|
m_ProcessAction = eProcessAction::FULL_RENDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererBase::EnterRender() { m_RenderingCs.Enter(); }
|
void RendererBase::EnterRender() { m_RenderingCs.lock(); }
|
||||||
void RendererBase::LeaveRender() { m_RenderingCs.Leave(); }
|
void RendererBase::LeaveRender() { m_RenderingCs.unlock(); }
|
||||||
|
|
||||||
void RendererBase::EnterFinalAccum() { m_FinalAccumCs.Enter(); m_InFinalAccum = true; }
|
void RendererBase::EnterFinalAccum() { m_FinalAccumCs.lock(); m_InFinalAccum = true; }
|
||||||
void RendererBase::LeaveFinalAccum() { m_FinalAccumCs.Leave(); m_InFinalAccum = false; }
|
void RendererBase::LeaveFinalAccum() { m_FinalAccumCs.unlock(); m_InFinalAccum = false; }
|
||||||
|
|
||||||
void RendererBase::EnterResize() { m_ResizeCs.Enter(); }
|
void RendererBase::EnterResize() { m_ResizeCs.lock(); }
|
||||||
void RendererBase::LeaveResize() { m_ResizeCs.Leave(); }
|
void RendererBase::LeaveResize() { m_ResizeCs.unlock(); }
|
||||||
|
|
||||||
void RendererBase::Abort() { m_Abort = true; }
|
void RendererBase::Abort() { m_Abort = true; }
|
||||||
bool RendererBase::Aborted() { return m_Abort; }
|
bool RendererBase::Aborted() { return m_Abort; }
|
||||||
|
@ -228,7 +228,7 @@ protected:
|
|||||||
vector<size_t> m_BadVals;
|
vector<size_t> m_BadVals;
|
||||||
vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>> m_Rand;
|
vector<QTIsaac<ISAAC_SIZE, ISAAC_INT>> m_Rand;
|
||||||
auto_ptr<tbb::task_group> m_TaskGroup;
|
auto_ptr<tbb::task_group> 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;
|
Timing m_RenderTimer, m_IterTimer, m_ProgressTimer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -804,7 +804,7 @@ public:
|
|||||||
|
|
||||||
if (best < 0)
|
if (best < 0)
|
||||||
{
|
{
|
||||||
cout << "Error in TryColors(), skipping ImproveColors()" << endl;
|
cout << "Error in TryColors(), skipping ImproveColors()\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,7 +815,7 @@ public:
|
|||||||
|
|
||||||
if (b < 0)
|
if (b < 0)
|
||||||
{
|
{
|
||||||
cout << "Error in TryColors, aborting tries." << endl;
|
cout << "Error in TryColors, aborting tries.\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,7 +861,7 @@ public:
|
|||||||
|
|
||||||
if (m_Renderer->Run(m_FinalImage) != eRenderStatus::RENDER_OK)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,7 +902,7 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ember.m_Palette.Clear(false);
|
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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,18 +159,18 @@ public:
|
|||||||
size_t i;
|
size_t i;
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss
|
ss
|
||||||
<< "Spatial Filter:" << endl
|
<< "Spatial Filter:"
|
||||||
<< " Support: " << m_Support << endl
|
<< "\n Support: " << m_Support
|
||||||
<< " Filter radius: " << m_FilterRadius << endl
|
<< "\n Filter radius: " << m_FilterRadius
|
||||||
<< " Supersample: " << m_Supersample << endl
|
<< "\n Supersample: " << m_Supersample
|
||||||
<< "Pixel aspect ratio: " << m_PixelAspectRatio << endl
|
<< "\nPixel aspect ratio: " << m_PixelAspectRatio
|
||||||
<< "Final filter width: " << m_FinalFilterWidth << endl
|
<< "\nFinal filter width: " << m_FinalFilterWidth
|
||||||
<< "Filter buffer size: " << m_Filter.size() << endl;
|
<< "\nFilter buffer size: " << m_Filter.size();
|
||||||
ss << "Filter: " << endl;
|
ss << "\nFilter: \n";
|
||||||
|
|
||||||
for (i = 0; i < m_Filter.size(); i++)
|
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();
|
return ss.str();
|
||||||
|
@ -115,22 +115,22 @@ public:
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << "Temporal Filter:" << endl
|
ss << "Temporal Filter:\n"
|
||||||
<< " Size: " << Size() << endl
|
<< "\n Size: " << Size()
|
||||||
<< " Type: " << TemporalFilterCreator<T>::ToString(m_FilterType) << endl
|
<< "\n Type: " << TemporalFilterCreator<T>::ToString(m_FilterType)
|
||||||
<< " Sum Filt: " << SumFilt() << endl;
|
<< "\n Sum Filt: " << SumFilt();
|
||||||
ss << "Deltas: " << endl;
|
ss << "\nDeltas: \n";
|
||||||
|
|
||||||
for (i = 0; i < m_Deltas.size(); i++)
|
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++)
|
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();
|
return ss.str();
|
||||||
|
@ -52,7 +52,7 @@ public:
|
|||||||
|
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
cout << string(str) << (fullString ? "" : " processing time: ") << Format(ms) << endl;
|
cout << string(str) << (fullString ? "" : " processing time: ") << Format(ms) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return ms;
|
return ms;
|
||||||
@ -77,7 +77,6 @@ public:
|
|||||||
double ElapsedTime() const
|
double ElapsedTime() const
|
||||||
{
|
{
|
||||||
duration<double> elapsed = duration_cast<milliseconds, Clock::rep, Clock::period>(m_EndTime - m_BeginTime);
|
duration<double> elapsed = duration_cast<milliseconds, Clock::rep, Clock::period>(m_EndTime - m_BeginTime);
|
||||||
|
|
||||||
return elapsed.count() * 1000.0;
|
return elapsed.count() * 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +91,6 @@ public:
|
|||||||
string Format(double ms) const
|
string Format(double ms) const
|
||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
|
|
||||||
double x = ms / 1000;
|
double x = ms / 1000;
|
||||||
double secs = fmod(x, 60);
|
double secs = fmod(x, 60);
|
||||||
x /= 60;
|
x /= 60;
|
||||||
@ -146,78 +144,4 @@ private:
|
|||||||
static bool m_TimingInit;//Whether the performance info has bee queried.
|
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().
|
static uint m_ProcessorCount;//The number of cores on the system, set in Init().
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Cross platform critical section class which can be used for thread locking.
|
|
||||||
/// </summary>
|
|
||||||
class EMBER_API CriticalSection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor which initialized the underlying CRITICAL_SECTION object.
|
|
||||||
/// </summary>
|
|
||||||
CriticalSection() { InitializeCriticalSection(&m_CriticalSection); }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor which initialized the underlying CRITICAL_SECTION object
|
|
||||||
/// with the specified spin count value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="spinCount">The spin count.</param>
|
|
||||||
CriticalSection(DWORD spinCount) { InitializeCriticalSectionAndSpinCount(&m_CriticalSection, spinCount); }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the underlying CRITICAL_SECTION object.
|
|
||||||
/// </summary>
|
|
||||||
~CriticalSection() { DeleteCriticalSection(&m_CriticalSection); }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Lock the critical section.
|
|
||||||
/// </summary>
|
|
||||||
void Enter() { EnterCriticalSection(&m_CriticalSection); }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unlock the critical section.
|
|
||||||
/// </summary>
|
|
||||||
void Leave() { LeaveCriticalSection(&m_CriticalSection); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
CRITICAL_SECTION m_CriticalSection;//The Windows specific critical section object.
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor which initialized the underlying pthread_mutex_t object.
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes the underlying pthread_mutex_t object.
|
|
||||||
/// </summary>
|
|
||||||
~CriticalSection() { pthread_mutex_destroy(&m_CriticalSection); }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Lock the critical section.
|
|
||||||
/// </summary>
|
|
||||||
void Enter() { pthread_mutex_lock(&m_CriticalSection); }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unlock the critical section.
|
|
||||||
/// </summary>
|
|
||||||
void Leave() { pthread_mutex_unlock(&m_CriticalSection); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
pthread_mutex_t m_CriticalSection;//The *nix/pthread specific critical section object.
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ public:
|
|||||||
{
|
{
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
|
|
||||||
for (auto& s : errorReport) ss << s << endl;
|
for (auto& s : errorReport) ss << s << "\n";
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
@ -288,12 +288,12 @@ static bool ReadFile(const char* filename, string& buf, bool nullTerminate = tru
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
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;
|
b = false;
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
cout << "Error: Reading file " << filename << " failed." << endl;
|
cout << "Error: Reading file " << filename << " failed.\n";
|
||||||
b = false;
|
b = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ public:
|
|||||||
//released under CC share-alike license.
|
//released under CC share-alike license.
|
||||||
//Less accurate for faster rendering (still very precise).
|
//Less accurate for faster rendering (still very precise).
|
||||||
T const CA = T(0.0003);//The accuracy is the square of CA.
|
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 bo;
|
||||||
int l;
|
int l;
|
||||||
int ii;
|
int ii;
|
||||||
|
@ -2023,9 +2023,9 @@ public:
|
|||||||
virtual string ToString() const override
|
virtual string ToString() const override
|
||||||
{
|
{
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
ss << Variation<T>::ToString() << endl;
|
ss << Variation<T>::ToString() << "\n";
|
||||||
|
|
||||||
for (auto& param : m_Params) ss << param.ToString() << endl;
|
for (auto& param : m_Params) ss << param.ToString() << "\n";
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
@ -1971,7 +1971,7 @@ public:
|
|||||||
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
||||||
{
|
{
|
||||||
int sl = int(rand.Frand01<T>() * m_Slices + T(0.5));
|
int sl = int(rand.Frand01<T>() * m_Slices + T(0.5));
|
||||||
T a = m_Rotation + M_2PI * (sl + rand.Frand01<T>() * m_Thickness) / m_Slices;
|
T a = m_Rotation + m_Pi2Slices * (sl + m_Thickness * rand.Frand01<T>());
|
||||||
T r = m_Weight * rand.Frand01<T>();
|
T r = m_Weight * rand.Frand01<T>();
|
||||||
helper.Out.x = r * std::cos(a);
|
helper.Out.x = r * std::cos(a);
|
||||||
helper.Out.y = r * std::sin(a);
|
helper.Out.y = r * std::sin(a);
|
||||||
@ -1987,9 +1987,10 @@ public:
|
|||||||
string slices = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
string slices = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||||
string rotation = "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 thickness = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||||
|
string pi2Slices = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||||
ss << "\t{\n"
|
ss << "\t{\n"
|
||||||
<< "\t\tint sl = (int)(MwcNext01(mwc) * " << slices << " + (real_t)(0.5));\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"
|
<< "\t\treal_t r = xform->m_VariationWeights[" << varIndex << "] * MwcNext01(mwc);\n"
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< "\t\tvOut.x = r * cos(a);\n"
|
<< "\t\tvOut.x = r * cos(a);\n"
|
||||||
@ -1999,6 +2000,11 @@ public:
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void Precalc() override
|
||||||
|
{
|
||||||
|
m_Pi2Slices = M_2PI / m_Slices;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void Random(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
virtual void Random(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
||||||
{
|
{
|
||||||
m_Params[0].Set(10 * rand.Frand01<T>());//Slices.
|
m_Params[0].Set(10 * rand.Frand01<T>());//Slices.
|
||||||
@ -2014,12 +2020,14 @@ protected:
|
|||||||
m_Params.push_back(ParamWithName<T>(&m_Slices, prefix + "pie_slices", 6, eParamType::INTEGER_NONZERO, 1));
|
m_Params.push_back(ParamWithName<T>(&m_Slices, prefix + "pie_slices", 6, eParamType::INTEGER_NONZERO, 1));
|
||||||
m_Params.push_back(ParamWithName<T>(&m_Rotation, prefix + "pie_rotation", T(0.5), eParamType::REAL_CYCLIC, 0, M_2PI));
|
m_Params.push_back(ParamWithName<T>(&m_Rotation, prefix + "pie_rotation", T(0.5), eParamType::REAL_CYCLIC, 0, M_2PI));
|
||||||
m_Params.push_back(ParamWithName<T>(&m_Thickness, prefix + "pie_thickness", T(0.5), eParamType::REAL, 0, 1));
|
m_Params.push_back(ParamWithName<T>(&m_Thickness, prefix + "pie_thickness", T(0.5), eParamType::REAL, 0, 1));
|
||||||
|
m_Params.push_back(ParamWithName<T>(true, &m_Pi2Slices, prefix + "pie_pi2_slices"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T m_Slices;
|
T m_Slices;
|
||||||
T m_Rotation;
|
T m_Rotation;
|
||||||
T m_Thickness;
|
T m_Thickness;
|
||||||
|
T m_Pi2Slices;//Precalc
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -88,15 +88,13 @@ public:
|
|||||||
<< "\t\t{\n"
|
<< "\t\t{\n"
|
||||||
<< "\t\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * t * cos(theta);\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.y = xform->m_VariationWeights[" << varIndex << "] * t * sin(theta);\n"
|
||||||
<< "\t\t\tvOut.z = 0;\n"
|
|
||||||
<< "\t\t}\n"
|
<< "\t\t}\n"
|
||||||
<< "\t\telse\n"
|
<< "\t\telse\n"
|
||||||
<< "\t\t{\n"
|
<< "\t\t{\n"
|
||||||
<< "\t\t\tvOut.x = 0;\n"
|
<< "\t\t\tvOut.x = 0;\n"
|
||||||
<< "\t\t\tvOut.y = 0;\n"
|
<< "\t\t\tvOut.y = 0;\n"
|
||||||
<< "\t\t\tvOut.z = 0;\n"
|
|
||||||
<< "\t\t}\n"
|
<< "\t\t}\n"
|
||||||
<< "\t\tvOut.Z = " << DefaultZCl()
|
<< "\t\tvOut.z = " << DefaultZCl()
|
||||||
<< "\t}\n";
|
<< "\t}\n";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
@ -2726,8 +2724,8 @@ public:
|
|||||||
|
|
||||||
virtual void Precalc() override
|
virtual void Precalc() override
|
||||||
{
|
{
|
||||||
T pa = 2 * T(M_PI) / m_P;
|
T pa = 2 * T(M_PI) / Zeps(m_P);
|
||||||
T qa = 2 * T(M_PI) / m_Q;
|
T qa = 2 * T(M_PI) / Zeps(m_Q);
|
||||||
T r = (1 - std::cos(pa)) / (std::cos(pa) + std::cos(qa)) + 1;
|
T r = (1 - std::cos(pa)) / (std::cos(pa) + std::cos(qa)) + 1;
|
||||||
T a = m_N * pa;
|
T a = m_N * pa;
|
||||||
|
|
||||||
@ -2822,15 +2820,15 @@ public:
|
|||||||
|
|
||||||
virtual void Precalc() override
|
virtual void Precalc() override
|
||||||
{
|
{
|
||||||
T r2 = 1 - (std::cos(2 * T(M_PI) / m_P) - 1) /
|
T r2 = 1 - (std::cos(2 * T(M_PI) / Zeps(m_P)) - 1) /
|
||||||
(std::cos(2 * T(M_PI) / m_P) + std::cos(2 * T(M_PI) / m_Q));
|
(std::cos(2 * T(M_PI) / Zeps(m_P)) + std::cos(2 * T(M_PI) / Zeps(m_Q)));
|
||||||
|
|
||||||
if (r2 > 0)
|
if (r2 > 0)
|
||||||
m_R = 1 / std::sqrt(r2);
|
m_R = 1 / std::sqrt(r2);
|
||||||
else
|
else
|
||||||
m_R = 1;
|
m_R = 1;
|
||||||
|
|
||||||
m_Pa = 2 * T(M_PI) / m_P;
|
m_Pa = 2 * T(M_PI) / Zeps(m_P);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -2841,7 +2839,7 @@ protected:
|
|||||||
m_Params.push_back(ParamWithName<T>(&m_P, prefix + "hypertile1_p", 3, eParamType::INTEGER, 3, T(0x7fffffff)));
|
m_Params.push_back(ParamWithName<T>(&m_P, prefix + "hypertile1_p", 3, eParamType::INTEGER, 3, T(0x7fffffff)));
|
||||||
m_Params.push_back(ParamWithName<T>(&m_Q, prefix + "hypertile1_q", 7, eParamType::INTEGER, 3, T(0x7fffffff)));
|
m_Params.push_back(ParamWithName<T>(&m_Q, prefix + "hypertile1_q", 7, eParamType::INTEGER, 3, T(0x7fffffff)));
|
||||||
m_Params.push_back(ParamWithName<T>(true, &m_Pa, prefix + "hypertile1_pa"));//Precalc.
|
m_Params.push_back(ParamWithName<T>(true, &m_Pa, prefix + "hypertile1_pa"));//Precalc.
|
||||||
m_Params.push_back(ParamWithName<T>(true, &m_R, prefix + "hypertile1_r"));
|
m_Params.push_back(ParamWithName<T>(true, &m_R, prefix + "hypertile1_r"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2913,15 +2911,15 @@ public:
|
|||||||
|
|
||||||
virtual void Precalc() override
|
virtual void Precalc() override
|
||||||
{
|
{
|
||||||
T r2 = 1 - (std::cos(2 * T(M_PI) / m_P) - 1) /
|
T r2 = 1 - (std::cos(2 * T(M_PI) / Zeps(m_P)) - 1) /
|
||||||
(std::cos(2 * T(M_PI) / m_P) + std::cos(2 * T(M_PI) / m_Q));
|
(std::cos(2 * T(M_PI) / Zeps(m_P)) + std::cos(2 * T(M_PI) / Zeps(m_Q)));
|
||||||
|
|
||||||
if (r2 > 0)
|
if (r2 > 0)
|
||||||
m_R = 1 / std::sqrt(r2);
|
m_R = 1 / std::sqrt(r2);
|
||||||
else
|
else
|
||||||
m_R = 1;
|
m_R = 1;
|
||||||
|
|
||||||
m_Pa = 2 * T(M_PI) / m_P;
|
m_Pa = 2 * T(M_PI) / Zeps(m_P);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -3001,13 +2999,13 @@ public:
|
|||||||
|
|
||||||
virtual void Precalc() override
|
virtual void Precalc() override
|
||||||
{
|
{
|
||||||
T pa = 2 * T(M_PI) / m_P;
|
T pa = 2 * T(M_PI) / Zeps(m_P);
|
||||||
T qa = 2 * T(M_PI) / m_Q;
|
T qa = 2 * T(M_PI) / Zeps(m_Q);
|
||||||
T r = -(std::cos(pa) - 1) / (std::cos(pa) + std::cos(qa));
|
T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa));
|
||||||
T na = m_N * pa;
|
T na = m_N * pa;
|
||||||
|
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
r = 1 / std::sqrt(1 + r);
|
r = 1 / Zeps(std::sqrt(1 + r));
|
||||||
else
|
else
|
||||||
r = 1;
|
r = 1;
|
||||||
|
|
||||||
@ -3119,12 +3117,12 @@ public:
|
|||||||
|
|
||||||
virtual void Precalc() override
|
virtual void Precalc() override
|
||||||
{
|
{
|
||||||
T pa = M_2PI / m_P;
|
T pa = M_2PI / Zeps(m_P);
|
||||||
T qa = M_2PI / m_Q;
|
T qa = M_2PI / Zeps(m_Q);
|
||||||
T r = -(std::cos(pa) - 1) / (std::cos(pa) + std::cos(qa));
|
T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa));
|
||||||
|
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
r = 1 / std::sqrt(1 + r);
|
r = 1 / Zeps(std::sqrt(1 + r));
|
||||||
else
|
else
|
||||||
r = 1;
|
r = 1;
|
||||||
|
|
||||||
@ -3219,12 +3217,12 @@ public:
|
|||||||
|
|
||||||
virtual void Precalc() override
|
virtual void Precalc() override
|
||||||
{
|
{
|
||||||
T pa = M_2PI / m_P;
|
T pa = M_2PI / Zeps(m_P);
|
||||||
T qa = M_2PI / m_Q;
|
T qa = M_2PI / Zeps(m_Q);
|
||||||
T r = -(std::cos(pa) - 1) / (std::cos(pa) + std::cos(qa));
|
T r = -(std::cos(pa) - 1) / Zeps(std::cos(pa) + std::cos(qa));
|
||||||
|
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
r = 1 / std::sqrt(1 + r);
|
r = 1 / Zeps(std::sqrt(1 + r));
|
||||||
else
|
else
|
||||||
r = 1;
|
r = 1;
|
||||||
|
|
||||||
|
@ -3466,7 +3466,7 @@ public:
|
|||||||
int loc;
|
int loc;
|
||||||
T tempx, tempy;
|
T tempx, tempy;
|
||||||
T lrmaj = m_Weight;//Sets hexagon length radius - major plane.
|
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;
|
T sumX, sumY;
|
||||||
|
|
||||||
if (m_VarType == eVariationType::VARTYPE_REG)
|
if (m_VarType == eVariationType::VARTYPE_REG)
|
||||||
@ -3561,7 +3561,7 @@ public:
|
|||||||
<< "\t\tint loc;\n"
|
<< "\t\tint loc;\n"
|
||||||
<< "\t\treal_t tempx, tempy;\n"
|
<< "\t\treal_t tempx, tempy;\n"
|
||||||
<< "\t\treal_t lrmaj = xform->m_VariationWeights[" << varIndex << "];\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";
|
<< "\t\treal_t sumX, sumY;\n\n";
|
||||||
|
|
||||||
if (m_VarType == eVariationType::VARTYPE_REG)
|
if (m_VarType == eVariationType::VARTYPE_REG)
|
||||||
|
@ -1495,7 +1495,7 @@ public:
|
|||||||
/// <param name="rand">The rand.</param>
|
/// <param name="rand">The rand.</param>
|
||||||
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
|
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& 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))
|
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 leftBorder = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||||
string rightBorder = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
string rightBorder = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
|
||||||
ss << "\t{\n"
|
ss << "\t{\n"
|
||||||
<< "\t\treal_t gradTmp, secTmp, xTmp, yTmp;\n"
|
<< "\t\treal_t gradTmp, secTmp, xTmp = 0, yTmp = 0;\n"
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< "\t\tif ((vIn.x < " << leftBorder << ") || (vIn.x > " << rightBorder << ") || (vIn.y < " << topBorder << ") || (vIn.y > " << bottomBorder << "))\n"
|
<< "\t\tif ((vIn.x < " << leftBorder << ") || (vIn.x > " << rightBorder << ") || (vIn.y < " << topBorder << ") || (vIn.y > " << bottomBorder << "))\n"
|
||||||
<< "\t\t{\n"
|
<< "\t\t{\n"
|
||||||
@ -3626,8 +3626,6 @@ private:
|
|||||||
case LERP_BEZIER:
|
case LERP_BEZIER:
|
||||||
return BezierQuadMap(x, m);
|
return BezierQuadMap(x, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
return x * m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SynthSinCos(SynthStruct& synth, T theta, T& s, T& c, int sineType)
|
inline void SynthSinCos(SynthStruct& synth, T theta, T& s, T& c, int sineType)
|
||||||
|
@ -573,7 +573,7 @@ public:
|
|||||||
{
|
{
|
||||||
int posNeg = 1;
|
int posNeg = 1;
|
||||||
T th = 0;
|
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 rad = helper.m_PrecalcSqrtSumSquares;
|
||||||
T curve1 = rad / m_L;
|
T curve1 = rad / m_L;
|
||||||
T curve2 = Sqr(curve1);
|
T curve2 = Sqr(curve1);
|
||||||
|
@ -1113,7 +1113,7 @@ public:
|
|||||||
<< "C: " << m_Affine.C() << " "
|
<< "C: " << m_Affine.C() << " "
|
||||||
<< "D: " << m_Affine.D() << " "
|
<< "D: " << m_Affine.D() << " "
|
||||||
<< "E: " << m_Affine.E() << " "
|
<< "E: " << m_Affine.E() << " "
|
||||||
<< "F: " << m_Affine.F() << " " << endl;
|
<< "F: " << m_Affine.F() << " \n";
|
||||||
|
|
||||||
if (m_HasPost)
|
if (m_HasPost)
|
||||||
{
|
{
|
||||||
@ -1122,27 +1122,27 @@ public:
|
|||||||
<< "Post C: " << m_Post.C() << " "
|
<< "Post C: " << m_Post.C() << " "
|
||||||
<< "Post D: " << m_Post.D() << " "
|
<< "Post D: " << m_Post.D() << " "
|
||||||
<< "Post E: " << m_Post.E() << " "
|
<< "Post E: " << m_Post.E() << " "
|
||||||
<< "Post F: " << m_Post.F() << " " << endl;
|
<< "Post F: " << m_Post.F() << " \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ss << "Weight: " << m_Weight << endl;
|
ss << "Weight: " << m_Weight;
|
||||||
ss << "ColorX: " << m_ColorX << endl;
|
ss << "\nColorX: " << m_ColorX;
|
||||||
ss << "ColorY: " << m_ColorY << endl;
|
ss << "\nColorY: " << m_ColorY;
|
||||||
ss << "Direct Color: " << m_DirectColor << endl;
|
ss << "\nDirect Color: " << m_DirectColor;
|
||||||
ss << "Color Speed: " << m_ColorSpeed << endl;
|
ss << "\nColor Speed: " << m_ColorSpeed;
|
||||||
ss << "Animate: " << m_Animate << endl;
|
ss << "\nAnimate: " << m_Animate;
|
||||||
ss << "Opacity: " << m_Opacity << endl;
|
ss << "\nOpacity: " << m_Opacity;
|
||||||
ss << "Viz Adjusted: " << m_VizAdjusted << endl;
|
ss << "\nViz Adjusted: " << m_VizAdjusted;
|
||||||
ss << "Wind: " << m_Wind[0] << ", " << m_Wind[1] << endl;
|
ss << "\nWind: " << m_Wind[0] << ", " << m_Wind[1];
|
||||||
ss << "Motion Frequency: " << m_MotionFreq << endl;
|
ss << "\nMotion Frequency: " << m_MotionFreq;
|
||||||
ss << "Motion Func: " << m_MotionFunc << endl;
|
ss << "\nMotion Func: " << m_MotionFunc;
|
||||||
ss << "Motion Offset: " << m_MotionOffset << endl;
|
ss << "\nMotion Offset: " << m_MotionOffset;
|
||||||
const_cast<Xform<T>*>(this)->AllVarsFunc([&] (vector<Variation<T>*>& variations, bool & keepGoing)
|
const_cast<Xform<T>*>(this)->AllVarsFunc([&] (vector<Variation<T>*>& variations, bool & keepGoing)
|
||||||
{
|
{
|
||||||
for (auto var : variations)
|
for (auto var : variations)
|
||||||
ss << var->ToString() << endl;
|
ss << var->ToString() << "\n";
|
||||||
|
|
||||||
ss << endl;
|
ss << "\n";
|
||||||
});
|
});
|
||||||
|
|
||||||
if (XaosPresent())
|
if (XaosPresent())
|
||||||
@ -1150,7 +1150,7 @@ public:
|
|||||||
for (auto xaos : m_Xaos)
|
for (auto xaos : m_Xaos)
|
||||||
ss << xaos << " ";
|
ss << xaos << " ";
|
||||||
|
|
||||||
ss << endl;
|
ss << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
|
@ -35,10 +35,10 @@ public:
|
|||||||
m_OriginalLocale = setlocale(category, nullptr);//Query.
|
m_OriginalLocale = setlocale(category, nullptr);//Query.
|
||||||
|
|
||||||
if (m_OriginalLocale.empty())
|
if (m_OriginalLocale.empty())
|
||||||
cout << "Couldn't get original locale." << endl;
|
cout << "Couldn't get original locale.\n";
|
||||||
|
|
||||||
if (setlocale(category, loc) == nullptr)//Set.
|
if (setlocale(category, loc) == nullptr)//Set.
|
||||||
cout << "Couldn't set new locale " << category << ", " << loc << "." << endl;
|
cout << "Couldn't set new locale " << category << ", " << loc << ".\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -48,7 +48,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (!m_OriginalLocale.empty())
|
if (!m_OriginalLocale.empty())
|
||||||
if (setlocale(m_Category, m_OriginalLocale.c_str()) == nullptr)//Restore.
|
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:
|
private:
|
||||||
@ -327,13 +327,13 @@ public:
|
|||||||
{
|
{
|
||||||
if (embers[0].m_Interp == eInterp::EMBER_INTERP_SMOOTH)
|
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;
|
embers[0].m_Interp = eInterp::EMBER_INTERP_LINEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emberSize >= 2 && embers[emberSize - 2].m_Interp == eInterp::EMBER_INTERP_SMOOTH)
|
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;
|
embers[emberSize - 2].m_Interp = eInterp::EMBER_INTERP_LINEAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,7 +526,7 @@ private:
|
|||||||
char* attStr;
|
char* attStr;
|
||||||
const char* loc = __FUNCTION__;
|
const char* loc = __FUNCTION__;
|
||||||
int soloXform = -1;
|
int soloXform = -1;
|
||||||
size_t i, count, index = 0;
|
size_t i, count = 0, index = 0;
|
||||||
double vals[16];
|
double vals[16];
|
||||||
xmlAttrPtr att, curAtt;
|
xmlAttrPtr att, curAtt;
|
||||||
xmlNodePtr editNode, childNode, motionNode;
|
xmlNodePtr editNode, childNode, motionNode;
|
||||||
|
@ -15,11 +15,11 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
std::cout.imbue(std::locale(""));
|
std::cout.imbue(std::locale(""));
|
||||||
|
|
||||||
if (opt.DumpArgs())
|
if (opt.DumpArgs())
|
||||||
cout << opt.GetValues(eOptionUse::OPT_USE_ANIMATE) << endl;
|
cout << opt.GetValues(eOptionUse::OPT_USE_ANIMATE) << "\n";
|
||||||
|
|
||||||
if (opt.OpenCLInfo())
|
if (opt.OpenCLInfo())
|
||||||
{
|
{
|
||||||
cout << "\nOpenCL Info: " << endl;
|
cout << "\nOpenCL Info: \n";
|
||||||
cout << info->DumpInfo();
|
cout << info->DumpInfo();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
unique_ptr<RenderProgress<T>> progress;
|
unique_ptr<RenderProgress<T>> progress;
|
||||||
vector<unique_ptr<Renderer<T, float>>> renderers;
|
vector<unique_ptr<Renderer<T, float>>> renderers;
|
||||||
vector<string> errorReport;
|
vector<string> errorReport;
|
||||||
CriticalSection verboseCs;
|
std::recursive_mutex verboseCs;
|
||||||
|
|
||||||
if (opt.EmberCL())
|
if (opt.EmberCL())
|
||||||
{
|
{
|
||||||
@ -53,7 +53,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (!renderers.size() || renderers.size() != devices.size())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,19 +63,19 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
renderers[0]->Callback(progress.get());
|
renderers[0]->Callback(progress.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "Using OpenCL to render." << endl;
|
cout << "Using OpenCL to render.\n";
|
||||||
|
|
||||||
if (opt.Verbose())
|
if (opt.Verbose())
|
||||||
{
|
{
|
||||||
for (auto& device : devices)
|
for (auto& device : devices)
|
||||||
{
|
{
|
||||||
cout << "Platform: " << info->PlatformName(device.first) << endl;
|
cout << "Platform: " << info->PlatformName(device.first) << "\n";
|
||||||
cout << "Device: " << info->DeviceName(device.first, device.second) << endl;
|
cout << "Device: " << info->DeviceName(device.first, device.second) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.ThreadCount() > 1)
|
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);
|
opt.ThreadCount(1);
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.BitsPerChannel() != 8)
|
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);
|
opt.BitsPerChannel(8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (!tempRenderer.get())
|
if (!tempRenderer.get())
|
||||||
{
|
{
|
||||||
cout << "Renderer creation failed, exiting." << endl;
|
cout << "Renderer creation failed, exiting.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,12 +110,12 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.ThreadCount() == 0)
|
if (opt.ThreadCount() == 0)
|
||||||
{
|
{
|
||||||
cout << "Using " << Timing::ProcessorCount() << " automatically detected threads." << endl;
|
cout << "Using " << Timing::ProcessorCount() << " automatically detected threads.\n";
|
||||||
opt.ThreadCount(Timing::ProcessorCount());
|
opt.ThreadCount(Timing::ProcessorCount());
|
||||||
}
|
}
|
||||||
else
|
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);
|
tempRenderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr);
|
||||||
@ -125,7 +125,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
if (!InitPaletteList<T>(opt.PalettePath()))
|
if (!InitPaletteList<T>(opt.PalettePath()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
cout << "Parsing ember file " << opt.Input() << endl;
|
cout << "Parsing ember file " << opt.Input() << "\n";
|
||||||
|
|
||||||
if (!ParseEmberFile(parser, opt.Input(), embers))
|
if (!ParseEmberFile(parser, opt.Input(), embers))
|
||||||
return false;
|
return false;
|
||||||
@ -134,7 +134,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (embers.size() <= 1)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,37 +143,37 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
opt.Format() != "ppm" &&
|
opt.Format() != "ppm" &&
|
||||||
opt.Format() != "bmp")
|
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;
|
channels = opt.Format() == "png" ? 4 : 3;
|
||||||
|
|
||||||
if (opt.BitsPerChannel() == 16 && opt.Format() != "png")
|
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);
|
opt.BitsPerChannel(8);
|
||||||
}
|
}
|
||||||
else if (opt.BitsPerChannel() != 8 && opt.BitsPerChannel() != 16)
|
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);
|
opt.BitsPerChannel(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.InsertPalette() && 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);
|
opt.InsertPalette(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.AspectRatio() < 0)
|
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);
|
opt.AspectRatio(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.Dtime() < 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);
|
opt.Dtime(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,13 +181,13 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
{
|
{
|
||||||
if (opt.Time())
|
if (opt.Time())
|
||||||
{
|
{
|
||||||
cout << "Cannot specify both time and frame." << endl;
|
cout << "Cannot specify both time and frame.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.FirstFrame() || opt.LastFrame())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
{
|
{
|
||||||
if (opt.FirstFrame() || opt.LastFrame())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (i > 0 && embers[i].m_Time == embers[i - 1].m_Time)
|
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++;
|
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.
|
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_FinalRasW = 1920;
|
||||||
embers[i].m_FinalRasH = 1080;
|
embers[i].m_FinalRasH = 1080;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (embers[i].m_FinalRasW == 0 || embers[i].m_FinalRasH == 0)
|
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_FinalRasW = 1920;
|
||||||
embers[i].m_FinalRasH = 1080;
|
embers[i].m_FinalRasH = 1080;
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
(embers[i].m_FinalRasH != embers[0].m_FinalRasH))
|
(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 <<
|
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_FinalRasW = embers[0].m_FinalRasW;
|
||||||
embers[i].m_FinalRasH = embers[0].m_FinalRasH;
|
embers[i].m_FinalRasH = embers[0].m_FinalRasH;
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (unsorted)
|
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<T>);
|
std::sort(embers.begin(), embers.end(), &CompareEmbers<T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (!opt.Out().empty())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +339,7 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
writeSuccess = WriteBmp(filename.c_str(), finalImagep, w, h);
|
writeSuccess = WriteBmp(filename.c_str(), finalImagep, w, h);
|
||||||
|
|
||||||
if (!writeSuccess)
|
if (!writeSuccess)
|
||||||
cout << "Error writing " << filename << endl;
|
cout << "Error writing " << filename << "\n";
|
||||||
};
|
};
|
||||||
atomfTime.store(opt.FirstFrame());
|
atomfTime.store(opt.FirstFrame());
|
||||||
std::function<void(size_t)> iterFunc = [&](size_t index)
|
std::function<void(size_t)> iterFunc = [&](size_t index)
|
||||||
@ -361,16 +361,15 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.Verbose() && ((opt.LastFrame() - opt.FirstFrame()) / opt.Dtime() >= 1))
|
if (opt.Verbose() && ((opt.LastFrame() - opt.FirstFrame()) / opt.Dtime() >= 1))
|
||||||
{
|
{
|
||||||
verboseCs.Enter();
|
rlg l(verboseCs);
|
||||||
cout << "Time = " << ftime << " / " << opt.LastFrame() << " / " << opt.Dtime() << endl;
|
cout << "Time = " << ftime << " / " << opt.LastFrame() << " / " << opt.Dtime() << "\n";
|
||||||
verboseCs.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->Reset();
|
renderer->Reset();
|
||||||
|
|
||||||
if ((renderer->Run(finalImages[finalImageIndex], localTime) != eRenderStatus::RENDER_OK) || renderer->Aborted() || finalImages[finalImageIndex].empty())
|
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.
|
renderer->DumpErrorReport();//Something went wrong, print errors.
|
||||||
atomfTime.store(opt.LastFrame() + 1);//Abort all threads if any of them encounter an error.
|
atomfTime.store(opt.LastFrame() + 1);//Abort all threads if any of them encounter an error.
|
||||||
break;
|
break;
|
||||||
@ -386,9 +385,8 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.Verbose())
|
if (opt.Verbose())
|
||||||
{
|
{
|
||||||
verboseCs.Enter();
|
rlg l(verboseCs);
|
||||||
cout << "Writing " << flameName << endl;
|
cout << "Writing " << flameName << "\n";
|
||||||
verboseCs.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Interpolater<T>::Interpolate(embers, localTime, 0, centerEmber);//Get center flame.
|
Interpolater<T>::Interpolate(embers, localTime, 0, centerEmber);//Get center flame.
|
||||||
@ -404,16 +402,15 @@ bool EmberAnimate(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.Verbose())
|
if (opt.Verbose())
|
||||||
{
|
{
|
||||||
verboseCs.Enter();
|
rlg l(verboseCs);
|
||||||
cout << "\nIters ran/requested: " + os.str() << endl;
|
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 << "Render time: " << t.Format(stats.m_RenderMs) << "\n";
|
||||||
cout << "Pure iter time: " << t.Format(stats.m_IterMs) << endl;
|
cout << "Pure iter time: " << t.Format(stats.m_IterMs) << "\n";
|
||||||
cout << "Iters/sec: " << size_t(stats.m_Iters / (stats.m_IterMs / 1000.0)) << endl;
|
cout << "Iters/sec: " << size_t(stats.m_Iters / (stats.m_IterMs / 1000.0)) << "\n";
|
||||||
cout << "Writing " << filename << endl << endl;
|
cout << "Writing " << filename << "\n\n";
|
||||||
verboseCs.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Run image writing in a thread. Although doing it this way duplicates the final output memory, it saves a lot of time
|
//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)
|
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<float>(opt);
|
b = EmberAnimate<float>(opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,39 +3,39 @@
|
|||||||
|
|
||||||
namespace EmberCLns
|
namespace EmberCLns
|
||||||
{
|
{
|
||||||
std::unordered_map<string, string> FunctionMapper::m_GlobalMap;
|
std::unordered_map<string, string> FunctionMapper::s_GlobalMap;
|
||||||
|
|
||||||
FunctionMapper::FunctionMapper()
|
FunctionMapper::FunctionMapper()
|
||||||
{
|
{
|
||||||
if (m_GlobalMap.empty())
|
if (s_GlobalMap.empty())
|
||||||
{
|
{
|
||||||
m_GlobalMap["LRint"] =
|
s_GlobalMap["LRint"] =
|
||||||
"inline real_t LRint(real_t x)\n"
|
"inline real_t LRint(real_t x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" intPrec temp = (x >= 0.0 ? (intPrec)(x + 0.5) : (intPrec)(x - 0.5));\n"
|
" intPrec temp = (x >= 0.0 ? (intPrec)(x + 0.5) : (intPrec)(x - 0.5));\n"
|
||||||
" return (real_t)temp;\n"
|
" return (real_t)temp;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Round"] =
|
s_GlobalMap["Round"] =
|
||||||
"inline real_t Round(real_t r)\n"
|
"inline real_t Round(real_t r)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);\n"
|
" return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Sign"] =
|
s_GlobalMap["Sign"] =
|
||||||
"inline real_t Sign(real_t v)\n"
|
"inline real_t Sign(real_t v)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return (v < 0.0) ? -1 : (v > 0.0) ? 1 : 0.0;\n"
|
" return (v < 0.0) ? -1 : (v > 0.0) ? 1 : 0.0;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["SignNz"] =
|
s_GlobalMap["SignNz"] =
|
||||||
"inline real_t SignNz(real_t v)\n"
|
"inline real_t SignNz(real_t v)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return (v < 0.0) ? -1.0 : 1.0;\n"
|
" return (v < 0.0) ? -1.0 : 1.0;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Sqr"] =
|
s_GlobalMap["Sqr"] =
|
||||||
"inline real_t Sqr(real_t v)\n"
|
"inline real_t Sqr(real_t v)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return v * v;\n"
|
" return v * v;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["SafeSqrt"] =
|
s_GlobalMap["SafeSqrt"] =
|
||||||
"inline real_t SafeSqrt(real_t x)\n"
|
"inline real_t SafeSqrt(real_t x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" if (x <= 0.0)\n"
|
" if (x <= 0.0)\n"
|
||||||
@ -43,7 +43,7 @@ FunctionMapper::FunctionMapper()
|
|||||||
"\n"
|
"\n"
|
||||||
" return sqrt(x);\n"
|
" return sqrt(x);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["SafeDivInv"] =
|
s_GlobalMap["SafeDivInv"] =
|
||||||
"inline real_t SafeDivInv(real_t q, real_t r)\n"
|
"inline real_t SafeDivInv(real_t q, real_t r)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" if (r < EPS)\n"
|
" if (r < EPS)\n"
|
||||||
@ -51,81 +51,81 @@ FunctionMapper::FunctionMapper()
|
|||||||
"\n"
|
"\n"
|
||||||
" return q / r;\n"
|
" return q / r;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Cube"] =
|
s_GlobalMap["Cube"] =
|
||||||
"inline real_t Cube(real_t v)\n"
|
"inline real_t Cube(real_t v)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return v * v * v;\n"
|
" return v * v * v;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Hypot"] =
|
s_GlobalMap["Hypot"] =
|
||||||
"inline real_t Hypot(real_t x, real_t y)\n"
|
"inline real_t Hypot(real_t x, real_t y)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return sqrt(SQR(x) + SQR(y));\n"
|
" return sqrt(SQR(x) + SQR(y));\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Spread"] =
|
s_GlobalMap["Spread"] =
|
||||||
"inline real_t Spread(real_t x, real_t y)\n"
|
"inline real_t Spread(real_t x, real_t y)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return Hypot(x, y) * ((x) > 0.0 ? 1.0 : -1.0);\n"
|
" return Hypot(x, y) * ((x) > 0.0 ? 1.0 : -1.0);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Powq4"] =
|
s_GlobalMap["Powq4"] =
|
||||||
"inline real_t Powq4(real_t x, real_t y)\n"
|
"inline real_t Powq4(real_t x, real_t y)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return pow(fabs(x), y) * SignNz(x);\n"
|
" return pow(fabs(x), y) * SignNz(x);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Powq4c"] =
|
s_GlobalMap["Powq4c"] =
|
||||||
"inline real_t Powq4c(real_t x, real_t y)\n"
|
"inline real_t Powq4c(real_t x, real_t y)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return y == 1.0 ? x : Powq4(x, y);\n"
|
" return y == 1.0 ? x : Powq4(x, y);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Zeps"] =
|
s_GlobalMap["Zeps"] =
|
||||||
"inline real_t Zeps(real_t x)\n"
|
"inline real_t Zeps(real_t x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return x == 0.0 ? EPS : x;\n"
|
" return x == 0.0 ? EPS : x;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Lerp"] =
|
s_GlobalMap["Lerp"] =
|
||||||
"inline real_t Lerp(real_t a, real_t b, real_t p)\n"
|
"inline real_t Lerp(real_t a, real_t b, real_t p)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return a + (b - a) * p;\n"
|
" return a + (b - a) * p;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Fabsmod"] =
|
s_GlobalMap["Fabsmod"] =
|
||||||
"inline real_t Fabsmod(real_t v)\n"
|
"inline real_t Fabsmod(real_t v)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" real_t dummy;\n"
|
" real_t dummy;\n"
|
||||||
"\n"
|
"\n"
|
||||||
" return modf(v, &dummy);\n"
|
" return modf(v, &dummy);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Fosc"] =
|
s_GlobalMap["Fosc"] =
|
||||||
"inline real_t Fosc(real_t p, real_t amp, real_t ph)\n"
|
"inline real_t Fosc(real_t p, real_t amp, real_t ph)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return 0.5 - cos(p * amp + ph) * 0.5;\n"
|
" return 0.5 - cos(p * amp + ph) * 0.5;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Foscn"] =
|
s_GlobalMap["Foscn"] =
|
||||||
"inline real_t Foscn(real_t p, real_t ph)\n"
|
"inline real_t Foscn(real_t p, real_t ph)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return 0.5 - cos(p + ph) * 0.5;\n"
|
" return 0.5 - cos(p + ph) * 0.5;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["LogScale"] =
|
s_GlobalMap["LogScale"] =
|
||||||
"inline real_t LogScale(real_t x)\n"
|
"inline real_t LogScale(real_t x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return x == 0.0 ? 0.0 : log((fabs(x) + 1) * M_E) * SignNz(x) / M_E;\n"
|
" return x == 0.0 ? 0.0 : log((fabs(x) + 1) * M_E) * SignNz(x) / M_E;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["LogMap"] =
|
s_GlobalMap["LogMap"] =
|
||||||
"inline real_t LogMap(real_t x)\n"
|
"inline real_t LogMap(real_t x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return x == 0.0 ? 0.0 : (M_E + log(x * M_E)) * 0.25 * SignNz(x);\n"
|
" return x == 0.0 ? 0.0 : (M_E + log(x * M_E)) * 0.25 * SignNz(x);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["ClampGte"] =
|
s_GlobalMap["ClampGte"] =
|
||||||
"inline real_t ClampGte(real_t val, real_t gte)\n"
|
"inline real_t ClampGte(real_t val, real_t gte)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" return (val < gte) ? gte : val;\n"
|
" return (val < gte) ? gte : val;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Swap"] =
|
s_GlobalMap["Swap"] =
|
||||||
"inline void Swap(real_t* val1, real_t* val2)\n"
|
"inline void Swap(real_t* val1, real_t* val2)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" real_t tmp = *val1;\n"
|
" real_t tmp = *val1;\n"
|
||||||
" *val1 = *val2;\n"
|
" *val1 = *val2;\n"
|
||||||
" *val2 = tmp;\n"
|
" *val2 = tmp;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Vratio"] =
|
s_GlobalMap["Vratio"] =
|
||||||
"inline real_t Vratio(real2* p, real2* q, real2* u)\n"
|
"inline real_t Vratio(real2* p, real2* q, real2* u)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" real2 pmq = *p - *q;\n"
|
" real2 pmq = *p - *q;\n"
|
||||||
@ -135,7 +135,7 @@ FunctionMapper::FunctionMapper()
|
|||||||
"\n"
|
"\n"
|
||||||
" return 2 * (((*u).x - (*q).x) * pmq.x + ((*u).y - (*q).y) * pmq.y) / Zeps(SQR(pmq.x) + SQR(pmq.y));\n"
|
" return 2 * (((*u).x - (*q).x) * pmq.x + ((*u).y - (*q).y) * pmq.y) / Zeps(SQR(pmq.x) + SQR(pmq.y));\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Closest"] =
|
s_GlobalMap["Closest"] =
|
||||||
"inline int Closest(real2* p, int n, real2* u)\n"
|
"inline int Closest(real2* p, int n, real2* u)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" real_t d2;\n"
|
" real_t d2;\n"
|
||||||
@ -155,7 +155,7 @@ FunctionMapper::FunctionMapper()
|
|||||||
"\n"
|
"\n"
|
||||||
" return j;\n"
|
" return j;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["Voronoi"] =
|
s_GlobalMap["Voronoi"] =
|
||||||
"inline real_t Voronoi(real2* p, int n, int q, real2* u)\n"
|
"inline real_t Voronoi(real2* p, int n, int q, real2* u)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" real_t ratio;\n"
|
" real_t ratio;\n"
|
||||||
@ -175,7 +175,7 @@ FunctionMapper::FunctionMapper()
|
|||||||
"\n"
|
"\n"
|
||||||
" return ratiomax;\n"
|
" return ratiomax;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
m_GlobalMap["SimplexNoise3D"] =
|
s_GlobalMap["SimplexNoise3D"] =
|
||||||
"inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real3* grad)\n"
|
"inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real3* grad)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" real3 c[4];\n"
|
" real3 c[4];\n"
|
||||||
@ -263,7 +263,7 @@ FunctionMapper::FunctionMapper()
|
|||||||
"\n"
|
"\n"
|
||||||
" return 32 * n;\n"
|
" return 32 * n;\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"
|
"inline real_t PerlinNoise3D(real3* v, __global real_t* p, __global real3* grad, real_t aScale, real_t fScale, int octaves)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int i;\n"
|
" int i;\n"
|
||||||
@ -281,11 +281,11 @@ FunctionMapper::FunctionMapper()
|
|||||||
"\n"
|
"\n"
|
||||||
" return n;\n"
|
" return n;\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"
|
"inline void JacobiElliptic(real_t uu, real_t emmc, real_t* sn, real_t* cn, real_t* dn)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" real_t CA = 0.0003;\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 bo;\n"
|
||||||
" int l;\n"
|
" int l;\n"
|
||||||
" int ii;\n"
|
" int ii;\n"
|
||||||
@ -371,11 +371,16 @@ FunctionMapper::FunctionMapper()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a pointer to the text of the global function whose name is the passed in string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The function name to retrieve</param>
|
||||||
|
/// <returns>A pointer to the function body string if found, else nullptr.</returns>
|
||||||
const string* FunctionMapper::GetGlobalFunc(const string& func)
|
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;
|
return &text->second;
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -16,6 +16,6 @@ public:
|
|||||||
static const string* GetGlobalFunc(const string& func);
|
static const string* GetGlobalFunc(const string& func);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unordered_map<string, string> m_GlobalMap;
|
static std::unordered_map<string, string> s_GlobalMap;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -575,7 +575,7 @@ string IterOpenCLKernelCreator<T>::GlobalFunctionsString(const Ember<T>& ember)
|
|||||||
|
|
||||||
for (auto& funcName : funcNames)
|
for (auto& funcName : funcNames)
|
||||||
if (auto text = m_FunctionMapper.GetGlobalFunc(funcName))
|
if (auto text = m_FunctionMapper.GetGlobalFunc(funcName))
|
||||||
os << *text << endl;
|
os << *text << "\n";
|
||||||
|
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
@ -643,7 +643,7 @@ void IterOpenCLKernelCreator<T>::ParVarIndexDefines(const Ember<T>& ember, pair<
|
|||||||
if (!parVar->Params()[k].IsState())
|
if (!parVar->Params()[k].IsState())
|
||||||
{
|
{
|
||||||
if (doString)
|
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);
|
auto elements = parVar->Params()[k].Size() / sizeof(T);
|
||||||
|
|
||||||
@ -710,7 +710,7 @@ void IterOpenCLKernelCreator<T>::SharedDataIndexDefines(const Ember<T>& 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 (auto dataInfo = varFuncs->GetSharedData(s))///Will contain a name, pointer to data, and size of the data in units of sizeof(T).
|
||||||
{
|
{
|
||||||
if (doString)
|
if (doString)
|
||||||
os << "#define " << ToUpper(name) << " " << offset << endl;
|
os << "#define " << ToUpper(name) << " " << offset << "\n";
|
||||||
|
|
||||||
if (doVals)
|
if (doVals)
|
||||||
params.second.insert(params.second.end(), dataInfo->first, dataInfo->first + dataInfo->second);
|
params.second.insert(params.second.end(), dataInfo->first, dataInfo->first + dataInfo->second);
|
||||||
|
@ -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)
|
static void OpenCLSim(size_t gridWidth, size_t gridHeight, size_t blockWidth, size_t blockHeight, KernelFuncPointer func)
|
||||||
{
|
{
|
||||||
cout << "OpenCLSim(): " << endl;
|
cout << "OpenCLSim(): ";
|
||||||
cout << " Params: " << endl;
|
cout << "\n Params: ";
|
||||||
cout << " gridW: " << gridWidth << endl;
|
cout << "\n gridW: " << gridWidth;
|
||||||
cout << " gridH: " << gridHeight << endl;
|
cout << "\n gridH: " << gridHeight;
|
||||||
cout << " blockW: " << blockWidth << endl;
|
cout << "\n blockW: " << blockWidth;
|
||||||
cout << " blockH: " << blockHeight << endl;
|
cout << "\n blockH: " << blockHeight;
|
||||||
|
|
||||||
for (size_t i = 0; i < gridHeight; i += blockHeight)
|
for (size_t i = 0; i < gridHeight; i += blockHeight)
|
||||||
{
|
{
|
||||||
|
@ -264,35 +264,35 @@ string OpenCLInfo::DumpInfo() const
|
|||||||
|
|
||||||
for (size_t platform = 0; platform < m_Platforms.size(); platform++)
|
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++)
|
for (size_t device = 0; device < m_Devices[platform].size(); device++)
|
||||||
{
|
{
|
||||||
os << "Device " << device << ": " << DeviceName(platform, device) << endl;
|
os << "Device " << device << ": " << DeviceName(platform, device);
|
||||||
os << "CL_DEVICE_OPENCL_C_VERSION: " << GetInfo<string>(platform, device, CL_DEVICE_OPENCL_C_VERSION) << endl;
|
os << "\nCL_DEVICE_OPENCL_C_VERSION: " << GetInfo<string>(platform, device, CL_DEVICE_OPENCL_C_VERSION);
|
||||||
os << "CL_DEVICE_LOCAL_MEM_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_LOCAL_MEM_SIZE) << endl;
|
os << "\nCL_DEVICE_LOCAL_MEM_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_LOCAL_MEM_SIZE);
|
||||||
os << "CL_DEVICE_LOCAL_MEM_TYPE: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_LOCAL_MEM_TYPE) << endl;
|
os << "\nCL_DEVICE_LOCAL_MEM_TYPE: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_LOCAL_MEM_TYPE);
|
||||||
os << "CL_DEVICE_MAX_COMPUTE_UNITS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_COMPUTE_UNITS) << endl;
|
os << "\nCL_DEVICE_MAX_COMPUTE_UNITS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_COMPUTE_UNITS);
|
||||||
os << "CL_DEVICE_MAX_READ_IMAGE_ARGS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_READ_IMAGE_ARGS) << endl;
|
os << "\nCL_DEVICE_MAX_READ_IMAGE_ARGS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_READ_IMAGE_ARGS);
|
||||||
os << "CL_DEVICE_MAX_WRITE_IMAGE_ARGS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS) << endl;
|
os << "\nCL_DEVICE_MAX_WRITE_IMAGE_ARGS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS);
|
||||||
os << "CL_DEVICE_MAX_MEM_ALLOC_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_MAX_MEM_ALLOC_SIZE) << endl;
|
os << "\nCL_DEVICE_MAX_MEM_ALLOC_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_MAX_MEM_ALLOC_SIZE);
|
||||||
os << "CL_DEVICE_ADDRESS_BITS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_ADDRESS_BITS) << endl;
|
os << "\nCL_DEVICE_ADDRESS_BITS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_ADDRESS_BITS);
|
||||||
os << "CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE) << endl;
|
os << "\nCL_DEVICE_GLOBAL_MEM_CACHE_TYPE: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE);
|
||||||
os << "CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE) << endl;
|
os << "\nCL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE);
|
||||||
os << "CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE) << endl;
|
os << "\nCL_DEVICE_GLOBAL_MEM_CACHE_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE);
|
||||||
os << "CL_DEVICE_GLOBAL_MEM_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_GLOBAL_MEM_SIZE) << endl;
|
os << "\nCL_DEVICE_GLOBAL_MEM_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_GLOBAL_MEM_SIZE);
|
||||||
os << "CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE) << endl;
|
os << "\nCL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: " << GetInfo<cl_ulong>(platform, device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE);
|
||||||
os << "CL_DEVICE_MAX_CONSTANT_ARGS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_CONSTANT_ARGS) << endl;
|
os << "\nCL_DEVICE_MAX_CONSTANT_ARGS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_CONSTANT_ARGS);
|
||||||
os << "CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS) << endl;
|
os << "\nCL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: " << GetInfo<cl_uint>(platform, device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
|
||||||
os << "CL_DEVICE_MAX_WORK_GROUP_SIZE: " << GetInfo<size_t>(platform, device, CL_DEVICE_MAX_WORK_GROUP_SIZE) << endl;
|
os << "\nCL_DEVICE_MAX_WORK_GROUP_SIZE: " << GetInfo<size_t>(platform, device, CL_DEVICE_MAX_WORK_GROUP_SIZE);
|
||||||
sizes = GetInfo<vector<size_t>>(platform, device, CL_DEVICE_MAX_WORK_ITEM_SIZES);
|
sizes = GetInfo<vector<size_t>>(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)
|
if (device != m_Devices[platform].size() - 1 && platform != m_Platforms.size() - 1)
|
||||||
os << endl;
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
os << endl;
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return os.str();
|
return os.str();
|
||||||
@ -309,7 +309,7 @@ bool OpenCLInfo::CheckCL(cl_int err, const char* name)
|
|||||||
if (err != CL_SUCCESS)
|
if (err != CL_SUCCESS)
|
||||||
{
|
{
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
ss << "ERROR: " << ErrorToStringCL(err) << " in " << name << "." << endl;
|
ss << "ERROR: " << ErrorToStringCL(err) << " in " << name << ".\n";
|
||||||
AddToReport(ss.str());
|
AddToReport(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ bool OpenCLWrapper::AddAndWriteImage(const string& name, cl_mem_flags flags, con
|
|||||||
if (shared)
|
if (shared)
|
||||||
{
|
{
|
||||||
//::wglMakeCurrent(wglGetCurrentDC(), wglGetCurrentContext());
|
//::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);
|
NamedImage2DGL namedImageGL(imageGL, name);
|
||||||
|
|
||||||
if (m_Info->CheckCL(err, "cl::ImageGL()"))
|
if (m_Info->CheckCL(err, "cl::ImageGL()"))
|
||||||
@ -360,11 +360,11 @@ bool OpenCLWrapper::AddAndWriteImage(const string& name, cl_mem_flags flags, con
|
|||||||
{
|
{
|
||||||
if (shared)
|
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))
|
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()"))
|
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())
|
if (shared && index < m_GLImages.size())
|
||||||
{
|
{
|
||||||
IMAGEGL2D imageGL = m_GLImages[index].m_Image;
|
cl::ImageGL imageGL = m_GLImages[index].m_Image;
|
||||||
|
|
||||||
if (EnqueueAcquireGLObjects(imageGL))
|
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())
|
if (shared && imageIndex < m_GLImages.size())
|
||||||
{
|
{
|
||||||
IMAGEGL2D imageGL = m_GLImages[imageIndex].m_Image;
|
cl::ImageGL imageGL = m_GLImages[imageIndex].m_Image;
|
||||||
|
|
||||||
if (EnqueueAcquireGLObjects(imageGL))
|
if (EnqueueAcquireGLObjects(imageGL))
|
||||||
{
|
{
|
||||||
@ -573,7 +573,7 @@ size_t OpenCLWrapper::GetImageSize(size_t imageIndex, bool shared)
|
|||||||
{
|
{
|
||||||
vector<cl::Memory> images;
|
vector<cl::Memory> images;
|
||||||
images.push_back(m_GLImages[imageIndex].m_Image);
|
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))
|
if (EnqueueAcquireGLObjects(&images))
|
||||||
size = image.getImageInfo<CL_IMAGE_WIDTH>(nullptr) * image.getImageInfo<CL_IMAGE_HEIGHT>(nullptr) * image.getImageInfo<CL_IMAGE_ELEMENT_SIZE>(nullptr);//Should pitch be checked here?
|
size = image.getImageInfo<CL_IMAGE_WIDTH>(nullptr) * image.getImageInfo<CL_IMAGE_HEIGHT>(nullptr) * image.getImageInfo<CL_IMAGE_ELEMENT_SIZE>(nullptr);//Should pitch be checked here?
|
||||||
@ -662,17 +662,17 @@ bool OpenCLWrapper::CreateImage2D(cl::Image2D& image2D, cl_mem_flags flags, cl::
|
|||||||
/// <param name="miplevel">The mip map level</param>
|
/// <param name="miplevel">The mip map level</param>
|
||||||
/// <param name="texobj">The texture ID of the shared OpenGL texture</param>
|
/// <param name="texobj">The texture ID of the shared OpenGL texture</param>
|
||||||
/// <returns>True if success, else false.</returns>
|
/// <returns>True if success, else false.</returns>
|
||||||
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)
|
if (m_Init)
|
||||||
{
|
{
|
||||||
cl_int err;
|
cl_int err;
|
||||||
image2DGL = IMAGEGL2D(m_Context,
|
image2DGL = cl::ImageGL(m_Context,
|
||||||
flags,
|
flags,
|
||||||
target,
|
target,
|
||||||
miplevel,
|
miplevel,
|
||||||
texobj,
|
texobj,
|
||||||
&err);
|
&err);
|
||||||
return m_Info->CheckCL(err, "cl::ImageGL()");
|
return m_Info->CheckCL(err, "cl::ImageGL()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,7 +699,7 @@ bool OpenCLWrapper::EnqueueAcquireGLObjects(const string& name)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="image">The image to acquire</param>
|
/// <param name="image">The image to acquire</param>
|
||||||
/// <returns>True if success, else false.</returns>
|
/// <returns>True if success, else false.</returns>
|
||||||
bool OpenCLWrapper::EnqueueAcquireGLObjects(IMAGEGL2D& image)
|
bool OpenCLWrapper::EnqueueAcquireGLObjects(cl::ImageGL& image)
|
||||||
{
|
{
|
||||||
if (m_Init && m_Shared)
|
if (m_Init && m_Shared)
|
||||||
{
|
{
|
||||||
@ -733,7 +733,7 @@ bool OpenCLWrapper::EnqueueReleaseGLObjects(const string& name)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="image">The image to release</param>
|
/// <param name="image">The image to release</param>
|
||||||
/// <returns>True if success, else false.</returns>
|
/// <returns>True if success, else false.</returns>
|
||||||
bool OpenCLWrapper::EnqueueReleaseGLObjects(IMAGEGL2D& image)
|
bool OpenCLWrapper::EnqueueReleaseGLObjects(cl::ImageGL& image)
|
||||||
{
|
{
|
||||||
if (m_Init && m_Shared)
|
if (m_Init && m_Shared)
|
||||||
{
|
{
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
|
|
||||||
namespace EmberCLns
|
namespace EmberCLns
|
||||||
{
|
{
|
||||||
#define IMAGEGL2D cl::ImageGL
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class to contain all of the things needed to store an OpenCL program.
|
/// 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.
|
/// 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_Image = image;
|
||||||
m_Name = name;
|
m_Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMAGEGL2D m_Image;
|
cl::ImageGL m_Image;
|
||||||
string m_Name;
|
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);
|
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);
|
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 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(const string& name);
|
||||||
bool EnqueueAcquireGLObjects(IMAGEGL2D& image);
|
bool EnqueueAcquireGLObjects(cl::ImageGL& image);
|
||||||
bool EnqueueReleaseGLObjects(const string& name);
|
bool EnqueueReleaseGLObjects(const string& name);
|
||||||
bool EnqueueReleaseGLObjects(IMAGEGL2D& image);
|
bool EnqueueReleaseGLObjects(cl::ImageGL& image);
|
||||||
bool EnqueueAcquireGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = NULL);
|
bool EnqueueAcquireGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = NULL);
|
||||||
bool EnqueueReleaseGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = NULL);
|
bool EnqueueReleaseGLObjects(const VECTOR_CLASS<cl::Memory>* memObjects = NULL);
|
||||||
bool CreateSampler(cl::Sampler& sampler, cl_bool normalizedCoords, cl_addressing_mode addressingMode, cl_filter_mode filterMode);
|
bool CreateSampler(cl::Sampler& sampler, cl_bool normalizedCoords, cl_addressing_mode addressingMode, cl_filter_mode filterMode);
|
||||||
|
@ -895,25 +895,23 @@ bool RendererCL<T, bucketT>::BuildIterProgramForEmber(bool doAccum)
|
|||||||
if (b)
|
if (b)
|
||||||
{
|
{
|
||||||
m_IterKernel = m_IterOpenCLKernelCreator.CreateIterKernelString(m_Ember, m_Params.first, m_GlobalShared.first, m_LockAccum, doAccum);
|
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<std::thread> threads;
|
vector<std::thread> threads;
|
||||||
std::function<void(RendererClDevice*)> func = [&](RendererClDevice * dev)
|
std::function<void(RendererClDevice*)> func = [&](RendererClDevice * dev)
|
||||||
{
|
{
|
||||||
if (!dev->m_Wrapper.AddProgram(m_IterOpenCLKernelCreator.IterEntryPoint(), m_IterKernel, m_IterOpenCLKernelCreator.IterEntryPoint(), m_DoublePrecision))
|
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;
|
b = false;
|
||||||
AddToReport(string(loc) + "()\n" + dev->m_Wrapper.DeviceName() + ":\nBuilding the following program failed: \n" + m_IterKernel + "\n");
|
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())
|
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])))
|
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;
|
b = false;
|
||||||
AddToReport(string(loc) + "()\n" + dev->m_Wrapper.DeviceName() + ":\nAdding global shared buffer failed.\n");
|
AddToReport(string(loc) + "()\n" + dev->m_Wrapper.DeviceName() + ":\nAdding global shared buffer failed.\n");
|
||||||
m_ResizeCs.Leave();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -934,7 +932,7 @@ bool RendererCL<T, bucketT>::BuildIterProgramForEmber(bool doAccum)
|
|||||||
if (b)
|
if (b)
|
||||||
{
|
{
|
||||||
//t.Toc(__FUNCTION__ " program build");
|
//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;
|
m_LastBuiltEmber = m_Ember;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -988,7 +986,7 @@ bool RendererCL<T, bucketT>::RunIter(size_t iterCount, size_t temporalSample, si
|
|||||||
{
|
{
|
||||||
bool b = true;
|
bool b = true;
|
||||||
auto& wrapper = m_Devices[dev]->m_Wrapper;
|
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))
|
while (atomLaunchesRan.fetch_add(1), (b && (atomLaunchesRan.load() <= launches) && ((itersRemaining = atomItersRemaining.load()) > 0) && !m_Abort))
|
||||||
{
|
{
|
||||||
@ -1002,7 +1000,7 @@ bool RendererCL<T, bucketT>::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).
|
//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>(uint(adjustedIterCountPerKernel), uint(ceil(double(itersRemaining) / IterGridKernelCount())));
|
uint iterCountPerKernel = std::min<uint>(uint(adjustedIterCountPerKernel), uint(ceil(double(itersRemaining) / IterGridKernelCount())));
|
||||||
size_t iterCountThisLaunch = iterCountPerKernel * IterGridKernelWidth() * IterGridKernelHeight();
|
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.
|
if (b && !(b = wrapper.SetArg (kernelIndex, argIndex++, iterCountPerKernel))) { AddToReport(loc); }//Number of iters for each thread to run.
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ private:
|
|||||||
cl::ImageFormat m_PaletteFormat;
|
cl::ImageFormat m_PaletteFormat;
|
||||||
cl::ImageFormat m_FinalFormat;
|
cl::ImageFormat m_FinalFormat;
|
||||||
cl::Image2D m_Palette;
|
cl::Image2D m_Palette;
|
||||||
IMAGEGL2D m_AccumImage;
|
cl::ImageGL m_AccumImage;
|
||||||
GLuint m_OutputTexID;
|
GLuint m_OutputTexID;
|
||||||
EmberCL<T> m_EmberCL;
|
EmberCL<T> m_EmberCL;
|
||||||
vector<XformCL<T>> m_XformsCL;
|
vector<XformCL<T>> m_XformsCL;
|
||||||
|
@ -439,7 +439,7 @@ public:
|
|||||||
|
|
||||||
case eOptionIDs::OPT_VERSION:
|
case eOptionIDs::OPT_VERSION:
|
||||||
{
|
{
|
||||||
cout << EmberVersion() << endl;
|
cout << EmberVersion() << "\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,8 +540,8 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Invalid argument: " << args.OptionText() << endl;
|
cout << "Invalid argument: " << args.OptionText() << "\n";
|
||||||
cout << "\tReason: " << GetLastErrorText(errorCode) << endl;
|
cout << "\tReason: " << GetLastErrorText(errorCode) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,15 +608,15 @@ public:
|
|||||||
{
|
{
|
||||||
ostringstream os;
|
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();
|
return os.str();
|
||||||
}
|
}
|
||||||
@ -631,15 +631,15 @@ public:
|
|||||||
ostringstream os;
|
ostringstream os;
|
||||||
os << std::boolalpha;
|
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();
|
return os.str();
|
||||||
}
|
}
|
||||||
@ -650,25 +650,25 @@ public:
|
|||||||
/// <param name="optUsage">The specified program usage</param>
|
/// <param name="optUsage">The specified program usage</param>
|
||||||
void ShowUsage(eOptionUse optUsage)
|
void ShowUsage(eOptionUse optUsage)
|
||||||
{
|
{
|
||||||
cout << DescriptionString << " version " << EmberVersion() << endl << endl;
|
cout << DescriptionString << " version " << EmberVersion() << "\n\n";
|
||||||
|
|
||||||
if (optUsage == eOptionUse::OPT_USE_RENDER)
|
if (optUsage == eOptionUse::OPT_USE_RENDER)
|
||||||
{
|
{
|
||||||
cout << "Usage:\n"
|
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)
|
else if (optUsage == eOptionUse::OPT_USE_ANIMATE)
|
||||||
{
|
{
|
||||||
cout << "Usage:\n"
|
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)
|
else if (optUsage == eOptionUse::OPT_USE_GENOME)
|
||||||
{
|
{
|
||||||
cout << "Usage:\n"
|
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";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -55,11 +55,11 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
std::cout.imbue(std::locale(""));
|
std::cout.imbue(std::locale(""));
|
||||||
|
|
||||||
if (opt.DumpArgs())
|
if (opt.DumpArgs())
|
||||||
cerr << opt.GetValues(eOptionUse::OPT_USE_GENOME) << endl;
|
cerr << opt.GetValues(eOptionUse::OPT_USE_GENOME) << "\n";
|
||||||
|
|
||||||
if (opt.OpenCLInfo())
|
if (opt.OpenCLInfo())
|
||||||
{
|
{
|
||||||
cerr << "\nOpenCL Info: " << endl;
|
cerr << "\nOpenCL Info: \n";
|
||||||
cerr << info->DumpInfo();
|
cerr << info->DumpInfo();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
|
|
||||||
if (!renderer.get())
|
if (!renderer.get())
|
||||||
{
|
{
|
||||||
cerr << "Renderer creation failed, exiting." << endl;
|
cerr << "Renderer creation failed, exiting.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,14 +112,14 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Using OpenCL to render." << endl;
|
cerr << "Using OpenCL to render.\n";
|
||||||
|
|
||||||
if (opt.Verbose())
|
if (opt.Verbose())
|
||||||
{
|
{
|
||||||
for (auto& device : devices)
|
for (auto& device : devices)
|
||||||
{
|
{
|
||||||
cerr << "Platform: " << info->PlatformName(device.first) << endl;
|
cerr << "Platform: " << info->PlatformName(device.first) << "\n";
|
||||||
cerr << "Device: " << info->DeviceName(device.first, device.second) << endl;
|
cerr << "Device: " << info->DeviceName(device.first, device.second) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.UseVars() != "" && opt.DontUseVars() != "")
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,19 +231,19 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
|
|
||||||
if (count > 1)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doCross0 != doCross1)//Must both be either true or 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.Method() != "" && (!doCross0 && !doMutate))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (templateEmbers.size() > 1)
|
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];
|
pTemplate = &templateEmbers[0];
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.CloneAll() != "")
|
if (opt.CloneAll() != "")
|
||||||
{
|
{
|
||||||
cout << "<clone_all version=\"Ember-" << EmberVersion() << "\">" << endl;
|
cout << "<clone_all version=\"Ember-" << EmberVersion() << "\">\n";
|
||||||
|
|
||||||
for (i = 0; i < embers.size(); i++)
|
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 << emberToXml.ToString(embers[i], opt.Extras(), opt.PrintEditDepth(), !opt.NoEdits(), false, opt.HexPalette());
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "</clone_all>" << endl;
|
cout << "</clone_all>\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +318,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
{
|
{
|
||||||
if (i > 0 && embers[i].m_Time <= embers[i - 1].m_Time)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +331,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
if (lastFrame < firstFrame)
|
if (lastFrame < firstFrame)
|
||||||
lastFrame = firstFrame;
|
lastFrame = firstFrame;
|
||||||
|
|
||||||
cout << "<animate version=\"EMBER-" << EmberVersion() << "\">" << endl;
|
cout << "<animate version=\"EMBER-" << EmberVersion() << "\">\n";
|
||||||
|
|
||||||
for (ftime = firstFrame; ftime <= lastFrame; ftime++)
|
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 << emberToXml.ToString(interpolated, opt.Extras(), opt.PrintEditDepth(), !opt.NoEdits(), false, opt.HexPalette());
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "</animate>" << endl;
|
cout << "</animate>\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,12 +380,12 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.Frames() == 0)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.Enclosed())
|
if (opt.Enclosed())
|
||||||
cout << "<sequence version=\"EMBER-" << EmberVersion() << "\">" << endl;
|
cout << "<sequence version=\"EMBER-" << EmberVersion() << "\">\n";
|
||||||
|
|
||||||
spread = 1 / T(opt.Frames());
|
spread = 1 / T(opt.Frames());
|
||||||
frameCount = 0;
|
frameCount = 0;
|
||||||
@ -437,7 +437,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
cout << emberToXml.ToString(result, opt.Extras(), opt.PrintEditDepth(), !opt.NoEdits(), false, opt.HexPalette());
|
cout << emberToXml.ToString(result, opt.Extras(), opt.PrintEditDepth(), !opt.NoEdits(), false, opt.HexPalette());
|
||||||
|
|
||||||
if (opt.Enclosed())
|
if (opt.Enclosed())
|
||||||
cout << "</sequence>" << endl;
|
cout << "</sequence>\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -448,7 +448,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.Frames() == 0)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,13 +456,13 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
spread = 1 / T(opt.Frames());
|
spread = 1 / T(opt.Frames());
|
||||||
|
|
||||||
if (opt.Enclosed())
|
if (opt.Enclosed())
|
||||||
cout << "<pick version=\"EMBER-" << EmberVersion() << "\">" << endl;
|
cout << "<pick version=\"EMBER-" << EmberVersion() << "\">\n";
|
||||||
|
|
||||||
if (doRotate)
|
if (doRotate)
|
||||||
{
|
{
|
||||||
if (embers.size() != 1)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,7 +477,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
{
|
{
|
||||||
if (embers.size() != 2)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +490,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opt.Enclosed())
|
if (opt.Enclosed())
|
||||||
cout << "</pick>" << endl;
|
cout << "</pick>\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -498,7 +498,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
if (doStrip)
|
if (doStrip)
|
||||||
{
|
{
|
||||||
if (opt.Enclosed())
|
if (opt.Enclosed())
|
||||||
cout << "<pick version=\"EMBER-" << EmberVersion() << "\">" << endl;
|
cout << "<pick version=\"EMBER-" << EmberVersion() << "\">\n";
|
||||||
|
|
||||||
for (i = 0; i < embers.size(); i++)
|
for (i = 0; i < embers.size(); i++)
|
||||||
{
|
{
|
||||||
@ -520,7 +520,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opt.Enclosed())
|
if (opt.Enclosed())
|
||||||
cout << "</pick>" << endl;
|
cout << "</pick>\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -534,12 +534,12 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
|
|
||||||
if (opt.Repeat() == 0)
|
if (opt.Repeat() == 0)
|
||||||
{
|
{
|
||||||
cerr << "Repeat must be positive, not " << opt.Repeat() << endl;
|
cerr << "Repeat must be positive, not " << opt.Repeat() << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.Enclosed())
|
if (opt.Enclosed())
|
||||||
cout << "<pick version=\"EMBER-" << EmberVersion() << "\">" << endl;
|
cout << "<pick version=\"EMBER-" << EmberVersion() << "\">\n";
|
||||||
|
|
||||||
for (rep = 0; rep < opt.Repeat(); rep++)
|
for (rep = 0; rep < opt.Repeat(); rep++)
|
||||||
{
|
{
|
||||||
@ -596,7 +596,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
mutMeth = eMutateMode::MUTATE_ALL_COEFS;
|
mutMeth = eMutateMode::MUTATE_ALL_COEFS;
|
||||||
else
|
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;
|
mutMeth = eMutateMode::MUTATE_NOT_SPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,7 +632,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
crossMeth = eCrossMode::CROSS_ALTERNATE;
|
crossMeth = eCrossMode::CROSS_ALTERNATE;
|
||||||
else
|
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;
|
crossMeth = eCrossMode::CROSS_NOT_SPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,7 +699,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
if (!didColor && rand.RandBit())
|
if (!didColor && rand.RandBit())
|
||||||
{
|
{
|
||||||
if (opt.Debug())
|
if (opt.Debug())
|
||||||
cerr << "improving colors..." << endl;
|
cerr << "improving colors...\n";
|
||||||
|
|
||||||
tools.ImproveColors(orig, 100, false, 10);
|
tools.ImproveColors(orig, 100, false, 10);
|
||||||
os << " improved colors";
|
os << " improved colors";
|
||||||
@ -712,7 +712,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
|
|
||||||
if (renderer->Run(finalImage) != eRenderStatus::RENDER_OK)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,7 +733,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
fractionWhite = totw / T(n);
|
fractionWhite = totw / T(n);
|
||||||
|
|
||||||
if (opt.Debug())
|
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();
|
orig.Clear();
|
||||||
count++;
|
count++;
|
||||||
@ -744,7 +744,7 @@ bool EmberGenome(EmberOptions& opt)
|
|||||||
count < opt.Tries());
|
count < opt.Tries());
|
||||||
|
|
||||||
if (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)
|
if (pTemplate)
|
||||||
@ -806,7 +806,7 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
}
|
}
|
||||||
else if (opt.Bits() == 32)
|
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<float>(opt);
|
b = EmberGenome<float>(opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,11 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
std::cout.imbue(std::locale(""));
|
std::cout.imbue(std::locale(""));
|
||||||
|
|
||||||
if (opt.DumpArgs())
|
if (opt.DumpArgs())
|
||||||
cout << opt.GetValues(eOptionUse::OPT_USE_RENDER) << endl;
|
cout << opt.GetValues(eOptionUse::OPT_USE_RENDER) << "\n";
|
||||||
|
|
||||||
if (opt.OpenCLInfo())
|
if (opt.OpenCLInfo())
|
||||||
{
|
{
|
||||||
cout << "\nOpenCL Info: " << endl;
|
cout << "\nOpenCL Info: \n";
|
||||||
cout << info->DumpInfo();
|
cout << info->DumpInfo();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
|
|
||||||
if (!renderer.get())
|
if (!renderer.get())
|
||||||
{
|
{
|
||||||
cout << "Renderer creation failed, exiting." << endl;
|
cout << "Renderer creation failed, exiting.\n" ;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,38 +72,38 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
{
|
{
|
||||||
if (opt.ThreadCount() == 0)
|
if (opt.ThreadCount() == 0)
|
||||||
{
|
{
|
||||||
cout << "Using " << Timing::ProcessorCount() << " automatically detected threads." << endl;
|
cout << "Using " << Timing::ProcessorCount() << " automatically detected threads.\n";
|
||||||
opt.ThreadCount(Timing::ProcessorCount());
|
opt.ThreadCount(Timing::ProcessorCount());
|
||||||
}
|
}
|
||||||
else
|
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);
|
renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Using OpenCL to render." << endl;
|
cout << "Using OpenCL to render.\n";
|
||||||
|
|
||||||
if (opt.Verbose())
|
if (opt.Verbose())
|
||||||
{
|
{
|
||||||
for (auto& device : devices)
|
for (auto& device : devices)
|
||||||
{
|
{
|
||||||
cout << "Platform: " << info->PlatformName(device.first) << endl;
|
cout << "Platform: " << info->PlatformName(device.first) << "\n";
|
||||||
cout << "Device: " << info->DeviceName(device.first, device.second) << endl;
|
cout << "Device: " << info->DeviceName(device.first, device.second) << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.ThreadCount() > 1)
|
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);
|
opt.ThreadCount(1);
|
||||||
renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr);
|
renderer->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr);
|
||||||
|
|
||||||
if (opt.BitsPerChannel() != 8)
|
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);
|
opt.BitsPerChannel(8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,37 +113,37 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
opt.Format() != "ppm" &&
|
opt.Format() != "ppm" &&
|
||||||
opt.Format() != "bmp")
|
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;
|
channels = opt.Format() == "png" ? 4 : 3;
|
||||||
|
|
||||||
if (opt.BitsPerChannel() == 16 && opt.Format() != "png")
|
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);
|
opt.BitsPerChannel(8);
|
||||||
}
|
}
|
||||||
else if (opt.BitsPerChannel() != 8 && opt.BitsPerChannel() != 16)
|
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);
|
opt.BitsPerChannel(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.InsertPalette() && 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);
|
opt.InsertPalette(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.AspectRatio() < 0)
|
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);
|
opt.AspectRatio(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opt.Out().empty() && (embers.size() > 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.Out("");
|
||||||
opt.Prefix("badname-changethis");
|
opt.Prefix("badname-changethis");
|
||||||
}
|
}
|
||||||
@ -165,9 +165,9 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
for (i = 0; i < embers.size(); i++)
|
for (i = 0; i < embers.size(); i++)
|
||||||
{
|
{
|
||||||
if (opt.Verbose() && embers.size() > 1)
|
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)
|
else if (embers.size() > 1)
|
||||||
VerbosePrint(endl);
|
VerbosePrint("\n");
|
||||||
|
|
||||||
if (opt.Supersample() > 0)
|
if (opt.Supersample() > 0)
|
||||||
embers[i].m_Supersample = opt.Supersample();
|
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)
|
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_FinalRasW = 1920;
|
||||||
embers[i].m_FinalRasH = 1080;
|
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.
|
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_FinalRasW = 1920;
|
||||||
embers[i].m_FinalRasH = 1080;
|
embers[i].m_FinalRasH = 1080;
|
||||||
}
|
}
|
||||||
@ -227,9 +227,9 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
strips = VerifyStrips(embers[i].m_FinalRasH, strips,
|
strips = VerifyStrips(embers[i].m_FinalRasH, strips,
|
||||||
[&](const string & s) { cout << s << endl; }, //Greater than height.
|
[&](const string & s) { cout << s << "\n"; }, //Greater than height.
|
||||||
[&](const string & s) { cout << s << endl; }, //Mod height != 0.
|
[&](const string & s) { cout << s << "\n"; }, //Mod height != 0.
|
||||||
[&](const string & s) { cout << s << endl; }); //Final strips value to be set.
|
[&](const string & s) { cout << s << "\n"; }); //Final strips value to be set.
|
||||||
//For testing incremental renderer.
|
//For testing incremental renderer.
|
||||||
//int sb = 1;
|
//int sb = 1;
|
||||||
//bool resume = false, success = false;
|
//bool resume = false, success = false;
|
||||||
@ -244,7 +244,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
[&](size_t strip)//Pre strip.
|
[&](size_t strip)//Pre strip.
|
||||||
{
|
{
|
||||||
if (opt.Verbose() && (strips > 1) && strip > 0)
|
if (opt.Verbose() && (strips > 1) && strip > 0)
|
||||||
cout << endl;
|
cout << "\n";
|
||||||
|
|
||||||
if (strips > 1)
|
if (strips > 1)
|
||||||
VerbosePrint("Strip = " << (strip + 1) << "/" << strips);
|
VerbosePrint("Strip = " << (strip + 1) << "/" << strips);
|
||||||
@ -256,7 +256,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
},
|
},
|
||||||
[&](size_t strip)//Error.
|
[&](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.
|
renderer->DumpErrorReport();//Something went wrong, print errors.
|
||||||
},
|
},
|
||||||
//Final strip.
|
//Final strip.
|
||||||
@ -291,7 +291,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
|
|
||||||
VerbosePrint("Render time: " + t.Format(stats.m_RenderMs));
|
VerbosePrint("Render time: " + t.Format(stats.m_RenderMs));
|
||||||
VerbosePrint("Pure iter time: " + t.Format(stats.m_IterMs));
|
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);
|
VerbosePrint("Writing " + filename);
|
||||||
|
|
||||||
if ((opt.Format() == "jpg" || opt.Format() == "bmp") && renderer->NumChannels() == 4)
|
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);
|
writeSuccess = WriteBmp(filename.c_str(), finalImagep, finalEmber.m_FinalRasW, finalEmber.m_FinalRasH);
|
||||||
|
|
||||||
if (!writeSuccess)
|
if (!writeSuccess)
|
||||||
cout << "Error writing " << filename << endl;
|
cout << "Error writing " << filename << "\n";
|
||||||
});
|
});
|
||||||
|
|
||||||
if (opt.EmberCL() && opt.DumpKernel())
|
if (opt.EmberCL() && opt.DumpKernel())
|
||||||
@ -322,7 +322,7 @@ bool EmberRender(EmberOptions& opt)
|
|||||||
"Density filter kernel:\n" <<
|
"Density filter kernel:\n" <<
|
||||||
rendererCL->DEKernel() << "\n\n" <<
|
rendererCL->DEKernel() << "\n\n" <<
|
||||||
"Final accumulation kernel:\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)
|
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<float>(opt);
|
b = EmberRender<float>(opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1962,6 +1962,28 @@ void DistribTester()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void TestAffine()
|
||||||
|
{
|
||||||
|
v2T x(1, 0), y(0, 1), t(1, 0);
|
||||||
|
Affine2D<T> 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 <typename T>
|
||||||
|
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
|
#define DO_NVIDIA 1
|
||||||
|
|
||||||
int _tmain(int argc, _TCHAR* argv[])
|
int _tmain(int argc, _TCHAR* argv[])
|
||||||
@ -1971,7 +1993,12 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
Timing t(4);
|
Timing t(4);
|
||||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand(1, 2, 3);
|
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand(1, 2, 3);
|
||||||
mt19937 meow(1729);
|
mt19937 meow(1729);
|
||||||
/* MakeTestAllVarsRegPrePostComboFile("testallvarsout.flame");
|
/* TestAffine<float>();
|
||||||
|
TestAffine<double>();*/
|
||||||
|
/* TestRotate<float>();
|
||||||
|
TestRotate<double>();
|
||||||
|
return 1;
|
||||||
|
MakeTestAllVarsRegPrePostComboFile("testallvarsout.flame");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
@ -2175,28 +2202,28 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DO_DOUBLE
|
//#ifdef DO_DOUBLE
|
||||||
|
//
|
||||||
//t.Tic();
|
// //t.Tic();
|
||||||
//TestCpuGpuResults<double>();
|
// //TestCpuGpuResults<double>();
|
||||||
//t.Toc("TestCpuGpuResults<double>()");
|
// //t.Toc("TestCpuGpuResults<double>()");
|
||||||
if (b)
|
// if (b)
|
||||||
{
|
// {
|
||||||
t.Tic();
|
// t.Tic();
|
||||||
TestAllVarsCLBuild<double>(0, 0, true);
|
// TestAllVarsCLBuild<double>(0, 0, true);
|
||||||
t.Toc("TestAllVarsCLBuild<double>()");
|
// t.Toc("TestAllVarsCLBuild<double>()");
|
||||||
|
//
|
||||||
if (b)
|
// if (b)
|
||||||
{
|
// {
|
||||||
#ifdef DO_NVIDIA
|
//#ifdef DO_NVIDIA
|
||||||
t.Tic();
|
// t.Tic();
|
||||||
TestAllVarsCLBuild<double>(1, 0, true);
|
// TestAllVarsCLBuild<double>(1, 0, true);
|
||||||
t.Toc("TestAllVarsCLBuild<double>()");
|
// t.Toc("TestAllVarsCLBuild<double>()");
|
||||||
#endif
|
//#endif
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
#endif
|
//#endif
|
||||||
#endif
|
#endif
|
||||||
//PrintAllVars();
|
//PrintAllVars();
|
||||||
//_CrtDumpMemoryLeaks();
|
//_CrtDumpMemoryLeaks();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "FractoriumPch.h"
|
#include "FractoriumPch.h"
|
||||||
#include "DoubleSpinBox.h"
|
#include "DoubleSpinBox.h"
|
||||||
|
|
||||||
QTimer DoubleSpinBox::m_Timer;
|
QTimer DoubleSpinBox::s_Timer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor that passes parent to the base and sets up height and step.
|
/// Constructor that passes parent to the base and sets up height and step.
|
||||||
@ -144,17 +144,16 @@ void DoubleSpinBox::OnTimeout()
|
|||||||
//qDebug() << "Shift pressed";
|
//qDebug() << "Shift pressed";
|
||||||
scale = 0.0001;
|
scale = 0.0001;
|
||||||
}
|
}
|
||||||
/*else if (ctrl)
|
/* else if (ctrl)
|
||||||
{
|
{
|
||||||
qDebug() << "Control pressed";
|
qDebug() << "Control pressed";
|
||||||
scale = 0.01;
|
scale = 0.01;
|
||||||
}*/
|
}*/
|
||||||
else
|
else
|
||||||
scale = 0.001;
|
scale = 0.001;
|
||||||
|
|
||||||
val = d + (distance * amount * scale);
|
val = d + (distance * amount * scale);
|
||||||
setValue(val);
|
setValue(val);
|
||||||
|
|
||||||
//qDebug() << "Timer on, orig val: " << d << ", new val: " << val << ", distance " << distance;
|
//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<QMouseEvent*>(e);
|
QMouseEvent* me = dynamic_cast<QMouseEvent*>(e);
|
||||||
|
|
||||||
if (isEnabled() &&
|
if (isEnabled() &&
|
||||||
me &&
|
me &&
|
||||||
me->type() == QMouseEvent::MouseButtonPress &&
|
me->type() == QMouseEvent::MouseButtonPress &&
|
||||||
me->button() == Qt::RightButton)
|
me->button() == Qt::RightButton)
|
||||||
{
|
{
|
||||||
m_MouseDownPoint = m_MouseMovePoint = me->pos();
|
m_MouseDownPoint = m_MouseMovePoint = me->pos();
|
||||||
StartTimer();
|
StartTimer();
|
||||||
//qDebug() << "Right mouse down";
|
//qDebug() << "Right mouse down";
|
||||||
// QPoint pt;
|
// QPoint pt;
|
||||||
//
|
//
|
||||||
// if (QMouseEvent* me = (QMouseEvent*)e)
|
// if (QMouseEvent* me = (QMouseEvent*)e)
|
||||||
// pt = me->localPos().toPoint();
|
// pt = me->localPos().toPoint();
|
||||||
//
|
//
|
||||||
// int pos = lineEdit()->cursorPositionAt(pt);
|
// int pos = lineEdit()->cursorPositionAt(pt);
|
||||||
//
|
//
|
||||||
// if (lineEdit()->selectedText() != "")
|
// if (lineEdit()->selectedText() != "")
|
||||||
// {
|
// {
|
||||||
// lineEdit()->deselect();
|
// lineEdit()->deselect();
|
||||||
// lineEdit()->setCursorPosition(pos);
|
// lineEdit()->setCursorPosition(pos);
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
// else if (m_Select)
|
// else if (m_Select)
|
||||||
// {
|
// {
|
||||||
// lineEdit()->setCursorPosition(pos);
|
// lineEdit()->setCursorPosition(pos);
|
||||||
// selectAll();
|
// selectAll();
|
||||||
// m_Select = false;
|
// m_Select = false;
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
else if (isEnabled() &&
|
else if (isEnabled() &&
|
||||||
me &&
|
me &&
|
||||||
me->type() == QMouseEvent::MouseButtonRelease &&
|
me->type() == QMouseEvent::MouseButtonRelease &&
|
||||||
me->button() == Qt::RightButton)
|
me->button() == Qt::RightButton)
|
||||||
{
|
{
|
||||||
StopTimer();
|
StopTimer();
|
||||||
m_MouseDownPoint = m_MouseMovePoint = me->pos();
|
m_MouseDownPoint = m_MouseMovePoint = me->pos();
|
||||||
//qDebug() << "Right mouse up";
|
//qDebug() << "Right mouse up";
|
||||||
}
|
}
|
||||||
else if (isEnabled() &&
|
else if (isEnabled() &&
|
||||||
me &&
|
me &&
|
||||||
me->type() == QMouseEvent::MouseMove &&
|
me->type() == QMouseEvent::MouseMove &&
|
||||||
QGuiApplication::mouseButtons() & Qt::RightButton)
|
QGuiApplication::mouseButtons() & Qt::RightButton)
|
||||||
{
|
{
|
||||||
m_MouseMovePoint = me->pos();
|
m_MouseMovePoint = me->pos();
|
||||||
qDebug() << "Mouse move while right down. Pt = " << me->pos() << ", global: " << mapToGlobal(me->pos());
|
qDebug() << "Mouse move while right down. Pt = " << me->pos() << ", global: " << mapToGlobal(me->pos());
|
||||||
@ -262,8 +261,8 @@ void DoubleSpinBox::focusInEvent(QFocusEvent* e)
|
|||||||
/// <param name="e">The event</param>
|
/// <param name="e">The event</param>
|
||||||
void DoubleSpinBox::focusOutEvent(QFocusEvent* e)
|
void DoubleSpinBox::focusOutEvent(QFocusEvent* e)
|
||||||
{
|
{
|
||||||
//lineEdit()->deselect();//Clear selection when leaving.
|
//lineEdit()->deselect();//Clear selection when leaving.
|
||||||
//lineEdit()->setReadOnly(true);//Clever hack to clear the cursor when leaving.
|
//lineEdit()->setReadOnly(true);//Clever hack to clear the cursor when leaving.
|
||||||
StopTimer();
|
StopTimer();
|
||||||
QDoubleSpinBox::focusOutEvent(e);
|
QDoubleSpinBox::focusOutEvent(e);
|
||||||
}
|
}
|
||||||
@ -299,9 +298,9 @@ void DoubleSpinBox::leaveEvent(QEvent* e)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void DoubleSpinBox::StartTimer()
|
void DoubleSpinBox::StartTimer()
|
||||||
{
|
{
|
||||||
m_Timer.stop();
|
s_Timer.stop();
|
||||||
connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
connect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
||||||
m_Timer.start(300);
|
s_Timer.start(300);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -309,6 +308,6 @@ void DoubleSpinBox::StartTimer()
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void DoubleSpinBox::StopTimer()
|
void DoubleSpinBox::StopTimer()
|
||||||
{
|
{
|
||||||
m_Timer.stop();
|
s_Timer.stop();
|
||||||
disconnect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
disconnect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
||||||
}
|
}
|
@ -51,7 +51,7 @@ private:
|
|||||||
double m_SmallStep;
|
double m_SmallStep;
|
||||||
QPoint m_MouseDownPoint;
|
QPoint m_MouseDownPoint;
|
||||||
QPoint m_MouseMovePoint;
|
QPoint m_MouseMovePoint;
|
||||||
static QTimer m_Timer;
|
static QTimer s_Timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -15,7 +15,6 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
|
|||||||
{
|
{
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
int row = 0, spinHeight = 20;
|
int row = 0, spinHeight = 20;
|
||||||
uint i;
|
|
||||||
double dmax = numeric_limits<double>::max();
|
double dmax = numeric_limits<double>::max();
|
||||||
QTableWidget* table = ui.FinalRenderParamsTable;
|
QTableWidget* table = ui.FinalRenderParamsTable;
|
||||||
QTableWidgetItem* item = nullptr;
|
QTableWidgetItem* item = nullptr;
|
||||||
|
@ -110,7 +110,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
|||||||
m_FinalPreviewRenderer->NumChannels(4);
|
m_FinalPreviewRenderer->NumChannels(4);
|
||||||
m_FinalPreviewRenderFunc = [&]()
|
m_FinalPreviewRenderFunc = [&]()
|
||||||
{
|
{
|
||||||
m_PreviewCs.Enter();//Thread prep.
|
rlg l(m_PreviewCs);//Thread prep.
|
||||||
m_PreviewRun = true;
|
m_PreviewRun = true;
|
||||||
m_FinalPreviewRenderer->Abort();
|
m_FinalPreviewRenderer->Abort();
|
||||||
T scalePercentage;
|
T scalePercentage;
|
||||||
@ -144,11 +144,10 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
|||||||
{
|
{
|
||||||
QImage image(finalEmber.m_FinalRasW, finalEmber.m_FinalRasH, QImage::Format_RGBA8888);//The label wants RGBA.
|
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.
|
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));
|
QMetaObject::invokeMethod(widget, "setPixmap", Qt::QueuedConnection, Q_ARG(QPixmap, pixmap));
|
||||||
});
|
});
|
||||||
m_PreviewRun = false;
|
m_PreviewRun = false;
|
||||||
m_PreviewCs.Leave();
|
|
||||||
};
|
};
|
||||||
//The main rendering function which will be called in a Qt thread.
|
//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.
|
//A backup Xml is made before the rendering process starts just in case it crashes before finishing.
|
||||||
@ -837,7 +836,7 @@ void FinalRenderEmberController<T>::HandleFinishedProgress()
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void FinalRenderEmberController<T>::RenderComplete(Ember<T>& ember, const EmberStats& stats, Timing& renderTimer)
|
void FinalRenderEmberController<T>::RenderComplete(Ember<T>& ember, const EmberStats& stats, Timing& renderTimer)
|
||||||
{
|
{
|
||||||
m_ProgressCs.Enter();
|
rlg l(m_ProgressCs);
|
||||||
string renderTimeString = renderTimer.Format(renderTimer.Toc()), totalTimeString;
|
string renderTimeString = renderTimer.Format(renderTimer.Toc()), totalTimeString;
|
||||||
QString status, filename = ComposePath(QString::fromStdString(ember.m_Name));
|
QString status, filename = ComposePath(QString::fromStdString(ember.m_Name));
|
||||||
QString itersString = ToString<qulonglong>(stats.m_Iters);
|
QString itersString = ToString<qulonglong>(stats.m_Iters);
|
||||||
@ -885,7 +884,6 @@ void FinalRenderEmberController<T>::RenderComplete(Ember<T>& ember, const EmberS
|
|||||||
}
|
}
|
||||||
|
|
||||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTextOutput, "update", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTextOutput, "update", Qt::QueuedConnection);
|
||||||
m_ProgressCs.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -82,11 +82,11 @@ protected:
|
|||||||
QFuture<void> m_FinalPreviewResult;
|
QFuture<void> m_FinalPreviewResult;
|
||||||
std::function<void (void)> m_FinalRenderFunc;
|
std::function<void (void)> m_FinalRenderFunc;
|
||||||
std::function<void (void)> m_FinalPreviewRenderFunc;
|
std::function<void (void)> m_FinalPreviewRenderFunc;
|
||||||
|
|
||||||
FractoriumSettings* m_Settings;
|
FractoriumSettings* m_Settings;
|
||||||
FractoriumFinalRenderDialog* m_FinalRenderDialog;
|
FractoriumFinalRenderDialog* m_FinalRenderDialog;
|
||||||
FinalRenderGuiState m_GuiState;
|
FinalRenderGuiState m_GuiState;
|
||||||
CriticalSection m_PreviewCs, m_ProgressCs;
|
std::recursive_mutex m_PreviewCs, m_ProgressCs;
|
||||||
Timing m_RenderTimer;
|
Timing m_RenderTimer;
|
||||||
Timing m_TotalTimer;
|
Timing m_TotalTimer;
|
||||||
};
|
};
|
||||||
|
@ -2780,7 +2780,7 @@
|
|||||||
<enum>QTabWidget::Triangular</enum>
|
<enum>QTabWidget::Triangular</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="XformColorTab">
|
<widget class="QWidget" name="XformColorTab">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -3470,8 +3470,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>263</width>
|
<width>118</width>
|
||||||
<height>700</height>
|
<height>618</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoFillBackground">
|
<property name="autoFillBackground">
|
||||||
@ -5485,8 +5485,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>259</width>
|
<width>133</width>
|
||||||
<height>652</height>
|
<height>52</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -6768,6 +6768,9 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Clear any existing flames and create a new file with 10 random flames in it</string>
|
<string>Clear any existing flames and create a new file with 10 random flames in it</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+N</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionOpen">
|
<action name="ActionOpen">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
@ -6777,6 +6780,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Open</string>
|
<string>&Open</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+O</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionExit">
|
<action name="ActionExit">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
@ -6798,6 +6804,9 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><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></string>
|
<string><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></string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+B</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionSaveCurrentAsXml">
|
<action name="ActionSaveCurrentAsXml">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
@ -6810,6 +6819,9 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Save the current flame as an xml file</string>
|
<string>Save the current flame as an xml file</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+S</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionAbout">
|
<action name="ActionAbout">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
@ -6861,6 +6873,9 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Add a new random flame to the end of the current file</string>
|
<string>Add a new random flame to the end of the current file</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+R</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionSaveEntireFileAsXml">
|
<action name="ActionSaveEntireFileAsXml">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
@ -6876,6 +6891,9 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Save all flames as a single xml file</string>
|
<string>Save all flames as a single xml file</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Shift+S</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionAddReflectiveSymmetry">
|
<action name="ActionAddReflectiveSymmetry">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
@ -6920,6 +6938,9 @@
|
|||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Add a new empty flame to the end of the current file</string>
|
<string>Add a new empty flame to the end of the current file</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+E</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionCopyFlameInCurrentFile">
|
<action name="ActionCopyFlameInCurrentFile">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
@ -6927,7 +6948,7 @@
|
|||||||
<normaloff>:/Fractorium/Icons/layers.png</normaloff>:/Fractorium/Icons/layers.png</iconset>
|
<normaloff>:/Fractorium/Icons/layers.png</normaloff>:/Fractorium/Icons/layers.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Co&py Flame</string>
|
<string>Add Co&py of Flame</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Add a copy of the current flame to the end of the current file</string>
|
<string>Add a copy of the current flame to the end of the current file</string>
|
||||||
@ -7069,11 +7090,6 @@
|
|||||||
<string>Remove the flatten variation from each xform</string>
|
<string>Remove the flatten variation from each xform</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionFlip">
|
|
||||||
<property name="text">
|
|
||||||
<string>Fl&ip</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="ActionCopySelectedXforms">
|
<action name="ActionCopySelectedXforms">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Copy Selected &Xforms</string>
|
<string>Copy Selected &Xforms</string>
|
||||||
@ -7082,7 +7098,7 @@
|
|||||||
<string>Copy selected xforms to the clipboard</string>
|
<string>Copy selected xforms to the clipboard</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+D</string>
|
<string>Ctrl+C, X</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionPasteSelectedXforms">
|
<action name="ActionPasteSelectedXforms">
|
||||||
@ -7093,7 +7109,7 @@
|
|||||||
<string>Paste copied xforms into the current flame</string>
|
<string>Paste copied xforms into the current flame</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+S</string>
|
<string>Ctrl+V, X</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="ActionResetWorkspace">
|
<action name="ActionResetWorkspace">
|
||||||
@ -7192,7 +7208,7 @@
|
|||||||
<string>Stop Renderer</string>
|
<string>Stop Renderer</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+R</string>
|
<string>Ctrl+P</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -20,15 +20,13 @@ FractoriumEmberControllerBase::FractoriumEmberControllerBase(Fractorium* fractor
|
|||||||
m_OutputTexID = 0;
|
m_OutputTexID = 0;
|
||||||
m_SubBatchCount = 1;//Will be ovewritten by the options on first render.
|
m_SubBatchCount = 1;//Will be ovewritten by the options on first render.
|
||||||
m_Fractorium = fractorium;
|
m_Fractorium = fractorium;
|
||||||
m_RenderTimer = nullptr;
|
|
||||||
m_RenderRestartTimer = nullptr;
|
|
||||||
m_Info = OpenCLInfo::Instance();
|
m_Info = OpenCLInfo::Instance();
|
||||||
m_Rand = QTIsaac<ISAAC_SIZE, ISAAC_INT>(ISAAC_INT(t.Tic()), ISAAC_INT(t.Tic() * 2), ISAAC_INT(t.Tic() * 3));//Ensure a different rand seed on each instance.
|
m_Rand = QTIsaac<ISAAC_SIZE, ISAAC_INT>(ISAAC_INT(t.Tic()), ISAAC_INT(t.Tic() * 2), ISAAC_INT(t.Tic() * 3));//Ensure a different rand seed on each instance.
|
||||||
m_RenderTimer = new QTimer(m_Fractorium);
|
m_RenderTimer = std::unique_ptr<QTimer>(new QTimer(m_Fractorium));
|
||||||
m_RenderTimer->setInterval(0);
|
m_RenderTimer->setInterval(0);
|
||||||
m_Fractorium->connect(m_RenderTimer, SIGNAL(timeout()), SLOT(IdleTimer()));
|
m_Fractorium->connect(m_RenderTimer.get(), SIGNAL(timeout()), SLOT(IdleTimer()));
|
||||||
m_RenderRestartTimer = new QTimer(m_Fractorium);
|
m_RenderRestartTimer = std::unique_ptr<QTimer>(new QTimer(m_Fractorium));
|
||||||
m_Fractorium->connect(m_RenderRestartTimer, SIGNAL(timeout()), SLOT(StartRenderTimer()));
|
m_Fractorium->connect(m_RenderRestartTimer.get(), SIGNAL(timeout()), SLOT(StartRenderTimer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -38,20 +36,8 @@ FractoriumEmberControllerBase::FractoriumEmberControllerBase(Fractorium* fractor
|
|||||||
FractoriumEmberControllerBase::~FractoriumEmberControllerBase()
|
FractoriumEmberControllerBase::~FractoriumEmberControllerBase()
|
||||||
{
|
{
|
||||||
StopRenderTimer(true);
|
StopRenderTimer(true);
|
||||||
|
m_RenderTimer->stop();
|
||||||
if (m_RenderTimer)
|
m_RenderRestartTimer->stop();
|
||||||
{
|
|
||||||
m_RenderTimer->stop();
|
|
||||||
delete m_RenderTimer;
|
|
||||||
m_RenderTimer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_RenderRestartTimer)
|
|
||||||
{
|
|
||||||
m_RenderRestartTimer->stop();
|
|
||||||
delete m_RenderRestartTimer;
|
|
||||||
m_RenderRestartTimer = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -64,26 +50,35 @@ template <typename T>
|
|||||||
FractoriumEmberController<T>::FractoriumEmberController(Fractorium* fractorium)
|
FractoriumEmberController<T>::FractoriumEmberController(Fractorium* fractorium)
|
||||||
: FractoriumEmberControllerBase(fractorium)
|
: FractoriumEmberControllerBase(fractorium)
|
||||||
{
|
{
|
||||||
|
bool b = false;
|
||||||
m_PreviewRun = false;
|
m_PreviewRun = false;
|
||||||
m_PreviewRunning = false;
|
m_PreviewRunning = false;
|
||||||
m_SheepTools = unique_ptr<SheepTools<T, float>>(new SheepTools<T, float>(
|
|
||||||
QString(QApplication::applicationDirPath() + "flam3-palettes.xml").toLocal8Bit().data(),
|
|
||||||
new EmberNs::Renderer<T, float>()));
|
|
||||||
m_GLController = unique_ptr<GLEmberController<T>>(new GLEmberController<T>(fractorium, fractorium->ui.GLDisplay, this));
|
m_GLController = unique_ptr<GLEmberController<T>>(new GLEmberController<T>(fractorium, fractorium->ui.GLDisplay, this));
|
||||||
m_PreviewRenderer = unique_ptr<EmberNs::Renderer<T, float>>(new EmberNs::Renderer<T, float>());
|
m_PreviewRenderer = unique_ptr<EmberNs::Renderer<T, float>>(new EmberNs::Renderer<T, float>());
|
||||||
|
|
||||||
//Initial combo change event to fill the palette table will be called automatically later.
|
//Initial combo change event to fill the palette table will be called automatically later.
|
||||||
|
|
||||||
//Look hard for a palette.
|
//Look hard for a palette.
|
||||||
if (!(InitPaletteList(QDir::currentPath().toLocal8Bit().data()) ||
|
static vector<string> paths =
|
||||||
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())) )
|
|
||||||
{
|
{
|
||||||
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<SheepTools<T, float>>(new SheepTools<T, float>(
|
||||||
|
m_PaletteList.Name(0), new EmberNs::Renderer<T, float>()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!b)
|
||||||
|
throw "No palettes found, exiting.";
|
||||||
|
|
||||||
BackgroundChanged(QColor(0, 0, 0));//Default to black.
|
BackgroundChanged(QColor(0, 0, 0));//Default to black.
|
||||||
ClearUndo();
|
ClearUndo();
|
||||||
m_PreviewRenderer->Callback(nullptr);
|
m_PreviewRenderer->Callback(nullptr);
|
||||||
@ -101,9 +96,9 @@ FractoriumEmberController<T>::FractoriumEmberController(Fractorium* fractorium)
|
|||||||
m_PreviewRun = true;
|
m_PreviewRun = true;
|
||||||
m_PreviewRunning = true;
|
m_PreviewRunning = true;
|
||||||
m_PreviewRenderer->ThreadCount(std::max(1u, Timing::ProcessorCount() - 1));//Leave one processor free so the GUI can breathe.
|
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++)
|
for (size_t i = start; m_PreviewRun && i < end && i < m_EmberFile.Size(); i++)
|
||||||
{
|
{
|
||||||
@ -117,7 +112,7 @@ FractoriumEmberController<T>::FractoriumEmberController(Fractorium* fractorium)
|
|||||||
|
|
||||||
if (m_PreviewRenderer->Run(m_PreviewFinalImage) == eRenderStatus::RENDER_OK)
|
if (m_PreviewRenderer->Run(m_PreviewFinalImage) == eRenderStatus::RENDER_OK)
|
||||||
{
|
{
|
||||||
if (EmberTreeWidgetItem<T>* treeItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))
|
if (auto treeItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))
|
||||||
{
|
{
|
||||||
//It is critical that Qt::BlockingQueuedConnection is passed because this is running on a different thread than the UI.
|
//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
|
//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<T>::SetEmber(size_t index)
|
|||||||
{
|
{
|
||||||
if (index < m_EmberFile.Size())
|
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++)
|
for (uint i = 0; i < top->childCount(); i++)
|
||||||
{
|
{
|
||||||
if (EmberTreeWidgetItem<T>* emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))
|
if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))
|
||||||
emberItem->setSelected(i == index);
|
emberItem->setSelected(i == index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,6 @@ public:
|
|||||||
|
|
||||||
//Xaos.
|
//Xaos.
|
||||||
virtual void FillXaos() { }
|
virtual void FillXaos() { }
|
||||||
virtual QString MakeXaosNameString(uint i) { return ""; }
|
|
||||||
virtual void XaosChanged(int x, int y, double val) { }
|
virtual void XaosChanged(int x, int y, double val) { }
|
||||||
virtual void ClearXaos() { }
|
virtual void ClearXaos() { }
|
||||||
virtual void RandomXaos() { }
|
virtual void RandomXaos() { }
|
||||||
@ -254,7 +253,7 @@ protected:
|
|||||||
QString m_LastSaveAll;
|
QString m_LastSaveAll;
|
||||||
QString m_LastSaveCurrent;
|
QString m_LastSaveCurrent;
|
||||||
string m_CurrentPaletteFilePath;
|
string m_CurrentPaletteFilePath;
|
||||||
CriticalSection m_Cs;
|
std::recursive_mutex m_Cs;
|
||||||
std::thread m_WriteThread;
|
std::thread m_WriteThread;
|
||||||
vector<byte> m_FinalImage;
|
vector<byte> m_FinalImage;
|
||||||
vector<byte> m_PreviewFinalImage;
|
vector<byte> m_PreviewFinalImage;
|
||||||
@ -263,8 +262,8 @@ protected:
|
|||||||
unique_ptr<EmberNs::RendererBase> m_Renderer;
|
unique_ptr<EmberNs::RendererBase> m_Renderer;
|
||||||
QTIsaac<ISAAC_SIZE, ISAAC_INT> m_Rand;
|
QTIsaac<ISAAC_SIZE, ISAAC_INT> m_Rand;
|
||||||
Fractorium* m_Fractorium;
|
Fractorium* m_Fractorium;
|
||||||
QTimer* m_RenderTimer;
|
std::unique_ptr<QTimer> m_RenderTimer;
|
||||||
QTimer* m_RenderRestartTimer;
|
std::unique_ptr<QTimer> m_RenderRestartTimer;
|
||||||
shared_ptr<OpenCLInfo> m_Info;
|
shared_ptr<OpenCLInfo> m_Info;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -439,7 +438,6 @@ public:
|
|||||||
|
|
||||||
//Xforms Xaos.
|
//Xforms Xaos.
|
||||||
virtual void FillXaos() override;
|
virtual void FillXaos() override;
|
||||||
virtual QString MakeXaosNameString(uint i) override;
|
|
||||||
virtual void XaosChanged(int x, int y, double val) override;
|
virtual void XaosChanged(int x, int y, double val) override;
|
||||||
virtual void ClearXaos() override;
|
virtual void ClearXaos() override;
|
||||||
virtual void RandomXaos() override;
|
virtual void RandomXaos() override;
|
||||||
@ -475,7 +473,6 @@ private:
|
|||||||
bool IsFinal(Xform<T>* xform);
|
bool IsFinal(Xform<T>* xform);
|
||||||
|
|
||||||
//Xforms Color.
|
//Xforms Color.
|
||||||
void SetCurrentXformColorIndex(double d, bool updateRender);
|
|
||||||
void FillCurvesControl();
|
void FillCurvesControl();
|
||||||
|
|
||||||
//Xforms Selection.
|
//Xforms Selection.
|
||||||
|
@ -32,7 +32,7 @@ void Fractorium::InitInfoUI()
|
|||||||
/// <param name="newSize">Ignored</param>
|
/// <param name="newSize">Ignored</param>
|
||||||
void Fractorium::OnSummaryTableHeaderResized(int logicalIndex, int oldSize, int newSize)
|
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);
|
SetPaletteTableItem(&pixmap, ui.SummaryTable, m_InfoPaletteItem, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ void Fractorium::OnSummaryTreeHeaderSectionClicked(int logicalIndex)
|
|||||||
/// values from the ember.
|
/// values from the ember.
|
||||||
/// It's also meant to be used in a fire-and-forget way. Once the tree is filled
|
/// It's also meant to be used in a fire-and-forget way. Once the tree is filled
|
||||||
/// individual nodes are never referenced again.
|
/// 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.
|
/// 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
|
/// If this ever presents a problem in the future, revisit with a more
|
||||||
/// intelligent design.
|
/// intelligent design.
|
||||||
@ -74,17 +74,6 @@ void FractoriumEmberController<T>::FillSummary()
|
|||||||
QColor color;
|
QColor color;
|
||||||
auto table = m_Fractorium->ui.SummaryTable;
|
auto table = m_Fractorium->ui.SummaryTable;
|
||||||
auto tree = m_Fractorium->ui.SummaryTree;
|
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->blockSignals(true);
|
||||||
tree->clear();
|
tree->clear();
|
||||||
m_Fractorium->m_InfoNameItem->setText(m_Ember.m_Name.c_str());
|
m_Fractorium->m_InfoNameItem->setText(m_Ember.m_Name.c_str());
|
||||||
@ -92,7 +81,7 @@ void FractoriumEmberController<T>::FillSummary()
|
|||||||
m_Fractorium->m_InfoXaosItem->setText(m_Ember.XaosPresent() ? "Yes" : "No");
|
m_Fractorium->m_InfoXaosItem->setText(m_Ember.XaosPresent() ? "Yes" : "No");
|
||||||
m_Fractorium->m_InfoXformCountItem->setText(QString::number(m_Ember.XformCount()));
|
m_Fractorium->m_InfoXformCountItem->setText(QString::number(m_Ember.XformCount()));
|
||||||
m_Fractorium->m_InfoFinalXformItem->setText(m_Ember.UseFinalXform() ? "Yes" : "No");
|
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);
|
QSize size(table->columnWidth(0), table->rowHeight(1) + 1);
|
||||||
m_Fractorium->m_InfoPaletteItem->setData(Qt::DecorationRole, pixmap.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
m_Fractorium->m_InfoPaletteItem->setData(Qt::DecorationRole, pixmap.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
|
||||||
@ -178,26 +167,7 @@ void FractoriumEmberController<T>::FillSummary()
|
|||||||
auto item2 = new QTreeWidgetItem(tree);//Empty item in between xforms.
|
auto item2 = new QTreeWidgetItem(tree);//Empty item in between xforms.
|
||||||
}
|
}
|
||||||
|
|
||||||
QTreeWidgetItemIterator it2(tree);
|
tree->expandAll();
|
||||||
|
|
||||||
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->blockSignals(false);
|
tree->blockSignals(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@ pair<size_t, QTreeWidgetItem*> Fractorium::GetCurrentEmberIndex()
|
|||||||
{
|
{
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
QTreeWidgetItem* item = nullptr;
|
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.
|
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<size_t, QTreeWidgetItem*> Fractorium::GetCurrentEmberIndex()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pair<size_t, QTreeWidgetItem*>(index, item);
|
return make_pair(index, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -57,11 +57,10 @@ template <typename T>
|
|||||||
void FractoriumEmberController<T>::SyncNames()
|
void FractoriumEmberController<T>::SyncNames()
|
||||||
{
|
{
|
||||||
EmberTreeWidgetItem<T>* item;
|
EmberTreeWidgetItem<T>* item;
|
||||||
QTreeWidget* tree = m_Fractorium->ui.LibraryTree;
|
auto tree = m_Fractorium->ui.LibraryTree;
|
||||||
|
|
||||||
tree->blockSignals(true);
|
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.
|
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 <typename T>
|
|||||||
void FractoriumEmberController<T>::SyncPointers()
|
void FractoriumEmberController<T>::SyncPointers()
|
||||||
{
|
{
|
||||||
EmberTreeWidgetItem<T>* item;
|
EmberTreeWidgetItem<T>* item;
|
||||||
QTreeWidget* tree = m_Fractorium->ui.LibraryTree;
|
auto tree = m_Fractorium->ui.LibraryTree;
|
||||||
|
|
||||||
tree->blockSignals(true);
|
tree->blockSignals(true);
|
||||||
|
|
||||||
if (QTreeWidgetItem* top = tree->topLevelItem(0))
|
if (auto top = tree->topLevelItem(0))
|
||||||
{
|
{
|
||||||
size_t childCount = top->childCount();
|
size_t childCount = top->childCount();
|
||||||
|
|
||||||
@ -107,28 +105,23 @@ void FractoriumEmberController<T>::SyncPointers()
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
|
void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
|
||||||
{
|
{
|
||||||
uint i, j, size = 64;
|
uint j, size = 64;
|
||||||
QTreeWidget* tree = m_Fractorium->ui.LibraryTree;
|
auto tree = m_Fractorium->ui.LibraryTree;
|
||||||
vector<byte> v(size * size * 4);
|
vector<byte> v(size * size * 4);
|
||||||
|
|
||||||
StopPreviewRender();
|
StopPreviewRender();
|
||||||
tree->clear();
|
tree->clear();
|
||||||
QCoreApplication::flush();
|
QCoreApplication::flush();
|
||||||
|
|
||||||
tree->blockSignals(true);
|
tree->blockSignals(true);
|
||||||
|
auto fileItem = new QTreeWidgetItem(tree);
|
||||||
QTreeWidgetItem* fileItem = new QTreeWidgetItem(tree);
|
|
||||||
QFileInfo info(m_EmberFile.m_Filename);
|
QFileInfo info(m_EmberFile.m_Filename);
|
||||||
|
|
||||||
fileItem->setText(0, info.fileName());
|
fileItem->setText(0, info.fileName());
|
||||||
fileItem->setToolTip(0, m_EmberFile.m_Filename);
|
fileItem->setToolTip(0, m_EmberFile.m_Filename);
|
||||||
fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
|
fileItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
|
||||||
|
|
||||||
for (j = 0; j < m_EmberFile.Size(); j++)
|
for (j = 0; j < m_EmberFile.Size(); j++)
|
||||||
{
|
{
|
||||||
Ember<T>* ember = &m_EmberFile.m_Embers[j];
|
auto ember = &m_EmberFile.m_Embers[j];
|
||||||
EmberTreeWidgetItem<T>* emberItem = new EmberTreeWidgetItem<T>(ember, fileItem);
|
auto emberItem = new EmberTreeWidgetItem<T>(ember, fileItem);
|
||||||
|
|
||||||
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
|
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
|
||||||
|
|
||||||
if (ember->m_Name.empty())
|
if (ember->m_Name.empty())
|
||||||
@ -143,13 +136,13 @@ void FractoriumEmberController<T>::FillLibraryTree(int selectIndex)
|
|||||||
tree->blockSignals(false);
|
tree->blockSignals(false);
|
||||||
|
|
||||||
if (selectIndex != -1)
|
if (selectIndex != -1)
|
||||||
if (QTreeWidgetItem* top = tree->topLevelItem(0))
|
if (auto top = tree->topLevelItem(0))
|
||||||
if (EmberTreeWidgetItem<T>* emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(selectIndex)))
|
if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(selectIndex)))
|
||||||
emberItem->setSelected(true);
|
emberItem->setSelected(true);
|
||||||
|
|
||||||
QCoreApplication::flush();
|
QCoreApplication::flush();
|
||||||
RenderPreviews(0, m_EmberFile.Size());
|
RenderPreviews(0, m_EmberFile.Size());
|
||||||
tree->expandAll();
|
tree->expandAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -160,20 +153,18 @@ template <typename T>
|
|||||||
void FractoriumEmberController<T>::UpdateLibraryTree()
|
void FractoriumEmberController<T>::UpdateLibraryTree()
|
||||||
{
|
{
|
||||||
uint i, size = 64;
|
uint i, size = 64;
|
||||||
QTreeWidget* tree = m_Fractorium->ui.LibraryTree;
|
auto tree = m_Fractorium->ui.LibraryTree;
|
||||||
vector<byte> v(size * size * 4);
|
vector<byte> v(size * size * 4);
|
||||||
|
|
||||||
if (QTreeWidgetItem* top = tree->topLevelItem(0))
|
if (auto top = tree->topLevelItem(0))
|
||||||
{
|
{
|
||||||
int childCount = top->childCount();
|
int childCount = top->childCount();
|
||||||
|
|
||||||
tree->blockSignals(true);
|
tree->blockSignals(true);
|
||||||
|
|
||||||
for (i = childCount; i < m_EmberFile.Size(); i++)
|
for (i = childCount; i < m_EmberFile.Size(); i++)
|
||||||
{
|
{
|
||||||
Ember<T>* ember = &m_EmberFile.m_Embers[i];
|
Ember<T>* ember = &m_EmberFile.m_Embers[i];
|
||||||
EmberTreeWidgetItem<T>* emberItem = new EmberTreeWidgetItem<T>(ember, top);
|
auto emberItem = new EmberTreeWidgetItem<T>(ember, top);
|
||||||
|
|
||||||
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
|
emberItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
|
||||||
|
|
||||||
if (ember->m_Name.empty())
|
if (ember->m_Name.empty())
|
||||||
@ -208,9 +199,9 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QTreeWidget* tree = m_Fractorium->ui.LibraryTree;
|
auto tree = m_Fractorium->ui.LibraryTree;
|
||||||
EmberTreeWidgetItem<T>* emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(item);
|
auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(item);
|
||||||
|
|
||||||
if (emberItem)
|
if (emberItem)
|
||||||
{
|
{
|
||||||
if (emberItem->text(0).isEmpty())//Prevent empty string.
|
if (emberItem->text(0).isEmpty())//Prevent empty string.
|
||||||
@ -220,7 +211,6 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
string oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name.
|
string oldName = emberItem->GetEmber()->m_Name;//First preserve the previous name.
|
||||||
|
|
||||||
tree->blockSignals(true);
|
tree->blockSignals(true);
|
||||||
emberItem->UpdateEmberName();//Copy edit text to the ember's name variable.
|
emberItem->UpdateEmberName();//Copy edit text to the ember's name variable.
|
||||||
m_EmberFile.MakeNamesUnique();//Ensure all names remain unique.
|
m_EmberFile.MakeNamesUnique();//Ensure all names remain unique.
|
||||||
@ -246,7 +236,7 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
qDebug() << "FractoriumEmberController<T>::EmberTreeItemChanged() : Exception thrown: " << e.what();
|
qDebug() << "FractoriumEmberController<T>::EmberTreeItemChanged() : Exception thrown: " << e.what();
|
||||||
}
|
}
|
||||||
@ -267,7 +257,7 @@ void Fractorium::OnEmberTreeItemChanged(QTreeWidgetItem* item, int col) { m_Cont
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::EmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col)
|
void FractoriumEmberController<T>::EmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col)
|
||||||
{
|
{
|
||||||
if (EmberTreeWidgetItem<T>* emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(item))
|
if (auto emberItem = dynamic_cast<EmberTreeWidgetItem<T>*>(item))
|
||||||
{
|
{
|
||||||
ClearUndo();
|
ClearUndo();
|
||||||
SetEmber(*emberItem->GetEmber());
|
SetEmber(*emberItem->GetEmber());
|
||||||
@ -285,8 +275,7 @@ void Fractorium::OnEmberTreeItemDoubleClicked(QTreeWidgetItem* item, int col) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::Delete(const pair<size_t, QTreeWidgetItem*>& p)
|
void FractoriumEmberController<T>::Delete(const pair<size_t, QTreeWidgetItem*>& p)
|
||||||
{
|
{
|
||||||
QTreeWidget* tree = m_Fractorium->ui.LibraryTree;
|
auto tree = m_Fractorium->ui.LibraryTree;
|
||||||
|
|
||||||
tree->blockSignals(true);
|
tree->blockSignals(true);
|
||||||
|
|
||||||
if (m_EmberFile.Delete(p.first))
|
if (m_EmberFile.Delete(p.first))
|
||||||
@ -298,7 +287,7 @@ void FractoriumEmberController<T>::Delete(const pair<size_t, QTreeWidgetItem*>&
|
|||||||
tree->blockSignals(false);
|
tree->blockSignals(false);
|
||||||
|
|
||||||
//If there is now only one item left and it wasn't selected, select it.
|
//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 (top->childCount() == 1)
|
||||||
if (auto item = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(0)))
|
if (auto item = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(0)))
|
||||||
@ -331,17 +320,16 @@ void FractoriumEmberController<T>::RenderPreviews(uint start, uint end)
|
|||||||
|
|
||||||
if (start == UINT_MAX && end == UINT_MAX)
|
if (start == UINT_MAX && end == UINT_MAX)
|
||||||
{
|
{
|
||||||
QTreeWidget* tree = m_Fractorium->ui.LibraryTree;
|
auto tree = m_Fractorium->ui.LibraryTree;
|
||||||
|
|
||||||
tree->blockSignals(true);
|
tree->blockSignals(true);
|
||||||
|
|
||||||
if (QTreeWidgetItem* top = tree->topLevelItem(0))
|
if (auto top = tree->topLevelItem(0))
|
||||||
{
|
{
|
||||||
int childCount = top->childCount();
|
int childCount = top->childCount();
|
||||||
vector<byte> emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 3);
|
vector<byte> emptyPreview(PREVIEW_SIZE * PREVIEW_SIZE * 3);
|
||||||
|
|
||||||
for (int i = 0; i < childCount; i++)
|
for (int i = 0; i < childCount; i++)
|
||||||
if (EmberTreeWidgetItem<T>* treeItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))
|
if (auto treeItem = dynamic_cast<EmberTreeWidgetItem<T>*>(top->child(i)))
|
||||||
treeItem->SetImage(emptyPreview, PREVIEW_SIZE, PREVIEW_SIZE);
|
treeItem->SetImage(emptyPreview, PREVIEW_SIZE, PREVIEW_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,10 +347,11 @@ template <typename T>
|
|||||||
void FractoriumEmberController<T>::StopPreviewRender()
|
void FractoriumEmberController<T>::StopPreviewRender()
|
||||||
{
|
{
|
||||||
m_PreviewRun = false;
|
m_PreviewRun = false;
|
||||||
|
m_PreviewRenderer->Abort();
|
||||||
|
|
||||||
while (m_PreviewRunning)
|
while (m_PreviewRunning)
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
|
||||||
m_PreviewResult.cancel();
|
m_PreviewResult.cancel();
|
||||||
|
|
||||||
while (m_PreviewResult.isRunning())
|
while (m_PreviewResult.isRunning())
|
||||||
@ -375,5 +364,5 @@ void FractoriumEmberController<T>::StopPreviewRender()
|
|||||||
template class FractoriumEmberController<float>;
|
template class FractoriumEmberController<float>;
|
||||||
|
|
||||||
#ifdef DO_DOUBLE
|
#ifdef DO_DOUBLE
|
||||||
template class FractoriumEmberController<double>;
|
template class FractoriumEmberController<double>;
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,7 +139,7 @@ void Fractorium::OnActionNewRandomFlameInCurrentFile(bool checked) { m_Controlle
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::CopyFlameInCurrentFile()
|
void FractoriumEmberController<T>::CopyFlameInCurrentFile()
|
||||||
{
|
{
|
||||||
Ember<T> ember = m_Ember;
|
auto ember = m_Ember;
|
||||||
StopPreviewRender();
|
StopPreviewRender();
|
||||||
ember.m_Name = EmberFile<T>::DefaultEmberName(m_EmberFile.Size() + 1).toStdString();
|
ember.m_Name = EmberFile<T>::DefaultEmberName(m_EmberFile.Size() + 1).toStdString();
|
||||||
ember.m_Index = m_EmberFile.Size();
|
ember.m_Index = m_EmberFile.Size();
|
||||||
@ -199,7 +199,7 @@ void FractoriumEmberController<T>::OpenAndPrepFiles(const QStringList& filenames
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vector<string> errors = parser.ErrorReport();
|
auto errors = parser.ErrorReport();
|
||||||
m_Fractorium->ErrorReportToQTextEdit(errors, m_Fractorium->ui.InfoFileOpeningTextEdit);
|
m_Fractorium->ErrorReportToQTextEdit(errors, m_Fractorium->ui.InfoFileOpeningTextEdit);
|
||||||
m_Fractorium->ShowCritical("Open Failed", "Could not open file, see info tab for details.");
|
m_Fractorium->ShowCritical("Open Failed", "Could not open file, see info tab for details.");
|
||||||
}
|
}
|
||||||
@ -246,7 +246,7 @@ template <typename T>
|
|||||||
void FractoriumEmberController<T>::SaveCurrentAsXml()
|
void FractoriumEmberController<T>::SaveCurrentAsXml()
|
||||||
{
|
{
|
||||||
QString filename;
|
QString filename;
|
||||||
FractoriumSettings* s = m_Fractorium->m_Settings;
|
auto s = m_Fractorium->m_Settings;
|
||||||
|
|
||||||
if (s->SaveAutoUnique() && m_LastSaveCurrent != "")
|
if (s->SaveAutoUnique() && m_LastSaveCurrent != "")
|
||||||
{
|
{
|
||||||
@ -266,10 +266,10 @@ void FractoriumEmberController<T>::SaveCurrentAsXml()
|
|||||||
|
|
||||||
if (filename != "")
|
if (filename != "")
|
||||||
{
|
{
|
||||||
Ember<T> ember = m_Ember;
|
auto ember = m_Ember;
|
||||||
EmberToXml<T> writer;
|
EmberToXml<T> writer;
|
||||||
QFileInfo fileInfo(filename);
|
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.
|
SaveCurrentToOpenedFile();//Save the current ember back to the opened file before writing to disk.
|
||||||
ApplyXmlSavingTemplate(ember);
|
ApplyXmlSavingTemplate(ember);
|
||||||
ember.m_Edits = writer.CreateNewEditdoc(&ember, nullptr, "edit", s->Nick().toStdString(), s->Url().toStdString(), s->Id().toStdString(), "", 0, 0);
|
ember.m_Edits = writer.CreateNewEditdoc(&ember, nullptr, "edit", s->Nick().toStdString(), s->Url().toStdString(), s->Id().toStdString(), "", 0, 0);
|
||||||
@ -300,7 +300,7 @@ template <typename T>
|
|||||||
void FractoriumEmberController<T>::SaveEntireFileAsXml()
|
void FractoriumEmberController<T>::SaveEntireFileAsXml()
|
||||||
{
|
{
|
||||||
QString filename;
|
QString filename;
|
||||||
FractoriumSettings* s = m_Fractorium->m_Settings;
|
auto s = m_Fractorium->m_Settings;
|
||||||
|
|
||||||
if (s->SaveAutoUnique() && m_LastSaveAll != "")
|
if (s->SaveAutoUnique() && m_LastSaveAll != "")
|
||||||
filename = EmberFile<T>::UniqueFilename(m_LastSaveAll);
|
filename = EmberFile<T>::UniqueFilename(m_LastSaveAll);
|
||||||
@ -340,12 +340,12 @@ void Fractorium::OnActionSaveEntireFileAsXml(bool checked) { m_Controller->SaveE
|
|||||||
/// <param name="checked">Ignored</param>
|
/// <param name="checked">Ignored</param>
|
||||||
void Fractorium::OnActionSaveCurrentScreen(bool checked)
|
void Fractorium::OnActionSaveCurrentScreen(bool checked)
|
||||||
{
|
{
|
||||||
QString filename = SetupSaveImageDialog(m_Controller->Name());
|
auto filename = SetupSaveImageDialog(m_Controller->Name());
|
||||||
auto renderer = m_Controller->Renderer();
|
auto renderer = m_Controller->Renderer();
|
||||||
auto& pixels = *m_Controller->FinalImage();
|
auto& pixels = *m_Controller->FinalImage();
|
||||||
RendererCLBase* rendererCL = dynamic_cast<RendererCLBase*>(m_Controller->Renderer());
|
auto rendererCL = dynamic_cast<RendererCLBase*>(m_Controller->Renderer());
|
||||||
auto stats = m_Controller->Stats();
|
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))
|
if (rendererCL && renderer->PrepFinalAccumVector(pixels))
|
||||||
{
|
{
|
||||||
@ -460,9 +460,9 @@ void Fractorium::OnActionRedo(bool checked) { m_Controller->Redo(); }
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::CopyXml()
|
void FractoriumEmberController<T>::CopyXml()
|
||||||
{
|
{
|
||||||
Ember<T> ember = m_Ember;
|
auto ember = m_Ember;
|
||||||
EmberToXml<T> emberToXml;
|
EmberToXml<T> emberToXml;
|
||||||
FractoriumSettings* settings = m_Fractorium->m_Settings;
|
auto settings = m_Fractorium->m_Settings;
|
||||||
ember.m_Quality = settings->XmlQuality();
|
ember.m_Quality = settings->XmlQuality();
|
||||||
ember.m_Supersample = settings->XmlSupersample();
|
ember.m_Supersample = settings->XmlSupersample();
|
||||||
ember.m_TemporalSamples = settings->XmlTemporalSamples();
|
ember.m_TemporalSamples = settings->XmlTemporalSamples();
|
||||||
@ -480,7 +480,7 @@ void FractoriumEmberController<T>::CopyAllXml()
|
|||||||
{
|
{
|
||||||
ostringstream os;
|
ostringstream os;
|
||||||
EmberToXml<T> emberToXml;
|
EmberToXml<T> emberToXml;
|
||||||
FractoriumSettings* settings = m_Fractorium->m_Settings;
|
auto settings = m_Fractorium->m_Settings;
|
||||||
os << "<flames>\n";
|
os << "<flames>\n";
|
||||||
|
|
||||||
for (auto& e : m_EmberFile.m_Embers)
|
for (auto& e : m_EmberFile.m_Embers)
|
||||||
@ -510,8 +510,8 @@ void FractoriumEmberController<T>::PasteXmlAppend()
|
|||||||
string s, errors;
|
string s, errors;
|
||||||
XmlToEmber<T> parser;
|
XmlToEmber<T> parser;
|
||||||
vector<Ember<T>> embers;
|
vector<Ember<T>> embers;
|
||||||
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
|
auto codec = QTextCodec::codecForName("UTF-8");
|
||||||
QByteArray b = codec->fromUnicode(QApplication::clipboard()->text());
|
auto b = codec->fromUnicode(QApplication::clipboard()->text());
|
||||||
s.reserve(b.size());
|
s.reserve(b.size());
|
||||||
|
|
||||||
for (i = 0; i < b.size(); i++)
|
for (i = 0; i < b.size(); i++)
|
||||||
@ -563,9 +563,9 @@ void FractoriumEmberController<T>::PasteXmlOver()
|
|||||||
uint i;
|
uint i;
|
||||||
string s, errors;
|
string s, errors;
|
||||||
XmlToEmber<T> parser;
|
XmlToEmber<T> parser;
|
||||||
Ember<T> backupEmber = m_EmberFile.m_Embers[0];
|
auto backupEmber = m_EmberFile.m_Embers[0];
|
||||||
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
|
auto codec = QTextCodec::codecForName("UTF-8");
|
||||||
QByteArray b = codec->fromUnicode(QApplication::clipboard()->text());
|
auto b = codec->fromUnicode(QApplication::clipboard()->text());
|
||||||
s.reserve(b.size());
|
s.reserve(b.size());
|
||||||
|
|
||||||
for (i = 0; i < b.size(); i++)
|
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.
|
//First completely stop what the current rendering process is doing.
|
||||||
m_Controller->DeleteRenderer();//Delete the renderer, but not the controller.
|
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.
|
OnActionSaveCurrentToOpenedFile(true);//Save whatever was edited back to the current open file.
|
||||||
m_RenderStatusLabel->setText("Renderer stopped.");
|
m_RenderStatusLabel->setText("Renderer stopped.");
|
||||||
m_FinalRenderDialog->show();
|
m_FinalRenderDialog->show();
|
||||||
|
@ -139,7 +139,7 @@ void Fractorium::OnPaletteFilenameComboChanged(const QString& text)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::ApplyPaletteToEmber()
|
void FractoriumEmberController<T>::ApplyPaletteToEmber()
|
||||||
{
|
{
|
||||||
int i, rot = 0;
|
int rot = 0;
|
||||||
uint blur = m_Fractorium->m_PaletteBlurSpin->value();
|
uint blur = m_Fractorium->m_PaletteBlurSpin->value();
|
||||||
uint freq = m_Fractorium->m_PaletteFrequencySpin->value();
|
uint freq = m_Fractorium->m_PaletteFrequencySpin->value();
|
||||||
double sat = double(m_Fractorium->m_PaletteSaturationSpin->value() / 100.0);
|
double sat = double(m_Fractorium->m_PaletteSaturationSpin->value() / 100.0);
|
||||||
@ -170,7 +170,7 @@ void FractoriumEmberController<T>::UpdateAdjustedPaletteGUI(Palette<T>& palette)
|
|||||||
vector<byte> v = palette.MakeRgbPaletteBlock(PALETTE_CELL_HEIGHT);//Make the palette repeat for PALETTE_CELL_HEIGHT rows.
|
vector<byte> 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.
|
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.
|
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.
|
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.
|
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);
|
auto previewNameItem = palettePreviewTable->item(0, 0);
|
||||||
@ -287,7 +287,7 @@ void Fractorium::OnPaletteRandomSelectButtonClicked(bool checked)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void Fractorium::OnPaletteRandomAdjustButtonClicked(bool checked)
|
void Fractorium::OnPaletteRandomAdjustButtonClicked(bool checked)
|
||||||
{
|
{
|
||||||
QTIsaac<ISAAC_SIZE, ISAAC_INT>* gRand = QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand.get();
|
auto gRand = QTIsaac<ISAAC_SIZE, ISAAC_INT>::GlobalRand.get();
|
||||||
m_PaletteHueSpin->setValue(-180 + gRand->Rand(361));
|
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_PaletteSaturationSpin->setValue(-50 + gRand->Rand(101));//Full range of these leads to bad palettes, so clamp range.
|
||||||
m_PaletteBrightnessSpin->setValue(-50 + gRand->Rand(101));
|
m_PaletteBrightnessSpin->setValue(-50 + gRand->Rand(101));
|
||||||
|
@ -565,7 +565,7 @@ void FractoriumEmberController<T>::FillParamTablesAndPalette()
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::ParamsToEmber(Ember<T>& ember)
|
void FractoriumEmberController<T>::ParamsToEmber(Ember<T>& 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_Brightness = m_Fractorium->m_BrightnessSpin->value();//Color.
|
||||||
ember.m_Gamma = m_Fractorium->m_GammaSpin->value();
|
ember.m_Gamma = m_Fractorium->m_GammaSpin->value();
|
||||||
ember.m_GammaThresh = m_Fractorium->m_GammaThresholdSpin->value();
|
ember.m_GammaThresh = m_Fractorium->m_GammaThresholdSpin->value();
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
/// <returns>True if running, else false.</returns>
|
/// <returns>True if running, else false.</returns>
|
||||||
bool FractoriumEmberControllerBase::RenderTimerRunning()
|
bool FractoriumEmberControllerBase::RenderTimerRunning()
|
||||||
{
|
{
|
||||||
return m_RenderTimer && m_RenderTimer->isActive();
|
return m_RenderTimer->isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -16,12 +16,9 @@ bool FractoriumEmberControllerBase::RenderTimerRunning()
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void FractoriumEmberControllerBase::StartRenderTimer()
|
void FractoriumEmberControllerBase::StartRenderTimer()
|
||||||
{
|
{
|
||||||
if (m_RenderTimer)
|
UpdateRender();
|
||||||
{
|
m_RenderTimer->start();
|
||||||
UpdateRender();
|
m_RenderElapsedTimer.Tic();
|
||||||
m_RenderTimer->start();
|
|
||||||
m_RenderElapsedTimer.Tic();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -33,12 +30,8 @@ void FractoriumEmberControllerBase::StartRenderTimer()
|
|||||||
void FractoriumEmberControllerBase::DelayedStartRenderTimer()
|
void FractoriumEmberControllerBase::DelayedStartRenderTimer()
|
||||||
{
|
{
|
||||||
DeleteRenderer();
|
DeleteRenderer();
|
||||||
|
m_RenderRestartTimer->setSingleShot(true);
|
||||||
if (m_RenderRestartTimer)
|
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.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -48,8 +41,7 @@ void FractoriumEmberControllerBase::DelayedStartRenderTimer()
|
|||||||
/// <param name="wait">True to block, else false.</param>
|
/// <param name="wait">True to block, else false.</param>
|
||||||
void FractoriumEmberControllerBase::StopRenderTimer(bool wait)
|
void FractoriumEmberControllerBase::StopRenderTimer(bool wait)
|
||||||
{
|
{
|
||||||
if (m_RenderTimer)
|
m_RenderTimer->stop();
|
||||||
m_RenderTimer->stop();
|
|
||||||
|
|
||||||
if (m_Renderer.get())
|
if (m_Renderer.get())
|
||||||
m_Renderer->Abort();
|
m_Renderer->Abort();
|
||||||
@ -130,12 +122,11 @@ void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, c
|
|||||||
if (filename != "")
|
if (filename != "")
|
||||||
{
|
{
|
||||||
bool b = false;
|
bool b = false;
|
||||||
uint i, j;
|
|
||||||
byte* data = nullptr;
|
byte* data = nullptr;
|
||||||
vector<byte> vecRgb;
|
vector<byte> vecRgb;
|
||||||
QFileInfo fileInfo(filename);
|
QFileInfo fileInfo(filename);
|
||||||
QString suffix = fileInfo.suffix();
|
QString suffix = fileInfo.suffix();
|
||||||
FractoriumSettings* settings = m_Fractorium->m_Settings;
|
auto settings = m_Fractorium->m_Settings;
|
||||||
|
|
||||||
//Ensure dimensions are valid.
|
//Ensure dimensions are valid.
|
||||||
if (pixels.size() < (width * height * channels * bpc))
|
if (pixels.size() < (width * height * channels * bpc))
|
||||||
@ -183,13 +174,11 @@ void FractoriumEmberControllerBase::SaveCurrentRender(const QString& filename, c
|
|||||||
/// <param name="action">The action for the renderer to take</param>
|
/// <param name="action">The action for the renderer to take</param>
|
||||||
void FractoriumEmberControllerBase::AddProcessAction(eProcessAction action)
|
void FractoriumEmberControllerBase::AddProcessAction(eProcessAction action)
|
||||||
{
|
{
|
||||||
m_Cs.Enter();
|
rlg l(m_Cs);
|
||||||
m_ProcessActions.push_back(action);
|
m_ProcessActions.push_back(action);
|
||||||
|
|
||||||
if (m_Renderer.get())
|
if (m_Renderer.get())
|
||||||
m_Renderer->Abort();
|
m_Renderer->Abort();
|
||||||
|
|
||||||
m_Cs.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -200,7 +189,7 @@ void FractoriumEmberControllerBase::AddProcessAction(eProcessAction action)
|
|||||||
/// <returns>The most significant processing action desired</returns>
|
/// <returns>The most significant processing action desired</returns>
|
||||||
eProcessAction FractoriumEmberControllerBase::CondenseAndClearProcessActions()
|
eProcessAction FractoriumEmberControllerBase::CondenseAndClearProcessActions()
|
||||||
{
|
{
|
||||||
m_Cs.Enter();
|
rlg l(m_Cs);
|
||||||
auto action = eProcessAction::NOTHING;
|
auto action = eProcessAction::NOTHING;
|
||||||
|
|
||||||
for (auto a : m_ProcessActions)
|
for (auto a : m_ProcessActions)
|
||||||
@ -208,7 +197,6 @@ eProcessAction FractoriumEmberControllerBase::CondenseAndClearProcessActions()
|
|||||||
action = a;
|
action = a;
|
||||||
|
|
||||||
m_ProcessActions.clear();
|
m_ProcessActions.clear();
|
||||||
m_Cs.Leave();
|
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +254,7 @@ template <typename T>
|
|||||||
bool FractoriumEmberController<T>::SyncSizes()
|
bool FractoriumEmberController<T>::SyncSizes()
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
GLWidget* gl = m_Fractorium->ui.GLDisplay;
|
auto gl = m_Fractorium->ui.GLDisplay;
|
||||||
RendererCL<T, float>* rendererCL = nullptr;
|
RendererCL<T, float>* rendererCL = nullptr;
|
||||||
|
|
||||||
if (!m_GLController->SizesMatch())
|
if (!m_GLController->SizesMatch())
|
||||||
@ -296,7 +284,7 @@ bool FractoriumEmberController<T>::Render()
|
|||||||
{
|
{
|
||||||
m_Rendering = true;
|
m_Rendering = true;
|
||||||
bool success = true;
|
bool success = true;
|
||||||
GLWidget* gl = m_Fractorium->ui.GLDisplay;
|
auto gl = m_Fractorium->ui.GLDisplay;
|
||||||
RendererCL<T, float>* rendererCL = nullptr;
|
RendererCL<T, float>* rendererCL = nullptr;
|
||||||
eProcessAction qualityAction, action;
|
eProcessAction qualityAction, action;
|
||||||
//Quality is the only parameter we update inside the timer.
|
//Quality is the only parameter we update inside the timer.
|
||||||
@ -403,10 +391,10 @@ bool FractoriumEmberController<T>::Render()
|
|||||||
//Rendering has finished, update final stats.
|
//Rendering has finished, update final stats.
|
||||||
if (ProcessState() == eProcessState::ACCUM_DONE)
|
if (ProcessState() == eProcessState::ACCUM_DONE)
|
||||||
{
|
{
|
||||||
EmberStats stats = m_Renderer->Stats();
|
auto stats = m_Renderer->Stats();
|
||||||
QString iters = ToString<qulonglong>(stats.m_Iters);
|
auto iters = ToString<qulonglong>(stats.m_Iters);
|
||||||
QString scaledQuality = ToString(uint(m_Renderer->ScaledQuality()));
|
auto scaledQuality = ToString(uint(m_Renderer->ScaledQuality()));
|
||||||
string renderTime = m_RenderElapsedTimer.Format(m_RenderElapsedTimer.Toc());
|
auto renderTime = m_RenderElapsedTimer.Format(m_RenderElapsedTimer.Toc());
|
||||||
m_Fractorium->m_ProgressBar->setValue(100);
|
m_Fractorium->m_ProgressBar->setValue(100);
|
||||||
|
|
||||||
//Only certain stats can be reported with OpenCL.
|
//Only certain stats can be reported with OpenCL.
|
||||||
@ -417,8 +405,8 @@ bool FractoriumEmberController<T>::Render()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
double percent = double(stats.m_Badvals) / double(stats.m_Iters);
|
double percent = double(stats.m_Badvals) / double(stats.m_Iters);
|
||||||
QString badVals = ToString<qulonglong>(stats.m_Badvals);
|
auto badVals = ToString<qulonglong>(stats.m_Badvals);
|
||||||
QString badPercent = QLocale::system().toString(percent * 100, 'f', 2);
|
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) + ".");
|
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<T>::Render()
|
|||||||
}
|
}
|
||||||
else if (m_EditState == eEditUndoState::REGULAR_EDIT)//Regular edit, just add to the end of the undo list.
|
else if (m_EditState == eEditUndoState::REGULAR_EDIT)//Regular edit, just add to the end of the undo list.
|
||||||
{
|
{
|
||||||
m_UndoList.push_back(m_Ember);
|
auto btn = QApplication::mouseButtons();
|
||||||
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)
|
if (!btn.testFlag(Qt::LeftButton) && !btn.testFlag(Qt::RightButton) && !btn.testFlag(Qt::MiddleButton))
|
||||||
m_UndoList.pop_front();
|
{
|
||||||
|
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.
|
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<T>::Render()
|
|||||||
if (m_FinalImage.size() == m_Renderer->FinalBufferSize())//Make absolutely sure the correct amount of data is passed.
|
if (m_FinalImage.size() == m_Renderer->FinalBufferSize())//Make absolutely sure the correct amount of data is passed.
|
||||||
gl->update();
|
gl->update();
|
||||||
|
|
||||||
//gl->repaint();
|
|
||||||
//m_Fractorium->update();
|
|
||||||
//m_Fractorium->ui.GLParentScrollArea->update();
|
|
||||||
//Uncomment for debugging kernel build and execution errors.
|
//Uncomment for debugging kernel build and execution errors.
|
||||||
//m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo()));
|
//m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo()));
|
||||||
//if (rendererCL)
|
//if (rendererCL)
|
||||||
@ -474,7 +464,7 @@ bool FractoriumEmberController<T>::Render()
|
|||||||
}
|
}
|
||||||
else//Something went very wrong, show error report.
|
else//Something went very wrong, show error report.
|
||||||
{
|
{
|
||||||
vector<string> errors = m_Renderer->ErrorReport();
|
auto errors = m_Renderer->ErrorReport();
|
||||||
success = false;
|
success = false;
|
||||||
m_FailedRenders++;
|
m_FailedRenders++;
|
||||||
m_Fractorium->m_RenderStatusLabel->setText("Rendering failed, see info tab. Try changing parameters.");
|
m_Fractorium->m_RenderStatusLabel->setText("Rendering failed, see info tab. Try changing parameters.");
|
||||||
@ -503,7 +493,6 @@ bool FractoriumEmberController<T>::Render()
|
|||||||
if (ProcessState() == eProcessState::ACCUM_DONE)
|
if (ProcessState() == eProcessState::ACCUM_DONE)
|
||||||
QThread::msleep(1);
|
QThread::msleep(1);
|
||||||
|
|
||||||
//QApplication::processEvents();
|
|
||||||
m_Rendering = false;
|
m_Rendering = false;
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -520,8 +509,8 @@ template <typename T>
|
|||||||
bool FractoriumEmberController<T>::CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, bool shared)
|
bool FractoriumEmberController<T>::CreateRenderer(eRendererType renderType, const vector<pair<size_t, size_t>>& devices, bool shared)
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
FractoriumSettings* s = m_Fractorium->m_Settings;
|
auto s = m_Fractorium->m_Settings;
|
||||||
GLWidget* gl = m_Fractorium->ui.GLDisplay;
|
auto gl = m_Fractorium->ui.GLDisplay;
|
||||||
|
|
||||||
if (!m_Renderer.get() || (m_Renderer->RendererType() != renderType) || !Equal(m_Devices, devices))
|
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.
|
//First check if a controller has already been created, and if so, save its embers and gracefully shut it down.
|
||||||
if (m_Controller.get())
|
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;
|
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
|
//Replace below with this once LLVM fixes a crash in their compiler with default lambda parameters.//TODO
|
||||||
//m_Controller->CopyEmber(ed);
|
//m_Controller->CopyEmber(ed);
|
||||||
|
@ -48,35 +48,6 @@ void FractoriumEmberController<T>::FillXaos()
|
|||||||
m_Fractorium->ui.XaosTableView->resizeColumnsToContents();
|
m_Fractorium->ui.XaosTableView->resizeColumnsToContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create and return a xaos name string.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="i">The index of the xform whose xaos will be used</param>
|
|
||||||
/// <returns>The xaos name string</returns>
|
|
||||||
template <typename T>
|
|
||||||
QString FractoriumEmberController<T>::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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the xaos value.
|
/// Set the xaos value.
|
||||||
/// Called when any xaos spinner is changed.
|
/// Called when any xaos spinner is changed.
|
||||||
@ -93,13 +64,13 @@ void FractoriumEmberController<T>::XaosChanged(int x, int y, double val)
|
|||||||
auto newVal = TruncPrecision(val, XAOS_PREC);//Sometimes 0 comes in as a very small number, so round.
|
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 (auto xform = m_Ember.GetXform(x))
|
||||||
if (!IsClose<T>(newVal, xform->Xaos(y), 1e-7))
|
if (!IsClose<T>(newVal, xform->Xaos(y), T(1e-7)))
|
||||||
Update([&] { xform->SetXaos(y, newVal); });
|
Update([&] { xform->SetXaos(y, newVal); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fractorium::OnXaosChanged(double d)
|
void Fractorium::OnXaosChanged(double d)
|
||||||
{
|
{
|
||||||
if (auto* senderSpinBox = qobject_cast<DoubleSpinBox*>(this->sender()))
|
if (auto senderSpinBox = qobject_cast<DoubleSpinBox*>(this->sender()))
|
||||||
{
|
{
|
||||||
auto p = senderSpinBox->property("tableindex").toPoint();
|
auto p = senderSpinBox->property("tableindex").toPoint();
|
||||||
m_Controller->XaosChanged(p.x(), p.y(), d);
|
m_Controller->XaosChanged(p.x(), p.y(), d);
|
||||||
|
@ -364,7 +364,7 @@ void FractoriumEmberController<T>::RotateXformsByAngle(double angle, bool pre)
|
|||||||
UpdateXform([&] (Xform<T>* xform)
|
UpdateXform([&] (Xform<T>* xform)
|
||||||
{
|
{
|
||||||
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
||||||
affine->Rotate(angle);
|
affine->Rotate(angle * DEG_2_RAD_T);
|
||||||
}, eXformUpdate::UPDATE_SELECTED);
|
}, eXformUpdate::UPDATE_SELECTED);
|
||||||
FillAffineWithXform(CurrentXform(), pre);
|
FillAffineWithXform(CurrentXform(), pre);
|
||||||
}
|
}
|
||||||
@ -595,7 +595,7 @@ template <typename T>
|
|||||||
void FractoriumEmberController<T>::FillAffineWithXform(Xform<T>* xform, bool pre)
|
void FractoriumEmberController<T>::FillAffineWithXform(Xform<T>* xform, bool pre)
|
||||||
{
|
{
|
||||||
DoubleSpinBox** spinners = pre ? m_Fractorium->m_PreSpins : m_Fractorium->m_PostSpins;
|
DoubleSpinBox** spinners = pre ? m_Fractorium->m_PreSpins : m_Fractorium->m_PostSpins;
|
||||||
const Affine2D<T>& affine = pre ? xform->m_Affine : xform->m_Post;
|
auto& affine = pre ? xform->m_Affine : xform->m_Post;
|
||||||
|
|
||||||
if (m_Fractorium->ui.PolarAffineCheckBox->isChecked())
|
if (m_Fractorium->ui.PolarAffineCheckBox->isChecked())
|
||||||
{
|
{
|
||||||
|
@ -47,7 +47,15 @@ void FractoriumEmberController<T>::XformColorIndexChanged(double d, bool updateR
|
|||||||
scroll->blockSignals(true);
|
scroll->blockSignals(true);
|
||||||
scroll->setValue(scrollVal);
|
scroll->setValue(scrollVal);
|
||||||
scroll->blockSignals(false);
|
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<T>* xform)
|
||||||
|
{
|
||||||
|
xform->m_ColorX = Clamp<T>(d, 0, 1);
|
||||||
|
}, eXformUpdate::UPDATE_SELECTED, updateRender);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fractorium::OnXformColorIndexChanged(double d) { OnXformColorIndexChanged(d, true); }
|
void Fractorium::OnXformColorIndexChanged(double d) { OnXformColorIndexChanged(d, true); }
|
||||||
@ -135,7 +143,7 @@ void Fractorium::OnSoloXformCheckBoxStateChanged(int state)
|
|||||||
/// <param name="newSize">Ignored</param>
|
/// <param name="newSize">Ignored</param>
|
||||||
void Fractorium::OnXformRefPaletteResized(int logicalIndex, int oldSize, int newSize)
|
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);
|
SetPaletteTableItem(&pixmap, ui.XformPaletteRefTable, m_PaletteRefItem, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,22 +212,6 @@ QColor FractoriumEmberController<T>::ColorIndexToQColor(double d)
|
|||||||
return QColor::fromRgb(rgb);
|
return QColor::fromRgb(rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the selected xforms color index to the passed in value.
|
|
||||||
/// Set the color cell in the palette ref table.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="d">The index value to set, 0-1.</param>
|
|
||||||
template <typename T>
|
|
||||||
void FractoriumEmberController<T>::SetCurrentXformColorIndex(double d, bool updateRender)
|
|
||||||
{
|
|
||||||
UpdateXform([&] (Xform<T>* xform)
|
|
||||||
{
|
|
||||||
xform->m_ColorX = Clamp<T>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the points in the curves control to the values of the curve points in the current ember.
|
/// Set the points in the curves control to the values of the curve points in the current ember.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -9,7 +9,6 @@ void Fractorium::InitXformsSelectUI()
|
|||||||
m_XformsSelectionLayout = (QFormLayout*)ui.XformsSelectGroupBoxScrollAreaWidget->layout();
|
m_XformsSelectionLayout = (QFormLayout*)ui.XformsSelectGroupBoxScrollAreaWidget->layout();
|
||||||
connect(ui.XformsSelectAllButton, SIGNAL(clicked(bool)), this, SLOT(OnXformsSelectAllButtonClicked(bool)), Qt::QueuedConnection);
|
connect(ui.XformsSelectAllButton, SIGNAL(clicked(bool)), this, SLOT(OnXformsSelectAllButtonClicked(bool)), Qt::QueuedConnection);
|
||||||
connect(ui.XformsSelectNoneButton, SIGNAL(clicked(bool)), this, SLOT(OnXformsSelectNoneButtonClicked(bool)), Qt::QueuedConnection);
|
connect(ui.XformsSelectNoneButton, SIGNAL(clicked(bool)), this, SLOT(OnXformsSelectNoneButtonClicked(bool)), Qt::QueuedConnection);
|
||||||
|
|
||||||
ClearXformsSelections();
|
ClearXformsSelections();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,13 +16,13 @@ void Fractorium::InitXformsSelectUI()
|
|||||||
/// Check all of the xform selection checkboxes.
|
/// Check all of the xform selection checkboxes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="checked">Ignored</param>
|
/// <param name="checked">Ignored</param>
|
||||||
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); }); }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Uncheck all of the xform selection checkboxes.
|
/// Uncheck all of the xform selection checkboxes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="checked">Ignored</param>
|
/// <param name="checked">Ignored</param>
|
||||||
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); }); }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clear all of the dynamically created xform checkboxes.
|
/// Clear all of the dynamically created xform checkboxes.
|
||||||
@ -31,7 +30,6 @@ void Fractorium::OnXformsSelectNoneButtonClicked(bool checked) { ForEachXformChe
|
|||||||
void Fractorium::ClearXformsSelections()
|
void Fractorium::ClearXformsSelections()
|
||||||
{
|
{
|
||||||
QLayoutItem* child = nullptr;
|
QLayoutItem* child = nullptr;
|
||||||
|
|
||||||
m_XformSelections.clear();
|
m_XformSelections.clear();
|
||||||
m_XformsSelectionLayout->blockSignals(true);
|
m_XformsSelectionLayout->blockSignals(true);
|
||||||
|
|
||||||
@ -95,9 +93,9 @@ void Fractorium::ForEachXformCheckbox(std::function<void(int, QCheckBox*)> func)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
bool FractoriumEmberController<T>::XformCheckboxAt(int i, std::function<void(QCheckBox*)> func)
|
bool FractoriumEmberController<T>::XformCheckboxAt(int i, std::function<void(QCheckBox*)> func)
|
||||||
{
|
{
|
||||||
if (QLayoutItem* child = m_Fractorium->m_XformsSelectionLayout->itemAt(i))
|
if (auto child = m_Fractorium->m_XformsSelectionLayout->itemAt(i))
|
||||||
{
|
{
|
||||||
if (auto* w = qobject_cast<QCheckBox*>(child->widget()))
|
if (auto w = qobject_cast<QCheckBox*>(child->widget()))
|
||||||
{
|
{
|
||||||
func(w);
|
func(w);
|
||||||
return true;
|
return true;
|
||||||
|
@ -171,11 +171,11 @@ void FractoriumEmberController<T>::SetupVariationTree()
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::ClearVariationsTree()
|
void FractoriumEmberController<T>::ClearVariationsTree()
|
||||||
{
|
{
|
||||||
QTreeWidget* tree = m_Fractorium->ui.VariationsTree;
|
auto tree = m_Fractorium->ui.VariationsTree;
|
||||||
|
|
||||||
for (int i = 0; i < tree->topLevelItemCount(); i++)
|
for (int i = 0; i < tree->topLevelItemCount(); i++)
|
||||||
{
|
{
|
||||||
QTreeWidgetItem* item = tree->topLevelItem(i);
|
auto item = tree->topLevelItem(i);
|
||||||
auto* spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(tree->itemWidget(item, 1));
|
auto* spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(tree->itemWidget(item, 1));
|
||||||
spinBox->SetValueStealth(0);
|
spinBox->SetValueStealth(0);
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ void FractoriumEmberController<T>::ClearVariationsTree()
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copy the value of a variation or param spinner to its corresponding value
|
/// 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.
|
/// Called when any spinner in the variations tree is changed.
|
||||||
/// Resets the rendering process.
|
/// Resets the rendering process.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -197,79 +197,82 @@ void FractoriumEmberController<T>::ClearVariationsTree()
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would be awesome to make this work for all.//TODO
|
void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would be awesome to make this work for all.//TODO
|
||||||
{
|
{
|
||||||
|
bool update = false;
|
||||||
auto objSender = m_Fractorium->sender();
|
auto objSender = m_Fractorium->sender();
|
||||||
auto tree = m_Fractorium->ui.VariationsTree;
|
auto tree = m_Fractorium->ui.VariationsTree;
|
||||||
auto sender = dynamic_cast<VariationTreeDoubleSpinBox*>(objSender);
|
auto sender = dynamic_cast<VariationTreeDoubleSpinBox*>(objSender);
|
||||||
auto xform = m_Ember.GetTotalXform(m_Fractorium->ui.CurrentXformCombo->currentIndex());//Will retrieve normal xform or final if needed.
|
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.
|
UpdateXform([&](Xform<T>* xform)
|
||||||
auto parVar = dynamic_cast<const ParametricVariation<T>*>(var);//The parametric cast of that variation.
|
|
||||||
auto xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform.
|
|
||||||
auto widgetItem = sender->WidgetItem();
|
|
||||||
bool isParam = parVar && sender->IsParam();
|
|
||||||
|
|
||||||
if (isParam)
|
|
||||||
{
|
{
|
||||||
//Do not take action if the xform doesn't contain the variation which this param is part of.
|
auto var = m_VariationList.GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only.
|
||||||
if (ParametricVariation<T>* xformParVar = dynamic_cast<ParametricVariation<T>*>(xformVar))//The parametric cast of the xform's variation.
|
auto parVar = dynamic_cast<const ParametricVariation<T>*>(var);//The parametric cast of that variation.
|
||||||
{
|
auto xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform.
|
||||||
if (xformParVar->SetParamVal(sender->ParamName().c_str(), d))
|
auto widgetItem = sender->WidgetItem();
|
||||||
{
|
bool isParam = parVar && sender->IsParam();
|
||||||
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());
|
|
||||||
|
|
||||||
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<T>* xformParVar = dynamic_cast<ParametricVariation<T>*>(xformVar))//The parametric cast of the xform's variation.
|
||||||
|
if (xformParVar->SetParamVal(sender->ParamName().c_str(), d))
|
||||||
|
update = true;
|
||||||
}
|
}
|
||||||
else
|
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
|
else
|
||||||
{
|
{
|
||||||
//If the item wasn't a param and the xform did not contain this variation,
|
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).
|
||||||
//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)
|
|
||||||
{
|
{
|
||||||
auto newParVar = dynamic_cast<ParametricVariation<T>*>(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 newParVar = dynamic_cast<ParametricVariation<T>*>(newVar);
|
||||||
auto itemWidget = tree->itemWidget(childItem, 1);//Get the widget for the child.
|
|
||||||
|
|
||||||
if (auto spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(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.
|
auto childItem = widgetItem->child(i);//Get the child.
|
||||||
newParVar->SetParamVal(s.c_str(), spinBox->value());
|
auto itemWidget = tree->itemWidget(childItem, 1);//Get the widget for the child.
|
||||||
|
|
||||||
|
if (auto spinBox = dynamic_cast<VariationTreeDoubleSpinBox*>(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();
|
UpdateRender();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +103,20 @@ T GLEmberController<T>::CalcRotation()
|
|||||||
return rotStart - rot;
|
return rotStart - rot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Snap the passed in world cartesian coordinate to the grid for rotation, scale or translation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vec">The world cartesian coordinate to be snapped</param>
|
||||||
|
/// <returns>The snapped world cartesian coordinate</returns>
|
||||||
|
template <typename T>
|
||||||
|
typename v2T GLEmberController<T>::SnapToGrid(v2T& vec)
|
||||||
|
{
|
||||||
|
v2T ret;
|
||||||
|
ret.x = glm::round(vec.x / GridStep) * GridStep;
|
||||||
|
ret.y = glm::round(vec.y / GridStep) * GridStep;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Snap the passed in world cartesian coordinate to the grid for rotation, scale or translation.
|
/// Snap the passed in world cartesian coordinate to the grid for rotation, scale or translation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -135,8 +149,8 @@ typename v3T GLEmberController<T>::SnapToNormalizedAngle(v3T& vec, uint division
|
|||||||
for (uint i = 0; i < divisions; i++)
|
for (uint i = 0; i < divisions; i++)
|
||||||
{
|
{
|
||||||
theta = 2.0 * M_PI * T(i) / T(divisions);
|
theta = 2.0 * M_PI * T(i) / T(divisions);
|
||||||
c.x = cos(theta);
|
c.x = std::cos(theta);
|
||||||
c.y = sin(theta);
|
c.y = std::sin(theta);
|
||||||
rsq = glm::distance(vec, c);
|
rsq = glm::distance(vec, c);
|
||||||
|
|
||||||
if (rsq < bestRsq)
|
if (rsq < bestRsq)
|
||||||
@ -220,7 +234,7 @@ void GLEmberController<double>::MultMatrix(tmat4x4<double, glm::defaultp>& mat)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void GLEmberController<T>::QueryMatrices(bool print)
|
void GLEmberController<T>::QueryMatrices(bool print)
|
||||||
{
|
{
|
||||||
RendererBase* renderer = m_FractoriumEmberController->Renderer();
|
auto renderer = m_FractoriumEmberController->Renderer();
|
||||||
|
|
||||||
if (renderer)
|
if (renderer)
|
||||||
{
|
{
|
||||||
@ -242,13 +256,13 @@ void GLEmberController<T>::QueryMatrices(bool print)
|
|||||||
if (print)
|
if (print)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < 4; i++)
|
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++)
|
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++)
|
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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,9 +109,9 @@ public:
|
|||||||
|
|
||||||
T CalcScale();
|
T CalcScale();
|
||||||
T CalcRotation();
|
T CalcRotation();
|
||||||
Affine2D<T> CalcDragXAxis();
|
void CalcDragXAxis();
|
||||||
Affine2D<T> CalcDragYAxis();
|
void CalcDragYAxis();
|
||||||
Affine2D<T> CalcDragTranslation();
|
void CalcDragTranslation();
|
||||||
|
|
||||||
void SetEmber(Ember<T>* ember);
|
void SetEmber(Ember<T>* ember);
|
||||||
void SetSelectedXform(Xform<T>* xform);
|
void SetSelectedXform(Xform<T>* xform);
|
||||||
@ -120,6 +120,7 @@ public:
|
|||||||
bool CheckXformHover(Xform<T>* xform, v3T& glCoords, T& bestDist, bool pre, bool post);
|
bool CheckXformHover(Xform<T>* xform, v3T& glCoords, T& bestDist, bool pre, bool post);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
v2T SnapToGrid(v2T& vec);
|
||||||
v3T SnapToGrid(v3T& vec);
|
v3T SnapToGrid(v3T& vec);
|
||||||
v3T SnapToNormalizedAngle(v3T& vec, uint divisions);
|
v3T SnapToNormalizedAngle(v3T& vec, uint divisions);
|
||||||
v3T WindowToWorld(v3T& v, bool flip);
|
v3T WindowToWorld(v3T& v, bool flip);
|
||||||
|
@ -63,8 +63,8 @@ void GLWidget::DrawQuad()
|
|||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
RendererBase* renderer = m_Fractorium->m_Controller->Renderer();
|
auto renderer = m_Fractorium->m_Controller->Renderer();
|
||||||
vector<byte>* finalImage = m_Fractorium->m_Controller->FinalImage();
|
auto finalImage = m_Fractorium->m_Controller->FinalImage();
|
||||||
|
|
||||||
//Ensure all allocation has taken place first.
|
//Ensure all allocation has taken place first.
|
||||||
if (m_OutputTexID != 0 && finalImage && !finalImage->empty())
|
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.
|
/// Helpers to set/get/clear which keys are pressed while dragging.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>bool</returns>
|
/// <returns>bool</returns>
|
||||||
bool GLEmberControllerBase::GetAlt() { return (m_DragModifier & et(eDragModifier::DragModAlt)) == et(eDragModifier::DragModAlt); }
|
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::GetShift() { return (m_DragModifier & et(eDragModifier::DragModShift)) == et(eDragModifier::DragModShift); }
|
||||||
bool GLEmberControllerBase::GetControl() { return (m_DragModifier & et(eDragModifier::DragModControl)) == et(eDragModifier::DragModControl); }
|
bool GLEmberControllerBase::GetControl() { return (m_DragModifier & et(eDragModifier::DragModControl)) == et(eDragModifier::DragModControl); }
|
||||||
void GLEmberControllerBase::SetAlt() { m_DragModifier |= et(eDragModifier::DragModAlt); }
|
void GLEmberControllerBase::SetAlt() { m_DragModifier |= et(eDragModifier::DragModAlt); }
|
||||||
void GLEmberControllerBase::SetShift() { m_DragModifier |= et(eDragModifier::DragModShift); }
|
void GLEmberControllerBase::SetShift() { m_DragModifier |= et(eDragModifier::DragModShift); }
|
||||||
void GLEmberControllerBase::SetControl() { m_DragModifier |= et(eDragModifier::DragModControl); }
|
void GLEmberControllerBase::SetControl() { m_DragModifier |= et(eDragModifier::DragModControl); }
|
||||||
void GLEmberControllerBase::ClearAlt() { m_DragModifier &= ~et(eDragModifier::DragModAlt); }
|
void GLEmberControllerBase::ClearAlt() { m_DragModifier &= ~et(eDragModifier::DragModAlt); }
|
||||||
void GLEmberControllerBase::ClearShift() { m_DragModifier &= ~et(eDragModifier::DragModShift); }
|
void GLEmberControllerBase::ClearShift() { m_DragModifier &= ~et(eDragModifier::DragModShift); }
|
||||||
void GLEmberControllerBase::ClearControl() { m_DragModifier &= ~et(eDragModifier::DragModControl); }
|
void GLEmberControllerBase::ClearControl() { m_DragModifier &= ~et(eDragModifier::DragModControl); }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -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.
|
//Ensure there is a renderer and that it's supposed to be drawing, signified by the running timer.
|
||||||
if (controller && controller->Renderer())
|
if (controller && controller->Renderer())
|
||||||
{
|
{
|
||||||
RendererBase* renderer = controller->Renderer();
|
auto renderer = controller->Renderer();
|
||||||
m_Drawing = true;
|
m_Drawing = true;
|
||||||
controller->GLController()->DrawImage();
|
GLController()->DrawImage();
|
||||||
//Affine drawing.
|
//Affine drawing.
|
||||||
bool pre = m_Fractorium->ui.PreAffineGroupBox->isChecked();
|
bool pre = m_Fractorium->ui.PreAffineGroupBox->isChecked();
|
||||||
bool post = m_Fractorium->ui.PostAffineGroupBox->isChecked();
|
bool post = m_Fractorium->ui.PostAffineGroupBox->isChecked();
|
||||||
@ -431,7 +431,7 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
|
|||||||
m_BoundsDown.x = renderer->LowerLeftY(false);
|
m_BoundsDown.x = renderer->LowerLeftY(false);
|
||||||
m_BoundsDown.y = renderer->UpperRightX(false);
|
m_BoundsDown.y = renderer->UpperRightX(false);
|
||||||
m_BoundsDown.z = renderer->UpperRightY(false);
|
m_BoundsDown.z = renderer->UpperRightY(false);
|
||||||
Qt::KeyboardModifiers mod = e->modifiers();
|
auto mod = e->modifiers();
|
||||||
|
|
||||||
if (mod.testFlag(Qt::ShiftModifier))
|
if (mod.testFlag(Qt::ShiftModifier))
|
||||||
SetShift();
|
SetShift();
|
||||||
@ -455,11 +455,11 @@ void GLEmberController<T>::MousePress(QMouseEvent* e)
|
|||||||
m_DragSrcTransform = Affine2D<T>(m_AffineType == eAffineType::AffinePre ? m_SelectedXform->m_Affine : m_SelectedXform->m_Post);//Copy the affine of the xform that was selected.
|
m_DragSrcTransform = Affine2D<T>(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.
|
//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_Fractorium->CurrentXform(xformIndex);//Must do this first so UpdateXform() below properly grabs the current plus any selected.
|
||||||
//m_DragSrcTransforms.clear();
|
m_DragSrcTransforms.clear();
|
||||||
//m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
|
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
|
||||||
//{
|
{
|
||||||
// m_DragSrcTransforms.push_back(m_AffineType == eAffineType::AffinePre ? xform->m_Affine : xform->m_Post);
|
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.
|
}, 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_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_DragHandleOffset = m_DragHandlePos - m_MouseWorldPos;//The distance in world coordinates from the point selected to the center of the spinner.
|
||||||
m_DragState = eDragState::DragDragging;
|
m_DragState = eDragState::DragDragging;
|
||||||
@ -505,7 +505,7 @@ void GLWidget::mousePressEvent(QMouseEvent* e)
|
|||||||
{
|
{
|
||||||
setFocus();//Must do this so that this window gets keyboard events.
|
setFocus();//Must do this so that this window gets keyboard events.
|
||||||
|
|
||||||
if (GLEmberControllerBase* controller = GLController())
|
if (auto controller = GLController())
|
||||||
controller->MousePress(e);
|
controller->MousePress(e);
|
||||||
|
|
||||||
QOpenGLWidget::mousePressEvent(e);
|
QOpenGLWidget::mousePressEvent(e);
|
||||||
@ -538,7 +538,7 @@ void GLWidget::mouseReleaseEvent(QMouseEvent* e)
|
|||||||
{
|
{
|
||||||
setFocus();//Must do this so that this window gets keyboard events.
|
setFocus();//Must do this so that this window gets keyboard events.
|
||||||
|
|
||||||
if (GLEmberControllerBase* controller = GLController())
|
if (auto controller = GLController())
|
||||||
controller->MouseRelease(e);
|
controller->MouseRelease(e);
|
||||||
|
|
||||||
QOpenGLWidget::mouseReleaseEvent(e);
|
QOpenGLWidget::mouseReleaseEvent(e);
|
||||||
@ -571,22 +571,13 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
|
|||||||
if (m_SelectedXform && m_DragState == eDragState::DragDragging)//Dragging and affine.
|
if (m_SelectedXform && m_DragState == eDragState::DragDragging)//Dragging and affine.
|
||||||
{
|
{
|
||||||
bool pre = m_AffineType == eAffineType::AffinePre;
|
bool pre = m_AffineType == eAffineType::AffinePre;
|
||||||
Affine2D<T>* affine = pre ? &m_SelectedXform->m_Affine : &m_SelectedXform->m_Post;//Determine pre or post affine.
|
|
||||||
|
|
||||||
if (m_HoverType == eHoverType::HoverTranslation)
|
if (m_HoverType == eHoverType::HoverTranslation)
|
||||||
{
|
CalcDragTranslation();
|
||||||
//m_FractoriumEmberController->UpdateXform([&](Xform<T>* 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();
|
|
||||||
}
|
|
||||||
else if (m_HoverType == eHoverType::HoverXAxis)
|
else if (m_HoverType == eHoverType::HoverXAxis)
|
||||||
*affine = CalcDragXAxis();
|
CalcDragXAxis();
|
||||||
else if (m_HoverType == eHoverType::HoverYAxis)
|
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->FillAffineWithXform(m_SelectedXform, pre);//Update the spinners in the affine tab of the main window.
|
||||||
m_FractoriumEmberController->UpdateRender();//Restart the rendering process.
|
m_FractoriumEmberController->UpdateRender();//Restart the rendering process.
|
||||||
@ -598,7 +589,7 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
|
|||||||
Affine2D<T> rotMat;
|
Affine2D<T> rotMat;
|
||||||
rotMat.C(m_CenterDownX);
|
rotMat.C(m_CenterDownX);
|
||||||
rotMat.F(m_CenterDownY);
|
rotMat.F(m_CenterDownY);
|
||||||
rotMat.Rotate(ember->m_Rotate);
|
rotMat.Rotate(ember->m_Rotate * DEG_2_RAD_T);
|
||||||
v2T v1(x, y);
|
v2T v1(x, y);
|
||||||
v2T v2 = rotMat.TransformVector(v1);
|
v2T v2 = rotMat.TransformVector(v1);
|
||||||
ember->m_CenterX = v2.x;
|
ember->m_CenterX = v2.x;
|
||||||
@ -611,8 +602,7 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
|
|||||||
T scale = CalcScale();
|
T scale = CalcScale();
|
||||||
ember->m_Rotate = NormalizeDeg180<T>(m_RotationDown + rot);
|
ember->m_Rotate = NormalizeDeg180<T>(m_RotationDown + rot);
|
||||||
m_Fractorium->SetRotation(ember->m_Rotate, true);
|
m_Fractorium->SetRotation(ember->m_Rotate, true);
|
||||||
ember->m_PixelsPerUnit = m_ScaleDown + scale;
|
m_Fractorium->SetScale(m_ScaleDown + scale);//Will restart the rendering process.
|
||||||
m_Fractorium->SetScale(ember->m_PixelsPerUnit);//Will restart the rendering process.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -625,22 +615,12 @@ void GLEmberController<T>::MouseMove(QMouseEvent* e)
|
|||||||
//In that case, nothing needs to be done.
|
//In that case, nothing needs to be done.
|
||||||
if (UpdateHover(mouseFlipped) == -1)
|
if (UpdateHover(mouseFlipped) == -1)
|
||||||
draw = false;
|
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.
|
//Only update if the user was dragging or hovered over a point.
|
||||||
//Use repaint() to update immediately for a more responsive feel.
|
//Use repaint() to update immediately for a more responsive feel.
|
||||||
if ((m_DragState != eDragState::DragNone) || draw)
|
if ((m_DragState != eDragState::DragNone) || draw)
|
||||||
m_GL->update();
|
m_GL->update();
|
||||||
|
|
||||||
//m_GL->repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -651,7 +631,7 @@ void GLWidget::mouseMoveEvent(QMouseEvent* e)
|
|||||||
{
|
{
|
||||||
setFocus();//Must do this so that this window gets keyboard events.
|
setFocus();//Must do this so that this window gets keyboard events.
|
||||||
|
|
||||||
if (GLEmberControllerBase* controller = GLController())
|
if (auto controller = GLController())
|
||||||
controller->MouseMove(e);
|
controller->MouseMove(e);
|
||||||
|
|
||||||
QOpenGLWidget::mouseMoveEvent(e);
|
QOpenGLWidget::mouseMoveEvent(e);
|
||||||
@ -679,28 +659,12 @@ void GLEmberController<T>::Wheel(QWheelEvent* e)
|
|||||||
/// <param name="e">The event</param>
|
/// <param name="e">The event</param>
|
||||||
void GLWidget::wheelEvent(QWheelEvent* e)
|
void GLWidget::wheelEvent(QWheelEvent* e)
|
||||||
{
|
{
|
||||||
if (GLEmberControllerBase* controller = GLController())
|
if (auto controller = GLController())
|
||||||
controller->Wheel(e);
|
controller->Wheel(e);
|
||||||
|
|
||||||
//Do not call QOpenGLWidget::wheelEvent(e) because this should only affect the scale and not the position of the scroll bars.
|
//Do not call QOpenGLWidget::wheelEvent(e) because this should only affect the scale and not the position of the scroll bars.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="e">The event</param>
|
|
||||||
//void GLWidget::resizeEvent(QResizeEvent* e)
|
|
||||||
//{
|
|
||||||
// if (m_Fractorium)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// QOpenGLWidget::resizeEvent(e);
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the dimensions of the drawing area.
|
/// Set the dimensions of the drawing area.
|
||||||
/// This will be called from the main window's SyncSizes() function.
|
/// 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)
|
void GLWidget::SetDimensions(int w, int h)
|
||||||
{
|
{
|
||||||
setFixedSize(w, h);
|
setFixedSize(w, h);
|
||||||
//resize(w, h);
|
|
||||||
//m_Fractorium->ui.GLParentScrollAreaContents->setFixedSize(w, h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -817,7 +779,7 @@ bool GLEmberController<T>::SizesMatch()
|
|||||||
/// <param name="scale">A value to scale by, used when locking the affine scale</param>
|
/// <param name="scale">A value to scale by, used when locking the affine scale</param>
|
||||||
void GLWidget::DrawGrid(double 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 unitX = std::abs(renderer->UpperRightX(false) - renderer->LowerLeftX(false)) / 2.0f;
|
||||||
float unitY = std::abs(renderer->UpperRightY(false) - renderer->LowerLeftY(false)) / 2.0f;
|
float unitY = std::abs(renderer->UpperRightY(false) - renderer->LowerLeftY(false)) / 2.0f;
|
||||||
float rad = std::max(unitX * scale, unitY * scale);
|
float rad = std::max(unitX * scale, unitY * scale);
|
||||||
@ -916,10 +878,10 @@ template <typename T>
|
|||||||
void GLEmberController<T>::DrawAffine(Xform<T>* xform, bool pre, bool selected)
|
void GLEmberController<T>::DrawAffine(Xform<T>* xform, bool pre, bool selected)
|
||||||
{
|
{
|
||||||
auto ember = m_FractoriumEmberController->CurrentEmber();
|
auto ember = m_FractoriumEmberController->CurrentEmber();
|
||||||
bool final = ember->IsFinalXform(xform);
|
auto final = ember->IsFinalXform(xform);
|
||||||
int index = ember->GetXformIndex(xform);
|
auto index = ember->GetXformIndex(xform);
|
||||||
size_t size = ember->m_Palette.m_Entries.size();
|
auto size = ember->m_Palette.m_Entries.size();
|
||||||
v4T color = ember->m_Palette.m_Entries[Clamp<T>(xform->m_ColorX * size, 0, size - 1)];
|
auto color = ember->m_Palette.m_Entries[Clamp<T>(xform->m_ColorX * size, 0, size - 1)];
|
||||||
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
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
|
//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
|
//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 px = 1.0f;
|
||||||
float py = 0.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);
|
glBegin(GL_LINES);
|
||||||
|
|
||||||
//Circle part.
|
//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.
|
for (size_t i = 1; i <= 64; i++)//The circle.
|
||||||
{
|
{
|
||||||
float theta = float(M_PI) * 2.0f * float(i % 64) / 64.0f;
|
float theta = float(M_PI) * 2.0f * float(i % 64) / 64.0f;
|
||||||
float fx = float(cos(theta));
|
float fx = std::cos(theta);
|
||||||
float fy = float(sin(theta));
|
float fy = std::sin(theta);
|
||||||
glVertex2f(px, py);
|
glVertex2f(px, py);
|
||||||
glVertex2f(fx, fy);
|
glVertex2f(fx, fy);
|
||||||
px = fx;
|
px = fx;
|
||||||
@ -1214,56 +1176,73 @@ bool GLEmberController<T>::CheckXformHover(Xform<T>* xform, v3T& glCoords, T& be
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The new affine transform to be assigned to the selected xform</returns>
|
/// <returns>The new affine transform to be assigned to the selected xform</returns>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Affine2D<T> GLEmberController<T>::CalcDragXAxis()
|
void GLEmberController<T>::CalcDragXAxis()
|
||||||
{
|
{
|
||||||
v3T t3, newAxis, newPos;
|
size_t index = 0;
|
||||||
auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
|
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();
|
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt();
|
||||||
|
|
||||||
if (worldPivotShiftAlt)
|
|
||||||
t3 = v3T(0, 0, 0);
|
|
||||||
else
|
|
||||||
t3 = v3T(m_DragSrcTransform.O(), 0);
|
|
||||||
|
|
||||||
if (GetShift())
|
if (GetShift())
|
||||||
{
|
{
|
||||||
v3T targetAxis = (m_MouseWorldPos * scale) - t3;
|
v3T snapped = GetControl() ? SnapToNormalizedAngle(m_MouseWorldPos + m_DragHandleOffset, 24) : m_MouseWorldPos + m_DragHandleOffset;
|
||||||
v3T norm = glm::normalize(targetAxis);
|
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<T>* xform)
|
||||||
|
{
|
||||||
|
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
||||||
|
auto srcRotated = m_DragSrcTransforms[index++];
|
||||||
|
|
||||||
if (GetControl())
|
if (worldPivotShiftAlt)
|
||||||
norm = SnapToNormalizedAngle(norm, 24);
|
{
|
||||||
|
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)
|
if (xform == m_FractoriumEmberController->CurrentXform())
|
||||||
newAxis = norm * glm::length(m_DragSrcTransform.O() + m_DragSrcTransform.X());
|
m_DragHandlePos = v3T((affine->O() + affine->X()) * scaleBack, 0);
|
||||||
else
|
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Calling code will update renderer.
|
||||||
newAxis = norm * glm::length(m_DragSrcTransform.X());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
v3T diff;
|
||||||
|
|
||||||
if (GetControl())
|
if (GetControl())
|
||||||
newPos = SnapToGrid(m_MouseWorldPos);
|
diff = SnapToGrid(m_MouseWorldPos + m_DragHandleOffset) - m_MouseDownWorldPos;
|
||||||
else
|
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<T>* xform)
|
||||||
|
{
|
||||||
|
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
||||||
|
auto axis = v3T(m_DragSrcTransforms[index++].X(), 0) + (diff * scale);
|
||||||
|
|
||||||
if (GetAlt())
|
if (GetAlt())
|
||||||
{
|
affine->X(v2T(origXPlusOff));//Absolute, not ratio.
|
||||||
if (worldPivotShiftAlt)
|
else
|
||||||
result.X(v2T(newAxis) - m_DragSrcTransform.O());
|
affine->RotateScaleXTo(v2T(axis));
|
||||||
else
|
|
||||||
result.X(v2T(newAxis));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.RotateScaleXTo(v2T(newAxis));
|
|
||||||
}
|
|
||||||
|
|
||||||
T scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked();
|
if (xform == m_FractoriumEmberController->CurrentXform())
|
||||||
m_DragHandlePos = v3T((result.O() + result.X()) * scaleBack, 0);
|
m_DragHandlePos = v3T((affine->O() + affine->X()) * scaleBack, 0);
|
||||||
return result;
|
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1285,56 +1264,73 @@ Affine2D<T> GLEmberController<T>::CalcDragXAxis()
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The new affine transform to be assigned to the selected xform</returns>
|
/// <returns>The new affine transform to be assigned to the selected xform</returns>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Affine2D<T> GLEmberController<T>::CalcDragYAxis()
|
void GLEmberController<T>::CalcDragYAxis()
|
||||||
{
|
{
|
||||||
v3T t3, newAxis, newPos;
|
size_t index = 0;
|
||||||
auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
|
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();
|
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt();
|
||||||
|
|
||||||
if (worldPivotShiftAlt)
|
|
||||||
t3 = v3T(0, 0, 0);
|
|
||||||
else
|
|
||||||
t3 = v3T(m_DragSrcTransform.O(), 0);
|
|
||||||
|
|
||||||
if (GetShift())
|
if (GetShift())
|
||||||
{
|
{
|
||||||
v3T targetAxis = (m_MouseWorldPos * scale) - t3;
|
v3T snapped = GetControl() ? SnapToNormalizedAngle(m_MouseWorldPos + m_DragHandleOffset, 24) : m_MouseWorldPos + m_DragHandleOffset;
|
||||||
v3T norm = glm::normalize(targetAxis);
|
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<T>* xform)
|
||||||
|
{
|
||||||
|
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
||||||
|
auto srcRotated = m_DragSrcTransforms[index++];
|
||||||
|
|
||||||
if (GetControl())
|
if (worldPivotShiftAlt)
|
||||||
norm = SnapToNormalizedAngle(norm, 24);
|
{
|
||||||
|
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)
|
if (xform == m_FractoriumEmberController->CurrentXform())
|
||||||
newAxis = norm * glm::length(m_DragSrcTransform.O() + m_DragSrcTransform.Y());
|
m_DragHandlePos = v3T((affine->O() + affine->Y()) * scaleBack, 0);
|
||||||
else
|
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);//Calling code will update renderer.
|
||||||
newAxis = norm * glm::length(m_DragSrcTransform.Y());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
v3T diff;
|
||||||
|
|
||||||
if (GetControl())
|
if (GetControl())
|
||||||
newPos = SnapToGrid(m_MouseWorldPos);
|
diff = SnapToGrid(m_MouseWorldPos + m_DragHandleOffset) - m_MouseDownWorldPos;
|
||||||
else
|
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<T>* xform)
|
||||||
|
{
|
||||||
|
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
||||||
|
auto axis = v3T(m_DragSrcTransforms[index++].Y(), 0) + (diff * scale);
|
||||||
|
|
||||||
if (GetAlt())
|
if (GetAlt())
|
||||||
{
|
affine->Y(v2T(origXPlusOff));//Absolute, not ratio.
|
||||||
if (worldPivotShiftAlt)
|
else
|
||||||
result.Y(v2T(newAxis) - m_DragSrcTransform.O());
|
affine->RotateScaleYTo(v2T(axis));
|
||||||
else
|
|
||||||
result.Y(v2T(newAxis));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.RotateScaleYTo(v2T(newAxis));
|
|
||||||
}
|
|
||||||
|
|
||||||
T scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked();
|
if (xform == m_FractoriumEmberController->CurrentXform())
|
||||||
m_DragHandlePos = v3T((result.O() + result.Y()) * scaleBack, 0);
|
m_DragHandlePos = v3T((affine->O() + affine->Y()) * scaleBack, 0);
|
||||||
return result;
|
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1350,58 +1346,65 @@ Affine2D<T> GLEmberController<T>::CalcDragYAxis()
|
|||||||
/// Control + Shift: Rotate about world center, rotating orientation, snapping to grid.
|
/// Control + Shift: Rotate about world center, rotating orientation, snapping to grid.
|
||||||
/// All others are the same as local pivot.
|
/// All others are the same as local pivot.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The new affine transform to be assigned to the selected xform</returns>
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Affine2D<T> GLEmberController<T>::CalcDragTranslation()
|
void GLEmberController<T>::CalcDragTranslation()
|
||||||
{
|
{
|
||||||
v3T newPos;
|
size_t index = 0;
|
||||||
auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
|
auto scale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
|
||||||
auto result = m_DragSrcTransform;
|
auto scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked();
|
||||||
bool worldPivotShift = !m_Fractorium->LocalPivot() && GetShift();
|
bool worldPivotShift = !m_Fractorium->LocalPivot() && GetShift();
|
||||||
|
bool pre = m_AffineType == eAffineType::AffinePre;
|
||||||
|
|
||||||
if (GetShift())
|
if (GetShift())
|
||||||
{
|
{
|
||||||
v3T norm = glm::normalize(m_MouseWorldPos);
|
v3T snapped = GetControl() ? SnapToNormalizedAngle(m_MouseWorldPos, 24) : m_MouseWorldPos;
|
||||||
|
T startAngle = std::atan2(m_DragSrcTransform.O().y, m_DragSrcTransform.O().x);
|
||||||
if (GetControl())
|
T endAngle = std::atan2(snapped.y, snapped.x);
|
||||||
norm = SnapToNormalizedAngle(norm, 12);
|
T angle = startAngle - endAngle;
|
||||||
|
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
|
||||||
newPos = glm::length(m_DragSrcTransform.O()) * norm;
|
|
||||||
|
|
||||||
if (worldPivotShift)
|
|
||||||
{
|
{
|
||||||
T startAngle = atan2(m_DragSrcTransform.O().y, m_DragSrcTransform.O().x);
|
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
||||||
T endAngle = atan2(newPos.y, newPos.x);
|
auto srcRotated = m_DragSrcTransforms[index++];
|
||||||
T angle = startAngle - endAngle;
|
srcRotated.RotateTrans(angle);
|
||||||
result.Rotate(angle * RAD_2_DEG);
|
|
||||||
//RotateXformsByAngle
|
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
|
else
|
||||||
{
|
{
|
||||||
|
auto diff = m_MouseWorldPos - m_MouseDownWorldPos;
|
||||||
|
|
||||||
if (GetControl())
|
if (GetControl())
|
||||||
{
|
{
|
||||||
newPos = SnapToGrid(m_MouseWorldPos);
|
m_FractoriumEmberController->UpdateXform([&](Xform<T>* 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
|
else
|
||||||
{
|
{
|
||||||
newPos = m_MouseWorldPos + m_DragHandleOffset;
|
m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
|
||||||
//bool pre = m_AffineType == eAffineType::AffinePre;
|
{
|
||||||
//size_t index = 0;
|
auto affine = pre ? &xform->m_Affine : &xform->m_Post;
|
||||||
//newPos = m_MouseWorldPos;
|
affine->O(m_DragSrcTransforms[index++].O() + (scale * v2T(diff)));
|
||||||
//auto diff = m_MouseWorldPos - m_MouseDownWorldPos;
|
}, eXformUpdate::UPDATE_CURRENT_AND_SELECTED, false);
|
||||||
//m_FractoriumEmberController->UpdateXform([&](Xform<T>* xform)
|
m_DragHandlePos = m_MouseWorldPos;
|
||||||
//{
|
|
||||||
// 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.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
T scaleBack = m_FractoriumEmberController->AffineScaleCurrentToLocked();
|
|
||||||
result.O(v2T(newPos * scale));
|
|
||||||
m_DragHandlePos = newPos;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -62,7 +62,6 @@ protected:
|
|||||||
virtual void mouseReleaseEvent(QMouseEvent* e) override;
|
virtual void mouseReleaseEvent(QMouseEvent* e) override;
|
||||||
virtual void mouseMoveEvent(QMouseEvent* e) override;
|
virtual void mouseMoveEvent(QMouseEvent* e) override;
|
||||||
virtual void wheelEvent(QWheelEvent* e) override;
|
virtual void wheelEvent(QWheelEvent* e) override;
|
||||||
//virtual void resizeEvent(QResizeEvent* e) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetDimensions(int w, int h);
|
void SetDimensions(int w, int h);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "FractoriumPch.h"
|
#include "FractoriumPch.h"
|
||||||
#include "SpinBox.h"
|
#include "SpinBox.h"
|
||||||
|
|
||||||
QTimer SpinBox::m_Timer;
|
QTimer SpinBox::s_Timer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor that passes parent to the base and sets up height and step.
|
/// Constructor that passes parent to the base and sets up height and step.
|
||||||
@ -118,17 +118,16 @@ void SpinBox::OnTimeout()
|
|||||||
//qDebug() << "Shift pressed";
|
//qDebug() << "Shift pressed";
|
||||||
scale = 0.001;
|
scale = 0.001;
|
||||||
}
|
}
|
||||||
/*else if (ctrl)
|
/* else if (ctrl)
|
||||||
{
|
{
|
||||||
qDebug() << "Control pressed";
|
qDebug() << "Control pressed";
|
||||||
scale = 0.01;
|
scale = 0.01;
|
||||||
}*/
|
}*/
|
||||||
else
|
else
|
||||||
scale = 0.01;
|
scale = 0.01;
|
||||||
|
|
||||||
val = d + (distance * amount * scale);
|
val = d + (distance * amount * scale);
|
||||||
setValue(int(val));
|
setValue(int(val));
|
||||||
|
|
||||||
//qDebug() << "Timer on, orig val: " << d << ", new val: " << val << ", distance " << distance;
|
//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<QMouseEvent*>(e);
|
QMouseEvent* me = dynamic_cast<QMouseEvent*>(e);
|
||||||
|
|
||||||
if (isEnabled() &&
|
if (isEnabled() &&
|
||||||
me &&
|
me &&
|
||||||
me->type() == QMouseEvent::MouseButtonPress &&
|
me->type() == QMouseEvent::MouseButtonPress &&
|
||||||
me->button() == Qt::RightButton)
|
me->button() == Qt::RightButton)
|
||||||
{
|
{
|
||||||
m_MouseDownPoint = m_MouseMovePoint = me->pos();
|
m_MouseDownPoint = m_MouseMovePoint = me->pos();
|
||||||
StartTimer();
|
StartTimer();
|
||||||
@ -172,18 +171,18 @@ bool SpinBox::eventFilter(QObject* o, QEvent* e)
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
else if (isEnabled() &&
|
else if (isEnabled() &&
|
||||||
me &&
|
me &&
|
||||||
me->type() == QMouseEvent::MouseButtonRelease &&
|
me->type() == QMouseEvent::MouseButtonRelease &&
|
||||||
me->button() == Qt::RightButton)
|
me->button() == Qt::RightButton)
|
||||||
{
|
{
|
||||||
StopTimer();
|
StopTimer();
|
||||||
m_MouseDownPoint = m_MouseMovePoint = me->pos();
|
m_MouseDownPoint = m_MouseMovePoint = me->pos();
|
||||||
//qDebug() << "Right mouse up";
|
//qDebug() << "Right mouse up";
|
||||||
}
|
}
|
||||||
else if (isEnabled() &&
|
else if (isEnabled() &&
|
||||||
me &&
|
me &&
|
||||||
me->type() == QMouseEvent::MouseMove &&
|
me->type() == QMouseEvent::MouseMove &&
|
||||||
QGuiApplication::mouseButtons() & Qt::RightButton)
|
QGuiApplication::mouseButtons() & Qt::RightButton)
|
||||||
{
|
{
|
||||||
m_MouseMovePoint = me->pos();
|
m_MouseMovePoint = me->pos();
|
||||||
qDebug() << "Mouse move while right down. Pt = " << me->pos() << ", global: " << mapToGlobal(me->pos());
|
qDebug() << "Mouse move while right down. Pt = " << me->pos() << ", global: " << mapToGlobal(me->pos());
|
||||||
@ -236,8 +235,8 @@ void SpinBox::focusInEvent(QFocusEvent* e)
|
|||||||
/// <param name="e">The event</param>
|
/// <param name="e">The event</param>
|
||||||
void SpinBox::focusOutEvent(QFocusEvent* e)
|
void SpinBox::focusOutEvent(QFocusEvent* e)
|
||||||
{
|
{
|
||||||
//lineEdit()->deselect();//Clear selection when leaving.
|
//lineEdit()->deselect();//Clear selection when leaving.
|
||||||
//lineEdit()->setReadOnly(true);//Clever hack to clear the cursor when leaving.
|
//lineEdit()->setReadOnly(true);//Clever hack to clear the cursor when leaving.
|
||||||
StopTimer();
|
StopTimer();
|
||||||
QSpinBox::focusOutEvent(e);
|
QSpinBox::focusOutEvent(e);
|
||||||
}
|
}
|
||||||
@ -273,9 +272,9 @@ void SpinBox::leaveEvent(QEvent* e)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void SpinBox::StartTimer()
|
void SpinBox::StartTimer()
|
||||||
{
|
{
|
||||||
m_Timer.stop();
|
s_Timer.stop();
|
||||||
connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
connect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
||||||
m_Timer.start(300);
|
s_Timer.start(300);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -283,6 +282,6 @@ void SpinBox::StartTimer()
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void SpinBox::StopTimer()
|
void SpinBox::StopTimer()
|
||||||
{
|
{
|
||||||
m_Timer.stop();
|
s_Timer.stop();
|
||||||
disconnect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
disconnect(&s_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout()));
|
||||||
}
|
}
|
||||||
|
@ -48,5 +48,5 @@ private:
|
|||||||
int m_SmallStep;
|
int m_SmallStep;
|
||||||
QPoint m_MouseDownPoint;
|
QPoint m_MouseDownPoint;
|
||||||
QPoint m_MouseMovePoint;
|
QPoint m_MouseMovePoint;
|
||||||
static QTimer m_Timer;
|
static QTimer s_Timer;
|
||||||
};
|
};
|
||||||
|
@ -53,25 +53,21 @@ private:
|
|||||||
bool operator < (const QTreeWidgetItem& other) const
|
bool operator < (const QTreeWidgetItem& other) const
|
||||||
{
|
{
|
||||||
int column = treeWidget()->sortColumn();
|
int column = treeWidget()->sortColumn();
|
||||||
eVariationId index1, index2;
|
|
||||||
double weight1 = 0, weight2 = 0;
|
|
||||||
VariationTreeWidgetItem* varItemWidget;
|
|
||||||
VariationTreeDoubleSpinBox* spinBox1, *spinBox2;
|
|
||||||
auto itemWidget1 = treeWidget()->itemWidget(const_cast<VariationTreeWidgetItem*>(this), 1);//Get the widget for the second column.
|
auto itemWidget1 = treeWidget()->itemWidget(const_cast<VariationTreeWidgetItem*>(this), 1);//Get the widget for the second column.
|
||||||
|
|
||||||
if ((spinBox1 = dynamic_cast<VariationTreeDoubleSpinBox*>(itemWidget1)))//Cast the widget to the VariationTreeDoubleSpinBox type.
|
if (auto spinBox1 = dynamic_cast<VariationTreeDoubleSpinBox*>(itemWidget1))//Cast the widget to the VariationTreeDoubleSpinBox type.
|
||||||
{
|
{
|
||||||
auto itemWidget2 = treeWidget()->itemWidget(const_cast<QTreeWidgetItem*>(&other), 1);//Get the widget for the second column of the widget item passed in.
|
auto itemWidget2 = treeWidget()->itemWidget(const_cast<QTreeWidgetItem*>(&other), 1);//Get the widget for the second column of the widget item passed in.
|
||||||
|
|
||||||
if ((spinBox2 = dynamic_cast<VariationTreeDoubleSpinBox*>(itemWidget2)))//Cast the widget to the VariationTreeDoubleSpinBox type.
|
if (auto spinBox2 = dynamic_cast<VariationTreeDoubleSpinBox*>(itemWidget2))//Cast the widget to the VariationTreeDoubleSpinBox type.
|
||||||
{
|
{
|
||||||
if (spinBox1->IsParam() || spinBox2->IsParam())//Do not sort params, their order will always remain the same.
|
if (spinBox1->IsParam() || spinBox2->IsParam())//Do not sort params, their order will always remain the same.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
weight1 = spinBox1->value();
|
auto weight1 = spinBox1->value();
|
||||||
weight2 = spinBox2->value();
|
auto weight2 = spinBox2->value();
|
||||||
index1 = spinBox1->GetVariationId();
|
auto index1 = spinBox1->GetVariationId();
|
||||||
index2 = spinBox2->GetVariationId();
|
auto index2 = spinBox2->GetVariationId();
|
||||||
|
|
||||||
if (column == 0)//First column clicked, sort by variation index.
|
if (column == 0)//First column clicked, sort by variation index.
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user