Input was broken, as well as palette generation, and even texture upload. Should be all good now.legacy
@@ -1,7 +1,7 @@ | |||||
// | // | ||||
// Lol Engine — Fractal tutorial | // 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 | // Lol Engine is free software. It comes without any warranty, to | ||||
// the extent permitted by applicable law. You can redistribute it | // 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_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_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 | /* Window size decides the world aspect ratio. For instance, 640×480 | ||||
* will be mapped to (-0.66,-0.5) - (0.66,0.5). */ | * will be mapped to (-0.66,-0.5) - (0.66,0.5). */ | ||||
#if !defined __native_client__ | #if !defined __native_client__ | ||||
@@ -74,21 +81,19 @@ public: | |||||
{ | { | ||||
double f = (double)i / PALETTE_STEP; | 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) | 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__ | #if defined __native_client__ | ||||
m_palette.push(u8vec4(red, green, blue, 255)); | m_palette.push(u8vec4(red, green, blue, 255)); | ||||
#else | #else | ||||
@@ -113,7 +118,6 @@ public: | |||||
m_position = vec3::zero; | m_position = vec3::zero; | ||||
m_aabb.aa = m_position; | m_aabb.aa = m_position; | ||||
m_aabb.bb = vec3((vec2)m_window_size, 0); | m_aabb.bb = vec3((vec2)m_window_size, 0); | ||||
//Input::TrackMouse(this); | |||||
#if LOL_FEATURE_THREADS | #if LOL_FEATURE_THREADS | ||||
/* Spawn worker threads and wait for their readiness. */ | /* Spawn worker threads and wait for their readiness. */ | ||||
@@ -163,7 +167,7 @@ public: | |||||
{ | { | ||||
WorldEntity::TickGame(seconds); | WorldEntity::TickGame(seconds); | ||||
ivec2 mousepos = ivec2::zero; /* FIXME: input */ | |||||
ivec2 mousepos = m_mouse->GetCursorPixel(0); | |||||
int prev_frame = (m_frame + 4) % 4; | int prev_frame = (m_frame + 4) % 4; | ||||
m_frame = (m_frame + 1) % 4; | m_frame = (m_frame + 1) % 4; | ||||
@@ -171,9 +175,7 @@ public: | |||||
rcmplx worldmouse = m_center | rcmplx worldmouse = m_center | ||||
+ rcmplx(ScreenToWorldOffset((vec2)mousepos)); | + rcmplx(ScreenToWorldOffset((vec2)mousepos)); | ||||
uint32_t buttons = 0; | |||||
//uint32_t buttons = Input::GetMouseButtons(); | |||||
if (buttons & 0x2) | |||||
if (m_controller->IsKeyPressed(2)) | |||||
{ | { | ||||
if (!m_drag) | 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; | m_zoom_speed += zoom * seconds; | ||||
if (m_zoom_speed / zoom > 5e-3f) | if (m_zoom_speed / zoom > 5e-3f) | ||||
m_zoom_speed = zoom * 5e-3f; | m_zoom_speed = zoom * 5e-3f; | ||||
@@ -308,7 +312,7 @@ public: | |||||
} | } | ||||
#if LOL_FEATURE_THREADS | #if LOL_FEATURE_THREADS | ||||
void DoWorkHelper(thread *inst) | |||||
void DoWorkHelper(thread *) | |||||
{ | { | ||||
m_spawnqueue.push(0); | m_spawnqueue.push(0); | ||||
for ( ; ; ) | for ( ; ; ) | ||||
@@ -332,8 +336,8 @@ public: | |||||
int jmax = jmin + MAX_LINES * 2; | int jmax = jmin + MAX_LINES * 2; | ||||
if (jmax > m_size.y) | if (jmax > m_size.y) | ||||
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; | dcmplx c = (dcmplx)m_center; | ||||
@@ -404,11 +408,11 @@ public: | |||||
+ 2.024664188044341212602376988171727038739) * k | + 2.024664188044341212602376988171727038739) * k | ||||
- 1.674876738008591047163498125918330313237; | - 1.674876738008591047163498125918330313237; | ||||
*m_pixelstart++ = m_palette[(int)(f * PALETTE_STEP)]; | |||||
*pixelstart++ = m_palette[(int)(f * PALETTE_STEP)]; | |||||
} | } | ||||
else | 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_vertexattrib = m_shader->GetAttribLocation(VertexUsage::Position, 0); | ||||
m_texattrib = m_shader->GetAttribLocation(VertexUsage::TexCoord, 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 = | m_vdecl = | ||||
new VertexDeclaration(VertexStream<vec2>(VertexUsage::Position), | new VertexDeclaration(VertexStream<vec2>(VertexUsage::Position), | ||||
@@ -491,6 +496,7 @@ public: | |||||
} | } | ||||
m_shader->Bind(); | m_shader->Bind(); | ||||
m_shader->SetUniform(m_texuni, m_texture->GetTextureUniform(), 0); | |||||
m_shader->SetUniform(m_texeluni, m_texel_settings); | m_shader->SetUniform(m_texeluni, m_texel_settings); | ||||
m_shader->SetUniform(m_screenuni, m_screen_settings); | m_shader->SetUniform(m_screenuni, m_screen_settings); | ||||
m_shader->SetUniform(m_zoomuni, m_zoom_settings); | m_shader->SetUniform(m_zoomuni, m_zoom_settings); | ||||
@@ -515,7 +521,7 @@ private: | |||||
Shader *m_shader; | Shader *m_shader; | ||||
ShaderAttrib m_vertexattrib, m_texattrib; | ShaderAttrib m_vertexattrib, m_texattrib; | ||||
ShaderUniform m_texeluni, m_screenuni, m_zoomuni; | |||||
ShaderUniform m_texuni, m_texeluni, m_screenuni, m_zoomuni; | |||||
VertexDeclaration *m_vdecl; | VertexDeclaration *m_vdecl; | ||||
VertexBuffer *m_vbo, *m_tbo; | VertexBuffer *m_vbo, *m_tbo; | ||||
@@ -531,6 +537,11 @@ private: | |||||
vec4 m_texel_settings, m_screen_settings; | vec4 m_texel_settings, m_screen_settings; | ||||
mat4 m_zoom_settings; | mat4 m_zoom_settings; | ||||
// Input support | |||||
InputDevice *m_mouse; | |||||
Controller *m_controller; | |||||
InputProfile m_profile; | |||||
#if LOL_FEATURE_THREADS | #if LOL_FEATURE_THREADS | ||||
/* Worker threads */ | /* Worker threads */ | ||||
thread *m_threads[MAX_THREADS]; | thread *m_threads[MAX_THREADS]; | ||||
@@ -548,7 +559,7 @@ int main(int argc, char **argv) | |||||
ivec2 window_size(640, 480); | ivec2 window_size(640, 480); | ||||
sys::init(argc, argv); | 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 DebugFps(5, 5); | ||||
new Fractal(window_size); | new Fractal(window_size); | ||||
@@ -1,15 +1,15 @@ | |||||
[vert.glsl] | [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_TexCoord; | ||||
attribute vec2 in_Position; | 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) | void main(void) | ||||
{ | { | ||||
@@ -21,55 +21,55 @@ void main(void) | |||||
* size of a texel: the distance from this new point to | * size of a texel: the distance from this new point to | ||||
* the final point will be our error. */ | * the final point will be our error. */ | ||||
vec4 offsets = vec4(0.5, -0.5, 0.015625, -0.015625); | 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 | /* Precompute the multiple of one texel where our ideal | ||||
* point lies. The fragment shader will call floor() on | * point lies. The fragment shader will call floor() on | ||||
* this value. We add or remove a slight offset to avoid | * this value. We add or remove a slight offset to avoid | ||||
* rounding issues at the image's edges. */ | * 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] | [frag.glsl] | ||||
#version 120 | |||||
#version 130 | |||||
#if defined GL_ES | #if defined GL_ES | ||||
precision highp float; | precision highp float; | ||||
#endif | #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) | void main(void) | ||||
{ | { | ||||
vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5); | vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5); | ||||
vec4 rx, ry, t0, dx, dy, dd; | vec4 rx, ry, t0, dx, dy, dd; | ||||
/* Get a pixel coordinate from each slice into rx & ry */ | /* 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, | /* Compute inverse distance to expected pixel in dd, | ||||
* and put zero if we fall outside the texture. */ | * and put zero if we fall outside the texture. */ | ||||
t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05); | 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 | #if 0 | ||||
vec4 dd = t0 * (abs(dx) + abs(dy)); | vec4 dd = t0 * (abs(dx) + abs(dy)); | ||||
vec4 dd = t0 / (0.001 + sqrt((dx * dx) + (dy * 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; | ret.xy = ret.xz * t2.yy + ret.yw * t2.xx; | ||||
# endif | # endif | ||||
/* Nearest neighbour */ | /* Nearest neighbour */ | ||||
gl_FragColor = texture2D(u_Texture, ret.xy); | |||||
gl_FragColor = texture2D(u_texture, ret.xy); | |||||
#else | #else | ||||
/* Alternate version: some kind of linear interpolation */ | /* 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) | gl_FragColor = 1.0 / (dd.x + dd.y + dd.z + dd.w) | ||||
* (dd.x * p0 + dd.y * p1 + dd.z * p2 + dd.w * p3); | * (dd.x * p0 + dd.y * p1 + dd.z * p2 + dd.w * p3); | ||||
#endif | #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); | |||||
} | |||||