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;