Nicolas Winkler 5 lat temu
rodzic
commit
a63b9a7531

+ 1 - 1
Almond.pro

@@ -76,7 +76,7 @@ else:unix:QMAKE_CXXFLAGS+= -fopenmp
 win32:QMAKE_LFLAGS +=  -openmp
 else:unix:QMAKE_LFLAGS+= -fopenmp
 LIBS += -fopenmp
-unix:LIBS += -lm -latomic
+unix:LIBS += -lm -latomic -lquadmath
 
 win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../libs/ffmpeg-4.1.1-win32-dev/lib/ -lavcodec
 else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../libs/ffmpeg-4.1.1-win32-dev/lib/ -lavcodec

+ 32 - 15
MandelWidget.cpp

@@ -202,6 +202,16 @@ void TexGrid::clearCells(void)
 }
 
 
+void TexGrid::clearUncleanCells(void)
+{
+    for (auto it = cells.begin(); it != cells.end();) {
+        if (it->second->img->getRecalcPriority() > 1)
+            cells.erase(it++);
+        else ++it;
+    }
+}
+
+
 void Job::run(void)
 {
     auto [absX, absY] = grid->getPositions(i, j);
@@ -293,6 +303,8 @@ void Calcer::redirect(int level, GridIndex i, GridIndex j, long calcState, Bitma
 }
 
 
+const int MandelView::chunkSize = 256;
+
 MandelView::MandelView(mnd::Generator* generator, MandelWidget& owner, int maxIter) :
     generator{ generator },
     calcer{ generator, owner.getGradient(), maxIter },
@@ -316,13 +328,13 @@ MandelView::MandelView(mnd::Generator* generator, MandelWidget& owner, int maxIt
 
 
 int MandelView::getLevel(mnd::Real dpp) {
-    return int(log2(dpp / chunkSize));
+    return int(mnd::log2(dpp / chunkSize));
 }
 
 
 mnd::Real MandelView::getDpp(int level)
 {
-    return ::pow(2, level) * chunkSize;
+    return mnd::pow(mnd::Real(2), mnd::Real(level)) * chunkSize;
 }
 
 
@@ -374,6 +386,10 @@ void MandelView::garbageCollect(int level, GridIndex i, GridIndex j)
     for(auto& [l, grid] : levels) {
         int dist = ::abs(l - level);
 
+        if (dist == 1) {
+            grid.clearUncleanCells();
+        }
+
         if (dist > 20) {
             grid.clearCells();
         }
@@ -485,8 +501,8 @@ void MandelView::paint(const mnd::MandelViewport& mvp)
     mnd::Real w = width * gw / mvp.width;
 
     auto [realXLeft, realYTop] = grid.getPositions(left, top);
-    realXLeft = (realXLeft - mvp.x) * width / mvp.width;
-    realYTop = (realYTop - mvp.y) * height / mvp.height;
+    realXLeft = ((realXLeft - mvp.x) * mnd::Real(width)) / mvp.width;
+    realYTop = ((realYTop - mvp.y) * mnd::Real(height)) / mvp.height;
     for(GridIndex i = left; i <= right; i++) {
         for(GridIndex j = top; j <= bottom; j++) {
             mnd::Real x = w * int(i - left) + realXLeft;
@@ -642,24 +658,25 @@ void MandelWidget::paintGL(void)
 
 void MandelWidget::updateAnimations(void)
 {
-    auto now = std::chrono::high_resolution_clock::now();
-    auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastAnimUpdate).count();
-    double factor = ::pow(0.97, millis);
-
-    currentViewport.x = currentViewport.x * factor + targetViewport.x * (1.0 - factor);
-    currentViewport.y = currentViewport.y * factor + targetViewport.y * (1.0 - factor);
-    currentViewport.width = currentViewport.width * factor + targetViewport.width * (1.0 - factor);
-    currentViewport.height = currentViewport.height * factor + targetViewport.height * (1.0 - factor);
-
-    lastAnimUpdate = now;
-
     if (mnd::abs(currentViewport.width / targetViewport.width - 1.0) < 0.1e-5
             && mnd::abs(currentViewport.height / targetViewport.height - 1.0) < 0.1e-5) {
         // animation finished
+        currentViewport = targetViewport;
     }
     else {
+        auto now = std::chrono::high_resolution_clock::now();
+        auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastAnimUpdate).count();
+        double factor = ::pow(0.97, millis);
+
+        currentViewport.x = currentViewport.x * factor + targetViewport.x * (1.0 - factor);
+        currentViewport.y = currentViewport.y * factor + targetViewport.y * (1.0 - factor);
+        currentViewport.width = currentViewport.width * factor + targetViewport.width * (1.0 - factor);
+        currentViewport.height = currentViewport.height * factor + targetViewport.height * (1.0 - factor);
+
+        lastAnimUpdate = now;
         emit update();
     }
+
 }
 
 

+ 2 - 1
MandelWidget.h

@@ -160,6 +160,7 @@ public:
 
     inline size_t countAllocatedCells(void) const { return cells.size(); }
     void clearCells(void);
+    void clearUncleanCells(void);
 };
 
 
@@ -252,7 +253,7 @@ public:
     int width;
     int height;
 public:
-    static const int chunkSize = 256;
+    static const int chunkSize;
     MandelView(mnd::Generator* generator, MandelWidget& owner, int maxIter);
     int getLevel(mnd::Real dpp);
     mnd::Real getDpp(int level);

+ 2 - 0
libmandel/CMakeLists.txt

@@ -11,6 +11,7 @@ project(mandel VERSION 1.0.0 DESCRIPTION "library for mandelbrot calculations")
 find_package(OpenCL)
 find_package(OpenMP)
 #set(Boost_DEBUG 1)
+set(Boost_USE_STATIC_LIBS ON)
 find_package(Boost 1.53)
 
 find_path(MPFR_INCLUDES
@@ -70,6 +71,7 @@ endif()
 if(Boost_FOUND)
     target_compile_definitions(mandel PUBLIC WITH_BOOST)
     target_include_directories(mandel PRIVATE ${Boost_INCLUDE_DIRS})
+    target_link_libraries(mandel PRIVATE ${Boost_LIBRARIES})
 endif(Boost_FOUND)
 
 if (ARCH STREQUAL "X86_64" OR ARCH STREQUAL "X86")

+ 6 - 0
libmandel/include/Types.h

@@ -24,6 +24,8 @@ namespace mnd
     inline Float128 abs(const Float128& x) { return boost::multiprecision::abs(x); }
     inline Float128 floor(const Float128& x) { return boost::multiprecision::floor(x); }
     inline Float128 log(const Float128& x) { return boost::multiprecision::log(x); }
+    inline Float128 log2(const Float128& x) { return boost::multiprecision::log2(x); }
+    inline Float128 pow(const Float128& x, const Float128& y) { return boost::multiprecision::pow(x, y); }
 
     using Real = Float128;
     using Integer = boost::multiprecision::int128_t;
@@ -38,6 +40,10 @@ namespace mnd
     inline float floor(float x) { return ::floorf(x); }
     inline double log(double x) { return ::log(x); }
     inline float log(float x) { return ::logf(x); }
+    inline double log2(double x) { return ::log2(x); }
+    inline float log2(float x) { return ::log2f(x); }
+    inline double pow(double x, double y) { return ::pow(x, y); }
+    inline float pow(float x, float y) { return ::powf(x, y); }
 }
 
 

+ 6 - 4
libmandel/src/MandelUtil.cpp

@@ -27,17 +27,19 @@ void MandelViewport::normalize(void)
 
 void MandelViewport::zoomCenter(float scale)
 {
-    x += width * (1 - scale) / 2;
+    /*x += width * (1 - scale) / 2;
     y += height * (1 - scale) / 2;
     width *= scale;
-    height *= scale;
+    height *= scale;*/
+    zoom(scale, 0.5f, 0.5f);
 }
 
 
 void MandelViewport::zoom(float scale, float xz, float yz)
 {
-    this->x += width * (1 - scale) * xz;
-    this->y += height * (1 - scale) * yz;
+    mnd::Real scaleR = 1.0f - scale;
+    this->x += width * scaleR * mnd::Real(xz);
+    this->y += height * scaleR * mnd::Real(yz);
     width *= scale;
     height *= scale;
 }