Changeset 1064


Ignore:
Timestamp:
Nov 12, 2011, 4:52:51 PM (11 years ago)
Author:
sam
Message:

tutorial: navigate in the fractal using the mouse.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/tutorial/tut03.cpp

    r1062 r1064  
    3939        m_pixels = new u8vec4[size.x * size.y];
    4040        m_frame = -1;
    41         m_center = 0;
    42         //m_target = f64cmplx(0.001643721971153, 0.822467633298876);
    43         m_target = f64cmplx(-1.207205434596, 0.315432814901);
    44         //m_target = f64cmplx(-0.79192956889854, -0.14632423080102);
    45         //m_target = f64cmplx(0.3245046418497685, 0.04855101129280834);
    46         //m_target = f64cmplx(0.28693186889504513, 0.014286693904085048);
    47         m_angle = 0.0;
    48         m_radius = 8.0;
     41        m_dirty = 8;
     42        m_center = -0.75;
     43        //f64cmplx(0.001643721971153, 0.822467633298876);
     44        //f64cmplx(-1.207205434596, 0.315432814901);
     45        //f64cmplx(-0.79192956889854, -0.14632423080102);
     46        //f64cmplx(0.3245046418497685, 0.04855101129280834);
     47        //f64cmplx(0.28693186889504513, 0.014286693904085048);
     48        m_radius = 1.5;
     49        m_screenradius = 0.5 * (m_size.x < m_size.y ? m_size.x : m_size.y);
    4950        m_ready = false;
     51
     52        m_centertext = new Text(NULL, "gfx/font/ascii.png");
     53        m_centertext->SetPos(ivec3(5, m_size.y - 15, 1));
     54        Ticker::Ref(m_centertext);
     55
     56        m_mousetext = new Text(NULL, "gfx/font/ascii.png");
     57        m_mousetext->SetPos(ivec3(5, m_size.y - 29, 1));
     58        Ticker::Ref(m_mousetext);
     59
     60        position = ivec3(0, 0, 0);
     61        bbox[0] = position;
     62        bbox[1] = ivec3(size, 0);
     63        Input::TrackMouse(this);
    5064    }
    5165
    5266    ~Fractal()
    5367    {
     68        Input::UntrackMouse(this);
     69        Ticker::Unref(m_centertext);
     70        Ticker::Unref(m_mousetext);
    5471        delete m_pixels;
    5572    }
    5673
     74    inline f64cmplx ScreenToWorldOffset(ivec2 pixel)
     75    {
     76        f64cmplx tmp = f64cmplx(pixel.x - m_size.x / 2,
     77                                m_size.y / 2 - pixel.y);
     78        return tmp * (m_radius / m_screenradius);
     79    }
     80
    5781    virtual void TickGame(float deltams)
    5882    {
     
    6185        m_frame = (m_frame + 1) % 4;
    6286
    63         double zoom = pow(2.0, -deltams * 0.0005);
    64         m_radius *= zoom;
    65         m_center = (m_center - m_target) * zoom * zoom + m_target;
    66 
    67         double step = m_radius / (m_size.x > m_size.y ? m_size.x : m_size.y);
    68 //        m_angle -= deltams * 0.00015;
    69         f64cmplx transform = step * f64cmplx(cos(m_angle), sin(m_angle));
     87        f64cmplx worldmouse = m_center + ScreenToWorldOffset(mousepos);
     88
     89        ivec3 buttons = Input::GetMouseButtons();
     90        if ((buttons[0] || buttons[2]) && mousepos.x != -1)
     91        {
     92            double zoom = pow(2.0, (buttons[0] ? -deltams : deltams) * 0.0015);
     93            if (m_radius * zoom > 1.5)
     94                zoom = 1.0;
     95            m_radius *= zoom;
     96            m_center = (m_center - worldmouse) * zoom + worldmouse;
     97            worldmouse = m_center + ScreenToWorldOffset(mousepos);
     98            m_dirty = 8;
     99        }
     100
     101        char buf[128];
     102        sprintf(buf, "center: %+13.11f%+13.11fi", m_center.x, m_center.y);
     103        m_centertext->SetText(buf);
     104        sprintf(buf, " mouse: %+13.11f%+13.11fi", worldmouse.x, worldmouse.y);
     105        m_mousetext->SetText(buf);
    70106
    71107        u8vec4 *m_pixelstart = m_pixels + m_size.x * m_size.y / 4 * m_frame;
    72108
    73         for (int j = ((m_frame + 1) % 4) / 2; j < m_size.y; j += 2)
    74         for (int i = m_frame % 2; i < m_size.x; i += 2)
    75         {
    76             double const maxlen = 32;
    77             int const maxiter = 170;
    78 
    79             f64cmplx delta(i - m_size.x / 2, j - m_size.y / 2);
    80 
    81             f64cmplx z0 = m_center + transform * delta;
    82             f64cmplx r0 = z0;
    83             //f64cmplx r0(0.28693186889504513, 0.014286693904085048);
    84             //f64cmplx r0(0.001643721971153, 0.822467633298876);
    85             f64cmplx z;
    86             int iter = maxiter;
    87             for (z = z0; iter && z.sqlen() < maxlen * maxlen; z = z * z + r0)
    88                 --iter;
    89 
    90             double f = iter;
    91             double n = z.sqlen();
    92 
    93             double k = log(n) * 0.5f / log(maxlen);
    94             /* Approximate log2(k) in [1,2]. */
    95             f += (- 0.344847817623168308695977510213252644185 * k
    96                   + 2.024664188044341212602376988171727038739) * k
    97                   - 1.674876738008591047163498125918330313237;
    98 
    99             if (iter)
     109        if (m_dirty)
     110        {
     111            m_dirty--;
     112
     113            for (int j = ((m_frame + 1) % 4) / 2; j < m_size.y; j += 2)
     114            for (int i = m_frame % 2; i < m_size.x; i += 2)
    100115            {
    101                 double r = 0.5 * sin(f * 0.27 - 2.0) + 0.5;
    102                 double g = 0.5 * sin(f * 0.13 + 1.0) + 0.5;
    103                 double b = 0.5 * sin(f * 0.21) + 0.5;
    104 
    105                 uint8_t red = r * 255.0f;
    106                 uint8_t green = g * 255.0f;
    107                 uint8_t blue = b * 255.0f;
    108                 *m_pixelstart++ = u8vec4(red, green, blue, 0);
    109             }
    110             else
    111             {
    112                 *m_pixelstart++ = u8vec4(0, 0, 0, 0);
     116                double const maxlen = 32;
     117                int const maxiter = 170;
     118
     119                f64cmplx z0 = m_center + ScreenToWorldOffset(ivec2(i, j));
     120                f64cmplx r0 = z0;
     121                //f64cmplx r0(0.28693186889504513, 0.014286693904085048);
     122                //f64cmplx r0(0.001643721971153, 0.822467633298876);
     123                f64cmplx z;
     124                int iter = maxiter;
     125                for (z = z0; iter && z.sqlen() < maxlen * maxlen; z = z * z + r0)
     126                    --iter;
     127
     128                double f = iter;
     129                double n = z.sqlen();
     130
     131                double k = log(n) * 0.5f / log(maxlen);
     132                /* Approximate log2(k) in [1,2]. */
     133                f += (- 0.344847817623168308695977510213252644185 * k
     134                      + 2.024664188044341212602376988171727038739) * k
     135                      - 1.674876738008591047163498125918330313237;
     136
     137                if (iter)
     138                {
     139                    double r = 0.5 * sin(f * 0.27 - 1.5) + 0.5;
     140                    double g = 0.5 * sin(f * 0.13 + 1.3) + 0.5;
     141                    double b = 0.5 * sin(f * 0.21 + 0.4) + 0.5;
     142
     143                    uint8_t red = r * 255.0f;
     144                    uint8_t green = g * 255.0f;
     145                    uint8_t blue = b * 255.0f;
     146                    *m_pixelstart++ = u8vec4(red, green, blue, 0);
     147                }
     148                else
     149                {
     150                    *m_pixelstart++ = u8vec4(0, 0, 0, 0);
     151                }
    113152            }
    114153        }
     
    131170        static float const texcoords[] =
    132171        {
     172             1.0f,  1.0f,
     173             0.0f,  1.0f,
     174             0.0f,  0.0f,
     175             0.0f,  0.0f,
    133176             1.0f,  0.0f,
    134              0.0f,  0.0f,
    135              0.0f,  1.0f,
    136              0.0f,  1.0f,
    137177             1.0f,  1.0f,
    138              1.0f,  0.0f,
    139178        };
    140179
     
    167206                 * 0.5 from gl_FragCoord.x. Also, (0,0) is at the bottom
    168207                 * left whereas our images have (0,0) at the top left, so we
    169                  * _add_ 0.5 to gl_FragCoord.y. */
     208                 * _add_ 0.5 to gl_FragCoord.y. (XXX: this is no longer true
     209                 * but will be again when mouse coordinates are back to
     210                 * being top-left again). */
    170211                "    float i = mod(gl_FragCoord.x - 0.5, 2.0);"
    171                 "    float j = mod(gl_FragCoord.y + 0.5 + i, 2.0);"
     212                "    float j = mod(gl_FragCoord.y - 0.5 + i, 2.0);"
    172213                "    coord.y += i + j * 2;"
    173214                "    coord.y *= 0.25;"
     
    217258        glEnable(GL_TEXTURE_2D);
    218259        glBindTexture(GL_TEXTURE_2D, m_texid);
    219         glTexSubImage2D(GL_TEXTURE_2D, 0,
    220                         0, m_frame * m_size.y / 2, m_size.x / 2, m_size.y / 2,
     260
     261        if (m_dirty)
     262        {
     263            m_dirty--;
     264
     265            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, m_frame * m_size.y / 2,
     266                            m_size.x / 2, m_size.y / 2,
    221267#if !defined __CELLOS_LV2__
    222                         GL_RGBA, GL_UNSIGNED_BYTE,
    223 #else
    224                         /* The PS3 is big-endian */
    225                         GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
    226 #endif
    227                         m_pixels + m_size.x * m_size.y / 4 * m_frame);
     268                            GL_RGBA, GL_UNSIGNED_BYTE,
     269#else
     270                            /* The PS3 is big-endian */
     271                            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
     272#endif
     273                            m_pixels + m_size.x * m_size.y / 4 * m_frame);
     274        }
    228275
    229276        m_shader->Bind();
     
    273320#endif
    274321    int m_vertexattrib, m_texattrib;
    275     int m_frame;
     322    int m_frame, m_dirty;
    276323    bool m_ready;
    277324
    278     f64cmplx m_center, m_target;
    279     double m_radius, m_angle;
     325    f64cmplx m_center;
     326    double m_radius, m_screenradius;
     327
     328    /* Debug information */
     329    Text *m_centertext, *m_mousetext;
    280330};
    281331
Note: See TracChangeset for help on using the changeset viewer.