Преглед изворни кода

reverted to no buffers but max iteration cutoff added

Nicolas Winkler пре 4 година
родитељ
комит
e4454d6bc7
6 измењених фајлова са 122 додато и 38 уклоњено
  1. 3 3
      Almond.cpp
  2. 87 33
      EscapeTimeVisualWidget.cpp
  3. 4 0
      EscapeTimeVisualWidget.h
  4. 23 2
      FractalZoomWidget.cpp
  5. 3 0
      FractalZoomWidget.h
  6. 2 0
      libmandel/src/ClGenerators.cpp

+ 3 - 3
Almond.cpp

@@ -28,7 +28,7 @@ Almond::Almond(QWidget* parent) :
     customViewSave = mnd::MandelViewport::centerView();
 
     on_maxIterations_editingFinished();
-    // TODO update mw->setSmoothColoring(ui.smooth->isChecked());
+    fractalWidget->setSmoothColoring(ui.smooth->isChecked());
 
     currentView = MANDELBROT;
     mandelGenerator = &mandelContext.getDefaultGenerator();
@@ -336,7 +336,7 @@ void Almond::on_maxIterations_editingFinished()
 {
     QString text = ui.maxIterations->text();
     int maxIter = text.toInt();
-    // TODO update mw->setMaxIterations(maxIter);
+    fractalWidget->setMaxIterations(maxIter);
 }
 
 
@@ -389,7 +389,7 @@ void Almond::on_exportVideo_clicked()
 
 void Almond::on_smooth_stateChanged(int checked)
 {
-    // TODO update this->mw->setSmoothColoring(checked != Qt::Unchecked);
+    fractalWidget->setSmoothColoring(checked != Qt::Unchecked);
 }
 
 

+ 87 - 33
EscapeTimeVisualWidget.cpp

@@ -7,6 +7,7 @@
 #include <QOpenGLFunctions>
 #include <QOpenGLExtraFunctions>
 #include <QOpenGLFunctions_3_0>
+#include <QOpenGLFunctions_4_0_Core>
 
 #include <vector>
 
@@ -78,24 +79,30 @@ void ETVImage::draw(float x, float y, float w, float h,
     int colorLocation = program->uniformLocation("color");
     int texLoc = program->uniformLocation("tex");
     int gradLoc = program->uniformLocation("gradient");
-    program->setAttributeArray(vertexLoc, fbVertices, 3);
+    int gradientScaler = program->uniformLocation("gradientScaler");
+    int maxIterations = program->uniformLocation("maxIterations");
+    program->setAttributeArray(vertexLoc, vertices, 3);
     program->setAttributeArray(texCoordsLoc, texCoords, 2);
     program->enableAttributeArray(vertexLoc);
     program->enableAttributeArray(texCoordsLoc);
     program->setUniformValue(colorLocation, color);
+    program->setUniformValue(gradientScaler, 1.0f / float(owner.gradientTextureMax));
+    program->setUniformValue(maxIterations, float(owner.maxIterations));
 
     gl.glEnable(GL_TEXTURE_2D);
     owner.program->bind();
 
     //GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
     //gle.glDrawBuffers(1, drawBuffers);
+    gl.glBindFramebuffer(GL_FRAMEBUFFER, owner.tileFramebuffer);
+    gl.glDisable(GL_DEPTH_TEST);
     if(gl.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
         printf("error intitializing framebuffer\n");
     }
-    gl.glBindFramebuffer(GL_FRAMEBUFFER, owner.tileFramebuffer);
     gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, owner.tileTexture, 0);
     //gl.glViewport(0, 0, 256, 256);
 
+    gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
     gl.glUniform1i(texLoc, 0);
     gl.glUniform1i(gradLoc, 2);
 
@@ -108,7 +115,7 @@ void ETVImage::draw(float x, float y, float w, float h,
     program->disableAttributeArray(vertexLoc);
     program->disableAttributeArray(texCoordsLoc);
 
-    owner.renderTextures->bind();
+    /*owner.renderTextures->bind();
     gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
     //gl.glViewport(0, 0, owner.getResolutionX(), owner.getResolutionY());
     int rtVertexLoc = owner.renderTextures->attributeLocation("vertex");
@@ -122,15 +129,19 @@ void ETVImage::draw(float x, float y, float w, float h,
     owner.renderTextures->enableAttributeArray(rtVertexLoc);
     owner.renderTextures->enableAttributeArray(rtTexCoordsLoc);
     gl.glBindTexture(GL_TEXTURE_2D, owner.tileTexture);
-    gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    //if (rand() % 2)
+    //gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     owner.renderTextures->disableAttributeArray(rtVertexLoc);
     owner.renderTextures->disableAttributeArray(rtTexCoordsLoc);
+    */
     gl.glActiveTexture(GL_TEXTURE0);
 }
 
 
 EscapeTimeVisualWidget::EscapeTimeVisualWidget(QWidget* parent) :
     QOpenGLWidget{ parent },
+    gradientTextureId{ 0 },
+    gradientTextureMax{ 1.0f },
     gradientNeedsUpdate{ false }
 {
 }
@@ -198,34 +209,65 @@ void EscapeTimeVisualWidget::initializeGL(void)
     "}");
 
     // TODO rewrite this monster
-    bool frag = program->addShaderFromSourceCode(QOpenGLShader::Fragment,
-    "#version 110\n"
-    "uniform sampler2D gradient;\n"
-    "uniform sampler2D tex;\n"
-    "uniform mediump vec4 color;\n"
-    "uniform highp float gradientScaler;\n"
-    "varying highp vec2 texc;\n"
-    "void main(void)\n"
-    "{\n"
-    "   float v = texture2D(tex, texc).r;\n"
-    /*"   vec2 size = textureSize(tex, 0);\n"
-    "   size = vec2(256.0, 256.0);\n"
-    "   vec2 accPoint = texc * size;\n"
-    "   vec2 ip = floor(accPoint);\n"
-    "   vec2 fp = fract(accPoint);\n"
-    "   vec4 inter = textureGather(tex, ip / size, 0);\n"
-    "   vec4 col1 = texture2D(gradient, vec2(inter.x*0.005, 0.0));\n"
-    "   vec4 col2 = texture2D(gradient, vec2(inter.y*0.005, 0.0));\n"
-    "   vec4 col3 = texture2D(gradient, vec2(inter.z*0.005, 0.0));\n"
-    "   vec4 col4 = texture2D(gradient, vec2(inter.w*0.005, 0.0));\n"
-    "   vec4 col = mix(mix(col4, col3, fp.x), mix(col1, col2, fp.x), fp.y);\n"*/
-    "   gl_FragColor = texture2D(gradient, vec2(v*0.005, 0.0));\n"
-    //"   gl_FragColor = col;\n"
-//    "   gl_FragColor = gl_FragColor * texture2D(tex, texc);\n"
-//    "   float v = texture2D(tex, texc).r;\n"
-//    "   gl_FragColor = vec4(v, 1.0 - v, v*v, 1);\n"
-//    "   gl_FragColor.g = 0.3;\n"
-    "}");
+    if (context()->versionFunctions<QOpenGLFunctions_4_0_Core>() != nullptr) {
+        bool frag = program->addShaderFromSourceCode(QOpenGLShader::Fragment,
+        "#version 400\n"
+        "uniform sampler2D gradient;\n"
+        "uniform sampler2D tex;\n"
+        "uniform mediump vec4 color;\n"
+        "uniform highp float gradientScaler;\n"
+        "uniform highp float maxIterations;\n"
+        "varying highp vec2 texc;\n"
+        "vec4 colorize(float pos) {\n"
+        "    if (pos >= maxIterations) {\n"
+        "        return vec4(0.0, 0.0, 0.0, 1.0);\n"
+        "    } else {\n"
+        "        return texture2D(gradient, vec2(pos * gradientScaler, 0.0));\n"
+        "    }\n"
+        "}\n"
+        "void main(void)\n"
+        "{\n"
+        "   vec2 size = textureSize(tex, 0);\n"
+        "   size = vec2(256.0, 256.0);\n"
+        "   vec2 accPoint = texc * size;\n"
+        "   vec2 ip = floor(accPoint);\n"
+        "   vec2 fp = fract(accPoint);\n"
+        "   vec4 inter = textureGather(tex, ip / size, 0);\n"
+        "   vec4 col1 = colorize(inter.x);\n"
+        "   vec4 col2 = colorize(inter.y);\n"
+        "   vec4 col3 = colorize(inter.z);\n"
+        "   vec4 col4 = colorize(inter.w);\n"
+        "   vec4 col = mix(mix(col4, col3, fp.x), mix(col1, col2, fp.x), fp.y);\n"
+        "   gl_FragColor = col;\n"
+    //    "   gl_FragColor = gl_FragColor * texture2D(tex, texc);\n"
+    //    "   float v = texture2D(tex, texc).r;\n"
+    //    "   gl_FragColor = vec4(v, 1.0 - v, v*v, 1);\n"
+    //    "   gl_FragColor.g = 0.3;\n"
+        "}");
+    }
+    else {
+        bool frag = program->addShaderFromSourceCode(QOpenGLShader::Fragment,
+        "#version 110\n"
+        "uniform sampler2D gradient;\n"
+        "uniform sampler2D tex;\n"
+        "uniform mediump vec4 color;\n"
+        "uniform highp float gradientScaler;\n"
+        "uniform highp float maxIterations;\n"
+        "varying highp vec2 texc;\n"
+        "void main(void)\n"
+        "{\n"
+        "   float v = texture2D(tex, texc).r;\n"
+        "   if (v >= maxIterations) {\n"
+        "       gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
+        "   } else {\n"
+        "       gl_FragColor = texture2D(gradient, vec2(v * gradientScaler, 0.0));\n"
+        "   }\n"
+    //    "   gl_FragColor = gl_FragColor * texture2D(tex, texc);\n"
+    //    "   float v = texture2D(tex, texc).r;\n"
+    //    "   gl_FragColor = vec4(v, 1.0 - v, v*v, 1);\n"
+    //    "   gl_FragColor.g = 0.3;\n"
+        "}");
+    }
     
     //program.link();
     bool bound = program->bind();
@@ -237,6 +279,9 @@ void EscapeTimeVisualWidget::initializeGL(void)
     int texLoc = program->uniformLocation("tex");
     int gradLoc = program->uniformLocation("gradient");
     int gradientScaler = program->uniformLocation("gradientScaler");
+    int maxIterations = program->uniformLocation("maxIterations");
+    program->setUniformValue(gradientScaler, 0.005f);
+    program->setUniformValue(maxIterations, 250.0f);
 
     auto& gle = *this->context()->extraFunctions();
 
@@ -245,6 +290,7 @@ void EscapeTimeVisualWidget::initializeGL(void)
     gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    gl.glBindTexture(GL_TEXTURE_2D, 0);
 
     gl.glGenFramebuffers(1, &tileFramebuffer);
     gl.glBindFramebuffer(GL_FRAMEBUFFER, tileFramebuffer);
@@ -254,6 +300,7 @@ void EscapeTimeVisualWidget::initializeGL(void)
     if(gl.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
         printf("error intitializing framebuffer\n");
     }
+    gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
     unsigned char pix[] = { 255, 0, 0, 0, 255, 0, 0, 0, 255 };
 
@@ -314,11 +361,17 @@ void EscapeTimeVisualWidget::paintGL(void)
 }
 
 
+void EscapeTimeVisualWidget::setMaxIterationCutoff(float maxIter)
+{
+    this->maxIterations = maxIter;
+}
+
+
 void EscapeTimeVisualWidget::updateGradient(void)
 {
     auto& gl = *this->context()->functions();
 
-    const int len = 512;
+    const int len = 1024;
     std::unique_ptr<uint8_t[]> pixels = std::make_unique<uint8_t[]>(len * 3);
 
     for (int i = 0; i < len; i++) {
@@ -337,6 +390,7 @@ void EscapeTimeVisualWidget::updateGradient(void)
     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     gl.glBindTexture(GL_TEXTURE_2D, 0);
+    this->gradientTextureMax = gradient.getMax();
 
     gradientNeedsUpdate = false;
 }

+ 4 - 0
EscapeTimeVisualWidget.h

@@ -34,6 +34,8 @@ class EscapeTimeVisualWidget :
     QOpenGLShaderProgram* program;
     QOpenGLShaderProgram* renderTextures;
     GLuint gradientTextureId;
+    float gradientTextureMax;
+    float maxIterations;
     Gradient gradient;
     bool gradientNeedsUpdate;
 
@@ -53,6 +55,8 @@ public:
     virtual void resizeGL(int w, int h) override;
     virtual void paintGL(void) override;
 
+    void setMaxIterationCutoff(float maxIter);
+
     void setResolutionX(int w);
     void setResolutionY(int h);
     int getResolutionX(void) const;

+ 23 - 2
FractalZoomWidget.cpp

@@ -135,7 +135,7 @@ void Calcer::redirect(int level, GridIndex i, GridIndex j, Bitmap<float>* bmp)
     jobsMutex.lock();
     jobs.erase({ level, i, j });
     jobsMutex.unlock();
-    if (this->calcState == calcState) {
+    if (this->calcState == calcState) { // TODO remove invalid results correctly
         emit done(level, i, j, bmp);
     }
     else {
@@ -153,7 +153,7 @@ FractalZoomWidget::FractalZoomWidget(QWidget* parent) :
 {
     qMetaTypeId<GridIndex>();
     connect(&calcer, &Calcer::done, this, &FractalZoomWidget::cellReady);
-    mandelInfo.maxIter = 250;
+    setMaxIterations(250);
 }
 
 
@@ -344,6 +344,27 @@ void FractalZoomWidget::zoom(float factor)
 }
 
 
+void FractalZoomWidget::setSmoothColoring(bool smooth)
+{
+    if (mandelInfo.smooth != smooth) {
+        mandelInfo.smooth = smooth;
+        clearCells();
+        update();
+    }
+}
+
+
+void FractalZoomWidget::setMaxIterations(int maxIterations)
+{
+    if (mandelInfo.maxIter != maxIterations) {
+        mandelInfo.maxIter = maxIterations;
+        EscapeTimeVisualWidget::setMaxIterationCutoff(float(maxIterations));
+        clearCells();
+        update();
+    }
+}
+
+
 void FractalZoomWidget::initializeGL(void)
 {
     EscapeTimeVisualWidget::initializeGL();

+ 3 - 0
FractalZoomWidget.h

@@ -113,6 +113,9 @@ public:
 
     virtual void zoom(float factor);
 
+    virtual void setSmoothColoring(bool smooth);
+    virtual void setMaxIterations(int maxIterations);
+
     virtual void initializeGL(void) override;
     virtual void resizeGL(int w, int h) override;
     virtual void paintGL(void) override;

+ 2 - 0
libmandel/src/ClGenerators.cpp

@@ -116,6 +116,8 @@ ClGeneratorFloat::ClGeneratorFloat(mnd::MandelDevice& device, const std::string&
 {
     const cl::Device& dev = device.getClDevice().device;
     useVec = dev.getInfo<CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT>() >= 4;
+    // often still slower than non-vec variation
+    useVec = false;
     kernel = Kernel(program, useVec ? "iterate_vec4" : "iterate");
 }