95 lines
2.0 KiB
GLSL
95 lines
2.0 KiB
GLSL
#version 330 core
|
|
|
|
out vec4 fragment_color;
|
|
|
|
uniform sampler2D tex_sampler;
|
|
uniform vec4 tex_size; // w h halfpx_w halfpx_h
|
|
uniform float input_length;
|
|
|
|
vec2 rectangular_position(float ix)
|
|
{
|
|
float y = floor(ix * tex_size.z * 2.0);
|
|
float x = ix - tex_size.x * y;
|
|
|
|
return vec2((x * 2.0 + 1) * tex_size.z,
|
|
(y * 2.0 + 1) * tex_size.w);
|
|
}
|
|
|
|
const float ascii_zero = 48.0;
|
|
const float ascii_nine = 57.0;
|
|
const float ascii_l = 76.0;
|
|
|
|
float get_input(float ix)
|
|
{
|
|
return texture(tex_sampler, rectangular_position(ix)).x * 255.0;
|
|
}
|
|
|
|
vec2 parse_integer(float ix)
|
|
{
|
|
float number = 0;
|
|
|
|
while (ix < input_length) {
|
|
float c = get_input(ix);
|
|
if (c < ascii_zero || c > ascii_nine) {
|
|
return vec2(ix + 1.0, number);
|
|
}
|
|
float digit = c - ascii_zero;
|
|
number = number * 10.0 + digit;
|
|
ix += 1.0;
|
|
}
|
|
}
|
|
|
|
vec2 parse_direction(float ix)
|
|
{
|
|
float c = get_input(ix);
|
|
float direction = (c == ascii_l) ? -1.0 : 1.0;
|
|
return vec2(ix + 1.0, direction);
|
|
}
|
|
|
|
vec3 simulate_movement(float ix, float position)
|
|
{
|
|
vec2 dir_result = parse_direction(ix);
|
|
ix = dir_result.x;
|
|
float direction = dir_result.y;
|
|
|
|
vec2 int_result = parse_integer(ix);
|
|
ix = int_result.x;
|
|
float number = int_result.y;
|
|
|
|
float old_position = position;
|
|
float crossings = floor(number / 100.0);
|
|
position += direction * mod(number, 100.0);
|
|
if (position < 0.0) {
|
|
position += 100.0;
|
|
crossings += float(old_position != 0.0);
|
|
}
|
|
if (position > 99.0) {
|
|
position -= 100.0;
|
|
crossings += float(position != 0.0);
|
|
}
|
|
crossings += float(position == 0.0);
|
|
|
|
return vec3(ix, position, crossings);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
float ix = 0.0;
|
|
float position = 50.0;
|
|
float zeros = 0.0;
|
|
float zero_crossings = 0.0;
|
|
|
|
while (ix < input_length) {
|
|
vec3 result = simulate_movement(ix, position);
|
|
ix = result.x;
|
|
position = result.y;
|
|
zero_crossings += result.z;
|
|
|
|
if (position == 0.0) {
|
|
zeros += 1.0;
|
|
}
|
|
}
|
|
|
|
fragment_color = vec4(zeros, zero_crossings, 0, 0);
|
|
}
|