rbgl 1.0.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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +7 -1
  4. data/README.md +130 -74
  5. data/Rakefile +7 -0
  6. data/bench/renderer_bench.rb +283 -0
  7. data/docs/.nojekyll +1 -0
  8. data/docs/index.html +38 -0
  9. data/examples/array_test.rb +1 -1
  10. data/examples/color_test.rb +1 -1
  11. data/examples/cube_spinning.rb +1 -1
  12. data/examples/gradient.rb +1 -1
  13. data/examples/multi_return_test.rb +1 -1
  14. data/examples/plasma.rb +1 -1
  15. data/examples/sphere_raymarch.rb +1 -1
  16. data/examples/triangle_window.rb +1 -1
  17. data/exe/rbgl +42 -0
  18. data/lib/rbgl/cli/doctor.rb +155 -0
  19. data/lib/rbgl/engine/buffer.rb +49 -8
  20. data/lib/rbgl/engine/clip_space_clipper.rb +23 -3
  21. data/lib/rbgl/engine/context.rb +23 -6
  22. data/lib/rbgl/engine/framebuffer.rb +137 -41
  23. data/lib/rbgl/engine/immutable_color.rb +32 -0
  24. data/lib/rbgl/engine/rasterizer/attribute_interpolator.rb +100 -10
  25. data/lib/rbgl/engine/rasterizer/line_renderer.rb +30 -14
  26. data/lib/rbgl/engine/rasterizer/point_renderer.rb +3 -3
  27. data/lib/rbgl/engine/rasterizer/triangle_renderer.rb +72 -23
  28. data/lib/rbgl/engine/rasterizer.rb +3 -20
  29. data/lib/rbgl/engine/shader/base_shader.rb +3 -7
  30. data/lib/rbgl/engine/shader/builtins.rb +13 -10
  31. data/lib/rbgl/engine/shader/dynamic_data.rb +18 -10
  32. data/lib/rbgl/engine/texture.rb +74 -50
  33. data/lib/rbgl/engine.rb +3 -1
  34. data/lib/rbgl/gui/backend.rb +12 -7
  35. data/lib/rbgl/gui/backend_factory.rb +7 -3
  36. data/lib/rbgl/gui/cocoa/backend.rb +50 -17
  37. data/lib/rbgl/gui/cocoa/key_mapper.rb +48 -0
  38. data/lib/rbgl/gui/event.rb +4 -2
  39. data/lib/rbgl/gui/file_backend/bmp_writer.rb +2 -2
  40. data/lib/rbgl/gui/file_backend/frame_writer.rb +7 -0
  41. data/lib/rbgl/gui/file_backend/png_writer.rb +18 -0
  42. data/lib/rbgl/gui/file_backend/ppm_writer.rb +1 -0
  43. data/lib/rbgl/gui/file_backend.rb +24 -6
  44. data/lib/rbgl/gui/wayland/backend.rb +127 -55
  45. data/lib/rbgl/gui/wayland/codec.rb +7 -11
  46. data/lib/rbgl/gui/wayland/connection.rb +137 -20
  47. data/lib/rbgl/gui/wayland/event_dispatcher.rb +103 -12
  48. data/lib/rbgl/gui/wayland/global_binder.rb +6 -4
  49. data/lib/rbgl/gui/wayland/input_mapper.rb +61 -0
  50. data/lib/rbgl/gui/wayland/protocol_objects/arguments.rb +14 -2
  51. data/lib/rbgl/gui/wayland/protocol_objects/seat.rb +115 -0
  52. data/lib/rbgl/gui/wayland/protocol_objects/shm.rb +23 -12
  53. data/lib/rbgl/gui/wayland/protocol_objects/xdg_shell.rb +15 -0
  54. data/lib/rbgl/gui/wayland/protocol_objects.rb +1 -0
  55. data/lib/rbgl/gui/window/render_loop.rb +71 -18
  56. data/lib/rbgl/gui/window.rb +39 -8
  57. data/lib/rbgl/gui/x11/atom_cache.rb +4 -1
  58. data/lib/rbgl/gui/x11/backend.rb +66 -28
  59. data/lib/rbgl/gui/x11/connection.rb +216 -86
  60. data/lib/rbgl/gui/x11/event_parser.rb +13 -2
  61. data/lib/rbgl/gui/x11/key_mapper.rb +48 -0
  62. data/lib/rbgl/gui/x11/pixel_encoder.rb +164 -0
  63. data/lib/rbgl/gui/x11/request_encoder.rb +29 -28
  64. data/lib/rbgl/gui/x11/setup_parser.rb +138 -0
  65. data/lib/rbgl/gui/x11/transport.rb +52 -2
  66. data/lib/rbgl/gui/x11/x_authority.rb +107 -0
  67. data/lib/rbgl/gui.rb +2 -5
  68. data/lib/rbgl/version.rb +1 -1
  69. metadata +36 -24
  70. data/examples/chemical_heartbeat.rb +0 -166
  71. data/examples/dark_transit.rb +0 -166
  72. data/examples/fractured_orb.rb +0 -428
  73. data/examples/fractured_orb_rb.rb +0 -598
  74. data/examples/hexagonal_flow.rb +0 -333
  75. data/examples/teapot.rb +0 -362
  76. data/examples/teapot_mcu.rb +0 -344
@@ -46,17 +46,18 @@ module RBGL
46
46
  value_list << encode_event_mask(values[:event_mask])
47
47
  end
48
48
 
49
- [
50
- depth,
49
+ data = [
51
50
  wid,
52
51
  parent,
53
52
  x, y,
54
53
  width, height,
55
54
  border_width,
56
- WINDOW_CLASSES.fetch(window_class, 0),
55
+ WINDOW_CLASSES.fetch(window_class),
57
56
  visual,
58
57
  mask
59
- ].pack("CVVSSSSSVV") + value_list.pack("V*")
58
+ ].pack("VVs<s<vvvvVV") + value_list.pack("V*")
59
+
60
+ [depth, data]
60
61
  end
61
62
 
62
63
  def create_gc_data(gc_id, drawable, values = {})
@@ -77,7 +78,7 @@ module RBGL
77
78
  end
78
79
 
79
80
  def put_image_data(format:, drawable:, gc:, width:, height:, dst_x:, dst_y:, depth:, data:)
80
- format_byte = IMAGE_FORMATS.fetch(format, IMAGE_FORMATS[:z_pixmap])
81
+ format_byte = IMAGE_FORMATS.fetch(format)
81
82
  header = [
82
83
  drawable,
83
84
  gc,
@@ -85,22 +86,19 @@ module RBGL
85
86
  dst_x, dst_y,
86
87
  0,
87
88
  depth
88
- ].pack("VVvvvvCC") + "\x00\x00"
89
+ ].pack("VVvvs<s<CC") + "\x00\x00"
89
90
 
90
91
  [format_byte, header, data]
91
92
  end
92
93
 
93
94
  def change_property_data(window, property_atom, type_atom, data, mode: :replace, format: 8)
94
95
  data_bytes, value_count = pack_property_data(data, format)
95
- request = [
96
- window,
97
- property_atom,
98
- type_atom,
99
- format,
100
- value_count
101
- ].pack("VVVCV") + "\x00\x00\x00" + pad_to_4(data_bytes)
102
-
103
- [PROPERTY_MODES.fetch(mode, 0), request]
96
+ request = [window, property_atom, type_atom, format].pack("VVVC") +
97
+ "\x00\x00\x00" +
98
+ [value_count].pack("V") +
99
+ pad_to_4(data_bytes)
100
+
101
+ [PROPERTY_MODES.fetch(mode), request]
104
102
  end
105
103
 
106
104
  def intern_atom_data(name)
@@ -108,24 +106,17 @@ module RBGL
108
106
  end
109
107
 
110
108
  def request_packet(opcode, data, extra = 0)
111
- length = (4 + data.bytesize + 3) / 4
112
- header = [opcode, extra, length].pack("CCv")
113
- padding = "\x00" * (length * 4 - 4 - data.bytesize)
114
- header + data + padding
109
+ encode_packet(opcode, extra, data)
115
110
  end
116
111
 
117
112
  def request_packet_with_data(opcode, extra, header_data, bulk_data)
118
- total_data = header_data + bulk_data
119
- length = (4 + total_data.bytesize + 3) / 4
120
- header = [opcode, extra, length].pack("CCv")
121
- padding = "\x00" * (length * 4 - 4 - total_data.bytesize)
122
- header + total_data + padding
113
+ encode_packet(opcode, extra, header_data + bulk_data)
123
114
  end
124
115
 
125
116
  def pack_property_data(data, format)
126
117
  case format
127
118
  when 8
128
- bytes = data.to_s
119
+ bytes = data.to_s.b
129
120
  [bytes, bytes.bytesize]
130
121
  when 16
131
122
  values = Array(data)
@@ -139,14 +130,24 @@ module RBGL
139
130
  end
140
131
 
141
132
  def pad_to_4(str)
142
- padding = (4 - str.bytesize % 4) % 4
143
- str + ("\x00" * padding)
133
+ bytes = str.b
134
+ padding = (4 - (bytes.bytesize % 4)) % 4
135
+ bytes + ("\x00" * padding)
144
136
  end
145
137
 
146
138
  private
147
139
 
140
+ def encode_packet(opcode, extra, data)
141
+ length = (4 + data.bytesize + 3) / 4
142
+ raise ArgumentError, "X11 request exceeds the 16-bit core protocol limit" if length > 65_535
143
+
144
+ header = [opcode, extra, length].pack("CCv")
145
+ padding = "\x00" * ((length * 4) - 4 - data.bytesize)
146
+ header + data + padding
147
+ end
148
+
148
149
  def encode_event_mask(events)
149
- Array(events).sum { |event| EVENT_MASKS.fetch(event, 0) }
150
+ Array(events).sum { |event| EVENT_MASKS.fetch(event) }
150
151
  end
151
152
  end
152
153
  end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBGL
4
+ module GUI
5
+ module X11
6
+ class SetupParser
7
+ Setup = Struct.new(
8
+ :resource_id_base,
9
+ :resource_id_mask,
10
+ :maximum_request_length,
11
+ :image_byte_order,
12
+ :minimum_keycode,
13
+ :maximum_keycode,
14
+ :pixmap_formats,
15
+ :screens,
16
+ keyword_init: true
17
+ )
18
+ PixmapFormat = Struct.new(:depth, :bits_per_pixel, :scanline_pad, keyword_init: true)
19
+ Depth = Struct.new(:depth, :visuals, keyword_init: true)
20
+ Screen = Struct.new(
21
+ :root,
22
+ :white_pixel,
23
+ :black_pixel,
24
+ :root_visual,
25
+ :root_depth,
26
+ :depths,
27
+ keyword_init: true
28
+ ) do
29
+ def visuals
30
+ depths.flat_map(&:visuals)
31
+ end
32
+ end
33
+ Visual = Struct.new(:id, :visual_class, :red_mask, :green_mask, :blue_mask, keyword_init: true)
34
+
35
+ def parse(data)
36
+ raise ArgumentError, "Truncated X11 setup response" if data.bytesize < 32
37
+
38
+ vendor_length = data.byteslice(16, 2).unpack1("v")
39
+ screen_count = data.getbyte(20)
40
+ format_count = data.getbyte(21)
41
+ format_offset = 32 + padded_length(vendor_length)
42
+ formats = parse_formats(data, format_offset, format_count)
43
+ screens = parse_screens(data, format_offset + (format_count * 8), screen_count)
44
+
45
+ Setup.new(
46
+ resource_id_base: data.byteslice(4, 4).unpack1("V"),
47
+ resource_id_mask: data.byteslice(8, 4).unpack1("V"),
48
+ maximum_request_length: data.byteslice(18, 2).unpack1("v"),
49
+ image_byte_order: parse_image_byte_order(data.getbyte(22)),
50
+ minimum_keycode: data.getbyte(26),
51
+ maximum_keycode: data.getbyte(27),
52
+ pixmap_formats: formats,
53
+ screens: screens
54
+ )
55
+ end
56
+
57
+ private
58
+
59
+ def parse_formats(data, offset, count)
60
+ count.times.map do |index|
61
+ bytes = required_slice(data, offset + (index * 8), 8)
62
+ PixmapFormat.new(
63
+ depth: bytes.getbyte(0),
64
+ bits_per_pixel: bytes.getbyte(1),
65
+ scanline_pad: bytes.getbyte(2)
66
+ )
67
+ end
68
+ end
69
+
70
+ def parse_screens(data, offset, count)
71
+ screens = []
72
+ count.times do
73
+ screen, offset = parse_screen(data, offset)
74
+ screens << screen
75
+ end
76
+ screens
77
+ end
78
+
79
+ def parse_screen(data, offset)
80
+ header = required_slice(data, offset, 40)
81
+ depth_count = header.getbyte(39)
82
+ cursor = offset + 40
83
+ depths = []
84
+
85
+ depth_count.times do
86
+ depth_header = required_slice(data, cursor, 8)
87
+ depth_value = depth_header.getbyte(0)
88
+ visual_count = depth_header.byteslice(2, 2).unpack1("v")
89
+ cursor += 8
90
+ visuals = []
91
+ visual_count.times do
92
+ visuals << parse_visual(required_slice(data, cursor, 24))
93
+ cursor += 24
94
+ end
95
+ depths << Depth.new(depth: depth_value, visuals: visuals)
96
+ end
97
+
98
+ screen = Screen.new(
99
+ root: header.byteslice(0, 4).unpack1("V"),
100
+ white_pixel: header.byteslice(8, 4).unpack1("V"),
101
+ black_pixel: header.byteslice(12, 4).unpack1("V"),
102
+ root_visual: header.byteslice(32, 4).unpack1("V"),
103
+ root_depth: header.getbyte(38),
104
+ depths: depths
105
+ )
106
+ [screen, cursor]
107
+ end
108
+
109
+ def parse_visual(bytes)
110
+ Visual.new(
111
+ id: bytes.byteslice(0, 4).unpack1("V"),
112
+ visual_class: bytes.getbyte(4),
113
+ red_mask: bytes.byteslice(8, 4).unpack1("V"),
114
+ green_mask: bytes.byteslice(12, 4).unpack1("V"),
115
+ blue_mask: bytes.byteslice(16, 4).unpack1("V")
116
+ )
117
+ end
118
+
119
+ def required_slice(data, offset, length)
120
+ bytes = data.byteslice(offset, length)
121
+ raise ArgumentError, "Truncated X11 setup response" unless bytes&.bytesize == length
122
+
123
+ bytes
124
+ end
125
+
126
+ def padded_length(length)
127
+ (length + 3) & ~3
128
+ end
129
+
130
+ def parse_image_byte_order(value)
131
+ { 0 => :little, 1 => :big }.fetch(value) do
132
+ raise ArgumentError, "Unsupported X11 image byte order: #{value}"
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -1,13 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "io/wait"
4
+
3
5
  module RBGL
4
6
  module GUI
5
7
  module X11
6
8
  class Transport
9
+ READ_CHUNK_SIZE = 16_384
10
+
7
11
  attr_reader :socket
8
12
 
9
13
  def initialize(socket)
10
14
  @socket = socket
15
+ @read_buffer = String.new(encoding: Encoding::BINARY)
11
16
  end
12
17
 
13
18
  def write(data)
@@ -15,7 +20,12 @@ module RBGL
15
20
  end
16
21
 
17
22
  def read(length)
18
- @socket.read(length)
23
+ read_exact(length)
24
+ end
25
+
26
+ def read_exact(length, timeout: nil)
27
+ fill_buffer(length, timeout: timeout)
28
+ @read_buffer.slice!(0, length)
19
29
  end
20
30
 
21
31
  def flush
@@ -23,7 +33,47 @@ module RBGL
23
33
  end
24
34
 
25
35
  def pending
26
- IO.select([@socket], nil, nil, 0) ? 1 : 0
36
+ read_available
37
+ return 0 if @read_buffer.bytesize < 32
38
+
39
+ packet_size = 32
40
+ if @read_buffer.getbyte(0) == 1
41
+ packet_size += @read_buffer.byteslice(4, 4).unpack1("V") * 4
42
+ end
43
+ @read_buffer.bytesize >= packet_size ? 1 : 0
44
+ end
45
+
46
+ def close
47
+ @socket.close unless @socket.closed?
48
+ end
49
+
50
+ private
51
+
52
+ def fill_buffer(length, timeout:)
53
+ deadline = timeout && (monotonic_time + timeout)
54
+
55
+ while @read_buffer.bytesize < length
56
+ wait = deadline && [deadline - monotonic_time, 0].max
57
+ raise IO::EAGAINWaitReadable unless @socket.wait_readable(wait)
58
+
59
+ read_available
60
+ end
61
+ end
62
+
63
+ def read_available
64
+ return unless @socket.wait_readable(0)
65
+
66
+ loop do
67
+ chunk = @socket.read_nonblock(READ_CHUNK_SIZE, exception: false)
68
+ break if chunk == :wait_readable
69
+ raise EOFError, "X11 server closed the connection" if chunk.nil?
70
+
71
+ @read_buffer << chunk
72
+ end
73
+ end
74
+
75
+ def monotonic_time
76
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
27
77
  end
28
78
  end
29
79
  end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+ require "ipaddr"
5
+
6
+ module RBGL
7
+ module GUI
8
+ module X11
9
+ class XAuthority
10
+ FAMILY_INTERNET = 0
11
+ FAMILY_INTERNET6 = 6
12
+ FAMILY_LOCAL = 256
13
+ FAMILY_WILD = 65_535
14
+ AUTH_NAME = "MIT-MAGIC-COOKIE-1"
15
+
16
+ Entry = Struct.new(:family, :address, :display_number, :name, :data, keyword_init: true)
17
+
18
+ def self.cookie_for(host:, display_number:, env: ENV)
19
+ path = env["XAUTHORITY"] || default_path(env)
20
+ return nil unless path && File.file?(path)
21
+
22
+ new(File.binread(path)).cookie_for(host: host, display_number: display_number)
23
+ rescue ArgumentError, EOFError
24
+ nil
25
+ end
26
+
27
+ def self.default_path(env)
28
+ home = env["HOME"] || Dir.home
29
+ File.join(home, ".Xauthority")
30
+ rescue ArgumentError
31
+ nil
32
+ end
33
+
34
+ def initialize(data)
35
+ @entries = parse(data)
36
+ end
37
+
38
+ def cookie_for(host:, display_number:)
39
+ candidates = @entries.select do |entry|
40
+ (entry.display_number.empty? || entry.display_number == display_number.to_s) && entry.name == AUTH_NAME
41
+ end
42
+ candidates.find { |entry| address_matches?(entry, host) }&.data
43
+ end
44
+
45
+ private
46
+
47
+ def parse(data)
48
+ offset = 0
49
+ entries = []
50
+
51
+ while offset < data.bytesize
52
+ family, offset = read_u16(data, offset)
53
+ address, offset = read_field(data, offset)
54
+ display_number, offset = read_field(data, offset)
55
+ name, offset = read_field(data, offset)
56
+ cookie, offset = read_field(data, offset)
57
+ entries << Entry.new(
58
+ family: family,
59
+ address: address,
60
+ display_number: display_number,
61
+ name: name,
62
+ data: cookie
63
+ )
64
+ end
65
+
66
+ entries
67
+ end
68
+
69
+ def read_u16(data, offset)
70
+ bytes = data.byteslice(offset, 2)
71
+ raise EOFError, "Truncated Xauthority entry" unless bytes&.bytesize == 2
72
+
73
+ [bytes.unpack1("n"), offset + 2]
74
+ end
75
+
76
+ def read_field(data, offset)
77
+ length, offset = read_u16(data, offset)
78
+ value = data.byteslice(offset, length)
79
+ raise EOFError, "Truncated Xauthority field" unless value&.bytesize == length
80
+
81
+ [value, offset + length]
82
+ end
83
+
84
+ def address_matches?(entry, host)
85
+ return true if entry.family == FAMILY_WILD
86
+ return local_address_matches?(entry.address) if host.nil? && entry.family == FAMILY_LOCAL
87
+ return false unless [FAMILY_INTERNET, FAMILY_INTERNET6].include?(entry.family)
88
+
89
+ family = entry.family == FAMILY_INTERNET ? :INET : :INET6
90
+ Addrinfo.getaddrinfo(host, nil, family).any? do |address|
91
+ IPAddr.new(address.ip_address).hton == entry.address
92
+ end
93
+ rescue SocketError
94
+ false
95
+ end
96
+
97
+ def local_address_matches?(address)
98
+ return true if address.empty?
99
+
100
+ expected = address.downcase
101
+ actual = Socket.gethostname.downcase
102
+ expected == actual || expected.split(".", 2).first == actual.split(".", 2).first
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
data/lib/rbgl/gui.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "version"
3
4
  require_relative "gui/event"
4
5
  require_relative "gui/backend"
5
6
  require_relative "gui/backend_factory"
@@ -8,10 +9,6 @@ require_relative "gui/window"
8
9
 
9
10
  module RBGL
10
11
  module GUI
11
- VERSION = "0.1.0"
12
-
13
- def self.load_tk_backend
14
- require_relative "gui/tk_backend"
15
- end
12
+ VERSION = RBGL::VERSION
16
13
  end
17
14
  end
data/lib/rbgl/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RBGL
4
- VERSION = "1.0.0"
4
+ VERSION = "1.0.1"
5
5
  end
metadata CHANGED
@@ -1,77 +1,79 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbgl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada
8
- bindir: bin
8
+ autorequire:
9
+ bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-09-25 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: larb
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
- - - ">="
17
+ - - "~>"
17
18
  - !ruby/object:Gem::Version
18
- version: 1.0.0
19
+ version: '1.0'
19
20
  type: :runtime
20
21
  prerelease: false
21
22
  version_requirements: !ruby/object:Gem::Requirement
22
23
  requirements:
23
- - - ">="
24
+ - - "~>"
24
25
  - !ruby/object:Gem::Version
25
- version: 1.0.0
26
+ version: '1.0'
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: rlsl
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ">="
31
+ - - "~>"
31
32
  - !ruby/object:Gem::Version
32
- version: '0'
33
+ version: '1.0'
33
34
  type: :runtime
34
35
  prerelease: false
35
36
  version_requirements: !ruby/object:Gem::Requirement
36
37
  requirements:
37
- - - ">="
38
+ - - "~>"
38
39
  - !ruby/object:Gem::Version
39
- version: '0'
40
+ version: '1.0'
40
41
  description: A pure Ruby graphics library with software rendering engine and cross-platform
41
42
  GUI support (X11, Wayland, Cocoa).
42
43
  email:
43
44
  - t.yudai92@gmail.com
44
- executables: []
45
+ executables:
46
+ - rbgl
45
47
  extensions: []
46
48
  extra_rdoc_files: []
47
49
  files:
50
+ - ".rubocop.yml"
48
51
  - CHANGELOG.md
49
52
  - LICENSE
50
53
  - README.md
51
54
  - Rakefile
55
+ - bench/renderer_bench.rb
56
+ - docs/.nojekyll
57
+ - docs/index.html
52
58
  - examples/array_test.rb
53
- - examples/chemical_heartbeat.rb
54
59
  - examples/color_test.rb
55
60
  - examples/cube_spinning.rb
56
- - examples/dark_transit.rb
57
- - examples/fractured_orb.rb
58
- - examples/fractured_orb_rb.rb
59
61
  - examples/gradient.rb
60
- - examples/hexagonal_flow.rb
61
62
  - examples/multi_return_test.rb
62
63
  - examples/plasma.rb
63
64
  - examples/sphere_raymarch.rb
64
- - examples/teapot.rb
65
- - examples/teapot_mcu.rb
66
65
  - examples/triangle_basic.rb
67
66
  - examples/triangle_window.rb
68
67
  - examples/window_test.rb
68
+ - exe/rbgl
69
69
  - lib/rbgl.rb
70
+ - lib/rbgl/cli/doctor.rb
70
71
  - lib/rbgl/engine.rb
71
72
  - lib/rbgl/engine/buffer.rb
72
73
  - lib/rbgl/engine/clip_space_clipper.rb
73
74
  - lib/rbgl/engine/context.rb
74
75
  - lib/rbgl/engine/framebuffer.rb
76
+ - lib/rbgl/engine/immutable_color.rb
75
77
  - lib/rbgl/engine/pipeline.rb
76
78
  - lib/rbgl/engine/rasterizer.rb
77
79
  - lib/rbgl/engine/rasterizer/attribute_interpolator.rb
@@ -87,19 +89,23 @@ files:
87
89
  - lib/rbgl/gui/backend.rb
88
90
  - lib/rbgl/gui/backend_factory.rb
89
91
  - lib/rbgl/gui/cocoa/backend.rb
92
+ - lib/rbgl/gui/cocoa/key_mapper.rb
90
93
  - lib/rbgl/gui/event.rb
91
94
  - lib/rbgl/gui/file_backend.rb
92
95
  - lib/rbgl/gui/file_backend/bmp_writer.rb
93
96
  - lib/rbgl/gui/file_backend/frame_writer.rb
97
+ - lib/rbgl/gui/file_backend/png_writer.rb
94
98
  - lib/rbgl/gui/file_backend/ppm_writer.rb
95
99
  - lib/rbgl/gui/wayland/backend.rb
96
100
  - lib/rbgl/gui/wayland/codec.rb
97
101
  - lib/rbgl/gui/wayland/connection.rb
98
102
  - lib/rbgl/gui/wayland/event_dispatcher.rb
99
103
  - lib/rbgl/gui/wayland/global_binder.rb
104
+ - lib/rbgl/gui/wayland/input_mapper.rb
100
105
  - lib/rbgl/gui/wayland/protocol_objects.rb
101
106
  - lib/rbgl/gui/wayland/protocol_objects/arguments.rb
102
107
  - lib/rbgl/gui/wayland/protocol_objects/display.rb
108
+ - lib/rbgl/gui/wayland/protocol_objects/seat.rb
103
109
  - lib/rbgl/gui/wayland/protocol_objects/shm.rb
104
110
  - lib/rbgl/gui/wayland/protocol_objects/surface.rb
105
111
  - lib/rbgl/gui/wayland/protocol_objects/xdg_shell.rb
@@ -110,16 +116,21 @@ files:
110
116
  - lib/rbgl/gui/x11/backend.rb
111
117
  - lib/rbgl/gui/x11/connection.rb
112
118
  - lib/rbgl/gui/x11/event_parser.rb
119
+ - lib/rbgl/gui/x11/key_mapper.rb
120
+ - lib/rbgl/gui/x11/pixel_encoder.rb
113
121
  - lib/rbgl/gui/x11/request_encoder.rb
122
+ - lib/rbgl/gui/x11/setup_parser.rb
114
123
  - lib/rbgl/gui/x11/transport.rb
124
+ - lib/rbgl/gui/x11/x_authority.rb
115
125
  - lib/rbgl/version.rb
116
- homepage: https://github.com/ydah/rbgl
126
+ homepage: https://rbgfx.github.io/rbgl/
117
127
  licenses:
118
128
  - MIT
119
129
  metadata:
120
- homepage_uri: https://github.com/ydah/rbgl
121
- source_code_uri: https://github.com/ydah/rbgl
122
- changelog_uri: https://github.com/ydah/rbgl/blob/main/CHANGELOG.md
130
+ homepage_uri: https://rbgfx.github.io/rbgl/
131
+ source_code_uri: https://github.com/rbgfx/rbgl/tree/main
132
+ changelog_uri: https://github.com/rbgfx/rbgl/blob/main/CHANGELOG.md
133
+ post_install_message:
123
134
  rdoc_options: []
124
135
  require_paths:
125
136
  - lib
@@ -134,7 +145,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
145
  - !ruby/object:Gem::Version
135
146
  version: '0'
136
147
  requirements: []
137
- rubygems_version: 4.0.6
148
+ rubygems_version: 3.4.19
149
+ signing_key:
138
150
  specification_version: 4
139
151
  summary: RuBy Graphics Library - Pure Ruby software rendering with cross-platform
140
152
  GUI