rbgl 0.1.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +20 -2
- data/README.md +130 -74
- data/Rakefile +7 -0
- data/bench/renderer_bench.rb +283 -0
- data/docs/.nojekyll +1 -0
- data/docs/index.html +38 -0
- data/examples/array_test.rb +1 -1
- data/examples/color_test.rb +1 -1
- data/examples/cube_spinning.rb +1 -1
- data/examples/gradient.rb +1 -1
- data/examples/multi_return_test.rb +1 -1
- data/examples/plasma.rb +1 -1
- data/examples/sphere_raymarch.rb +1 -1
- data/examples/triangle_window.rb +1 -1
- data/exe/rbgl +42 -0
- data/lib/rbgl/cli/doctor.rb +155 -0
- data/lib/rbgl/engine/buffer.rb +150 -40
- data/lib/rbgl/engine/clip_space_clipper.rb +163 -0
- data/lib/rbgl/engine/context.rb +133 -63
- data/lib/rbgl/engine/framebuffer.rb +153 -48
- data/lib/rbgl/engine/immutable_color.rb +32 -0
- data/lib/rbgl/engine/pipeline.rb +38 -7
- data/lib/rbgl/engine/rasterizer/attribute_interpolator.rb +195 -0
- data/lib/rbgl/engine/rasterizer/line_renderer.rb +88 -0
- data/lib/rbgl/engine/rasterizer/point_renderer.rb +35 -0
- data/lib/rbgl/engine/rasterizer/triangle_renderer.rb +136 -0
- data/lib/rbgl/engine/rasterizer.rb +65 -171
- data/lib/rbgl/engine/shader/base_shader.rb +51 -0
- data/lib/rbgl/engine/shader/builtins.rb +257 -0
- data/lib/rbgl/engine/shader/dynamic_data.rb +73 -0
- data/lib/rbgl/engine/shader.rb +5 -318
- data/lib/rbgl/engine/texture.rb +264 -51
- data/lib/rbgl/engine.rb +4 -1
- data/lib/rbgl/gui/backend.rb +21 -34
- data/lib/rbgl/gui/backend_factory.rb +89 -0
- data/lib/rbgl/gui/cocoa/backend.rb +59 -46
- data/lib/rbgl/gui/cocoa/key_mapper.rb +48 -0
- data/lib/rbgl/gui/event.rb +4 -2
- data/lib/rbgl/gui/file_backend/bmp_writer.rb +63 -0
- data/lib/rbgl/gui/file_backend/frame_writer.rb +35 -0
- data/lib/rbgl/gui/file_backend/png_writer.rb +18 -0
- data/lib/rbgl/gui/file_backend/ppm_writer.rb +26 -0
- data/lib/rbgl/gui/file_backend.rb +50 -55
- data/lib/rbgl/gui/wayland/backend.rb +214 -60
- data/lib/rbgl/gui/wayland/codec.rb +50 -0
- data/lib/rbgl/gui/wayland/connection.rb +188 -231
- data/lib/rbgl/gui/wayland/event_dispatcher.rb +165 -0
- data/lib/rbgl/gui/wayland/global_binder.rb +46 -0
- data/lib/rbgl/gui/wayland/input_mapper.rb +61 -0
- data/lib/rbgl/gui/wayland/protocol_objects/arguments.rb +63 -0
- data/lib/rbgl/gui/wayland/protocol_objects/display.rb +54 -0
- data/lib/rbgl/gui/wayland/protocol_objects/seat.rb +115 -0
- data/lib/rbgl/gui/wayland/protocol_objects/shm.rb +157 -0
- data/lib/rbgl/gui/wayland/protocol_objects/surface.rb +33 -0
- data/lib/rbgl/gui/wayland/protocol_objects/xdg_shell.rb +60 -0
- data/lib/rbgl/gui/wayland/protocol_objects.rb +8 -0
- data/lib/rbgl/gui/window/event_dispatcher.rb +30 -0
- data/lib/rbgl/gui/window/render_loop.rb +111 -0
- data/lib/rbgl/gui/window.rb +74 -84
- data/lib/rbgl/gui/x11/atom_cache.rb +29 -0
- data/lib/rbgl/gui/x11/backend.rb +73 -49
- data/lib/rbgl/gui/x11/connection.rb +284 -219
- data/lib/rbgl/gui/x11/event_parser.rb +71 -0
- data/lib/rbgl/gui/x11/key_mapper.rb +48 -0
- data/lib/rbgl/gui/x11/pixel_encoder.rb +164 -0
- data/lib/rbgl/gui/x11/request_encoder.rb +155 -0
- data/lib/rbgl/gui/x11/setup_parser.rb +138 -0
- data/lib/rbgl/gui/x11/transport.rb +81 -0
- data/lib/rbgl/gui/x11/x_authority.rb +107 -0
- data/lib/rbgl/gui.rb +3 -5
- data/lib/rbgl/version.rb +1 -1
- metadata +63 -24
- data/examples/chemical_heartbeat.rb +0 -166
- data/examples/dark_transit.rb +0 -166
- data/examples/fractured_orb.rb +0 -428
- data/examples/fractured_orb_rb.rb +0 -598
- data/examples/hexagonal_flow.rb +0 -333
- data/examples/teapot.rb +0 -362
- data/examples/teapot_mcu.rb +0 -344
data/examples/teapot_mcu.rb
DELETED
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Teapot - Raymarched Bezier Curves (Metal Compute Shader)
|
|
4
|
-
# Original: https://www.shadertoy.com/view/MdKcDw
|
|
5
|
-
# GPU-accelerated version
|
|
6
|
-
# License: Creative Commons Attribution-NonCommercial-ShareAlike 3.0
|
|
7
|
-
# https://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
|
|
8
|
-
|
|
9
|
-
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
10
|
-
|
|
11
|
-
require "rbgl"
|
|
12
|
-
require "rlsl"
|
|
13
|
-
|
|
14
|
-
WIDTH = 640
|
|
15
|
-
HEIGHT = 480
|
|
16
|
-
|
|
17
|
-
# Generate control points as Metal constants
|
|
18
|
-
def generate_teapot_constants
|
|
19
|
-
body = [
|
|
20
|
-
[0.0, 0.0], [0.64, 0.0], [0.64, 0.03],
|
|
21
|
-
[0.8, 0.12], [0.8, 0.3], [0.8, 0.48],
|
|
22
|
-
[0.64, 0.9], [0.6, 0.93], [0.56, 0.9],
|
|
23
|
-
[0.56, 0.96], [0.12, 1.02], [0.0, 1.05],
|
|
24
|
-
[0.16, 1.14], [0.2, 1.2], [0.0, 1.2]
|
|
25
|
-
]
|
|
26
|
-
spout = [
|
|
27
|
-
[1.16, 0.96], [1.04, 0.9], [1.0, 0.72],
|
|
28
|
-
[0.92, 0.48], [0.72, 0.42]
|
|
29
|
-
]
|
|
30
|
-
handle = [
|
|
31
|
-
[-0.6, 0.78], [-1.16, 0.84], [-1.16, 0.63],
|
|
32
|
-
[-1.2, 0.42], [-0.72, 0.24]
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
body_init = body.map.with_index { |(x, y), i| "constant float2 A#{i} = float2(#{x}f, #{y}f);" }.join("\n")
|
|
36
|
-
spout_init = spout.map.with_index { |(x, y), i| "constant float2 T1_#{i} = float2(#{x}f, #{y}f);" }.join("\n")
|
|
37
|
-
handle_init = handle.map.with_index { |(x, y), i| "constant float2 T2_#{i} = float2(#{x}f, #{y}f);" }.join("\n")
|
|
38
|
-
|
|
39
|
-
<<~MSL
|
|
40
|
-
// Control points as constants
|
|
41
|
-
#{body_init}
|
|
42
|
-
#{spout_init}
|
|
43
|
-
#{handle_init}
|
|
44
|
-
|
|
45
|
-
// Pre-computed: normalize(float3(1.0f, 0.72f, 1.0f))
|
|
46
|
-
constant float3 L = float3(0.6302f, 0.4537f, 0.6302f);
|
|
47
|
-
constant float3 Y_VEC = float3(0.0f, 1.0f, 0.0f);
|
|
48
|
-
|
|
49
|
-
// Material properties
|
|
50
|
-
constant float2 lo = float2(0.450f, 0.048f);
|
|
51
|
-
constant float2 alpha_m = float2(0.045f, 0.068f);
|
|
52
|
-
constant float3 Scale = float3(1.0f, 20.0f, 10.0f);
|
|
53
|
-
constant float3 surfaceColor = float3(0.45f, 0.54f, 1.0f);
|
|
54
|
-
constant float ONE_OVER_PI = 0.31830988618f;
|
|
55
|
-
MSL
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
shader = RLSL.define_metal(:teapot_metal) do
|
|
59
|
-
uniforms do
|
|
60
|
-
float :time
|
|
61
|
-
vec2 :mouse
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
helpers(:c) do
|
|
65
|
-
teapot_constants = generate_teapot_constants
|
|
66
|
-
|
|
67
|
-
<<~MSL
|
|
68
|
-
#{teapot_constants}
|
|
69
|
-
|
|
70
|
-
// Cross product 2D
|
|
71
|
-
#define U(a,b) ((a).x*(b).y-(b).x*(a).y)
|
|
72
|
-
|
|
73
|
-
// Distance to quadratic Bezier curve
|
|
74
|
-
float2 bezier_dist(float2 m, float2 n, float2 o, float3 p) {
|
|
75
|
-
float2 q = float2(p.x, p.y);
|
|
76
|
-
m = m - q;
|
|
77
|
-
n = n - q;
|
|
78
|
-
o = o - q;
|
|
79
|
-
|
|
80
|
-
float x = U(m, o);
|
|
81
|
-
float y = 2.0f * U(n, m);
|
|
82
|
-
float z = 2.0f * U(o, n);
|
|
83
|
-
|
|
84
|
-
float2 i = o - m;
|
|
85
|
-
float2 j = o - n;
|
|
86
|
-
float2 k = n - m;
|
|
87
|
-
|
|
88
|
-
float2 s = float2(
|
|
89
|
-
2.0f * (x * i.x + y * j.x + z * k.x),
|
|
90
|
-
2.0f * (x * i.y + y * j.y + z * k.y)
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
float dot_s = dot(s, s);
|
|
94
|
-
if (dot_s < 1e-10f) dot_s = 1e-10f;
|
|
95
|
-
|
|
96
|
-
float2 r = float2(
|
|
97
|
-
m.x + (y * z - x * x) * s.y / dot_s,
|
|
98
|
-
m.y - (y * z - x * x) * s.x / dot_s
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
float denom = x + x + y + z;
|
|
102
|
-
if (abs(denom) < 1e-10f) denom = 1e-10f;
|
|
103
|
-
|
|
104
|
-
float t = clamp((U(r, i) + 2.0f * U(k, r)) / denom, 0.0f, 1.0f);
|
|
105
|
-
|
|
106
|
-
float2 jk = j - k;
|
|
107
|
-
r.x = m.x + t * (k.x + k.x + t * jk.x);
|
|
108
|
-
r.y = m.y + t * (k.y + k.y + t * jk.y);
|
|
109
|
-
|
|
110
|
-
return float2(sqrt(dot(r, r) + p.z * p.z), t);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Smooth minimum for blending
|
|
114
|
-
float smin(float a, float b, float k) {
|
|
115
|
-
float h = clamp(0.5f + 0.5f * (b - a) / k, 0.0f, 1.0f);
|
|
116
|
-
return mix(b, a, h) - k * h * (1.0f - h);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Scene distance function
|
|
120
|
-
float scene_dist(float3 p) {
|
|
121
|
-
// Spout
|
|
122
|
-
float2 h = bezier_dist(T1_2, T1_3, T1_4, p);
|
|
123
|
-
|
|
124
|
-
// Handle
|
|
125
|
-
float handle_d = min(
|
|
126
|
-
bezier_dist(T2_0, T2_1, T2_2, p).x,
|
|
127
|
-
bezier_dist(T2_2, T2_3, T2_4, p).x
|
|
128
|
-
) - 0.06f;
|
|
129
|
-
|
|
130
|
-
// Spout
|
|
131
|
-
float spout_hole = abs(bezier_dist(T1_0, T1_1, T1_2, p).x - 0.07f) - 0.01f;
|
|
132
|
-
float spout_body = h.x * (1.0f - 0.75f * h.y) - 0.08f;
|
|
133
|
-
float spout_d = max(p.y - 0.9f, min(spout_hole, spout_body));
|
|
134
|
-
|
|
135
|
-
float b = min(handle_d, spout_d);
|
|
136
|
-
|
|
137
|
-
// Body (rotation symmetry)
|
|
138
|
-
float r_xz = sqrt(p.x * p.x + p.z * p.z);
|
|
139
|
-
float3 qq = float3(r_xz, p.y, 0.0f);
|
|
140
|
-
|
|
141
|
-
float a = 99.0f;
|
|
142
|
-
a = min(a, (bezier_dist(A0, A1, A2, qq).x - 0.015f) * 0.7f);
|
|
143
|
-
a = min(a, (bezier_dist(A2, A3, A4, qq).x - 0.015f) * 0.7f);
|
|
144
|
-
a = min(a, (bezier_dist(A4, A5, A6, qq).x - 0.015f) * 0.7f);
|
|
145
|
-
a = min(a, (bezier_dist(A6, A7, A8, qq).x - 0.015f) * 0.7f);
|
|
146
|
-
a = min(a, (bezier_dist(A8, A9, A10, qq).x - 0.015f) * 0.7f);
|
|
147
|
-
a = min(a, (bezier_dist(A10, A11, A12, qq).x - 0.015f) * 0.7f);
|
|
148
|
-
a = min(a, (bezier_dist(A12, A13, A14, qq).x - 0.015f) * 0.7f);
|
|
149
|
-
|
|
150
|
-
return smin(a, b, 0.02f);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Normal calculation
|
|
154
|
-
float3 calc_normal(float3 p, float3 ray, float t, float res_x) {
|
|
155
|
-
float eps = 0.4f * t / res_x;
|
|
156
|
-
|
|
157
|
-
float d0 = scene_dist(p);
|
|
158
|
-
float dx = scene_dist(p + float3(eps, 0.0f, 0.0f)) - d0;
|
|
159
|
-
float dy = scene_dist(p + float3(0.0f, eps, 0.0f)) - d0;
|
|
160
|
-
float dz = scene_dist(p + float3(0.0f, 0.0f, eps)) - d0;
|
|
161
|
-
|
|
162
|
-
float3 grad = float3(dx, dy, dz);
|
|
163
|
-
|
|
164
|
-
float d = dot(grad, ray);
|
|
165
|
-
if (d > 0.0f) {
|
|
166
|
-
grad = grad - ray * d;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return normalize(grad);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Build orthonormal basis
|
|
173
|
-
void basis(float3 n, thread float3* xp, thread float3* yp) {
|
|
174
|
-
float a = n.y / (1.0f + n.z + 1e-10f);
|
|
175
|
-
float b = n.y * a;
|
|
176
|
-
float c = -n.x * a;
|
|
177
|
-
*xp = float3(n.z + b, c, -n.x);
|
|
178
|
-
*yp = float3(c, 1.0f - b, -n.y);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// BRDF
|
|
182
|
-
float3 compute_brdf(float3 n, float3 l, float3 h, float3 r, float3 tang, float3 binorm) {
|
|
183
|
-
float e1 = dot(h, tang) / alpha_m.x;
|
|
184
|
-
float e2 = dot(h, binorm) / alpha_m.y;
|
|
185
|
-
float hn = dot(h, n);
|
|
186
|
-
float E = -2.0f * ((e1 * e1 + e2 * e2) / (1.0f + hn));
|
|
187
|
-
|
|
188
|
-
float cos_i = dot(n, l);
|
|
189
|
-
float cos_r = dot(n, r);
|
|
190
|
-
float denom = sqrt(abs(cos_i * cos_r) + 1e-6f);
|
|
191
|
-
|
|
192
|
-
float brdf = lo.x * ONE_OVER_PI +
|
|
193
|
-
lo.y * (1.0f / denom) * (1.0f / (4.0f * 3.14159265f * alpha_m.x * alpha_m.y)) * exp(E);
|
|
194
|
-
|
|
195
|
-
float intensity = Scale.x * lo.x * ONE_OVER_PI +
|
|
196
|
-
Scale.y * lo.y * cos_i * brdf +
|
|
197
|
-
Scale.z * hn * lo.y;
|
|
198
|
-
|
|
199
|
-
return surfaceColor * intensity;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// HSV to RGB
|
|
203
|
-
float3 hsv2rgb_smooth(float h, float s, float v) {
|
|
204
|
-
float3 rgb = float3(
|
|
205
|
-
abs(fmod(h * 6.0f + 0.0f, 6.0f) - 3.0f) - 1.0f,
|
|
206
|
-
abs(fmod(h * 6.0f + 4.0f, 6.0f) - 3.0f) - 1.0f,
|
|
207
|
-
abs(fmod(h * 6.0f + 2.0f, 6.0f) - 3.0f) - 1.0f
|
|
208
|
-
);
|
|
209
|
-
rgb = clamp(rgb, 0.0f, 1.0f);
|
|
210
|
-
rgb = rgb * rgb * (3.0f - 2.0f * rgb);
|
|
211
|
-
|
|
212
|
-
return float3(
|
|
213
|
-
v * (1.0f + s * (rgb.x - 1.0f)),
|
|
214
|
-
v * (1.0f + s * (rgb.y - 1.0f)),
|
|
215
|
-
v * (1.0f + s * (rgb.z - 1.0f))
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
MSL
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
fragment do
|
|
222
|
-
<<~MSL
|
|
223
|
-
float2 q = float2(uv.x * resolution.y / resolution.x, uv.y);
|
|
224
|
-
float2 p = q * 2.0f - float2(1.0f, 1.0f);
|
|
225
|
-
p.x *= resolution.x / resolution.y;
|
|
226
|
-
|
|
227
|
-
// Camera with mouse control
|
|
228
|
-
float mouse_x = u.mouse.x / resolution.x;
|
|
229
|
-
float mouse_y = u.mouse.y / resolution.y;
|
|
230
|
-
float cam_angle = 5.0f + 0.2f * u.time + 4.0f * mouse_x;
|
|
231
|
-
|
|
232
|
-
float3 origin = float3(cos(cam_angle), 0.7f - mouse_y, sin(cam_angle)) * 3.5f;
|
|
233
|
-
float3 w = normalize(Y_VEC * 0.4f - origin);
|
|
234
|
-
float3 cam_u = normalize(cross(w, Y_VEC));
|
|
235
|
-
float3 cam_v = cross(cam_u, w);
|
|
236
|
-
|
|
237
|
-
float3 ray = normalize(cam_u * p.x + cam_v * p.y + w + w);
|
|
238
|
-
|
|
239
|
-
// Raymarching
|
|
240
|
-
float t = 0.0f;
|
|
241
|
-
float h = 0.1f;
|
|
242
|
-
for (int i = 0; i < 48; i++) {
|
|
243
|
-
if (h < 0.0001f || t > 4.7f) break;
|
|
244
|
-
h = scene_dist(origin + ray * t);
|
|
245
|
-
t += h;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Background
|
|
249
|
-
float3 color = mix(
|
|
250
|
-
hsv2rgb_smooth(0.5f + u.time * 0.02f, 0.35f, 0.4f),
|
|
251
|
-
hsv2rgb_smooth(-0.5f + u.time * 0.02f, 0.35f, 0.7f),
|
|
252
|
-
q.y
|
|
253
|
-
);
|
|
254
|
-
|
|
255
|
-
if (h < 0.001f) {
|
|
256
|
-
float3 hit = origin + ray * t;
|
|
257
|
-
float3 n = calc_normal(hit, ray, t, resolution.x);
|
|
258
|
-
|
|
259
|
-
float3 V = normalize(origin - hit);
|
|
260
|
-
float3 H = normalize(L + V);
|
|
261
|
-
float3 R = normalize(n * 2.0f * dot(n, L) - L);
|
|
262
|
-
|
|
263
|
-
float3 tang, binorm;
|
|
264
|
-
basis(n, &tang, &binorm);
|
|
265
|
-
|
|
266
|
-
color = compute_brdf(n, L, H, R, tang, binorm);
|
|
267
|
-
|
|
268
|
-
// Shadows
|
|
269
|
-
float shadow = 1.0f;
|
|
270
|
-
float j = 0.0f;
|
|
271
|
-
for (int i = 0; i < 20; i++) {
|
|
272
|
-
j += 0.02f;
|
|
273
|
-
shadow = min(shadow, scene_dist(hit + L * j) / j);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Vignette
|
|
278
|
-
float vignette = pow(16.0f * q.x * q.y * (1.0f - q.x) * (1.0f - q.y), 0.16f);
|
|
279
|
-
color = color * vignette;
|
|
280
|
-
|
|
281
|
-
return color;
|
|
282
|
-
MSL
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
# Initialize display
|
|
287
|
-
window = RBGL::GUI::Window.new(width: WIDTH, height: HEIGHT, title: "Teapot Metal (GPU)")
|
|
288
|
-
|
|
289
|
-
puts "Teapot Metal - GPU Compute Shader"
|
|
290
|
-
puts "Original: https://www.shadertoy.com/view/MdKcDw"
|
|
291
|
-
puts "License: Creative Commons Attribution-NonCommercial-ShareAlike 3.0"
|
|
292
|
-
puts "https://creativecommons.org/licenses/by-nc-sa/3.0/deed.en"
|
|
293
|
-
puts "Move mouse to rotate camera"
|
|
294
|
-
puts "Press 'q' or Escape to quit"
|
|
295
|
-
|
|
296
|
-
# Check Metal availability
|
|
297
|
-
unless window.metal_available?
|
|
298
|
-
puts "Metal compute is NOT available"
|
|
299
|
-
exit 1
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
puts "Metal compute is available!"
|
|
303
|
-
|
|
304
|
-
start_time = Time.now
|
|
305
|
-
frame_count = 0
|
|
306
|
-
last_fps_time = start_time
|
|
307
|
-
running = true
|
|
308
|
-
mouse_x = 0.0
|
|
309
|
-
mouse_y = 0.0
|
|
310
|
-
|
|
311
|
-
while running && !window.should_close?
|
|
312
|
-
time = Time.now - start_time
|
|
313
|
-
|
|
314
|
-
begin
|
|
315
|
-
shader.render_metal(window.native_handle, WIDTH, HEIGHT, { time: time, mouse: [mouse_x, mouse_y] })
|
|
316
|
-
rescue => e
|
|
317
|
-
puts "Error: #{e.message}"
|
|
318
|
-
puts e.backtrace.first(10).join("\n")
|
|
319
|
-
running = false
|
|
320
|
-
break
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
events = window.poll_events_raw
|
|
324
|
-
events.each do |e|
|
|
325
|
-
case e[:type]
|
|
326
|
-
when :key_press
|
|
327
|
-
running = false if e[:key] == 12 || e[:key] == "q"
|
|
328
|
-
when :mouse_move
|
|
329
|
-
mouse_x = e[:x].to_f
|
|
330
|
-
mouse_y = e[:y].to_f
|
|
331
|
-
end
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
frame_count += 1
|
|
335
|
-
now = Time.now
|
|
336
|
-
if now - last_fps_time >= 1.0
|
|
337
|
-
fps = frame_count / (now - last_fps_time)
|
|
338
|
-
puts "FPS: #{fps.round(1)}"
|
|
339
|
-
frame_count = 0
|
|
340
|
-
last_fps_time = now
|
|
341
|
-
end
|
|
342
|
-
end
|
|
343
|
-
|
|
344
|
-
window.close
|