From e5dcf4dd2a2643fcdfeb71a3b3c180b70cda4bc4 Mon Sep 17 00:00:00 2001
From: Sam Hocevar <sam@hocevar.net>
Date: Mon, 14 Nov 2011 08:23:19 +0000
Subject: [PATCH] tutorial: try to reduce the blur effect; now it's
 pixelated...

---
 test/tutorial/tut03.cpp | 71 ++++++++++++++++++++++++++++++++---------
 1 file changed, 56 insertions(+), 15 deletions(-)

diff --git a/test/tutorial/tut03.cpp b/test/tutorial/tut03.cpp
index cab5ed7f..d91c6747 100644
--- a/test/tutorial/tut03.cpp
+++ b/test/tutorial/tut03.cpp
@@ -37,14 +37,15 @@ public:
     {
         m_size = size;
         m_pixels = new u8vec4[size.x * size.y];
+        m_tmppixels = new u8vec4[size.x / 2 * size.y / 2];
         m_frame = -1;
-        m_dirty = 8;
+        for (int i = 0; i < 4; i++)
+        {
+            m_deltashift[i] = 0.0;
+            m_deltascale[i] = 1.0;
+            m_dirty[i] = 2;
+        }
         m_center = -0.75;
-        //f64cmplx(0.001643721971153, 0.822467633298876);
-        //f64cmplx(-1.207205434596, 0.315432814901);
-        //f64cmplx(-0.79192956889854, -0.14632423080102);
-        //f64cmplx(0.3245046418497685, 0.04855101129280834);
-        //f64cmplx(0.28693186889504513, 0.014286693904085048);
         m_radius = 1.5;
         m_screenradius = 0.5 * (m_size.x < m_size.y ? m_size.x : m_size.y);
         m_ready = false;
@@ -74,12 +75,13 @@ public:
         Ticker::Unref(m_mousetext);
         Ticker::Unref(m_zoomtext);
         delete m_pixels;
+        delete m_tmppixels;
     }
 
     inline f64cmplx ScreenToWorldOffset(ivec2 pixel)
     {
-        f64cmplx tmp = f64cmplx(pixel.x - m_size.x / 2,
-                                m_size.y / 2 - pixel.y);
+        f64cmplx tmp = f64cmplx(0.5 + pixel.x - m_size.x / 2,
+                                0.5 + m_size.y / 2 - pixel.y);
         return tmp * (m_radius / m_screenradius);
     }
 
@@ -94,6 +96,8 @@ public:
         ivec3 buttons = Input::GetMouseButtons();
         if ((buttons[0] || buttons[2]) && mousepos.x != -1)
         {
+            f64cmplx oldcenter = m_center;
+            double oldradius = m_radius;
             double zoom = pow(2.0, (buttons[0] ? -deltams : deltams) * 0.0015);
             if (m_radius * zoom > 8.0)
                 zoom = 8.0 / m_radius;
@@ -102,9 +106,24 @@ public:
             m_radius *= zoom;
             m_center = (m_center - worldmouse) * zoom + worldmouse;
             worldmouse = m_center + ScreenToWorldOffset(mousepos);
-            m_dirty = 8;
+
+            /* Store the transformation properties to go from m_frame-1
+             * to m_frame. */
+            m_deltashift[m_frame] = (oldcenter - m_center) / m_radius;
+            m_deltascale[m_frame] = oldradius / m_radius;
+            m_dirty[0] = m_dirty[1] = m_dirty[2] = m_dirty[3] = 2;
+        }
+        else
+        {
+            /* If settings didn't change, set transformation from previous
+             * frame to identity. */
+            m_deltashift[m_frame] = 0.0;
+            m_deltascale[m_frame] = 1.0;
         }
 
+        if (buttons[1])
+            m_dirty[0] = m_dirty[1] = m_dirty[2] = m_dirty[3] = 2;
+
         char buf[128];
         sprintf(buf, "center: %+13.11f%+13.11fi", m_center.x, m_center.y);
         m_centertext->SetText(buf);
@@ -115,9 +134,9 @@ public:
 
         u8vec4 *m_pixelstart = m_pixels + m_size.x * m_size.y / 4 * m_frame;
 
-        if (m_dirty)
+        if (m_dirty[m_frame])
         {
-            m_dirty--;
+            m_dirty[m_frame]--;
 
             for (int j = ((m_frame + 1) % 4) / 2; j < m_size.y; j += 2)
             for (int i = m_frame % 2; i < m_size.x; i += 2)
@@ -129,6 +148,9 @@ public:
                 f64cmplx r0 = z0;
                 //f64cmplx r0(0.28693186889504513, 0.014286693904085048);
                 //f64cmplx r0(0.001643721971153, 0.822467633298876);
+                //f64cmplx r0(-1.207205434596, 0.315432814901);
+                //f64cmplx r0(-0.79192956889854, -0.14632423080102);
+                //f64cmplx r0(0.3245046418497685, 0.04855101129280834);
                 f64cmplx z;
                 int iter = maxiter;
                 for (z = z0; iter && z.sqlen() < maxlen * maxlen; z = z * z + r0)
@@ -267,9 +289,9 @@ public:
         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, m_texid);
 
-        if (m_dirty)
+        if (m_dirty[m_frame])
         {
-            m_dirty--;
+            m_dirty[m_frame]--;
 
             glTexSubImage2D(GL_TEXTURE_2D, 0, 0, m_frame * m_size.y / 2,
                             m_size.x / 2, m_size.y / 2,
@@ -282,6 +304,23 @@ public:
                             m_pixels + m_size.x * m_size.y / 4 * m_frame);
         }
 
+/* If other frames are dirty, upload fake data for now */
+for (int i = 0; i < 4; i++)
+{
+    if (m_dirty[i])
+    {
+            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i * m_size.y / 2,
+                            m_size.x / 2, m_size.y / 2,
+#if !defined __CELLOS_LV2__
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+#else
+                            /* The PS3 is big-endian */
+                            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
+#endif
+                            m_pixels + m_size.x * m_size.y / 4 * m_frame);
+    }
+}
+
         m_shader->Bind();
 #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
         glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
@@ -320,7 +359,7 @@ public:
 
 private:
     ivec2 m_size;
-    u8vec4 *m_pixels;
+    u8vec4 *m_pixels, *m_tmppixels;
     Shader *m_shader;
     GLuint m_texid;
 #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
@@ -328,11 +367,13 @@ private:
     GLuint m_tco;
 #endif
     int m_vertexattrib, m_texattrib;
-    int m_frame, m_dirty;
+    int m_frame, m_dirty[4];
     bool m_ready;
 
     f64cmplx m_center;
     double m_radius, m_screenradius;
+    f64cmplx m_deltashift[4];
+    double m_deltascale[4];
 
     /* Debug information */
     Text *m_centertext, *m_mousetext, *m_zoomtext;