mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-08-16 12:25:08 -04:00
--User changes
-Clear all color curves when clicking Reset while holding down Ctrl. --Code changes -No longer assume palettes are 256 elements. Can now read and write longer palettes. -Ensure OpenCL images always get written when created.
This commit is contained in:
@ -53,7 +53,6 @@ namespace EmberNs
|
||||
#define SQRT5 T(2.2360679774997896964091736687313)
|
||||
#define M_PHI T(1.61803398874989484820458683436563)
|
||||
#define COLORMAP_LENGTH 256//These will need to change if 2D palette support is ever added, or variable sized palettes.
|
||||
#define COLORMAP_LENGTH_MINUS_1 255
|
||||
#define WHITE 255
|
||||
#define DEFAULT_SBS (1024 * 10)
|
||||
//#define XC(c) ((const xmlChar*)(c))
|
||||
|
@ -259,7 +259,7 @@ string EmberToXml<T>::ToString(Ember<T>& ember, const string& extraAttributes, s
|
||||
//less error prone to just embed the palette.
|
||||
if (hexPalette)
|
||||
{
|
||||
os << " <palette count=\"256\" format=\"RGB\"";
|
||||
os << " <palette count=\"" << ember.m_Palette.Size() << "\" format=\"RGB\"";
|
||||
|
||||
if (!ember.m_Palette.m_SourceColors.empty())
|
||||
{
|
||||
@ -279,8 +279,9 @@ string EmberToXml<T>::ToString(Ember<T>& ember, const string& extraAttributes, s
|
||||
|
||||
os << ">\n";
|
||||
os << std::uppercase;
|
||||
auto rows = ember.m_Palette.Size() / 8;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
for (i = 0; i < rows; i++)
|
||||
{
|
||||
os << " ";
|
||||
|
||||
@ -300,7 +301,7 @@ string EmberToXml<T>::ToString(Ember<T>& ember, const string& extraAttributes, s
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
for (i = 0; i < ember.m_Palette.Size(); i++)
|
||||
{
|
||||
double r = ember.m_Palette[i][0] * 255;
|
||||
double g = ember.m_Palette[i][1] * 255;
|
||||
|
@ -246,7 +246,7 @@ public:
|
||||
|
||||
for (size_t i = 0; i < Size(); i++)
|
||||
{
|
||||
size_t ii = (i * 256) / COLORMAP_LENGTH;
|
||||
size_t ii = (i * Size()) / Size();
|
||||
T rgb[3], hsv[3];
|
||||
rgb[0] = m_Entries[ii].r;
|
||||
rgb[1] = m_Entries[ii].g;
|
||||
@ -279,6 +279,7 @@ public:
|
||||
void MakeAdjustedPalette(Palette<T>& palette, int rot, T hue, T sat, T bright, T cont, uint blur, uint freq)
|
||||
{
|
||||
T rgb[3], hsv[3];
|
||||
palette.m_Entries.resize(Size());
|
||||
|
||||
if (freq > 1)
|
||||
{
|
||||
@ -306,13 +307,13 @@ public:
|
||||
}
|
||||
|
||||
auto tempPal = palette;
|
||||
intmax_t iSize = intmax_t(Size());
|
||||
|
||||
for (size_t i = 0; i < Size(); i++)
|
||||
for (intmax_t i = 0; i < iSize; i++)
|
||||
{
|
||||
int ii = int(i);
|
||||
rgb[0] = tempPal[std::abs(COLORMAP_LENGTH + ii - rot) % COLORMAP_LENGTH].r;//Rotation.
|
||||
rgb[1] = tempPal[std::abs(COLORMAP_LENGTH + ii - rot) % COLORMAP_LENGTH].g;
|
||||
rgb[2] = tempPal[std::abs(COLORMAP_LENGTH + ii - rot) % COLORMAP_LENGTH].b;
|
||||
rgb[0] = tempPal[std::abs(iSize + i - rot) % iSize].r;//Rotation.
|
||||
rgb[1] = tempPal[std::abs(iSize + i - rot) % iSize].g;
|
||||
rgb[2] = tempPal[std::abs(iSize + i - rot) % iSize].b;
|
||||
RgbToHsv(rgb, hsv);
|
||||
hsv[0] += hue * T(6.0);//Hue.
|
||||
hsv[1] = Clamp<T>(hsv[1] + sat, 0, 1);//Saturation.
|
||||
@ -335,7 +336,7 @@ public:
|
||||
{
|
||||
tempPal = palette;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
for (int i = 0; i < iSize; i++)
|
||||
{
|
||||
int n = -1;
|
||||
rgb[0] = 0;
|
||||
@ -345,7 +346,7 @@ public:
|
||||
for (int j = i - int(blur); j <= i + int(blur); j++)
|
||||
{
|
||||
n++;
|
||||
int k = (256 + j) % 256;
|
||||
auto k = (iSize + j) % iSize;
|
||||
|
||||
if (k != i)
|
||||
{
|
||||
|
@ -1497,6 +1497,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
|
||||
{
|
||||
size_t histIndex, intColorIndex, histSize = m_HistBuckets.size();
|
||||
bucketT colorIndex, colorIndexFrac;
|
||||
auto psm1 = m_Ember.m_Palette.Size() - 1;
|
||||
|
||||
//Linear is a linear scale for when the color index is not a whole number, which is most of the time.
|
||||
//It uses a portion of the value of the index, and the remainder of the next index.
|
||||
@ -1506,6 +1507,8 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
|
||||
//Use overloaded addition and multiplication operators in vec4 to perform the accumulation.
|
||||
if (PaletteMode() == ePaletteMode::PALETTE_LINEAR)
|
||||
{
|
||||
auto psm2 = psm1 - 1;
|
||||
|
||||
//It's critical to understand what's going on here as it's one of the most important parts of the algorithm.
|
||||
//A color value gets retrieved from the palette and
|
||||
//its RGB values are added to the existing RGB values in the histogram bucket.
|
||||
@ -1542,7 +1545,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
|
||||
//This will result in a few points at the very edges getting discarded, but prevents a crash and doesn't seem to make a speed difference.
|
||||
if (histIndex < histSize)
|
||||
{
|
||||
colorIndex = bucketT(p.m_ColorX) * COLORMAP_LENGTH_MINUS_1;
|
||||
colorIndex = bucketT(p.m_ColorX) * psm1;
|
||||
intColorIndex = size_t(colorIndex);
|
||||
|
||||
if (intColorIndex < 0)
|
||||
@ -1550,9 +1553,9 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
|
||||
intColorIndex = 0;
|
||||
colorIndexFrac = 0;
|
||||
}
|
||||
else if (intColorIndex >= COLORMAP_LENGTH_MINUS_1)
|
||||
else if (intColorIndex >= psm1)
|
||||
{
|
||||
intColorIndex = COLORMAP_LENGTH_MINUS_1 - 1;
|
||||
intColorIndex = psm2;
|
||||
colorIndexFrac = 1;
|
||||
}
|
||||
else
|
||||
@ -1608,7 +1611,7 @@ void Renderer<T, bucketT>::Accumulate(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand, Poin
|
||||
|
||||
if (histIndex < histSize)
|
||||
{
|
||||
intColorIndex = Clamp<size_t>(size_t(p.m_ColorX * COLORMAP_LENGTH_MINUS_1), 0, COLORMAP_LENGTH_MINUS_1);
|
||||
intColorIndex = Clamp<size_t>(size_t(p.m_ColorX * psm1), 0, psm1);
|
||||
bucketT* __restrict hist = glm::value_ptr(m_HistBuckets[histIndex]);//Vectorizer can't tell these point to different locations.
|
||||
const bucketT* __restrict pal = glm::value_ptr(palette->m_Entries[intColorIndex]);
|
||||
|
||||
|
@ -1310,19 +1310,18 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
|
||||
{
|
||||
if (auto palettevalsnode = GetChildNodeByNodeName(palettenode, "values"))
|
||||
{
|
||||
int i = 0;
|
||||
float r = 0, g = 0, b = 0;
|
||||
auto colors = CCX(palettevalsnode->children->content);
|
||||
istringstream istr(colors);
|
||||
currentEmber.m_Palette.m_Entries.clear();
|
||||
std::vector<v4F> tempv;
|
||||
tempv.reserve(256);
|
||||
|
||||
while (istr >> r && istr >> g && istr >> b && i < COLORMAP_LENGTH)
|
||||
{
|
||||
currentEmber.m_Palette.m_Entries[i][0] = r;
|
||||
currentEmber.m_Palette.m_Entries[i][1] = g;
|
||||
currentEmber.m_Palette.m_Entries[i][2] = b;
|
||||
currentEmber.m_Palette.m_Entries[i][3] = 1;
|
||||
i++;
|
||||
}
|
||||
while (istr >> r && istr >> g && istr >> b)
|
||||
tempv.push_back(v4F(r, g, b, 1));
|
||||
|
||||
if (!tempv.empty())
|
||||
currentEmber.m_Palette.m_Entries = std::move(tempv);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1393,9 +1392,10 @@ bool XmlToEmber<T>::ParseEmberElementFromChaos(xmlNode* emberNode, Ember<T>& cur
|
||||
Spline<float> hspline(hvec);
|
||||
Spline<float> sspline(svec);
|
||||
Spline<float> vspline(vvec);
|
||||
auto stepsize = (1.0f / (COLORMAP_LENGTH - 1));
|
||||
currentEmber.m_Palette.m_Entries.resize(COLORMAP_LENGTH);
|
||||
auto stepsize = (1.0f / (currentEmber.m_Palette.Size() - 1));
|
||||
|
||||
for (auto palindex = 0; palindex < COLORMAP_LENGTH; palindex++)
|
||||
for (auto palindex = 0; palindex < currentEmber.m_Palette.Size(); palindex++)
|
||||
{
|
||||
float t = palindex * stepsize;
|
||||
auto h = hspline.Interpolate(t);
|
||||
@ -1768,22 +1768,15 @@ bool XmlToEmber<T>::ParseEmberElement(xmlNode* emberNode, Ember<T>& currentEmber
|
||||
xmlFree(attStr);
|
||||
}
|
||||
|
||||
//Palette colors are [0..255], convert to [0..1].
|
||||
if (index >= 0 && index <= 255)
|
||||
{
|
||||
float alphaPercent = a / 255.0f;//Aplha percentage in the range of 0 to 1.
|
||||
//Premultiply the palette.
|
||||
currentEmber.m_Palette.m_Entries[index].r = alphaPercent * (r / 255.0f);
|
||||
currentEmber.m_Palette.m_Entries[index].g = alphaPercent * (g / 255.0f);
|
||||
currentEmber.m_Palette.m_Entries[index].b = alphaPercent * (b / 255.0f);
|
||||
currentEmber.m_Palette.m_Entries[index].a = a / 255.0f;//Will be one for RGB, and other than one if RGBA with A != 255.
|
||||
}
|
||||
else
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "ParseEmberElement() : Color element with bad/missing index attribute " << index;
|
||||
AddToReport(ss.str());
|
||||
}
|
||||
while (index >= currentEmber.m_Palette.Size())
|
||||
currentEmber.m_Palette.m_Entries.push_back(v4F());
|
||||
|
||||
float alphaPercent = a / 255.0f;//Aplha percentage in the range of 0 to 1.
|
||||
//Premultiply the palette.
|
||||
currentEmber.m_Palette.m_Entries[index].r = alphaPercent * (r / 255.0f);//Palette colors are [0..255], convert to [0..1].
|
||||
currentEmber.m_Palette.m_Entries[index].g = alphaPercent * (g / 255.0f);
|
||||
currentEmber.m_Palette.m_Entries[index].b = alphaPercent * (b / 255.0f);
|
||||
currentEmber.m_Palette.m_Entries[index].a = a / 255.0f;//Will be one for RGB, and other than one if RGBA with A != 255.
|
||||
}
|
||||
else if (!Compare(childNode->name, "colors"))
|
||||
{
|
||||
@ -2487,12 +2480,16 @@ bool XmlToEmber<T>::ParseHexColors(const char* colstr, Ember<T>& ember, size_t n
|
||||
|
||||
for (size_t strIndex = 0; strIndex < length;)
|
||||
{
|
||||
for (glm::length_t i = 0; i < 3 && colorCount < ember.m_Palette.Size(); i++)
|
||||
for (glm::length_t i = 0; i < 3; i++)
|
||||
{
|
||||
const char tmpStr[3] = { s[strIndex++], s[strIndex++], 0 };//Read out and convert the string two characters at a time.
|
||||
ss.clear();//Reset and fill the string stream.
|
||||
ss.str(tmpStr);
|
||||
ss >> tmp;//Do the conversion.
|
||||
|
||||
while (colorCount >= ember.m_Palette.Size())
|
||||
ember.m_Palette.m_Entries.push_back(v4F());
|
||||
|
||||
ember.m_Palette.m_Entries[colorCount][i] = float(tmp) / 255.0f;//Hex palette is [0..255], convert to [0..1].
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user