Procházet zdrojové kódy

tutorial: fix tutorial 11 (fractal)

Input was broken, as well as palette generation, and even texture
upload. Should be all good now.
legacy
Sam Hocevar před 8 roky
rodič
revize
2149187abd
2 změnil soubory, kde provedl 75 přidání a 127 odebrání
  1. +39
    -28
      doc/tutorial/11_fractal.cpp
  2. +36
    -99
      doc/tutorial/11_fractal.lolfx

+ 39
- 28
doc/tutorial/11_fractal.cpp Zobrazit soubor

@@ -1,7 +1,7 @@
//
// Lol Engine — Fractal tutorial
//
// Copyright © 2011—2015 Sam Hocevar <sam@hocevar.net>
// Copyright © 2011—2016 Sam Hocevar <sam@hocevar.net>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
@@ -38,6 +38,13 @@ public:
m_texel_settings = vec4(1.0, 1.0, 2.0, 2.0) / (vec4)m_size.xyxy;
m_screen_settings = vec4(1.0, 1.0, 0.5, 0.5) * (vec4)m_size.xyxy;

m_controller = new Controller("Default");
m_profile << InputProfile::MouseKey(0, "Left")
<< InputProfile::MouseKey(1, "Right")
<< InputProfile::MouseKey(2, "Middle");
m_controller->Init(m_profile);
m_mouse = InputDevice::GetMouse();

/* Window size decides the world aspect ratio. For instance, 640×480
* will be mapped to (-0.66,-0.5) - (0.66,0.5). */
#if !defined __native_client__
@@ -74,21 +81,19 @@ public:
{
double f = (double)i / PALETTE_STEP;

double r = 0.5 * lol::sin(f * 0.27 + 2.0) + 0.5;
double g = 0.5 * lol::sin(f * 0.17 - 1.8) + 0.5;
double b = 0.5 * lol::sin(f * 0.21 - 2.6) + 0.5;
vec3 hsv(lol::fmod(i * 0.002f, 1.f),
0.4 * lol::sin(f * 0.27 + 2.0) + 0.4,
0.4 * lol::sin(f * 0.21 - 2.6) + 0.4);
vec3 rgb = Color::HSVToRGB(hsv);

if (f < 7.0)
{
f = f < 1.0 ? 0.0 : (f - 1.0) / 6.0;
r *= f;
g *= f;
b *= f;
rgb *= f < 1.0 ? 0.0 : (f - 1.0) / 6.0;
}

uint8_t red = (uint8_t)r * 256;
uint8_t green = (uint8_t)g * 256;
uint8_t blue = (uint8_t)b * 256;
uint8_t red = (uint8_t)(rgb.r * 256);
uint8_t green = (uint8_t)(rgb.g * 256);
uint8_t blue = (uint8_t)(rgb.b * 256);
#if defined __native_client__
m_palette.push(u8vec4(red, green, blue, 255));
#else
@@ -113,7 +118,6 @@ public:
m_position = vec3::zero;
m_aabb.aa = m_position;
m_aabb.bb = vec3((vec2)m_window_size, 0);
//Input::TrackMouse(this);

#if LOL_FEATURE_THREADS
/* Spawn worker threads and wait for their readiness. */
@@ -163,7 +167,7 @@ public:
{
WorldEntity::TickGame(seconds);

ivec2 mousepos = ivec2::zero; /* FIXME: input */
ivec2 mousepos = m_mouse->GetCursorPixel(0);

int prev_frame = (m_frame + 4) % 4;
m_frame = (m_frame + 1) % 4;
@@ -171,9 +175,7 @@ public:
rcmplx worldmouse = m_center
+ rcmplx(ScreenToWorldOffset((vec2)mousepos));

uint32_t buttons = 0;
//uint32_t buttons = Input::GetMouseButtons();
if (buttons & 0x2)
if (m_controller->IsKeyPressed(2))
{
if (!m_drag)
{
@@ -201,9 +203,11 @@ public:
}
}

if (buttons & 0x5 && mousepos.x != -1)
bool hold_right = m_controller->IsKeyPressed(0);
bool hold_left = m_controller->IsKeyPressed(1);
if ((hold_right || hold_left) && mousepos.x != -1)
{
double zoom = (buttons & 0x1) ? -0.5 : 0.5;
double zoom = hold_right ? -0.5 : 0.5;
m_zoom_speed += zoom * seconds;
if (m_zoom_speed / zoom > 5e-3f)
m_zoom_speed = zoom * 5e-3f;
@@ -308,7 +312,7 @@ public:
}

#if LOL_FEATURE_THREADS
void DoWorkHelper(thread *inst)
void DoWorkHelper(thread *)
{
m_spawnqueue.push(0);
for ( ; ; )
@@ -332,8 +336,8 @@ public:
int jmax = jmin + MAX_LINES * 2;
if (jmax > m_size.y)
jmax = m_size.y;
u8vec4 *m_pixelstart = &m_pixels[0]
+ m_size.x * (m_size.y / 4 * m_frame + line / 4);
u8vec4 *pixelstart = &m_pixels[0]
+ m_size.x * (m_size.y / 4 * m_frame + line / 4);

dcmplx c = (dcmplx)m_center;

@@ -404,11 +408,11 @@ public:
+ 2.024664188044341212602376988171727038739) * k
- 1.674876738008591047163498125918330313237;

*m_pixelstart++ = m_palette[(int)(f * PALETTE_STEP)];
*pixelstart++ = m_palette[(int)(f * PALETTE_STEP)];
}
else
{
*m_pixelstart++ = u8vec4(0, 0, 0, 255);
*pixelstart++ = u8vec4(0, 0, 0, 255);
}
}
}
@@ -452,9 +456,10 @@ public:

m_vertexattrib = m_shader->GetAttribLocation(VertexUsage::Position, 0);
m_texattrib = m_shader->GetAttribLocation(VertexUsage::TexCoord, 0);
m_texeluni = m_shader->GetUniformLocation("u_TexelSize");
m_screenuni = m_shader->GetUniformLocation("u_ScreenSize");
m_zoomuni = m_shader->GetUniformLocation("u_ZoomSettings");
m_texuni = m_shader->GetUniformLocation("u_texture");
m_texeluni = m_shader->GetUniformLocation("u_texel_size");
m_screenuni = m_shader->GetUniformLocation("u_screen_size");
m_zoomuni = m_shader->GetUniformLocation("u_zoom_settings");

m_vdecl =
new VertexDeclaration(VertexStream<vec2>(VertexUsage::Position),
@@ -491,6 +496,7 @@ public:
}

m_shader->Bind();
m_shader->SetUniform(m_texuni, m_texture->GetTextureUniform(), 0);
m_shader->SetUniform(m_texeluni, m_texel_settings);
m_shader->SetUniform(m_screenuni, m_screen_settings);
m_shader->SetUniform(m_zoomuni, m_zoom_settings);
@@ -515,7 +521,7 @@ private:

Shader *m_shader;
ShaderAttrib m_vertexattrib, m_texattrib;
ShaderUniform m_texeluni, m_screenuni, m_zoomuni;
ShaderUniform m_texuni, m_texeluni, m_screenuni, m_zoomuni;

VertexDeclaration *m_vdecl;
VertexBuffer *m_vbo, *m_tbo;
@@ -531,6 +537,11 @@ private:
vec4 m_texel_settings, m_screen_settings;
mat4 m_zoom_settings;

// Input support
InputDevice *m_mouse;
Controller *m_controller;
InputProfile m_profile;

#if LOL_FEATURE_THREADS
/* Worker threads */
thread *m_threads[MAX_THREADS];
@@ -548,7 +559,7 @@ int main(int argc, char **argv)
ivec2 window_size(640, 480);

sys::init(argc, argv);
Application app("Tutorial 3: Fractal", window_size, 60.0f);
Application app("Tutorial 11: Fractal", window_size, 60.0f);

new DebugFps(5, 5);
new Fractal(window_size);


+ 36
- 99
doc/tutorial/11_fractal.lolfx Zobrazit soubor

@@ -1,15 +1,15 @@
[vert.glsl]

#version 120
#version 130

uniform mat4 u_ZoomSettings;
uniform vec4 u_TexelSize;
uniform vec4 u_ScreenSize;
uniform mat4 u_zoom_settings;
uniform vec4 u_texel_size;
uniform vec4 u_screen_size;

attribute vec2 in_TexCoord;
attribute vec2 in_Position;

varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;
out vec4 v_center_x, v_center_y, v_index_x, v_index_y;

void main(void)
{
@@ -21,55 +21,55 @@ void main(void)
* size of a texel: the distance from this new point to
* the final point will be our error. */
vec4 offsets = vec4(0.5, -0.5, 0.015625, -0.015625);
vec4 zoomscale = vec4(u_ZoomSettings[0][2],
u_ZoomSettings[1][2],
u_ZoomSettings[2][2],
u_ZoomSettings[3][2]);
vec4 zoomtx = vec4(u_ZoomSettings[0][0],
u_ZoomSettings[1][0],
u_ZoomSettings[2][0],
u_ZoomSettings[3][0]);
vec4 zoomty = vec4(u_ZoomSettings[0][1],
u_ZoomSettings[1][1],
u_ZoomSettings[2][1],
u_ZoomSettings[3][1]);
v_CenterX = zoomscale * in_TexCoord.x + zoomtx
+ offsets.xyxy * u_TexelSize.x;
v_CenterY = zoomscale * in_TexCoord.y - zoomty
+ offsets.xyyx * u_TexelSize.y;
vec4 zoomscale = vec4(u_zoom_settings[0][2],
u_zoom_settings[1][2],
u_zoom_settings[2][2],
u_zoom_settings[3][2]);
vec4 zoomtx = vec4(u_zoom_settings[0][0],
u_zoom_settings[1][0],
u_zoom_settings[2][0],
u_zoom_settings[3][0]);
vec4 zoomty = vec4(u_zoom_settings[0][1],
u_zoom_settings[1][1],
u_zoom_settings[2][1],
u_zoom_settings[3][1]);
v_center_x = zoomscale * in_TexCoord.x + zoomtx
+ offsets.xyxy * u_texel_size.x;
v_center_y = zoomscale * in_TexCoord.y - zoomty
+ offsets.xyyx * u_texel_size.y;
/* Precompute the multiple of one texel where our ideal
* point lies. The fragment shader will call floor() on
* this value. We add or remove a slight offset to avoid
* rounding issues at the image's edges. */
v_IndexX = v_CenterX * u_ScreenSize.z - offsets.zwzw;
v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;
v_index_x = v_center_x * u_screen_size.z - offsets.zwzw;
v_index_y = v_center_y * u_screen_size.w - offsets.zwwz;
}

[frag.glsl]

#version 120
#version 130

#if defined GL_ES
precision highp float;
#endif

uniform vec4 u_TexelSize;
uniform sampler2D u_Texture;
uniform vec4 u_texel_size;
uniform sampler2D u_texture;

varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;
in vec4 v_center_x, v_center_y, v_index_x, v_index_y;

void main(void)
{
vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5);
vec4 rx, ry, t0, dx, dy, dd;
/* Get a pixel coordinate from each slice into rx & ry */
rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);
ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);
rx = u_texel_size.x + u_texel_size.z * floor(v_index_x);
ry = u_texel_size.y + u_texel_size.w * floor(v_index_y);
/* Compute inverse distance to expected pixel in dd,
* and put zero if we fall outside the texture. */
t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
dx = rx - v_CenterX;
dy = ry - v_CenterY;
dx = rx - v_center_x;
dy = ry - v_center_y;
#if 0
vec4 dd = t0 * (abs(dx) + abs(dy));
vec4 dd = t0 / (0.001 + sqrt((dx * dx) + (dy * dy)));
@@ -115,78 +115,15 @@ void main(void)
ret.xy = ret.xz * t2.yy + ret.yw * t2.xx;
# endif
/* Nearest neighbour */
gl_FragColor = texture2D(u_Texture, ret.xy);
gl_FragColor = texture2D(u_texture, ret.xy);
#else
/* Alternate version: some kind of linear interpolation */
vec4 p0 = texture2D(u_Texture, vec2(rx.x, ry.x));
vec4 p1 = texture2D(u_Texture, vec2(rx.y, ry.y));
vec4 p2 = texture2D(u_Texture, vec2(rx.z, ry.z));
vec4 p3 = texture2D(u_Texture, vec2(rx.w, ry.w));
vec4 p0 = texture2D(u_texture, vec2(rx.x, ry.x));
vec4 p1 = texture2D(u_texture, vec2(rx.y, ry.y));
vec4 p2 = texture2D(u_texture, vec2(rx.z, ry.z));
vec4 p3 = texture2D(u_texture, vec2(rx.w, ry.w));
gl_FragColor = 1.0 / (dd.x + dd.y + dd.z + dd.w)
* (dd.x * p0 + dd.y * p1 + dd.z * p2 + dd.w * p3);
#endif
}

[vert.hlsl]

void main(float2 a_Vertex : POSITION,
float2 a_TexCoord : TEXCOORD0,
uniform float4x4 u_ZoomSettings,
uniform float4 u_TexelSize,
uniform float4 u_ScreenSize,
out float4 out_Position : POSITION0,
out float4 v_CenterX : TEXCOORD0,
out float4 v_CenterY : TEXCOORD1,
out float4 v_IndexX : TEXCOORD2,
out float4 v_IndexY : TEXCOORD3)
{
out_Position = float4(a_Vertex, 0.0, 1.0);
float4 offsets = float4(0.5, -0.5, 0.015625, -0.015625);
float4 zoomscale = float4(u_ZoomSettings[2][0],
u_ZoomSettings[2][1],
u_ZoomSettings[2][2],
u_ZoomSettings[2][3]);
float4 zoomtx = float4(u_ZoomSettings[0][0],
u_ZoomSettings[0][1],
u_ZoomSettings[0][2],
u_ZoomSettings[0][3]);
float4 zoomty = float4(u_ZoomSettings[1][0],
u_ZoomSettings[1][1],
u_ZoomSettings[1][2],
u_ZoomSettings[1][3]);
v_CenterX = zoomscale * a_TexCoord.x + zoomtx
+ offsets.xyxy * u_TexelSize.x;
v_CenterY = zoomscale * a_TexCoord.y - zoomty
+ offsets.xyyx * u_TexelSize.y;
v_IndexX = v_CenterX * u_ScreenSize.z - offsets.zwzw;
v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;
}

[frag.hlsl]

void main(in float4 v_CenterX : TEXCOORD0,
in float4 v_CenterY : TEXCOORD1,
in float4 v_IndexX : TEXCOORD2,
in float4 v_IndexY : TEXCOORD3,
uniform float4 u_TexelSize,
uniform sampler2D u_Texture,
out float4 out_FragColor : COLOR)
{
float4 v05 = float4(0.5, 0.5, 0.5, 0.5);
float4 rx, ry, t0, dx, dy, dd;
rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);
ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);
t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
dx = rx - v_CenterX;
dy = ry - v_CenterY;
dd = t0 / (0.000001 + (dx * dx) + (dy * dy));
ry = ry * 0.25 + float4(0.0, 0.25, 0.5, 0.75);
float2 t1 = step(dd.xz, dd.yw);
float4 ret = lerp(float4(rx.xz, ry.xz),
float4(rx.yw, ry.yw), t1.xyxy);
dd.xy = lerp(dd.xz, dd.yw, t1);
float t2 = step(dd.x, dd.y);
ret.xy = lerp(ret.xz, ret.yw, t2);
out_FragColor = tex2D(u_Texture, ret.xy);
}


Načítá se…
Zrušit
Uložit