Explorar el Código

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 hace 10 años
padre
commit
2149187abd
Se han modificado 2 ficheros con 75 adiciones y 127 borrados
  1. +39
    -28
      doc/tutorial/11_fractal.cpp
  2. +36
    -99
      doc/tutorial/11_fractal.lolfx

+ 39
- 28
doc/tutorial/11_fractal.cpp Ver fichero

@@ -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 Ver fichero

@@ -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);
}


Cargando…
Cancelar
Guardar