Prechádzať zdrojové kódy

fixed stuff
also opengl still hard

Nicolas Winkler 4 rokov pred
rodič
commit
3bdd6cac10

+ 27 - 63
Almond.cpp

@@ -22,6 +22,8 @@ Almond::Almond(QWidget* parent) :
     fractalWidget->setGradient(Gradient::defaultGradient());
     fractalWidget->setSmoothColoring(ui.smooth->isChecked());
 
+    connect(fractalWidget, &FractalWidget::pointSelected, this, &Almond::pointSelected);
+
     customGeneratorDialog = std::make_unique<CustomGenerator>(mandelContext);
     customGenerator = nullptr;
     customViewSave = mnd::MandelViewport::centerView();
@@ -30,9 +32,8 @@ Almond::Almond(QWidget* parent) :
 
     currentView = MANDELBROT;
     mandelGenerator = &mandelContext.getDefaultGenerator();
-    // TODO update mandelViewSave = mw->getViewport();
+    mandelViewSave = fractalWidget->getViewport();
 
-    //QObject::connect(mw.get(), &MandelWidget::pointSelected, this, &Almond::pointSelected);
     ui.mandel_container->addWidget(fractalWidget);
     //ui.mandel_container->addWidget(mw.get());
     ui.maxIterations->setValidator(new QIntValidator(1, 1000000000, this));
@@ -291,48 +292,15 @@ void Almond::on_maxIterations_editingFinished()
 
 void Almond::on_chooseGradient_clicked()
 {
-    /*const auto& gradient = fractalWidget->getGradient(); // TODO update
-    auto points = gradient.getPoints();
-    std::for_each(points.begin(), points.end(), [](auto& x) { x.second /= 300; });
-
-    QVector<QPair<float, QColor>> np;
-    std::transform(points.begin(), points.end(), std::back_inserter(np),
-        [](auto& qp) -> QPair<float, QColor> {
-        auto& [col, pos] = qp;
-        return { pos, QColor{ (col.r), (col.g), (col.b) } };
-    });*/
     this->gradientMenu->setGradient(fractalWidget->getGradient());
     emit this->amw->showSubMenu(2);
-    //gcd.exec();
-    //auto gradient = gcd.getGradient();
-    //if (gradient)
-    //    mw->setGradient(std::move(*gradient));
 }
 
 
 void Almond::on_exportVideo_clicked()
 {
-    // TODO update
-    /*
-    evm->setEndViewport(mw->getViewport());
+    evm->setEndViewport(fractalWidget->getViewport());
     emit this->amw->showSubMenu(1);
-    return;
-    ExportVideoInfo evi;
-    evi.start = mnd::MandelViewport::standardView();
-    evi.end = mw->getViewport();
-    evi.gradient = mw->getGradient();
-    ExportVideoDialog dialog(this, evi);
-    //dialog.show();
-    auto response = dialog.exec();
-    printf("dialog executed\n"); fflush(stdout);
-    if (response == 1) {
-        mnd::MandelInfo mi;
-        evi = dialog.getExportVideoInfo();
-        MandelVideoGenerator mvg(evi);
-        mnd::MandelGenerator& g = *mw->getGenerator();
-        submitBackgroundTask(new VideoExportTask(std::move(mvg), g));
-        //if (exportVideo(evi)) {
-    }*/
 }
 
 
@@ -403,12 +371,11 @@ void Almond::pointSelected(mnd::Real x, mnd::Real y)
 {
     if (currentView != JULIA) {
         saveView();
-        // TODO update
-        /*
-        this->mw->setViewport(mnd::MandelViewport::centerView());
-        this->mw->setJuliaPos(x, y);
-        this->mw->getMandelInfo().julia = true;
-        this->mw->clearAll();*/
+        this->fractalWidget->setViewport(mnd::MandelViewport::centerView());
+        this->fractalWidget->getMandelInfo().julia = true;
+        this->fractalWidget->getMandelInfo().juliaX = x;
+        this->fractalWidget->getMandelInfo().juliaY = y;
+        this->fractalWidget->clearCells();
     }
     currentView = JULIA;
 }
@@ -423,34 +390,32 @@ void Almond::on_wMandel_clicked()
 void Almond::saveView()
 {
     if (currentView == MANDELBROT)
-        ; // TODO update mandelViewSave = mw->getViewport();
+        mandelViewSave = fractalWidget->getViewport();
     else if (currentView == CUSTOM)
-        ; // TODO update customViewSave = mw->getViewport();
+        customViewSave = fractalWidget->getViewport();
 }
 
 
 void Almond::setViewType(ViewType v)
 {
-    // TODO update
-    /*
     saveView();
     if (v == MANDELBROT) {
         currentGenerator = mandelGenerator;
-        emit this->mw->stopSelectingPoint();
-        this->mw->setViewport(mandelViewSave);
-        this->mw->setGenerator(currentGenerator);
-        this->mw->getMandelInfo().julia = false;
-        this->mw->clearAll();
+        emit this->fractalWidget->stopSelectingPoint();
+        this->fractalWidget->setViewport(mandelViewSave);
+        this->fractalWidget->setGenerator(currentGenerator);
+        this->fractalWidget->getMandelInfo().julia = false;
+        this->fractalWidget->clearCells();
         currentView = MANDELBROT;
     }
     else if (v == CUSTOM) {
         if (customGenerator != nullptr) {
             currentGenerator = customGenerator;
-            this->mw->setGenerator(currentGenerator);
-            emit this->mw->stopSelectingPoint();
-            this->mw->setViewport(customViewSave);
-            this->mw->getMandelInfo().julia = false;
-            this->mw->clearAll();
+            this->fractalWidget->setGenerator(currentGenerator);
+            emit this->fractalWidget->stopSelectingPoint();
+            this->fractalWidget->setViewport(customViewSave);
+            this->fractalWidget->getMandelInfo().julia = false;
+            this->fractalWidget->clearCells();
             currentView = CUSTOM;
         }
         else {
@@ -459,19 +424,18 @@ void Almond::setViewType(ViewType v)
     }
     else if (v == JULIA) {
         if (currentView == MANDELBROT) {
-            emit this->mw->selectPoint();
+            emit this->fractalWidget->selectJuliaPoint();
         }
         else {
             currentView = MANDELBROT;
             currentGenerator = mandelGenerator;
-            this->mw->setGenerator(currentGenerator);
-            this->mw->setViewport(mandelViewSave);
-            this->mw->getMandelInfo().julia = false;
-            this->mw->clearAll();
-            emit this->mw->selectPoint();
+            this->fractalWidget->setGenerator(currentGenerator);
+            this->fractalWidget->setViewport(mandelViewSave);
+            this->fractalWidget->getMandelInfo().julia = false;
+            this->fractalWidget->clearCells();
+            emit this->fractalWidget->selectJuliaPoint();
         }
     }
-    */
 }
 
 

+ 124 - 16
EscapeTimeVisualWidget.cpp

@@ -71,7 +71,6 @@ void ETVImage::draw(float x, float y, float w, float h,
         1, 1,
     };
 
-
     QColor color{ 255, 255, 255 };
     auto& program = owner.program;
     int vertexLoc = program->attributeLocation("vertex");
@@ -175,26 +174,78 @@ void EscapeTimeVisualWidget::initializeGL(void)
 
     renderTextures = new QOpenGLShaderProgram{ this->context() };
     renderTextures->addShaderFromSourceCode(QOpenGLShader::Vertex,
-    "attribute highp vec4 vertex;\n"
-    "attribute highp vec2 texCoord;\n"
-    "uniform highp mat4 matrix;\n"
-    "varying highp vec2 texc;\n"
-    "void main(void)\n"
-    "{\n"
-    "   gl_Position = matrix * vertex;\n"
-    "   texc = texCoord;\n"
-    "}");
+        "attribute highp vec4 vertex;\n"
+        "attribute highp vec2 texCoord;\n"
+        "uniform highp mat4 matrix;\n"
+        "varying highp vec2 texc;\n"
+        "void main(void)\n"
+        "{\n"
+        "   gl_Position = matrix * vertex;\n"
+        "   texc = texCoord;\n"
+        "}");
     renderTextures->addShaderFromSourceCode(QOpenGLShader::Fragment,
+        "#version 110\n"
+        "uniform sampler2D tex;\n"
+        "varying highp vec2 texc;\n"
+        "void main(void)\n"
+        "{\n"
+        "    gl_FragColor = texture2D(tex, texc);\n"
+        "}");
+
+    renderTextures->link();
+
+    juliaPreviewer = new QOpenGLShaderProgram{ this->context() };
+    juliaPreviewer->addShaderFromSourceCode(QOpenGLShader::Vertex,
+        "attribute highp vec4 vertex;\n"
+        "attribute highp vec2 texCoord;\n"
+        "uniform highp mat4 matrix;\n"
+        "varying highp vec2 texc;\n"
+        "void main(void)\n"
+        "{\n"
+        "   gl_Position = matrix * vertex;\n"
+        "   texc = texCoord;\n"
+        "}");
+    juliaPreviewer->addShaderFromSourceCode(QOpenGLShader::Fragment,
     "#version 110\n"
-    "uniform sampler2D tex;\n"
+    "uniform sampler2D gradient;\n"
+    "uniform highp float gradientScaler;\n"
+    "uniform highp float maxIterations;\n"
     "varying highp vec2 texc;\n"
+    "uniform highp float juliaX;\n"
+    "uniform highp float juliaY;\n"
+    "const highp float left = -1.5;\n"
+    "const highp float right = 1.5;\n"
+    "const highp float top = -1.5;\n"
+    "const highp float bottom = 1.5;\n"
+    "float map(float a, float b, float v) {\n"
+    "    return (1.0 - v) * a + b * v;\n"
+    "}\n"
+    "float iterate(float x, float y, float ca, float cb) {\n"
+    "    int k = 0;\n"
+    "    float a = x;\n"
+    "    float b = y;\n"
+    "    while(k <= 250) {\n"
+    "        float aa = a * a;\n"
+    "        float bb = b * b;\n"
+    "        float abab = 2 * a * b;\n"
+    "        a = aa - bb + ca;\n"
+    "        b = abab + cb;\n"
+    "        if (aa + bb >= 16.0f) break;\n"
+    "        k = k + 1;\n"
+    "    }\n"
+    "    return float(k);\n"
+    "}\n"
     "void main(void)\n"
     "{\n"
-    "    gl_FragColor = texture2D(tex, texc);\n"
+    "    float x = map(left, right, texc.x);\n"
+    "    float y = map(top, bottom, texc.y);\n"
+    "    float v = iterate(x, y, juliaX, juliaY);\n"
+//    "    if (v >= maxIterations) { v = 0.0; }\n"
+    "    float vnorm = v * gradientScaler;\n"
+    "    gl_FragColor = texture2D(gradient, vec2(vnorm, 0.0));\n"
+    //"    gl_FragColor = vec4(vnorm, 0.0, 0.0, 0.0);\n"
     "}");
-
-    renderTextures->link();
-
+    juliaPreviewer->link();
 
     program = new QOpenGLShaderProgram{ this->context() };
     bool vert = program->addShaderFromSourceCode(QOpenGLShader::Vertex,
@@ -268,7 +319,7 @@ void EscapeTimeVisualWidget::initializeGL(void)
     //    "   gl_FragColor.g = 0.3;\n"
         "}");
     }
-    
+
     //program.link();
     bool bound = program->bind();
     bound = renderTextures->bind();
@@ -341,8 +392,10 @@ void EscapeTimeVisualWidget::resizeGL(int w, int h)
     pmvMatrix.ortho(QRectF{ 0, 0, newW, newH });
     int matrixLocation = program->uniformLocation("matrix");
     int rtMatrixLocation = renderTextures->uniformLocation("matrix");
+    int jMatrixLocation = juliaPreviewer->uniformLocation("matrix");
     program->setUniformValue(matrixLocation, pmvMatrix);
     renderTextures->setUniformValue(rtMatrixLocation, pmvMatrix);
+    juliaPreviewer->setUniformValue(jMatrixLocation, pmvMatrix);
 }
 
 
@@ -361,6 +414,61 @@ void EscapeTimeVisualWidget::paintGL(void)
 }
 
 
+void EscapeTimeVisualWidget::drawJulia(float jx, float jy)
+{
+    int gradLoc = juliaPreviewer->uniformLocation("gradient");
+    int gradientScaler = juliaPreviewer->uniformLocation("gradientScaler");
+    int juliaX = juliaPreviewer->uniformLocation("juliaX");
+    int juliaY = juliaPreviewer->uniformLocation("juliaY");
+    int vertexLoc = juliaPreviewer->attributeLocation("vertex");
+    int texCoordsLoc = juliaPreviewer->attributeLocation("texCoord");
+    int maxIterLoc = juliaPreviewer->attributeLocation("maxIterations");
+
+    const float x = 100;
+    const float y = 100;
+    const float w = 200;
+    const float h = 200;
+    GLfloat const vertices[] = {
+        x, y,  0.0f,
+        x, y + h, 0.0f,
+        x + w, y, 0.0f,
+        x + w, y + h, 0.0f,
+    };
+
+    GLfloat const texCoords[] = {
+        0, 0,
+        0, 1,
+        1, 0,
+        1, 1,
+    };
+
+    auto& gl = *this->context()->functions();
+    gl.glEnable(GL_TEXTURE_2D);
+    gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    juliaPreviewer->setAttributeArray(vertexLoc, vertices, 3);
+    juliaPreviewer->setAttributeArray(texCoordsLoc, texCoords, 2);
+    juliaPreviewer->enableAttributeArray(vertexLoc);
+    juliaPreviewer->enableAttributeArray(texCoordsLoc);
+    juliaPreviewer->setUniformValue(gradientScaler, 1.0f / float(gradientTextureMax));
+    juliaPreviewer->setUniformValue(maxIterLoc, float(250));
+    juliaPreviewer->setUniformValue(juliaX, float(jx));
+    juliaPreviewer->setUniformValue(juliaY, float(jy));
+
+    juliaPreviewer->bind();
+    gl.glUniform1i(gradLoc, 0);
+
+    gl.glActiveTexture(GL_TEXTURE0);
+    gl.glBindTexture(GL_TEXTURE_2D, gradientTextureId);
+
+    gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+    juliaPreviewer->disableAttributeArray(vertexLoc);
+    juliaPreviewer->disableAttributeArray(texCoordsLoc);
+    //juliaPreviewer->release();
+    //program->bind();
+}
+
+
 void EscapeTimeVisualWidget::setMaxIterationCutoff(float maxIter)
 {
     this->maxIterations = maxIter;

+ 3 - 0
EscapeTimeVisualWidget.h

@@ -33,6 +33,7 @@ class EscapeTimeVisualWidget :
     friend class ETVImage;
     QOpenGLShaderProgram* program;
     QOpenGLShaderProgram* renderTextures;
+    QOpenGLShaderProgram* juliaPreviewer;
     GLuint gradientTextureId;
     float gradientTextureMax;
     float maxIterations;
@@ -54,9 +55,11 @@ public:
     virtual void initializeGL(void) override;
     virtual void resizeGL(int w, int h) override;
     virtual void paintGL(void) override;
+    void drawJulia(float jx, float jy);
 
     void setMaxIterationCutoff(float maxIter);
 
+
     void setResolutionX(int w);
     void setResolutionY(int h);
     int getResolutionX(void) const;

+ 55 - 30
FractalWidget.cpp

@@ -6,31 +6,6 @@
 
 
 
-Q_DECLARE_METATYPE(mnd::MandelViewport)
-
-
-ViewportAnimation::ViewportAnimation(QObject* parent) :
-    QPropertyAnimation{ parent }
-{
-}
-
-
-QVariant ViewportAnimation::interpolated(const QVariant& from, const QVariant& to,
-                      qreal progress) const
-{
-    const mnd::MandelViewport& a = from.value<mnd::MandelViewport>();
-    const mnd::MandelViewport& b = to.value<mnd::MandelViewport>();
-
-    auto retVal = mnd::MandelViewport {
-        a.x * (1 - progress) + b.x * progress,
-        a.y * (1 - progress) + b.y * progress,
-        a.width * (1 - progress) + b.width * progress,
-        a.height * (1 - progress) + b.height * progress,
-    };
-
-    return QVariant::fromValue(retVal);
-}
-
 
 FractalWidget::FractalWidget(QWidget* parent) :
     FractalZoomWidget{ parent }
@@ -115,14 +90,16 @@ void FractalWidget::mouseReleaseEvent(QMouseEvent* me)
     else if (selectingPoint) {
         selectingPoint = false;
         this->setMouseTracking(false);
-        /*mnd::Real x = currentViewport.x + currentViewport.width * mnd::convert<mnd::Real>(float(me->x()) / width());
-        mnd::Real y = currentViewport.y + currentViewport.height * mnd::convert<mnd::Real>(float(me->y()) / height());
-        emit pointSelected(x, y);*/
+        const auto& vp = getViewport();
+        mnd::Real x = vp.x + vp.width * (float(me->pos().x()) / this->width());
+        mnd::Real y = vp.y + vp.height * (float(me->pos().y()) / this->height());
+        emit pointSelected(x, y);
         update();
     }
     dragging = false;
 }
 
+
 void FractalWidget::wheelEvent(QWheelEvent* we)
 {
     QOpenGLWidget::wheelEvent(we);
@@ -184,6 +161,22 @@ void FractalWidget::setDisplayInfo(bool displayInfo)
 }
 
 
+void FractalWidget::selectJuliaPoint(void)
+{
+    this->selectingPoint = true;
+    this->setMouseTracking(true);
+    update();
+}
+
+
+void FractalWidget::stopSelectingPoint(void)
+{
+    this->selectingPoint = false;
+    this->setMouseTracking(false);
+    update();
+}
+
+
 void FractalWidget::resizeGL(int w, int h)
 {
     FractalZoomWidget::resizeGL(w, h);
@@ -193,9 +186,19 @@ void FractalWidget::resizeGL(int w, int h)
 
 void FractalWidget::paintGL(void)
 {
-    FractalZoomWidget::paintGL();
     updateAnimations();
-
+    FractalZoomWidget::paintGL();
+    EscapeTimeVisualWidget::drawJulia(0.3, 0.2);
+
+    if (selectingPoint) {
+        const auto& vp = getViewport();
+        float jx = float(vp.x) + float(vp.width) * pointX / this->width();
+        float jy = float(vp.y) + float(vp.height) * pointY / this->height();
+        EscapeTimeVisualWidget::drawJulia(jx, jy);
+        drawSelectingPoint();
+    }
+    if (rubberbanding)
+        drawRubberband();
     if (displayInfo)
         drawDisplayInfo();
 }
@@ -246,6 +249,28 @@ void FractalWidget::drawDisplayInfo(void)
 }
 
 
+void FractalWidget::drawSelectingPoint(void)
+{
+    QPainter pointPainter{ this };
+    pointPainter.setPen(QColor{ 255, 255, 255 });
+    pointPainter.drawLine(0, pointY, width(), pointY);
+    pointPainter.drawLine(pointX, 0, pointX, height());
+}
+
+
+void FractalWidget::drawRubberband(void)
+{
+    QPainter rubberbandPainter{ this };
+    rubberbandPainter.fillRect(rubberband, QColor{ 125, 140, 225, 120 });
+
+    QPen pen{ QColor{ 100, 115, 200 } };
+    pen.setWidth(2);
+    rubberbandPainter.setPen(pen);
+
+    rubberbandPainter.drawRect(rubberband);
+}
+
+
 void FractalWidget::newAnimation(void)
 {
     auto now = std::chrono::high_resolution_clock::now();

+ 10 - 9
FractalWidget.h

@@ -5,19 +5,12 @@
 #include <QPropertyAnimation>
 #include <chrono>
 
-class ViewportAnimation :
-    public QPropertyAnimation
-{
-public:
-    ViewportAnimation(QObject* parent = nullptr);
-
-    QVariant interpolated(const QVariant& from, const QVariant& to,
-                          qreal progress) const override;
-};
 
 class FractalWidget :
     public FractalZoomWidget
 {
+    Q_OBJECT
+
     bool rubberbanding = false;
     QRectF rubberband;
 
@@ -48,10 +41,18 @@ public:
 
     void setDisplayInfo(bool displayInfo);
 
+    void selectJuliaPoint(void);
+    void stopSelectingPoint(void);
+
     virtual void resizeGL(int w, int h) override;
     virtual void paintGL(void) override;
 
     void drawDisplayInfo(void);
+    void drawSelectingPoint(void);
+    void drawRubberband(void);
+
+signals:
+    void pointSelected(mnd::Real x, mnd::Real y);
 
 private:
     void newAnimation(void);

+ 9 - 0
FractalZoomWidget.cpp

@@ -207,6 +207,9 @@ void FractalZoomWidget::clearCells(void)
     for(auto& [level, grid] : this->levels) {
         grid.clearCells();
     }
+    calcer.changeState();
+    calcer.clearAll();
+    update();
 }
 
 
@@ -322,6 +325,12 @@ const mnd::MandelInfo& FractalZoomWidget::getMandelInfo(void) const
 }
 
 
+mnd::MandelInfo& FractalZoomWidget::getMandelInfo(void)
+{
+    return mandelInfo;
+}
+
+
 void FractalZoomWidget::setGenerator(mnd::MandelGenerator* gen)
 {
     bool changed = true;

+ 1 - 0
FractalZoomWidget.h

@@ -107,6 +107,7 @@ public:
                  int recursionLevel);
 
     const mnd::MandelInfo& getMandelInfo(void) const;
+    mnd::MandelInfo& getMandelInfo(void);
 
     void setGenerator(mnd::MandelGenerator*);
     mnd::MandelGenerator* getGenerator(void) const;

+ 3 - 38
GradientWidget.cpp

@@ -26,11 +26,6 @@ GradientWidget::GradientWidget(QWidget* parent) :
 }
 
 
-/*const QVector<QPair<float, QColor>>& GradientWidget::getGradient(void) const
-{
-    return points;
-}*/
-
 const Gradient& GradientWidget::getGradient(void) const
 {
     return gradient;
@@ -45,38 +40,6 @@ void GradientWidget::setGradient(Gradient gr)
 }
 
 
-QColor lerp(const QColor& a, const QColor& b, float v)
-{
-    float ar = a.redF();
-    float ag = a.greenF();
-    float ab = a.blueF();
-
-    float br = b.redF();
-    float bg = b.greenF();
-    float bb = b.blueF();
-
-    const float gamma = 2.2;
-
-    ar = std::pow(ar, gamma);
-    ag = std::pow(ag, gamma);
-    ab = std::pow(ab, gamma);
-
-    br = std::pow(br, gamma);
-    bg = std::pow(bg, gamma);
-    bb = std::pow(bb, gamma);
-
-    float nr = br * v + (1 - v) * ar;
-    float ng = bg * v + (1 - v) * ag;
-    float nb = bb * v + (1 - v) * ab;
-
-    nr = std::pow(nr, 1/gamma);
-    ng = std::pow(ng, 1/gamma);
-    nb = std::pow(nb, 1/gamma);
-
-    return QColor{ int(255 * nr), int(255 * ng), int(255 * nb) };
-}
-
-
 void GradientWidget::updateGradient(void)
 {
     gradient = Gradient{ points, maxValue };
@@ -86,6 +49,8 @@ void GradientWidget::updateGradient(void)
 QColor GradientWidget::colorAtY(float y)
 {
     float v = handleYToGradVal(y);
+    return fromRGB(gradient.get(v));
+    /*float v = handleYToGradVal(y);
     QColor up = QColor(QColor::Invalid);
     QColor down = QColor(QColor::Invalid);
     float upv = 0;
@@ -105,7 +70,7 @@ QColor GradientWidget::colorAtY(float y)
         return down;
     if (!down.isValid())
         return up;
-    return lerp(up, down, (v - upv) / (downv - upv));
+    return lerp(up, down, (v - upv) / (downv - upv));*/
 }
 
 

+ 1 - 1
libalmond/src/Gradient.cpp

@@ -132,7 +132,7 @@ Gradient Gradient::defaultGradient(void)
         { RGBColor{ 20, 30, 180 }, 210.0f },
         { RGBColor{ 20, 190, 30 }, 240.0f },
         { RGBColor{ 120, 240, 120 }, 270.0f },
-        { RGBColor{ 40, 40, 40 }, 300.0f },
+        { RGBColor{ 0, 0, 0 }, 300.0f },
     }, true);
 }