Selaa lähdekoodia

Merge branch 'master' of https://git.winfor.ch/nicolas/Almond

Nicolas Winkler 5 vuotta sitten
vanhempi
commit
ec29ef5c25

+ 13 - 1
Almond.cpp

@@ -33,6 +33,7 @@ Almond::Almond(QWidget* parent) :
     ui.maxIterations->setValidator(new QIntValidator(1, 1000000000, this));
     ui.backgroundProgress->setVisible(false);
 
+    backgroundTasks.setMaxThreadCount(1);
     this->setWindowIcon(QIcon(":/icons/icon"));
     //ui.verticalLayout_left->addWidget(new MyGLWidget(ui.centralWidget));
     //mw->show();
@@ -57,8 +58,19 @@ void Almond::submitBackgroundTask(BackgroundTask* task)
 }
 
 
-void Almond::backgroundTaskFinished(bool succ)
+void Almond::backgroundTaskFinished(bool succ, QString message)
 {
+    if (succ) {
+        QMessageBox info = QMessageBox(QMessageBox::Icon::Information, "Task Finished", message);
+        //info->setParent(this);
+        emit info.exec();
+    }
+    else {
+        QMessageBox info = QMessageBox(QMessageBox::Icon::Critical, "Task Failed", message);
+        //info->setParent(this);
+        emit info.exec();
+    }
+
     ui.backgroundProgress->setVisible(false);
     ui.backgroundProgress->setFormat("");
 }

+ 1 - 1
Almond.h

@@ -73,7 +73,7 @@ private slots:
 
     void on_chooseGenerator_clicked();
 
-    void backgroundTaskFinished(bool);
+    void backgroundTaskFinished(bool, QString message);
     void backgroundTaskProgress(float percentage);
 
     void pointSelected(mnd::Real x, mnd::Real y);

+ 164 - 143
Almond.ui

@@ -9,8 +9,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>950</width>
-    <height>744</height>
+    <width>1202</width>
+    <height>829</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -44,124 +44,146 @@
      <item>
       <layout class="QVBoxLayout" name="verticalLayout_right">
        <item>
-        <layout class="QFormLayout" name="formLayout">
-         <item row="1" column="0">
-          <widget class="QLabel" name="label">
-           <property name="text">
-            <string>max. iterations</string>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="1">
-          <widget class="QLineEdit" name="maxIterations">
-           <property name="minimumSize">
-            <size>
-             <width>70</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="text">
-            <string>500</string>
-           </property>
-           <property name="maxLength">
-            <number>32</number>
-           </property>
-          </widget>
-         </item>
-         <item row="0" column="0" colspan="2">
-          <widget class="QPushButton" name="chooseGradient">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Choose Gradient</string>
-           </property>
-          </widget>
-         </item>
-         <item row="2" column="0" colspan="2">
-          <widget class="QCheckBox" name="smooth">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>smooth coloring</string>
-           </property>
-           <property name="checked">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item row="3" column="0" colspan="2">
-          <widget class="QCheckBox" name="displayInfo">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>display scale</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
+        <widget class="QGroupBox" name="groupBox_3">
+         <property name="title">
+          <string>Display/Calculation Options</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_3">
+          <item>
+           <layout class="QFormLayout" name="formLayout">
+            <item row="1" column="0">
+             <widget class="QLabel" name="label">
+              <property name="text">
+               <string>Max. Iterations</string>
+              </property>
+             </widget>
+            </item>
+            <item row="2" column="0" colspan="2">
+             <widget class="QCheckBox" name="smooth">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="text">
+               <string>smooth coloring</string>
+              </property>
+              <property name="checked">
+               <bool>true</bool>
+              </property>
+             </widget>
+            </item>
+            <item row="3" column="0" colspan="2">
+             <widget class="QCheckBox" name="displayInfo">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="text">
+               <string>display scale</string>
+              </property>
+             </widget>
+            </item>
+            <item row="4" column="0" colspan="2">
+             <widget class="QPushButton" name="chooseGenerator">
+              <property name="text">
+               <string>Select Generators</string>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="1">
+             <widget class="QLineEdit" name="maxIterations">
+              <property name="minimumSize">
+               <size>
+                <width>70</width>
+                <height>0</height>
+               </size>
+              </property>
+              <property name="text">
+               <string>500</string>
+              </property>
+              <property name="maxLength">
+               <number>32</number>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="0" colspan="2">
+             <widget class="QPushButton" name="chooseGradient">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
+              </property>
+              <property name="text">
+               <string>Choose Gradient</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+         </layout>
+        </widget>
        </item>
        <item>
-        <spacer name="verticalSpacer">
+        <spacer name="verticalSpacer_3">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::Expanding</enum>
-         </property>
          <property name="sizeHint" stdset="0">
           <size>
-           <width>20</width>
-           <height>40</height>
+           <width>0</width>
+           <height>0</height>
           </size>
          </property>
         </spacer>
        </item>
        <item>
         <layout class="QGridLayout" name="gridLayout">
-         <item row="0" column="1">
-          <widget class="QPushButton" name="zoom_out">
-           <property name="text">
-            <string>Zoom Out</string>
-           </property>
-          </widget>
-         </item>
          <item row="0" column="0">
-          <widget class="QPushButton" name="zoom_in">
-           <property name="text">
-            <string>Zoom In</string>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="0" colspan="2">
-          <widget class="QPushButton" name="resetZoom">
-           <property name="text">
-            <string>Reset Zoom</string>
+          <widget class="QGroupBox" name="groupBox_2">
+           <property name="title">
+            <string>Zoom</string>
            </property>
+           <layout class="QGridLayout" name="gridLayout_2">
+            <item row="1" column="0">
+             <widget class="QPushButton" name="zoom_in">
+              <property name="text">
+               <string>Zoom In</string>
+              </property>
+             </widget>
+            </item>
+            <item row="1" column="1">
+             <widget class="QPushButton" name="zoom_out">
+              <property name="text">
+               <string>Zoom Out</string>
+              </property>
+             </widget>
+            </item>
+            <item row="0" column="0" colspan="2">
+             <widget class="QPushButton" name="resetZoom">
+              <property name="text">
+               <string>Reset Zoom</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
           </widget>
          </item>
         </layout>
        </item>
        <item>
-        <spacer name="verticalSpacer_3">
+        <spacer name="verticalSpacer_2">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
          <property name="sizeHint" stdset="0">
           <size>
-           <width>20</width>
-           <height>40</height>
+           <width>0</width>
+           <height>0</height>
           </size>
          </property>
         </spacer>
@@ -211,65 +233,64 @@
         </widget>
        </item>
        <item>
-        <spacer name="verticalSpacer_2">
+        <spacer name="verticalSpacer">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::MinimumExpanding</enum>
-         </property>
          <property name="sizeHint" stdset="0">
           <size>
-           <width>20</width>
-           <height>40</height>
+           <width>0</width>
+           <height>0</height>
           </size>
          </property>
         </spacer>
        </item>
        <item>
-        <widget class="QPushButton" name="chooseGenerator">
-         <property name="text">
-          <string>Select Generators</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="exportVideo">
-         <property name="text">
-          <string>Export Video</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="exportImage">
-         <property name="text">
-          <string>Export Image</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QProgressBar" name="backgroundProgress">
-         <property name="enabled">
-          <bool>true</bool>
-         </property>
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="maximum">
-          <number>1</number>
-         </property>
-         <property name="value">
-          <number>0</number>
-         </property>
-         <property name="alignment">
-          <set>Qt::AlignCenter</set>
-         </property>
-         <property name="format">
-          <string>Background Tasks</string>
+        <widget class="QGroupBox" name="export_box">
+         <property name="title">
+          <string>Export</string>
          </property>
+         <layout class="QVBoxLayout" name="verticalLayout_2">
+          <item>
+           <widget class="QPushButton" name="exportVideo">
+            <property name="text">
+             <string>Export Video</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="exportImage">
+            <property name="text">
+             <string>Export Image</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QProgressBar" name="backgroundProgress">
+            <property name="enabled">
+             <bool>true</bool>
+            </property>
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="maximum">
+             <number>1</number>
+            </property>
+            <property name="value">
+             <number>0</number>
+            </property>
+            <property name="alignment">
+             <set>Qt::AlignCenter</set>
+            </property>
+            <property name="format">
+             <string>Background Tasks</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
         </widget>
        </item>
       </layout>

+ 21 - 16
BackgroundTask.cpp

@@ -1,5 +1,4 @@
 #include "BackgroundTask.h"
-#include <QMessageBox>
 
 BackgroundTask::BackgroundTask(const std::string& shortDescription) :
     shortDescription{ shortDescription }
@@ -8,7 +7,7 @@ BackgroundTask::BackgroundTask(const std::string& shortDescription) :
 
 
 ImageExportTask::ImageExportTask(const alm::ImageExportInfo& iei) :
-    BackgroundTask{ "exporting image" },
+    BackgroundTask{ "Exporting Image" },
     iei{ iei }
 {
 }
@@ -16,15 +15,20 @@ ImageExportTask::ImageExportTask(const alm::ImageExportInfo& iei) :
 
 void ImageExportTask::run(void)
 {
-    alm::exportPng(iei, [this](float percentage) {
-        emit progress(percentage);
-    });
-    emit finished(true);
+    try {
+        alm::exportPng(iei, [this](float percentage) {
+            emit progress(percentage);
+        });
+        emit finished(true, "Image successfully exported.");
+    }
+    catch (...) {
+        emit finished(false, "Error occurred during image export.");
+    }
 }
 
 
 VideoExportTask::VideoExportTask(MandelVideoGenerator mvg, mnd::MandelGenerator& generator) :
-    BackgroundTask{ "exporting video" },
+    BackgroundTask{ "Exporting Video" },
     mvg{ std::move(mvg) },
     generator{ generator }
 {
@@ -33,14 +37,15 @@ VideoExportTask::VideoExportTask(MandelVideoGenerator mvg, mnd::MandelGenerator&
 
 void VideoExportTask::run(void)
 {
-
-    mvg.addProgressCallback([this](const MandelVideoProgressInfo& mvpi) {
-        emit progress(0);
-    });
-    mvg.generate(generator);
-    emit finished(true);
-    QMessageBox* msgBox = new QMessageBox;
-    msgBox->setText("Video successfully exported.");
-    emit msgBox->exec();
+    try {
+        mvg.addProgressCallback([this](const MandelVideoProgressInfo& mvpi) {
+            emit progress(mvpi.progress);
+        });
+        mvg.generate(generator);
+        emit finished(true, "Video successfully exported.");
+    }
+    catch (...) {
+        emit finished(false, "Error occurred during video export.");
+    }
 }
 

+ 1 - 1
BackgroundTask.h

@@ -22,7 +22,7 @@ public:
 
 signals:
     void progress(float percentage);
-    void finished(bool success);
+    void finished(bool success, QString message);
 };
 
 

+ 1 - 1
CMakeLists.txt

@@ -75,7 +75,7 @@ ELSEIF (UNIX AND NOT APPLE)
     set(CPACK_SOURCE_GENERATOR "DEB")
     set(CPACK_COMPONENTS_ALL Almond)
     set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Nicolas Winkler")
-    set(CPACK_DEBIAN_PACKAGE_DEPENDS "qt5-default,libavformat58,libavdevice58,libavfilter7,libavutil56,libswscale5,libgl1,ocl-icd-libopencl1")
+    set(CPACK_DEBIAN_PACKAGE_DEPENDS "qt5-default,libavformat58,libavdevice58,libavfilter7,libavutil56,libswscale5,libgl1,ocl-icd-libopencl1,libpng16-16")
     set(CPACK_SET_DESTDIR True)
     set(CPACK_INSTALL_PREFIX "/usr")
     include(CPack)

+ 37 - 10
MandelWidget.cpp

@@ -4,8 +4,6 @@
 
 using namespace mnd;
 
-#include <QPainter>
-
 #include <cstdio>
 
 
@@ -492,7 +490,7 @@ GridElement* MandelView::searchUnder(int level, GridIndex i, GridIndex j, int re
 }
 
 
-void MandelView::paint(const mnd::MandelViewport& mvp)
+void MandelView::paint(const mnd::MandelViewport& mvp, QPainter& qp)
 {
     mnd::Real dpp = mvp.width / width;
     int level = getLevel(dpp) - 1;
@@ -678,6 +676,18 @@ void MandelWidget::initializeGL(void)
     requestRecalc();
 }
 
+void MandelWidget::resizeGL(int w, int h)
+{
+    double aspect = double(geometry().width()) / geometry().height();
+
+    currentViewport.height = currentViewport.width / aspect;
+    targetViewport = currentViewport;
+
+    if (mandelView.get() != nullptr) {
+        mandelView->width = this->width();
+        mandelView->height = this->height();
+    }
+}
 
 void MandelWidget::paintGL(void)
 {
@@ -691,7 +701,7 @@ void MandelWidget::paintGL(void)
     mandelView->width = width;
     mandelView->height = height;
 
-    glViewport(0, 0, width, height);
+    //glViewport(0, 0, width, height);
 
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
@@ -701,12 +711,15 @@ void MandelWidget::paintGL(void)
     glOrtho(0, width, height, 0, -1.0, 1.0);
 #endif
     glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
 
     glClear(GL_COLOR_BUFFER_BIT);
-    glLoadIdentity();
 
     updateAnimations();
-    mandelView->paint(this->currentViewport);
+
+    QPainter painter{ this };
+
+    mandelView->paint(this->currentViewport, painter);
 
     if (rubberbanding)
         drawRubberband();
@@ -744,7 +757,15 @@ void MandelWidget::updateAnimations(void)
 
 void MandelWidget::drawRubberband(void)
 {
-    glColor3ub(10, 200, 10);
+    QPainter rubberbandPainter{ this };
+    rubberbandPainter.fillRect(rubberband, QColor{ 25, 225, 25, 50 });
+
+    QPen pen{ QColor{ 10, 200, 10 } };
+    pen.setWidth(2);
+    rubberbandPainter.setPen(pen);
+
+    rubberbandPainter.drawRect(rubberband);
+    /*glColor3ub(10, 200, 10);
     glBegin(GL_LINE_LOOP);
     glVertex2d(rubberband.x(), rubberband.y());
     glVertex2d(rubberband.right(), rubberband.y());
@@ -761,7 +782,7 @@ void MandelWidget::drawRubberband(void)
     glVertex2d(rubberband.right(), rubberband.bottom());
     glVertex2d(rubberband.x(), rubberband.bottom());
     glEnd();
-    glDisable(GL_BLEND);
+    glDisable(GL_BLEND);*/
 }
 
 
@@ -812,14 +833,20 @@ void MandelWidget::drawInfo(void)
 
 void MandelWidget::drawPoint(void)
 {
-    glColor3ub(255, 255, 255);
+    QPainter pointPainter{ this };
+    pointPainter.setPen(QColor{ 255, 255, 255 });
+    pointPainter.drawLine(0, pointY, width(), pointY);
+    pointPainter.drawLine(pointX, 0, pointX, height());
+
+
+    /*glColor3ub(255, 255, 255);
     glBegin(GL_LINES);
     glVertex2f(0, pointY);
     glVertex2f(width(), pointY);
 
     glVertex2f(pointX, 0);
     glVertex2f(pointX, height());
-    glEnd();
+    glEnd();*/
 }
 
 

+ 3 - 1
MandelWidget.h

@@ -7,6 +7,7 @@
 #include <QOpenGLContext>
 #include <QOpenGLFunctions>
 #include <QMutex>
+#include <QPainter>
 //#include <qopengl.h>
 //#include <qopenglfunctions.h>
 //#include <qopenglcontext.h>
@@ -263,7 +264,7 @@ public:
     void garbageCollect(int level, GridIndex i, GridIndex j);
     GridElement* searchAbove(int level, GridIndex i, GridIndex j, int recursionLevel);
     GridElement* searchUnder(int level, GridIndex i, GridIndex j, int recursionLevel);
-    void paint(const mnd::MandelViewport& mvp);
+    void paint(const mnd::MandelViewport& mvp, QPainter& qp);
 public slots:
     void cellReady(int level, GridIndex i, GridIndex j, Bitmap<RGBColor>* bmp);
 signals:
@@ -327,6 +328,7 @@ public:
     void clearAll(void);
 
     void initializeGL(void) override;
+    void resizeGL(int w, int h) override;
     void paintGL() override;
 
 private:

+ 7 - 5
exportdialogs.cpp

@@ -141,9 +141,11 @@ void ExportVideoDialog::on_buttonBox_accepted()
     }
 
     evi.path = evd.savePath->text().toStdString();
-    evi.width = evd.vidWidth->text().toInt();
-    evi.height = evd.vidHeight->text().toInt();
-    evi.maxIterations = evd.maxIterations->text().toInt();
+
+    evi.mi = almond->mw->getMandelInfo();
+    evi.mi.bWidth = evd.vidWidth->text().toInt();
+    evi.mi.bHeight = evd.vidHeight->text().toInt();
+    evi.mi.maxIter = evd.maxIterations->text().toInt();
 
     evi.bitrate = evd.bitrate->text().toInt();
     evi.preset = evd.encodingPresetBox->currentText().toStdString();
@@ -162,8 +164,8 @@ void ExportVideoDialog::on_buttonBox_accepted()
         evd.endH->text().toDouble(),
     };*/
 
-    evi.start.adjustAspectRatio(evi.width, evi.height);
-    evi.end.adjustAspectRatio(evi.width, evi.height);
+    evi.start.adjustAspectRatio(evi.mi.bWidth, evi.mi.bHeight);
+    evi.end.adjustAspectRatio(evi.mi.bWidth, evi.mi.bHeight);
     evi.gradient = almond->mw->getGradient();
 
     //}

+ 9 - 3
libalmond/include/MandelVideoGenerator.h

@@ -8,13 +8,18 @@
 
 struct ExportVideoInfo
 {
+    /// the viewport at the start of the video
     mnd::MandelViewport start;
+    /// the viewport at the end of the video
     mnd::MandelViewport end;
+    /// Info struct to hold further data about the generation
+    /// of mandelbrot images. The Viewport specified in this
+    /// struct is ignored.
+    mnd::MandelInfo mi;
+
+    /// the gradient to use
     Gradient gradient;
 
-    int width;
-    int height;
-    int maxIterations;
     int fps;
     double zoomSpeed;
 
@@ -30,6 +35,7 @@ struct ExportVideoInfo
 struct MandelVideoProgressInfo
 {
     int64_t framesExported;
+    float progress;
 };
 
 

+ 18 - 23
libalmond/src/MandelVideoGenerator.cpp

@@ -17,7 +17,9 @@ void MandelVideoGenerator::addProgressCallback(ProgressCallback pc)
 
 void MandelVideoGenerator::generate(mnd::MandelGenerator& gen)
 {
-    VideoStream vs(evi.width, evi.height, evi.path, evi.bitrate, evi.fps, evi.preset.c_str());
+    const long width = evi.mi.bWidth;
+    const long height = evi.mi.bHeight;
+    VideoStream vs(width, height, evi.path, evi.bitrate, evi.fps, evi.preset.c_str());
 
     mnd::Real x = evi.end.x + evi.end.width / 2;
     mnd::Real y = evi.end.y + evi.end.height / 2;
@@ -33,56 +35,49 @@ void MandelVideoGenerator::generate(mnd::MandelGenerator& gen)
 
     const float oversizeFactor = 2;
     const float sqrFactor = sqrt(oversizeFactor);
-    //const mnd::Real invsqrt2 = mnd::Real(1.0) / mnd::sqrt(mnd::Real(2));
 
-    mnd::MandelInfo mi;
-    mi.bWidth = evi.width * oversizeFactor;
-    mi.bHeight = evi.height * oversizeFactor;
-    mi.maxIter = evi.maxIterations;
+    mnd::MandelInfo mi = evi.mi;
+    mi.bHeight *= oversizeFactor;
+    mi.bWidth *= oversizeFactor;
 
     bool first = true;
 
-    while(w > evi.end.width || h > evi.end.height) {
+    double zoomFactor = ::pow(0.99, evi.zoomSpeed);
+    double approxFrames = double(mnd::log(evi.end.width / evi.start.width) / mnd::log(zoomFactor));
 
+    while(w > evi.end.width || h > evi.end.height) {
         if (bigW > sqrt(oversizeFactor) * w) {
             mi.view = mnd::MandelViewport{ x - w/2, y - h/2, w, h };
-            Bitmap<float> raw{ long(evi.width * oversizeFactor), long(evi.height * oversizeFactor) };
-            Bitmap<float> rawSmall{ long(evi.width * oversizeFactor), long(evi.height * oversizeFactor) };
+            Bitmap<float> raw{ long(width * oversizeFactor), long(height * oversizeFactor) };
+            Bitmap<float> rawSmall{ long(width * oversizeFactor), long(height * oversizeFactor) };
             mi.view.zoomCenter(oversizeFactor);
             gen.generate(mi, rawSmall.pixels.get());
-            //mi.view.zoomCenter(sqrt(oversizeFactor));
-            //gen.generate(mi, raw.pixels.get());
-            //auto before = std::chrono::high_resolution_clock::now();
             if (first) {
                 mi.view.zoomCenter(sqrt(oversizeFactor));
                 gen.generate(mi, raw.pixels.get());
                 small = raw.map<RGBColor>([&mi, this] (float i) {
                     return i >= mi.maxIter ? RGBColor{ 0, 0, 0 } : evi.gradient.get(i);
                 });
+                first = false;
             }
             big = std::move(small);
             small = rawSmall.map<RGBColor>([&mi, this] (float i) {
                 return i >= mi.maxIter ? RGBColor{ 0, 0, 0 } : evi.gradient.get(i);
             });
             printf("recalced\n");
-            /*mi.view.zoomCenter(0.5);
-            gen.generate(mi, raw.pixels.get());
-            small = raw.map<RGBColor>([] (float x) { return
-                RGBColor{ uint8_t(::sin(x / 100) * 127 + 127), uint8_t(::sin(x / 213) * 127 + 127), uint8_t(::cos(x / 173) * 127 + 127) };
-            });*/
             bigW = w;
             bigFac = 1.0;
-            first = false;
         }
 
-        vs.addFrame(overlay(big, small, evi.width, evi.height, bigFac, sqrt(oversizeFactor)));
+        vs.addFrame(overlay(big, small, evi.mi.bWidth, evi.mi.bHeight, bigFac, sqrt(oversizeFactor)));
         frameCounter++;
-        MandelVideoProgressInfo mvpi{ frameCounter };
+        float progress = float(frameCounter / approxFrames);
+        MandelVideoProgressInfo mvpi{ frameCounter, progress * 100 };
         callCallbacks(mvpi);
 
-        w *= ::pow(0.99, evi.zoomSpeed);
-        h *= ::pow(0.99, evi.zoomSpeed);
-        bigFac *= ::pow(0.99, evi.zoomSpeed);
+        w *= zoomFactor;
+        h *= zoomFactor;
+        bigFac *= zoomFactor;
     }
 }
 

+ 6 - 8
libmandel/CMakeLists.txt

@@ -89,6 +89,7 @@ if(OPENCL_FOUND)
     )
     target_include_directories(mandel PUBLIC "include")
     link_directories(${OpenCL_LIBRARY})
+    target_link_libraries(mandel PUBLIC OpenCL::OpenCL)
 else(OPENCL_FOUND)
     include_directories("include")
 endif(OPENCL_FOUND)
@@ -97,6 +98,11 @@ if (APPLE AND OpenCL_FOUND)
     SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -framework OpenCL")
 endif()
 
+
+if(OpenMP_CXX_FOUND)
+    target_link_libraries(mandel PUBLIC OpenMP::OpenMP_CXX)
+endif()
+
 if(Boost_FOUND)
     target_compile_definitions(mandel PUBLIC WITH_BOOST)
     target_include_directories(mandel PUBLIC ${Boost_INCLUDE_DIRS})
@@ -126,11 +132,3 @@ if (ARCH STREQUAL "X86_64" OR ARCH STREQUAL "X86")
 elseif(ARCH STREQUAL "ARM")
     set_source_files_properties(src/CpuGeneratorsNeon.cpp PROPERTIES COMPILE_FLAGS -march=armv8-a+simd)
 endif()
-
-
-if(OpenMP_CXX_FOUND)
-    target_link_libraries(mandel PUBLIC OpenMP::OpenMP_CXX)
-endif()
-if(OpenCL_FOUND)
-    target_link_libraries(mandel PUBLIC OpenCL::OpenCL)
-endif()

+ 1 - 1
libmandel/include/Fixed.h

@@ -116,7 +116,7 @@ struct Fixed512
 
     inline Fixed512(double val)
     {
-        body = Once{ boost::multiprecision::pow(Float256{ 2 }, 512 - 32) * val };
+        body = Once{ boost::multiprecision::pow(Float512{ 2 }, 512 - 32) * val };
     }
 
     inline operator Float256(void) const {

+ 6 - 5
libmandel/include/NaiveIRGenerator.h

@@ -66,10 +66,10 @@ namespace mnd
         struct Sub : BinaryOperation {};
         struct Mul : BinaryOperation {};
         struct Div : BinaryOperation {};
-    
+
         struct Neg : UnaryOperation {};
-    
-    
+
+
         struct Atan2 : BinaryOperation {};
         struct Pow : BinaryOperation {};
         struct Cos : UnaryOperation {};
@@ -83,9 +83,10 @@ namespace mnd
         struct EvalStruct
         {
             std::map<std::string, size_t> variableNames;
-            std::vector<T> variables;
+            std::vector<T*> variables;
+            std::vector<T> temporaries;
 
-            void prepare(const T& zre, const T& zim, const T& cre, const T& cim)
+            void prepare(T* zre, T* zim, T* cre, T* cim)
             {
                 auto z_re = variableNames.find("z_re");
                 auto z_im = variableNames.find("z_im");

+ 6 - 2
libmandel/src/IterationCompiler.cpp

@@ -18,6 +18,7 @@ using namespace std::string_literals;
 namespace mnd
 {
 #ifdef WITH_ASMJIT
+#if defined(__x86_64__) || defined(_M_X64)
     struct CompileVisitor
     {
         using Reg = asmjit::x86::Xmm;
@@ -564,6 +565,7 @@ namespace mnd
         return CompiledGeneratorVec{ std::move(ed) };
     }
 
+#endif // defined(__x86_64__) || defined(_M_X64)
 #endif // WITH_ASMJIT
 
     struct OpenClVisitor
@@ -783,6 +785,7 @@ namespace mnd
 
 
 #ifdef WITH_ASMJIT
+#if defined(__x86_64__) || defined(_M_X64)
         printf("ir: %s\n", irf.toString().c_str()); fflush(stdout);
         auto dg = std::make_unique<CompiledGenerator>(compile(irf));
         printf("asm: %s\n", dg->dump().c_str()); fflush(stdout);
@@ -792,10 +795,11 @@ namespace mnd
             printf("asm avxvec: %s\n", dgavx->dump().c_str()); fflush(stdout);
             vec.push_back(std::move(dgavx));
         }
+#endif // defined(__x86_64__) || defined(_M_X64)
 #endif // WITH_ASMJIT
 
-        vec.push_back(std::make_unique<NaiveIRGenerator<mnd::DoubleDouble>>(irf));
-        vec.push_back(std::make_unique<NaiveIRGenerator<mnd::QuadDouble>>(irf));
+        //vec.push_back(std::make_unique<NaiveIRGenerator<mnd::DoubleDouble>>(irf));
+        //vec.push_back(std::make_unique<NaiveIRGenerator<mnd::QuadDouble>>(irf));
         
         //auto dg = std::make_unique<NaiveIRGenerator>(*irf, mnd::getPrecision<double>());
 

+ 2 - 24
libmandel/src/IterationGenerator.cpp

@@ -124,6 +124,7 @@ std::complex<double> NaiveGenerator::calc(mnd::Expression& expr, std::complex<do
 }
 
 #ifdef WITH_ASMJIT
+#if defined(__x86_64__) || defined(_M_X64)
 
 #include "ExecData.h"
 
@@ -147,29 +148,6 @@ CompiledGenerator::~CompiledGenerator(void)
 }
 
 
-/*__declspec(noinline)
-int iter(double x, double y, int maxIter)
-{
-int k = 0;
-
-double a = x;
-double b = y;
-
-for (k = 0; k < maxIter; k++) {
-double aa = a * a;
-double bb = b * b;
-double abab = a * b + a * b;
-a = aa - bb + x;
-b = abab + y;
-if (aa + bb >= 16)
-break;
-}
-
-return k;
-}*/
-
-
-
 void CompiledGenerator::generate(const mnd::MandelInfo& info, float* data)
 {
     using IterFunc = int (*)(double, double, int);
@@ -235,7 +213,7 @@ void CompiledGeneratorVec::generate(const mnd::MandelInfo& info, float* data)
         }
     }
 }
-
+#endif // defined(__x86_64__) || defined(_M_X64)
 #endif // WITH_ASMJIT
 
 #ifdef WITH_OPENCL

+ 24 - 17
libmandel/src/NaiveIRGenerator.cpp

@@ -55,19 +55,21 @@ namespace mnd::eval
 
         size_t createTemp(void)
         {
-            es.variables.push_back(0);
+            es.temporaries.push_back(0);
+            es.variables.push_back(&es.temporaries[es.temporaries.size() - 1]);
             return es.variables.size() - 1;
         }
 
         size_t createConstant(mnd::Real& value)
         {
-            es.variables.push_back(mnd::convert<T>(value));
+            es.temporaries.push_back(mnd::convert<T>(value));
+            es.variables.push_back(&es.temporaries[es.temporaries.size() - 1]);
             return es.variables.size() - 1;
         }
 
         size_t createVariable(std::string& value)
         {
-            es.variables.push_back(0);
+            es.variables.push_back(nullptr);
             es.variableNames.emplace(value, es.variables.size() - 1);
             return es.variables.size() - 1;
         }
@@ -79,25 +81,31 @@ namespace mnd::eval
             return Load{ createVariable(x.name) };
         }
         EvalNode operator()(ir::Addition& x) {
-            return Add{ visit(x.left), visit(x.right) };
+            auto left = visit(x.left);
+            return Add{ std::move(left), visit(x.right) };
         }
         EvalNode operator()(ir::Subtraction& x) {
-            return Sub{ visit(x.left), visit(x.right) };
+            auto left = visit(x.left);
+            return Sub{ std::move(left), visit(x.right) };
         }
         EvalNode operator()(ir::Multiplication& x) {
-            return Mul{ visit(x.left), visit(x.right) };
+            auto left = visit(x.left);
+            return Mul{ std::move(left), visit(x.right) };
         }
         EvalNode operator()(ir::Division& x) {
-            return Div{ visit(x.left), visit(x.right) };
+            auto left = visit(x.left);
+            return Div{ std::move(left), visit(x.right) };
         }
         EvalNode operator()(ir::Negation& x) {
             return Neg{ visit(x.value) };
         }
         EvalNode operator()(ir::Atan2& x) {
-            return Atan2{ visit(x.left), visit(x.right) };
+            auto left = visit(x.left);
+            return Atan2{ std::move(left), visit(x.right) };
         }
         EvalNode operator()(ir::Pow& x) {
-            return Pow{ visit(x.left), visit(x.right) };
+            auto left = visit(x.left);
+            return Pow{ std::move(left), visit(x.right) };
         }
         EvalNode operator()(ir::Cos& x) {
             return Cos{ visit(x.value) };
@@ -125,12 +133,12 @@ namespace mnd::eval
         }
 
         T operator()(const Load& x) {
-            return es.variables[x.index];
+            return *es.variables[x.index];
         }
 
         T operator()(const Store& x) {
             T r = visit(*x.v);
-            es.variables[x.index] = r;
+            *es.variables[x.index] = r;
             return r;
         }
 
@@ -215,15 +223,14 @@ void NaiveIRGenerator<T>::generate(const mnd::MandelInfo& info, float* data)
         T y = viewy + T(double(j)) * hpp;
         for (long i = 0; i < info.bWidth; i++) {
             T x = viewx + T(double(i)) * wpp;
-
-            es.prepare(0, 0, x, y);
+            T a;
+            T b;
+            es.prepare(&a, &b, &x, &y);
 
             eval::EvalVisitor<T> visitor{ es };
 
-            T a = visitor.visit(*start_re);
-            T b = visitor.visit(*start_im);
-
-            es.prepare(a, b, x, y);
+            a = visitor.visit(*start_re);
+            b = visitor.visit(*start_im);
 
             int k = 0;
             for (k = 0; k < info.maxIter; k++) {

+ 2 - 78
main.cpp

@@ -3,78 +3,8 @@
 #include <QPixmap>
 #include <QScreen>
 #include <QSplashScreen>
-//#include <QTimer>
 #include <cmath>
 
-class AlmondSplashScreen : public QSplashScreen
-{
-private:
-    float animOff = 0.0f;
-    //QTimer animUpdate;
-    volatile bool updated = true;
-public:
-    AlmondSplashScreen(QPixmap splash) :
-        QSplashScreen{ splash }
-        //animUpdate{ this }
-    {
-        //animUpdate.start(10);
-        //loading.start();
-        //this->add(loading);
-        //connect(&loading, &QMovie::updated, this, &AlmondSplashScreen::nextFrame);
-        //connect(&animUpdate, &QTimer::timeout, this, &AlmondSplashScreen::nextFrame);
-    }
-
-    ~AlmondSplashScreen(void)
-    {
-        //animUpdate.stop();
-    }
-
-    void drawContents(QPainter* painter) override
-    {
-        QSplashScreen::drawContents(painter);
-        //drawAnimation(painter);
-        //updated = true;
-    }
-
-    void drawAnimation(QPainter* painter)
-    {
-        const auto minimum = [] (auto a, auto b, auto c) {
-            return a < b ? (a < c ? a : c) : (b < c ? b : c);
-        };
-        int width = this->width();
-        int height = this->height();
-        int pieces = 7;
-        float off = ::fmod(animOff, width / pieces);
-        for (int i = 0; i < pieces; i++) {
-            float x = off + i * width / pieces;
-            float accelOff = 0;
-
-            if (x < 160)
-                accelOff = (160 - x) * (160 - x) / 160 ;
-            else if (x > width - 160)
-                accelOff = -(width - 160 - x) * (width - 160 - x) / 160 ;
-            
-            x -= accelOff;
-
-            if (x < 0 || x > width)
-                continue;
-
-            float opacity = minimum(x, width - x, 130);
-            QPen pen(QColor(255, 255, 255, int(opacity)));
-            pen.setWidth(4);
-            painter->setPen(pen);
-            painter->drawEllipse(QRectF{ x, double(height - 40), 16, 16 });
-        }
-    }
-
-public slots:
-    void nextFrame() //(const QRect& rect)
-    {
-        emit this->repaint();
-        //animOff += 3;
-    }
-};
-
 int main(int argc, char *argv[])
 {
     QApplication a(argc, argv);
@@ -84,19 +14,13 @@ int main(int argc, char *argv[])
 
     QPixmap splashImg(":/splash/splash");
     QPixmap splashScaled = splashImg.scaled(splashW, splashW * splashImg.height() / splashImg.width());
-    AlmondSplashScreen splash{ splashScaled };
+    QSplashScreen splash{ splashScaled };
     a.processEvents();
     splash.show();
-    a.processEvents();
-    /*for (int i = 0; i < 100; i++) {
-        a.processEvents();
-        system("sleep 0.03");
-    }*/
     Almond w;
-    a.processEvents();
     splash.finish(&w);
     a.processEvents();
-    w.show();
+    w.showMaximized();
     return a.exec();
 }