2025-12-07 20:21:26 -06:00

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