cyberarm_engine 0.14.0 → 0.18.0

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/Gemfile +1 -1
  4. data/README.md +5 -4
  5. data/Rakefile +1 -1
  6. data/assets/textures/default.png +0 -0
  7. data/assets/textures/logo.png +0 -0
  8. data/cyberarm_engine.gemspec +11 -9
  9. data/lib/cyberarm_engine.rb +19 -7
  10. data/lib/cyberarm_engine/animator.rb +13 -11
  11. data/lib/cyberarm_engine/background.rb +19 -15
  12. data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
  13. data/lib/cyberarm_engine/bounding_box.rb +18 -18
  14. data/lib/cyberarm_engine/builtin/intro_state.rb +128 -0
  15. data/lib/cyberarm_engine/cache.rb +4 -0
  16. data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
  17. data/lib/cyberarm_engine/common.rb +18 -13
  18. data/lib/cyberarm_engine/config_file.rb +2 -2
  19. data/lib/cyberarm_engine/game_object.rb +63 -72
  20. data/lib/cyberarm_engine/game_state.rb +11 -3
  21. data/lib/cyberarm_engine/model.rb +207 -0
  22. data/lib/cyberarm_engine/model/material.rb +21 -0
  23. data/lib/cyberarm_engine/model/model_object.rb +131 -0
  24. data/lib/cyberarm_engine/model/parser.rb +74 -0
  25. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
  26. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
  27. data/lib/cyberarm_engine/model_cache.rb +31 -0
  28. data/lib/cyberarm_engine/opengl.rb +28 -0
  29. data/lib/cyberarm_engine/opengl/light.rb +50 -0
  30. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
  31. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
  32. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
  33. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
  34. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
  35. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
  36. data/lib/cyberarm_engine/{shader.rb → opengl/shader.rb} +51 -43
  37. data/lib/cyberarm_engine/opengl/texture.rb +69 -0
  38. data/lib/cyberarm_engine/ray.rb +5 -5
  39. data/lib/cyberarm_engine/stats.rb +2 -2
  40. data/lib/cyberarm_engine/text.rb +51 -27
  41. data/lib/cyberarm_engine/timer.rb +1 -1
  42. data/lib/cyberarm_engine/transform.rb +43 -20
  43. data/lib/cyberarm_engine/ui/border_canvas.rb +4 -3
  44. data/lib/cyberarm_engine/ui/dsl.rb +45 -12
  45. data/lib/cyberarm_engine/ui/element.rb +211 -61
  46. data/lib/cyberarm_engine/ui/elements/button.rb +72 -42
  47. data/lib/cyberarm_engine/ui/elements/check_box.rb +5 -2
  48. data/lib/cyberarm_engine/ui/elements/container.rb +81 -29
  49. data/lib/cyberarm_engine/ui/elements/edit_box.rb +175 -2
  50. data/lib/cyberarm_engine/ui/elements/edit_line.rb +139 -48
  51. data/lib/cyberarm_engine/ui/elements/flow.rb +1 -1
  52. data/lib/cyberarm_engine/ui/elements/image.rb +32 -12
  53. data/lib/cyberarm_engine/ui/elements/list_box.rb +78 -2
  54. data/lib/cyberarm_engine/ui/elements/progress.rb +5 -5
  55. data/lib/cyberarm_engine/ui/elements/radio.rb +1 -1
  56. data/lib/cyberarm_engine/ui/elements/slider.rb +13 -16
  57. data/lib/cyberarm_engine/ui/elements/stack.rb +1 -1
  58. data/lib/cyberarm_engine/ui/elements/text_block.rb +153 -0
  59. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +27 -19
  60. data/lib/cyberarm_engine/ui/event.rb +7 -7
  61. data/lib/cyberarm_engine/ui/gui_state.rb +88 -16
  62. data/lib/cyberarm_engine/ui/style.rb +23 -11
  63. data/lib/cyberarm_engine/ui/theme.rb +95 -21
  64. data/lib/cyberarm_engine/vector.rb +33 -30
  65. data/lib/cyberarm_engine/version.rb +2 -2
  66. data/lib/cyberarm_engine/window.rb +35 -18
  67. metadata +70 -18
  68. data/lib/cyberarm_engine/ui/elements/label.rb +0 -52
@@ -0,0 +1,69 @@
1
+ module CyberarmEngine
2
+ class Texture
3
+ DEFAULT_TEXTURE = "#{CYBERARM_ENGINE_ROOT_PATH}/assets/textures/default.png".freeze
4
+
5
+ CACHE = {}
6
+
7
+ def self.release_textures
8
+ CACHE.values.each do |id|
9
+ glDeleteTextures(id)
10
+ end
11
+ end
12
+
13
+ def self.from_cache(path, retro)
14
+ CACHE.dig("#{path}?retro=#{retro}")
15
+ end
16
+
17
+ attr_reader :id
18
+
19
+ def initialize(path: nil, image: nil, retro: false)
20
+ raise "keyword :path or :image must be provided!" if path.nil? && image.nil?
21
+
22
+ @retro = retro
23
+ @path = path
24
+
25
+ if @path
26
+ unless File.exist?(@path)
27
+ warn "Missing texture at: #{@path}"
28
+ @retro = true # override retro setting
29
+ @path = DEFAULT_TEXTURE
30
+ end
31
+
32
+ if texture = Texture.from_cache(@path, @retro)
33
+ @id = texture.id
34
+ return
35
+ end
36
+
37
+ image = load_image(@path)
38
+ @id = create_from_image(image)
39
+ else
40
+ @id = create_from_image(image)
41
+ end
42
+ end
43
+
44
+ def load_image(path)
45
+ CACHE["#{path}?retro=#{@retro}"] = self
46
+ Gosu::Image.new(path, retro: @retro)
47
+ end
48
+
49
+ def create_from_image(image)
50
+ array_of_pixels = image.to_blob
51
+
52
+ tex_names_buf = " " * 4
53
+ glGenTextures(1, tex_names_buf)
54
+ texture_id = tex_names_buf.unpack1("L2")
55
+
56
+ glBindTexture(GL_TEXTURE_2D, texture_id)
57
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, array_of_pixels)
58
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
59
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
60
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) if @retro
61
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) unless @retro
62
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
63
+ glGenerateMipmap(GL_TEXTURE_2D)
64
+ gl_error?
65
+
66
+ texture_id
67
+ end
68
+ end
69
+ end
@@ -4,7 +4,7 @@ module CyberarmEngine
4
4
  raise "Origin must be a Vector!" unless origin.is_a?(Vector)
5
5
  raise "Direction must be a Vector!" unless direction.is_a?(Vector)
6
6
 
7
- @origin = origin
7
+ @origin = origin
8
8
  @direction = direction
9
9
  @range = range
10
10
 
@@ -42,15 +42,15 @@ module CyberarmEngine
42
42
  tmin = max(tmin, min(tz1, tz2))
43
43
  tmax = min(tmax, max(tz1, tz2))
44
44
 
45
- return tmax >= max(tmin, 0.0);
45
+ tmax >= max(tmin, 0.0)
46
46
  end
47
47
 
48
48
  def min(x, y)
49
- ((x) < (y) ? (x) : (y))
49
+ ((x) < (y) ? x : y)
50
50
  end
51
51
 
52
52
  def max(x, y)
53
- ((x) > (y) ? (x) : (y))
53
+ ((x) > (y) ? x : y)
54
54
  end
55
55
  end
56
- end
56
+ end
@@ -13,9 +13,9 @@ module CyberarmEngine
13
13
  end
14
14
 
15
15
  def self.clear
16
- @@hash.each do |key, value|
16
+ @@hash.each do |key, _value|
17
17
  @@hash[key] = 0
18
18
  end
19
19
  end
20
20
  end
21
- end
21
+ end
@@ -5,7 +5,7 @@ module CyberarmEngine
5
5
  attr_accessor :x, :y, :z, :size, :options
6
6
  attr_reader :text, :textobject, :factor_x, :factor_y, :color, :shadow, :shadow_size, :shadow_alpha, :shadow_color
7
7
 
8
- def initialize(text, options={})
8
+ def initialize(text, options = {})
9
9
  @text = text.to_s || ""
10
10
  @options = options
11
11
  @size = options[:size] || 18
@@ -16,28 +16,29 @@ module CyberarmEngine
16
16
  @factor_x = options[:factor_x] || 1
17
17
  @factor_y = options[:factor_y] || 1
18
18
  @color = options[:color] || Gosu::Color::WHITE
19
- @alignment= options[:alignment] || nil
19
+ @mode = options[:mode] || :default
20
+ @alignment = options[:alignment] || nil
20
21
  @shadow = true if options[:shadow] == true
21
22
  @shadow = false if options[:shadow] == false
22
- @shadow = true if options[:shadow] == nil
23
- @shadow_size = options[:shadow_size] ? options[:shadow_size] : 1
24
- @shadow_alpha= options[:shadow_alpha] ? options[:shadow_alpha] : 30
25
- @shadow_alpha= options[:shadow_alpha] ? options[:shadow_alpha] : 30
26
- @shadow_color= options[:shadow_color]
23
+ @shadow = true if options[:shadow].nil?
24
+ @shadow_size = options[:shadow_size] || 1
25
+ @shadow_alpha = options[:shadow_alpha] || 30
26
+ @shadow_alpha = options[:shadow_alpha] || 30
27
+ @shadow_color = options[:shadow_color]
27
28
  @textobject = check_cache(@size, @font)
28
29
 
29
30
  if @alignment
30
31
  case @alignment
31
32
  when :left
32
- @x = 0+BUTTON_PADDING
33
+ @x = 0 + BUTTON_PADDING
33
34
  when :center
34
- @x = ($window.width/2)-(@textobject.text_width(@text)/2)
35
+ @x = ($window.width / 2) - (@textobject.text_width(@text) / 2)
35
36
  when :right
36
- @x = $window.width-BUTTON_PADDING-@textobject.text_width(@text)
37
+ @x = $window.width - BUTTON_PADDING - @textobject.text_width(@text)
37
38
  end
38
39
  end
39
40
 
40
- return self
41
+ self
41
42
  end
42
43
 
43
44
  def check_cache(size, font_name)
@@ -61,7 +62,16 @@ module CyberarmEngine
61
62
  CACHE[@size][@font] = font
62
63
  end
63
64
 
64
- return font
65
+ font
66
+ end
67
+
68
+ def swap_font(size, font_name = @font)
69
+ if @size != size || @font != font_name
70
+ @size = size
71
+ @font = font_name
72
+
73
+ @textobject = check_cache(size, font_name)
74
+ end
65
75
  end
66
76
 
67
77
  def text=(string)
@@ -73,26 +83,32 @@ module CyberarmEngine
73
83
  @rendered_shadow = nil
74
84
  @factor_x = n
75
85
  end
86
+
76
87
  def factor_y=(n)
77
88
  @rendered_shadow = nil
78
89
  @factor_y = n
79
90
  end
91
+
80
92
  def color=(color)
81
93
  @rendered_shadow = nil
82
94
  @color = color
83
95
  end
96
+
84
97
  def shadow=(boolean)
85
98
  @rendered_shadow = nil
86
99
  @shadow = boolean
87
100
  end
101
+
88
102
  def shadow_size=(n)
89
103
  @rendered_shadow = nil
90
104
  @shadow_size = n
91
105
  end
106
+
92
107
  def shadow_alpha=(n)
93
108
  @rendered_shadow = nil
94
109
  @shadow_alpha = n
95
110
  end
111
+
96
112
  def shadow_color=(n)
97
113
  @rendered_shadow = nil
98
114
  @shadow_color = n
@@ -102,35 +118,42 @@ module CyberarmEngine
102
118
  textobject.text_width(text)
103
119
  end
104
120
 
121
+ def markup_width(text = @text)
122
+ textobject.markup_width(text)
123
+ end
124
+
105
125
  def height(text = @text)
106
- text.lines.count > 0 ? (text.lines.count) * textobject.height : @textobject.height
126
+ text.lines.count > 0 ? text.lines.count * textobject.height : @textobject.height
107
127
  end
108
128
 
109
- def draw
129
+ def draw(method = :draw_markup)
110
130
  if @shadow && !ARGV.join.include?("--no-shadow")
111
131
  shadow_alpha = @color.alpha <= 30 ? @color.alpha : @shadow_alpha
112
- shadow_color = @shadow_color ? @shadow_color : Gosu::Color.rgba(@color.red, @color.green, @color.blue, shadow_alpha)
132
+ shadow_color = @shadow_color || Gosu::Color.rgba(@color.red, @color.green, @color.blue,
133
+ shadow_alpha)
134
+ white = Gosu::Color::WHITE
113
135
 
114
136
  _x = @shadow_size
115
137
  _y = @shadow_size
116
138
 
117
- @rendered_shadow ||= Gosu.render((self.width+(shadow_size*2)).ceil, (self.height+(@shadow_size*2)).ceil) do
118
- @textobject.draw_markup(@text, _x-@shadow_size, _y, @z)
119
- @textobject.draw_markup(@text, _x-@shadow_size, _y-@shadow_size, @z)
139
+ @rendered_shadow ||= Gosu.render((width + (shadow_size * 2)).ceil, (height + (@shadow_size * 2)).ceil) do
140
+ @textobject.send(method, @text, _x - @shadow_size, _y, @z, @factor_x, @factor_y, white, :add)
141
+ @textobject.send(method, @text, _x - @shadow_size, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
120
142
 
121
- @textobject.draw_markup(@text, _x, _y-@shadow_size, @z, @factor_x)
122
- @textobject.draw_markup(@text, _x+@shadow_size, _y-@shadow_size, @z)
143
+ @textobject.send(method, @text, _x, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
144
+ @textobject.send(method, @text, _x + @shadow_size, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
123
145
 
124
- @textobject.draw_markup(@text, _x, _y+@shadow_size, @z)
125
- @textobject.draw_markup(@text, _x-@shadow_size, _y+@shadow_size, @z)
146
+ @textobject.send(method, @text, _x, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add)
147
+ @textobject.send(method, @text, _x - @shadow_size, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add)
126
148
 
127
- @textobject.draw_markup(@text, _x+@shadow_size, _y, @z)
128
- @textobject.draw_markup(@text, _x+@shadow_size, _y+@shadow_size, @z)
149
+ @textobject.send(method, @text, _x + @shadow_size, _y, @z, @factor_x, @factor_y, white, :add)
150
+ @textobject.send(method, @text, _x + @shadow_size, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add)
129
151
  end
130
- @rendered_shadow.draw(@x-@shadow_size, @y-@shadow_size, @z, @factor_x, @factor_y, shadow_color)
152
+
153
+ @rendered_shadow.draw(@x - @shadow_size, @y - @shadow_size, @z, @factor_x, @factor_y, shadow_color)
131
154
  end
132
155
 
133
- @textobject.draw_markup(@text, @x, @y, @z, @factor_x, @factor_y, @color)
156
+ @textobject.send(method, @text, @x, @y, @z, @factor_x, @factor_y, @color, @mode)
134
157
  end
135
158
 
136
159
  def alpha=(n)
@@ -141,6 +164,7 @@ module CyberarmEngine
141
164
  @color.alpha
142
165
  end
143
166
 
144
- def update; end
167
+ def update
168
+ end
145
169
  end
146
170
  end
@@ -20,4 +20,4 @@ module CyberarmEngine
20
20
  end
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -2,11 +2,12 @@ module CyberarmEngine
2
2
  # Basic 4x4 matrix operations
3
3
  class Transform
4
4
  attr_reader :elements
5
+
5
6
  def initialize(matrix)
6
7
  @elements = matrix
7
8
 
8
9
  raise "Transform is wrong size! Got #{@elements.size}, expected 16" if 16 != @elements.size
9
- raise "Invalid value for matrix, must all be numeric!" if @elements.any? { |e| e.nil? || !e.is_a?(Numeric)}
10
+ raise "Invalid value for matrix, must all be numeric!" if @elements.any? { |e| e.nil? || !e.is_a?(Numeric) }
10
11
  end
11
12
 
12
13
  def self.identity
@@ -27,10 +28,10 @@ module CyberarmEngine
27
28
  double c = Math.cos(angle).degrees_to_radians
28
29
  double s = Math.sin(angle).degrees_to_radians
29
30
  matrix = [
30
- +c, +s, 0, 0,
31
- -s, +c, 0, 0,
32
- 0, 0, 1, 0,
33
- 0, 0, 0, 1,
31
+ +c, +s, 0, 0,
32
+ -s, +c, 0, 0,
33
+ 0, 0, 1, 0,
34
+ 0, 0, 0, 1
34
35
  ]
35
36
 
36
37
  rotate_matrix = Transform.new(matrix, rows: 4, columns: 4)
@@ -44,7 +45,7 @@ module CyberarmEngine
44
45
  )
45
46
  end
46
47
 
47
- return rotate_matrix
48
+ rotate_matrix
48
49
  end
49
50
 
50
51
  # 2d translate operation, replicates Gosu's Gosu.translate function
@@ -54,7 +55,7 @@ module CyberarmEngine
54
55
  1, 0, 0, 0,
55
56
  0, 1, 0, 0,
56
57
  0, 0, 1, 0,
57
- x, y, z, 1,
58
+ x, y, z, 1
58
59
  ]
59
60
 
60
61
  Transform.new(matrix)
@@ -67,7 +68,7 @@ module CyberarmEngine
67
68
  scale_x, 0, 0, 0,
68
69
  0, scale_y, 0, 0,
69
70
  0, 0, scale_z, 0,
70
- 0, 0, 0, 1,
71
+ 0, 0, 0, 1
71
72
  ]
72
73
 
73
74
  scale_matrix = Transform.new(matrix)
@@ -81,7 +82,7 @@ module CyberarmEngine
81
82
  )
82
83
  end
83
84
 
84
- return scale_matrix
85
+ scale_matrix
85
86
  end
86
87
 
87
88
  def self.concat(left, right)
@@ -107,13 +108,13 @@ module CyberarmEngine
107
108
  1, 0, 0, x,
108
109
  0, 1, 0, y,
109
110
  0, 0, 1, z,
110
- 0, 0, 0, 1,
111
+ 0, 0, 0, 1
111
112
  ]
112
113
 
113
114
  Transform.new(matrix)
114
115
  end
115
116
 
116
- def self.rotate_3d(vector, order = "zyx")
117
+ def self.rotate_3d(vector, _order = "zyx")
117
118
  x, y, z = vector.to_a[0..2].map { |axis| axis * Math::PI / 180.0 }
118
119
 
119
120
  rotation_x = Transform.new(
@@ -163,7 +164,7 @@ module CyberarmEngine
163
164
  x * x * n + c, x * y * n - z * s, x * z * n + y * s, 0,
164
165
  y * x * n + z * s, y * y * n + c, y * z * n - x * s, 0,
165
166
  x * z * n - y * s, y * z * n + x * s, z * z * n + c, 0,
166
- 0, 0, 0, 1.0
167
+ 0, 0, 0, 1.0
167
168
  ]
168
169
  )
169
170
  end
@@ -190,12 +191,35 @@ module CyberarmEngine
190
191
  [
191
192
  f / aspect_ratio, 0.0, 0.0, 0.0,
192
193
  0.0, f, 0.0, 0.0,
193
- 0.0, 0.0, zn, zf,
194
+ 0.0, 0.0, zn, zf,
194
195
  0.0, 0.0, -1.0, 0.0
195
196
  ]
196
197
  )
197
198
  end
198
199
 
200
+ def self.orthographic(left, right, bottom, top, near, far)
201
+ s = Vector.new(
202
+ 2 / (right - left.to_f),
203
+ 2 / (top - bottom.to_f),
204
+ -2 / (far - near.to_f)
205
+ )
206
+
207
+ t = Vector.new(
208
+ (right + left.to_f) / (right - left.to_f),
209
+ (top + bottom.to_f) / (top - bottom.to_f),
210
+ (far + near.to_f) / (far - near.to_f)
211
+ )
212
+
213
+ Transform.new(
214
+ [
215
+ s.x, 0.0, 0.0, t.x,
216
+ 0.0, s.y, 0.0, t.y,
217
+ 0.0, 0.0, s.z, t.z,
218
+ 0.0, 0.0, 0.0, 1.0
219
+ ]
220
+ )
221
+ end
222
+
199
223
  def self.view(eye, orientation)
200
224
  # https://www.3dgep.com/understanding-the-view-matrix/#The_View_Matrix
201
225
  cosPitch = Math.cos(orientation.z * Math::PI / 180.0)
@@ -209,16 +233,15 @@ module CyberarmEngine
209
233
 
210
234
  Transform.new(
211
235
  [
212
- x_axis.x, y_axis.y, z_axis.z, 0,
213
- x_axis.x, y_axis.y, z_axis.z, 0,
214
- x_axis.x, y_axis.y, z_axis.z, 0,
236
+ x_axis.x, y_axis.y, z_axis.z, 0,
237
+ x_axis.x, y_axis.y, z_axis.z, 0,
238
+ x_axis.x, y_axis.y, z_axis.z, 0,
215
239
  -x_axis.dot(eye), -y_axis.dot(eye), -z_axis.dot(eye), 1
216
240
  ]
217
241
  )
218
242
  end
219
243
 
220
244
  def *(other)
221
-
222
245
  case other
223
246
  when CyberarmEngine::Vector
224
247
  matrix = @elements.clone
@@ -231,7 +254,7 @@ module CyberarmEngine
231
254
  Transform.new(matrix)
232
255
 
233
256
  when CyberarmEngine::Transform
234
- return multiply_matrices(other)
257
+ multiply_matrices(other)
235
258
  else
236
259
  p other.class
237
260
  raise TypeError, "Expected CyberarmEngine::Vector or CyberarmEngine::Transform got #{other.class}"
@@ -256,7 +279,7 @@ module CyberarmEngine
256
279
  end
257
280
  end
258
281
 
259
- return Transform.new(matrix)
282
+ Transform.new(matrix)
260
283
  end
261
284
 
262
285
  # arranges Matrix in column major form
@@ -270,4 +293,4 @@ module CyberarmEngine
270
293
  ]
271
294
  end
272
295
  end
273
- end
296
+ end