소스 검색

temporarily bad gradients to improve performance

Nicolas Winkler 4 년 전
부모
커밋
6c57a699be
3개의 변경된 파일54개의 추가작업 그리고 1개의 파일을 삭제
  1. 5 0
      libalmond/include/Gradient.h
  2. 43 1
      libalmond/src/Gradient.cpp
  3. 6 0
      ui/GradientMenu.ui

+ 5 - 0
libalmond/include/Gradient.h

@@ -2,6 +2,7 @@
 #define GRADIENT_H
 
 #include <vector>
+#include <map>
 #include <string>
 #include "Color.h"
 #include <tuple>
@@ -11,6 +12,8 @@
 class Gradient
 {
     std::vector<std::pair<RGBColor, float>> points;
+    std::map<float, RGBColor, std::greater<float>> pointMap;
+
     /// the colors of this gradient stored in linear RGB format
     /// so they can be easily interpolated
     std::vector<RGBColorf> colors;
@@ -44,6 +47,8 @@ public:
     /// \return the color in sRGB format
     ///
     RGBColor get(float x) const;
+
+    RGBColor interpolate(float x) const;
 private:
     static RGBColorf lerpColors(RGBColorf a, RGBColorf b, float val);
     static RGBColor lerpColors(RGBColor a, RGBColor b, float val);

+ 43 - 1
libalmond/src/Gradient.cpp

@@ -27,9 +27,14 @@ Gradient::Gradient(std::vector<std::pair<RGBColor, float>> colors, bool repeat,
             return a.second < b.second;
         });
 
+    for (auto& [col, at] : colors) {
+        pointMap[at] = col;
+    }
+
     points = colors;
     max = colors.at(colors.size() - 1).second;
 
+    return;
     std::vector<std::pair<RGBColorf, float>> linearColors;
     std::transform(colors.begin(), colors.end(), std::back_inserter(linearColors),
                    [] (auto c) { return c; });
@@ -78,9 +83,13 @@ Gradient::Gradient(std::vector<std::pair<RGBColor, float>> colors, float maxVal,
             return a.second < b.second;
         });
 
+    for (auto& [col, at] : colors) {
+        pointMap[at] = col;
+    }
+
     points = colors;
     max = maxVal;
-
+    return;
     std::vector<std::pair<RGBColorf, float>> linearColors;
     std::transform(colors.begin(), colors.end(), std::back_inserter(linearColors),
                    [] (auto c) { return c; });
@@ -217,6 +226,7 @@ float Gradient::getMax(void) const
 
 RGBColor Gradient::get(float x) const
 {
+    return interpolate(x);
     if (colors.empty() || std::isnan(x) || std::isinf(x))
         return RGBColor();
     /*const auto [left, right, lerp] = getNeighbors(x);
@@ -252,6 +262,38 @@ RGBColor Gradient::get(float x) const
 }
 
 
+RGBColor Gradient::interpolate(float x) const
+{
+    if (pointMap.empty()) {
+        return RGBColor{ 0, 0, 0 };
+    }
+
+    if (x < 0)
+        return pointMap.begin()->second;
+    if (x > this->max) {
+        if (repeat)
+            x = ::fmodf(x, this->max);
+        else
+            return (pointMap.rbegin())->second;
+    }
+
+    auto firstLess = pointMap.lower_bound(x);
+
+    if (firstLess == pointMap.begin())
+        return firstLess->second;
+    if (firstLess == pointMap.end())
+        return (pointMap.rbegin())->second;
+
+    auto oneBefore = firstLess; oneBefore--;
+    float lo = oneBefore->first;
+    float hi = firstLess->first;
+    RGBColor loCol = oneBefore->second;
+    RGBColor hiCol = firstLess->second;
+
+    return lerpColors(loCol, hiCol, (x - lo) / (hi - lo));
+}
+
+
 RGBColorf Gradient::lerpColors(RGBColorf a, RGBColorf b, float val)
 {
     return RGBColorf {

+ 6 - 0
ui/GradientMenu.ui

@@ -13,6 +13,9 @@
   <property name="windowTitle">
    <string>Select Gradient</string>
   </property>
+  <property name="toolTip">
+   <string>Remove color from gradient</string>
+  </property>
   <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1,0,0">
    <property name="leftMargin">
     <number>0</number>
@@ -165,6 +168,9 @@
        </item>
        <item>
         <widget class="QPushButton" name="removeBtn">
+         <property name="toolTip">
+          <string>Remove color point from gradient</string>
+         </property>
          <property name="icon">
           <iconset resource="../resources/Almond.qrc">
            <normaloff>:/icons/cancel</normaloff>:/icons/cancel</iconset>