cyberarm_engine 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -0
  3. data/Gemfile +1 -1
  4. data/Rakefile +1 -1
  5. data/assets/textures/default.png +0 -0
  6. data/cyberarm_engine.gemspec +10 -8
  7. data/lib/cyberarm_engine.rb +13 -2
  8. data/lib/cyberarm_engine/animator.rb +6 -4
  9. data/lib/cyberarm_engine/background.rb +19 -15
  10. data/lib/cyberarm_engine/background_nine_slice.rb +125 -0
  11. data/lib/cyberarm_engine/bounding_box.rb +18 -18
  12. data/lib/cyberarm_engine/cache.rb +4 -0
  13. data/lib/cyberarm_engine/cache/download_manager.rb +121 -0
  14. data/lib/cyberarm_engine/common.rb +13 -13
  15. data/lib/cyberarm_engine/config_file.rb +2 -2
  16. data/lib/cyberarm_engine/game_object.rb +63 -72
  17. data/lib/cyberarm_engine/game_state.rb +6 -3
  18. data/lib/cyberarm_engine/model.rb +207 -0
  19. data/lib/cyberarm_engine/model/material.rb +21 -0
  20. data/lib/cyberarm_engine/model/model_object.rb +131 -0
  21. data/lib/cyberarm_engine/model/parser.rb +74 -0
  22. data/lib/cyberarm_engine/model/parsers/collada_parser.rb +138 -0
  23. data/lib/cyberarm_engine/model/parsers/wavefront_parser.rb +154 -0
  24. data/lib/cyberarm_engine/model_cache.rb +31 -0
  25. data/lib/cyberarm_engine/opengl.rb +28 -0
  26. data/lib/cyberarm_engine/opengl/light.rb +50 -0
  27. data/lib/cyberarm_engine/opengl/orthographic_camera.rb +46 -0
  28. data/lib/cyberarm_engine/opengl/perspective_camera.rb +38 -0
  29. data/lib/cyberarm_engine/opengl/renderer/bounding_box_renderer.rb +249 -0
  30. data/lib/cyberarm_engine/opengl/renderer/g_buffer.rb +164 -0
  31. data/lib/cyberarm_engine/opengl/renderer/opengl_renderer.rb +289 -0
  32. data/lib/cyberarm_engine/opengl/renderer/renderer.rb +22 -0
  33. data/lib/cyberarm_engine/{shader.rb → opengl/shader.rb} +51 -43
  34. data/lib/cyberarm_engine/opengl/texture.rb +69 -0
  35. data/lib/cyberarm_engine/ray.rb +5 -5
  36. data/lib/cyberarm_engine/stats.rb +2 -2
  37. data/lib/cyberarm_engine/text.rb +41 -27
  38. data/lib/cyberarm_engine/timer.rb +1 -1
  39. data/lib/cyberarm_engine/transform.rb +43 -20
  40. data/lib/cyberarm_engine/ui/border_canvas.rb +4 -3
  41. data/lib/cyberarm_engine/ui/dsl.rb +25 -11
  42. data/lib/cyberarm_engine/ui/element.rb +30 -20
  43. data/lib/cyberarm_engine/ui/elements/button.rb +86 -16
  44. data/lib/cyberarm_engine/ui/elements/check_box.rb +1 -1
  45. data/lib/cyberarm_engine/ui/elements/container.rb +44 -20
  46. data/lib/cyberarm_engine/ui/elements/edit_box.rb +175 -2
  47. data/lib/cyberarm_engine/ui/elements/edit_line.rb +121 -37
  48. data/lib/cyberarm_engine/ui/elements/flow.rb +1 -1
  49. data/lib/cyberarm_engine/ui/elements/image.rb +12 -9
  50. data/lib/cyberarm_engine/ui/elements/label.rb +93 -14
  51. data/lib/cyberarm_engine/ui/elements/list_box.rb +64 -2
  52. data/lib/cyberarm_engine/ui/elements/progress.rb +5 -5
  53. data/lib/cyberarm_engine/ui/elements/radio.rb +1 -1
  54. data/lib/cyberarm_engine/ui/elements/slider.rb +13 -16
  55. data/lib/cyberarm_engine/ui/elements/stack.rb +1 -1
  56. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +27 -19
  57. data/lib/cyberarm_engine/ui/event.rb +7 -7
  58. data/lib/cyberarm_engine/ui/gui_state.rb +44 -10
  59. data/lib/cyberarm_engine/ui/style.rb +10 -9
  60. data/lib/cyberarm_engine/ui/theme.rb +28 -20
  61. data/lib/cyberarm_engine/vector.rb +33 -30
  62. data/lib/cyberarm_engine/version.rb +2 -2
  63. data/lib/cyberarm_engine/window.rb +27 -18
  64. metadata +65 -15
@@ -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_RGBA, 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,7 @@ module CyberarmEngine
61
62
  CACHE[@size][@font] = font
62
63
  end
63
64
 
64
- return font
65
+ font
65
66
  end
66
67
 
67
68
  def text=(string)
@@ -73,26 +74,32 @@ module CyberarmEngine
73
74
  @rendered_shadow = nil
74
75
  @factor_x = n
75
76
  end
77
+
76
78
  def factor_y=(n)
77
79
  @rendered_shadow = nil
78
80
  @factor_y = n
79
81
  end
82
+
80
83
  def color=(color)
81
84
  @rendered_shadow = nil
82
85
  @color = color
83
86
  end
87
+
84
88
  def shadow=(boolean)
85
89
  @rendered_shadow = nil
86
90
  @shadow = boolean
87
91
  end
92
+
88
93
  def shadow_size=(n)
89
94
  @rendered_shadow = nil
90
95
  @shadow_size = n
91
96
  end
97
+
92
98
  def shadow_alpha=(n)
93
99
  @rendered_shadow = nil
94
100
  @shadow_alpha = n
95
101
  end
102
+
96
103
  def shadow_color=(n)
97
104
  @rendered_shadow = nil
98
105
  @shadow_color = n
@@ -102,35 +109,41 @@ module CyberarmEngine
102
109
  textobject.text_width(text)
103
110
  end
104
111
 
112
+ def markup_width(text = @text)
113
+ textobject.markup_width(text)
114
+ end
115
+
105
116
  def height(text = @text)
106
- text.lines.count > 0 ? (text.lines.count) * textobject.height : @textobject.height
117
+ text.lines.count > 0 ? text.lines.count * textobject.height : @textobject.height
107
118
  end
108
119
 
109
- def draw
120
+ def draw(method = :draw_markup)
110
121
  if @shadow && !ARGV.join.include?("--no-shadow")
111
122
  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)
123
+ shadow_color = @shadow_color || Gosu::Color.rgba(@color.red, @color.green, @color.blue,
124
+ shadow_alpha)
125
+ white = Gosu::Color::WHITE
113
126
 
114
127
  _x = @shadow_size
115
128
  _y = @shadow_size
116
129
 
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)
130
+ @rendered_shadow ||= Gosu.render((width + (shadow_size * 2)).ceil, (height + (@shadow_size * 2)).ceil) do
131
+ @textobject.send(method, @text, _x - @shadow_size, _y, @z, @factor_x, @factor_y, white, :add)
132
+ @textobject.send(method, @text, _x - @shadow_size, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
120
133
 
121
- @textobject.draw_markup(@text, _x, _y-@shadow_size, @z, @factor_x)
122
- @textobject.draw_markup(@text, _x+@shadow_size, _y-@shadow_size, @z)
134
+ @textobject.send(method, @text, _x, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
135
+ @textobject.send(method, @text, _x + @shadow_size, _y - @shadow_size, @z, @factor_x, @factor_y, white, :add)
123
136
 
124
- @textobject.draw_markup(@text, _x, _y+@shadow_size, @z)
125
- @textobject.draw_markup(@text, _x-@shadow_size, _y+@shadow_size, @z)
137
+ @textobject.send(method, @text, _x, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add)
138
+ @textobject.send(method, @text, _x - @shadow_size, _y + @shadow_size, @z, @factor_x, @factor_y, white, :add)
126
139
 
127
- @textobject.draw_markup(@text, _x+@shadow_size, _y, @z)
128
- @textobject.draw_markup(@text, _x+@shadow_size, _y+@shadow_size, @z)
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)
129
142
  end
130
- @rendered_shadow.draw(@x-@shadow_size, @y-@shadow_size, @z, @factor_x, @factor_y, shadow_color)
143
+ @rendered_shadow.draw(@x - @shadow_size, @y - @shadow_size, @z, @factor_x, @factor_y, shadow_color)
131
144
  end
132
145
 
133
- @textobject.draw_markup(@text, @x, @y, @z, @factor_x, @factor_y, @color)
146
+ @textobject.send(method, @text, @x, @y, @z, @factor_x, @factor_y, @color, @mode)
134
147
  end
135
148
 
136
149
  def alpha=(n)
@@ -141,6 +154,7 @@ module CyberarmEngine
141
154
  @color.alpha
142
155
  end
143
156
 
144
- def update; end
157
+ def update
158
+ end
145
159
  end
146
160
  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
@@ -1,6 +1,7 @@
1
1
  module CyberarmEngine
2
2
  class BorderCanvas
3
3
  attr_reader :element, :top, :right, :bottom, :left
4
+
4
5
  def initialize(element:)
5
6
  @element = element
6
7
 
@@ -25,7 +26,7 @@ module CyberarmEngine
25
26
 
26
27
  elsif color.is_a?(Array)
27
28
  if color.size == 1
28
- color=color.first
29
+ color = color.first
29
30
 
30
31
  elsif color.size == 2
31
32
  @top.background = color.first
@@ -61,7 +62,7 @@ module CyberarmEngine
61
62
 
62
63
  def update
63
64
  # TOP
64
- @top.x = @element.x# + @element.border_thickness_left
65
+ @top.x = @element.x # + @element.border_thickness_left
65
66
  @top.y = @element.y
66
67
  @top.z = @element.z
67
68
 
@@ -98,4 +99,4 @@ module CyberarmEngine
98
99
  @left.update
99
100
  end
100
101
  end
101
- end
102
+ end