浏览代码

tutorial: decorrelate window size and texture size in the Mandelbrot viewer.

legacy
Sam Hocevar sam 13 年前
父节点
当前提交
adf0dfcc7e
共有 1 个文件被更改,包括 50 次插入27 次删除
  1. +50
    -27
      test/tutorial/tut03.cpp

+ 50
- 27
test/tutorial/tut03.cpp 查看文件

@@ -35,9 +35,14 @@ class Fractal : public WorldEntity
public:
Fractal(ivec2 const &size)
{
/* Ensure size has even X and Y values */
m_size = size;
m_pixels = new u8vec4[size.x * size.y];
m_tmppixels = new u8vec4[size.x / 2 * size.y / 2];
m_size.x = (m_size.x + 1) & ~1;
m_size.y = (m_size.y + 1) & ~1;

m_window_size = Video::GetSize();
m_pixels = new u8vec4[m_size.x * m_size.y];
m_tmppixels = new u8vec4[m_size.x / 2 * m_size.y / 2];
m_frame = -1;
for (int i = 0; i < 4; i++)
{
@@ -47,11 +52,13 @@ public:
}
m_center = -0.75;
m_radius = 1.5;
m_screenradius = 0.5 * (m_size.x < m_size.y ? m_size.x : m_size.y);
m_texture_radius = 0.5 * (m_size.x < m_size.y ? m_size.x : m_size.y);
m_window_radius = 0.5 * (m_window_size.x < m_window_size.y ? m_window_size.x : m_window_size.y);
m_pixel_delta = vec4(vec2(1.0, 1.0) / (vec2)m_size, m_size);
m_ready = false;

m_palette = new u8vec4[MAX_ITERATIONS * PALETTE_STEP];
for (int i = 0; i < MAX_ITERATIONS * PALETTE_STEP; i++)
m_palette = new u8vec4[(MAX_ITERATIONS + 1) * PALETTE_STEP];
for (int i = 0; i < (MAX_ITERATIONS + 1) * PALETTE_STEP; i++)
{
float f = i / (double)PALETTE_STEP;

@@ -66,20 +73,20 @@ public:
}

m_centertext = new Text(NULL, "gfx/font/ascii.png");
m_centertext->SetPos(ivec3(5, m_size.y - 15, 1));
m_centertext->SetPos(ivec3(5, m_window_size.y - 15, 1));
Ticker::Ref(m_centertext);

m_mousetext = new Text(NULL, "gfx/font/ascii.png");
m_mousetext->SetPos(ivec3(5, m_size.y - 29, 1));
m_mousetext->SetPos(ivec3(5, m_window_size.y - 29, 1));
Ticker::Ref(m_mousetext);

m_zoomtext = new Text(NULL, "gfx/font/ascii.png");
m_zoomtext->SetPos(ivec3(5, m_size.y - 43, 1));
m_zoomtext->SetPos(ivec3(5, m_window_size.y - 43, 1));
Ticker::Ref(m_zoomtext);

position = ivec3(0, 0, 0);
bbox[0] = position;
bbox[1] = ivec3(size, 0);
bbox[1] = ivec3(m_window_size, 0);
Input::TrackMouse(this);
}

@@ -94,11 +101,20 @@ public:
delete m_palette;
}

inline f64cmplx TexelToWorldOffset(ivec2 texel)
{
f64cmplx tmp = f64cmplx(0.5 + texel.x - m_size.x / 2,
0.5 + m_size.y / 2 - texel.y);
return tmp * (m_radius / m_texture_radius);
}

inline f64cmplx ScreenToWorldOffset(ivec2 pixel)
{
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);
/* No 0.5 offset here, because we want to be able to position the
* mouse at (0,0) exactly. */
f64cmplx tmp = f64cmplx(pixel.x - m_window_size.x / 2,
m_window_size.y / 2 - pixel.y);
return tmp * (m_radius / m_window_radius);
}

virtual void TickGame(float deltams)
@@ -150,9 +166,9 @@ public:
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);
sprintf(buf, "center: %+16.14f%+16.14fi", m_center.x, m_center.y);
m_centertext->SetText(buf);
sprintf(buf, " mouse: %+13.11f%+13.11fi", worldmouse.x, worldmouse.y);
sprintf(buf, " mouse: %+16.14f%+16.14fi", worldmouse.x, worldmouse.y);
m_mousetext->SetText(buf);
sprintf(buf, " zoom: %g", 1.0 / m_radius);
m_zoomtext->SetText(buf);
@@ -166,9 +182,9 @@ public:
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)
{
double const maxsqlen = 32;
double const maxsqlen = 1024;

f64cmplx z0 = m_center + ScreenToWorldOffset(ivec2(i, j));
f64cmplx z0 = m_center + TexelToWorldOffset(ivec2(i, j));
f64cmplx r0 = z0;
//f64cmplx r0(0.28693186889504513, 0.014286693904085048);
//f64cmplx r0(0.001643721971153, 0.822467633298876);
@@ -184,6 +200,8 @@ public:
{
double f = iter;
double n = z.sqlen();
if (n > maxsqlen * maxsqlen)
n = maxsqlen * maxsqlen;

/* Approximate log(sqrt(n))/log(sqrt(maxsqlen)) */
union { double n; uint64_t x; } u = { n };
@@ -251,19 +269,20 @@ public:
"}",

"#version 120\n"
"uniform vec4 in_PixelDelta;\n"
"uniform sampler2D in_Texture;\n"
"void main(void) {"
" vec2 coord = gl_TexCoord[0].xy;"
/* gl_FragCoord is centered inside the pixel, so we remove
* 0.5 from gl_FragCoord.x. Also, (0,0) is at the bottom
* left whereas our images have (0,0) at the top left, so we
* _add_ 0.5 to gl_FragCoord.y. (XXX: this is no longer true
* but will be again when mouse coordinates are back to
* being top-left again). */
" float i = mod(gl_FragCoord.x - 0.5, 2.0);"
" float j = mod(gl_FragCoord.y - 0.5 + i, 2.0);"
/* i is 0 or 1, depending on the current X coordinate within
* the current 2×2 texel. j is 0 or 1, depending on the Y
* coordinate _and_ the value of i, in order to stay on the
* Bayer dithering pattern. */
" int i = int(mod(coord.x, 2.0 * in_PixelDelta.x) * in_PixelDelta.z);"
" int j = int(mod(coord.y + i * in_PixelDelta.y, 2.0 * in_PixelDelta.y) * in_PixelDelta.w);"
/* Choose the best slice depending on the value of i and j. */
" coord.y += i + j * 2;"
" coord.y *= 0.25;"
/* Get a pixel from the best slice */
" vec4 p = texture2D(in_Texture, coord);"
" gl_FragColor = p;"
"}"
@@ -279,6 +298,7 @@ public:

"void main(float4 in_FragCoord : WPOS,"
" float2 in_TexCoord : TEXCOORD0,"
" uniform float4 in_PixelDelta,"
" uniform sampler2D in_Texture,"
" out float4 out_FragColor : COLOR)"
"{"
@@ -294,6 +314,7 @@ public:
);
m_vertexattrib = m_shader->GetAttribLocation("in_Vertex");
m_texattrib = m_shader->GetAttribLocation("in_TexCoord");
m_pixeluni = m_shader->GetUniformLocation("in_PixelDelta");
m_ready = true;

#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
@@ -340,6 +361,7 @@ if (0) for (int i = 0; i < 4; i++)
}

m_shader->Bind();
m_shader->SetUniform(m_pixeluni, m_pixel_delta);
#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glEnableVertexAttribArray(m_vertexattrib);
@@ -379,7 +401,7 @@ private:
static int const MAX_ITERATIONS = 170;
static int const PALETTE_STEP = 32;

ivec2 m_size;
ivec2 m_size, m_window_size;
u8vec4 *m_pixels, *m_tmppixels, *m_palette;
Shader *m_shader;
GLuint m_texid;
@@ -387,12 +409,13 @@ private:
GLuint m_vbo, m_tbo;
GLuint m_tco;
#endif
int m_vertexattrib, m_texattrib;
int m_vertexattrib, m_texattrib, m_pixeluni;
int m_frame, m_dirty[4];
bool m_ready;

f64cmplx m_center;
double m_radius, m_screenradius;
double m_radius, m_texture_radius, m_window_radius;
vec4 m_pixel_delta;
f64cmplx m_deltashift[4];
double m_deltascale[4];



正在加载...
取消
保存