mittsu 0.1.1 → 0.1.2

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/README.md +1 -1
  4. data/lib/mittsu/cameras/orthographic_camera.rb +13 -0
  5. data/lib/mittsu/cameras/perspective_camera.rb +11 -0
  6. data/lib/mittsu/core/geometry.rb +12 -9
  7. data/lib/mittsu/core/object_3d.rb +33 -66
  8. data/lib/mittsu/lights/ambient_light.rb +8 -0
  9. data/lib/mittsu/lights/directional_light.rb +9 -0
  10. data/lib/mittsu/lights/hemisphere_light.rb +9 -0
  11. data/lib/mittsu/lights/point_light.rb +11 -0
  12. data/lib/mittsu/lights/spot_light.rb +13 -0
  13. data/lib/mittsu/loaders.rb +1 -0
  14. data/lib/mittsu/loaders/mtl_loader.rb +5 -12
  15. data/lib/mittsu/loaders/obj_loader.rb +212 -0
  16. data/lib/mittsu/loaders/obj_mtl_loader.rb +11 -207
  17. data/lib/mittsu/materials/material.rb +5 -2
  18. data/lib/mittsu/materials/mesh_basic_material.rb +0 -9
  19. data/lib/mittsu/math/color.rb +44 -104
  20. data/lib/mittsu/math/matrix3.rb +8 -1
  21. data/lib/mittsu/math/matrix4.rb +6 -0
  22. data/lib/mittsu/math/vector.rb +251 -0
  23. data/lib/mittsu/math/vector2.rb +14 -213
  24. data/lib/mittsu/math/vector3.rb +61 -351
  25. data/lib/mittsu/math/vector4.rb +45 -295
  26. data/lib/mittsu/objects/line.rb +12 -2
  27. data/lib/mittsu/objects/mesh.rb +18 -9
  28. data/lib/mittsu/renderers/glfw_window.rb +15 -13
  29. data/lib/mittsu/renderers/opengl/core/opengl_geometry.rb +253 -0
  30. data/lib/mittsu/renderers/opengl/core/opengl_object_3d.rb +131 -0
  31. data/lib/mittsu/renderers/opengl/lights/opengl_ambient_light.rb +26 -0
  32. data/lib/mittsu/renderers/opengl/lights/opengl_directional_light.rb +35 -0
  33. data/lib/mittsu/renderers/opengl/lights/opengl_hemisphere_light.rb +42 -0
  34. data/lib/mittsu/renderers/opengl/lights/opengl_light.rb +52 -0
  35. data/lib/mittsu/renderers/opengl/lights/opengl_point_light.rb +36 -0
  36. data/lib/mittsu/renderers/opengl/lights/opengl_spot_light.rb +47 -0
  37. data/lib/mittsu/renderers/opengl/materials/opengl_line_basic_material.rb +16 -0
  38. data/lib/mittsu/renderers/opengl/materials/opengl_material.rb +275 -0
  39. data/lib/mittsu/renderers/opengl/materials/opengl_mesh_basic_material.rb +69 -0
  40. data/lib/mittsu/renderers/opengl/materials/opengl_mesh_lambert_material.rb +29 -0
  41. data/lib/mittsu/renderers/opengl/materials/opengl_mesh_phong_material.rb +40 -0
  42. data/lib/mittsu/renderers/opengl/materials/opengl_shader_material.rb +11 -0
  43. data/lib/mittsu/renderers/opengl/objects/opengl_group.rb +8 -0
  44. data/lib/mittsu/renderers/opengl/objects/opengl_line.rb +54 -0
  45. data/lib/mittsu/renderers/opengl/objects/opengl_mesh.rb +77 -0
  46. data/lib/mittsu/renderers/opengl/opengl_buffer.rb +5 -0
  47. data/lib/mittsu/renderers/opengl/opengl_debug.rb +49 -7
  48. data/lib/mittsu/renderers/opengl/opengl_default_target.rb +54 -0
  49. data/lib/mittsu/renderers/opengl/opengl_geometry_group.rb +763 -0
  50. data/lib/mittsu/renderers/opengl/opengl_geometry_like.rb +130 -0
  51. data/lib/mittsu/renderers/opengl/opengl_helper.rb +161 -0
  52. data/lib/mittsu/renderers/opengl/opengl_implementations.rb +61 -0
  53. data/lib/mittsu/renderers/opengl/opengl_light_renderer.rb +43 -0
  54. data/lib/mittsu/renderers/opengl/opengl_mittsu_params.rb +53 -0
  55. data/lib/mittsu/renderers/opengl/opengl_program.rb +147 -296
  56. data/lib/mittsu/renderers/opengl/opengl_state.rb +3 -5
  57. data/lib/mittsu/renderers/opengl/plugins/shadow_map_plugin.rb +12 -10
  58. data/lib/mittsu/renderers/opengl/scenes/opengl_scene.rb +8 -0
  59. data/lib/mittsu/renderers/opengl/textures/opengl_compressed_texture.rb +21 -0
  60. data/lib/mittsu/renderers/opengl/textures/opengl_cube_texture.rb +75 -0
  61. data/lib/mittsu/renderers/opengl/textures/opengl_data_texture.rb +23 -0
  62. data/lib/mittsu/renderers/opengl/textures/opengl_texture.rb +111 -0
  63. data/lib/mittsu/renderers/opengl_render_target.rb +117 -2
  64. data/lib/mittsu/renderers/opengl_renderer.rb +653 -2978
  65. data/lib/mittsu/renderers/shaders/rbsl_loader.rb +166 -0
  66. data/lib/mittsu/renderers/shaders/shader_chunk.rb +6 -9
  67. data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_fragment.glsl +36 -37
  68. data/lib/mittsu/renderers/shaders/shader_lib.rb +26 -403
  69. data/lib/mittsu/renderers/shaders/shader_lib/basic/basic_fragment.rbsl +37 -0
  70. data/lib/mittsu/renderers/shaders/shader_lib/basic/basic_uniforms.rbslu +3 -0
  71. data/lib/mittsu/renderers/shaders/shader_lib/basic/basic_vertex.rbsl +33 -0
  72. data/lib/mittsu/renderers/shaders/shader_lib/cube/cube_fragment.rbsl +12 -0
  73. data/lib/mittsu/renderers/shaders/shader_lib/cube/cube_uniforms.rbslu +2 -0
  74. data/lib/mittsu/renderers/shaders/shader_lib/cube/cube_vertex.rbsl +12 -0
  75. data/lib/mittsu/renderers/shaders/shader_lib/depth_rgba/depth_rgba_fragment.rbsl +26 -0
  76. data/lib/mittsu/renderers/shaders/shader_lib/depth_rgba/depth_rgba_uniforms.rbslu +0 -0
  77. data/lib/mittsu/renderers/shaders/shader_lib/depth_rgba/depth_rgba_vertex.rbsl +12 -0
  78. data/lib/mittsu/renderers/shaders/shader_lib/lambert/lambert_fragment.rbsl +56 -0
  79. data/lib/mittsu/renderers/shaders/shader_lib/lambert/lambert_uniforms.rbslu +7 -0
  80. data/lib/mittsu/renderers/shaders/shader_lib/lambert/lambert_vertex.rbsl +37 -0
  81. data/lib/mittsu/renderers/shaders/shader_lib/phong/phong_fragment.rbsl +45 -0
  82. data/lib/mittsu/renderers/shaders/shader_lib/phong/phong_uniforms.rbslu +11 -0
  83. data/lib/mittsu/renderers/shaders/shader_lib/phong/phong_vertex.rbsl +43 -0
  84. data/lib/mittsu/renderers/shaders/shader_templates/fragment.glsl.erb +105 -0
  85. data/lib/mittsu/renderers/shaders/shader_templates/vertex.glsl.erb +143 -0
  86. data/lib/mittsu/renderers/shaders/uniforms_lib.rb +54 -55
  87. data/lib/mittsu/textures/texture.rb +5 -2
  88. data/lib/mittsu/version.rb +1 -1
  89. data/run_all_examples.sh +7 -0
  90. metadata +77 -28
  91. data/.ruby-version +0 -1
  92. data/lib/mittsu/core/hash_object.rb +0 -19
@@ -0,0 +1,69 @@
1
+ module Mittsu
2
+ class OpenGLMeshBasicMaterial < OpenGLMaterial
3
+ def refresh_uniforms(uniforms)
4
+ refresh_map_uniforms(uniforms)
5
+ refresh_env_map_uniforms(uniforms)
6
+ refresh_other_uniforms(uniforms)
7
+ end
8
+
9
+ protected
10
+
11
+ def init_shader
12
+ @shader = ShaderLib.create_shader(shader_id)
13
+ end
14
+
15
+ def shader_id
16
+ :basic
17
+ end
18
+
19
+ private
20
+
21
+ def get_uv_scale_map
22
+ @material.map ||
23
+ @material.specular_map ||
24
+ @material.normal_map ||
25
+ @material.bump_map ||
26
+ @material.alpha_map
27
+ end
28
+
29
+ def refresh_map_uniforms(uniforms)
30
+ uniforms['map'].value = @material.map
31
+ uniforms['lightMap'].value = @material.light_map
32
+ uniforms['specularMap'].value = @material.specular_map
33
+ uniforms['alphaMap'].value = @material.alpha_map
34
+
35
+ if @material.bump_map
36
+ uniforms['bumpMap'].value = @material.bump_map
37
+ uniforms['bumpScale'].value = @material.bump_scale
38
+ end
39
+
40
+ if @material.normal_map
41
+ uniforms['normalMap'].value = @material.normal_map
42
+ uniforms['normalScale'].value.copy(@material.normal_scale)
43
+ end
44
+ end
45
+
46
+ def refresh_env_map_uniforms(uniforms)
47
+ uv_scale_map = get_uv_scale_map
48
+
49
+ if uv_scale_map
50
+ offset = uv_scale_map.offset
51
+ repeat = uv_scale_map.repeat
52
+
53
+ uniforms['offsetRepeat'].value.set(offset.x, offset.y, repeat.x, repeat.y)
54
+ end
55
+
56
+ uniforms['envMap'].value = @material.env_map
57
+ # TODO: when OpenGLRenderTargetCube exists
58
+ # uniforms['flipEnvMap'].value = @material.envMap.is_a?(OpenGLRenderTargetCube) ? 1 : - 1
59
+ end
60
+
61
+ def refresh_other_uniforms(uniforms)
62
+ uniforms['opacity'].value = @material.opacity
63
+ uniforms['diffuse'].value = @material.color
64
+
65
+ uniforms['reflectivity'].value = @material.reflectivity
66
+ uniforms['refractionRatio'].value = @material.refraction_ratio
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,29 @@
1
+ module Mittsu
2
+ class OpenGLMeshLambertMaterial < OpenGLMeshBasicMaterial
3
+ def refresh_uniforms(uniforms)
4
+ super
5
+
6
+ uniforms['emissive'].value = @material.emissive
7
+
8
+ if @material.wrap_around
9
+ uniforms['wrapRGB'].value.copy(@material.wrap_rgb)
10
+ end
11
+ end
12
+
13
+ def needs_view_matrix_uniform?
14
+ true
15
+ end
16
+
17
+ def needs_lights?
18
+ true
19
+ end
20
+
21
+ def init_shader
22
+ @shader = ShaderLib.create_shader(shader_id)
23
+ end
24
+
25
+ def shader_id
26
+ :lambert
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ module Mittsu
2
+ class OpenGLMeshPhongMaterial < OpenGLMeshBasicMaterial
3
+ def needs_face_normals?
4
+ false
5
+ end
6
+
7
+ def refresh_uniforms(uniforms)
8
+ super
9
+
10
+ uniforms['shininess'].value = @material.shininess
11
+
12
+ uniforms['emissive'].value = @material.emissive
13
+ uniforms['specular'].value = @material.specular
14
+
15
+ if @material.wrap_around
16
+ uniforms['wrapRGB'].value.copy(@material.wrap_rgb)
17
+ end
18
+ end
19
+
20
+ def needs_camera_position_uniform?
21
+ true
22
+ end
23
+
24
+ def needs_view_matrix_uniform?
25
+ true
26
+ end
27
+
28
+ def needs_lights?
29
+ true
30
+ end
31
+
32
+ def init_shader
33
+ @shader = ShaderLib.create_shader(shader_id)
34
+ end
35
+
36
+ def shader_id
37
+ :phong
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,11 @@
1
+ module Mittsu
2
+ class OpenGLShaderMaterial < OpenGLMaterial
3
+ def needs_camera_position_uniform?
4
+ true
5
+ end
6
+
7
+ def needs_view_matrix_uniform?
8
+ true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ module Mittsu
2
+ class OpenGLGroup < OpenGLObject3D
3
+ def project
4
+ return unless @object.visible
5
+ project_children
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,54 @@
1
+ module Mittsu
2
+ class OpenGLLine < OpenGLObject3D
3
+ def initialize(line, renderer)
4
+ super
5
+ @line = line
6
+ end
7
+
8
+ def render_buffer(camera, lights, fog, material, geometry_group, update_buffers)
9
+ mode = @line.mode == LineStrip ? GL_LINE_STRIP : GL_LINES
10
+
11
+ @renderer.state.set_line_width(material.line_width * @renderer.pixel_ratio)
12
+
13
+ glDrawArrays(mode, 0, geometry_group.line_count)
14
+
15
+ @renderer.info[:render][:calls] += 1
16
+ end
17
+
18
+ def update
19
+ # TODO: glBindVertexArray ???
20
+ geometry = @line.geometry
21
+ material = buffer_material(geometry)
22
+ material_impl = material.implementation(@renderer)
23
+ custom_attributes_dirty = material.attributes && material_impl.custom_attributes_dirty?
24
+
25
+ if geometry.vertices_need_update || geometry.colors_need_update || geometry.line_distances_need_update || custom_attributes_dirty
26
+ geometry_impl = geometry.implementation(self)
27
+ geometry_impl.set_line_buffers(GL_DYNAMIC_DRAW)
28
+ end
29
+
30
+ geometry.vertices_need_update = false
31
+ geometry.colors_need_update = false
32
+ geometry.line_distances_need_update = false
33
+
34
+ material.attributes && material_impl.clear_custom_attributes
35
+ end
36
+
37
+ def init_geometry
38
+ geometry = @object.geometry
39
+ geometry_impl = geometry.implementation(@renderer)
40
+ if geometry_impl.vertex_buffer.nil?
41
+ geometry_impl.create_line_buffers
42
+ geometry_impl.init_line_buffers(@object)
43
+
44
+ geometry.vertices_need_update = true
45
+ geometry.colors_need_update = true
46
+ geometry.line_distances_need_update
47
+ end
48
+ end
49
+
50
+ def add_opengl_object
51
+ @renderer.add_opengl_object(@object.geometry, @object)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,77 @@
1
+ module Mittsu
2
+ class OpenGLMesh < OpenGLObject3D
3
+ def initialize(mesh, renderer)
4
+ super
5
+ @mesh = mesh
6
+ end
7
+
8
+ def render_buffer(camera, lights, fog, material, geometry_group, update_buffers)
9
+ type = GL_UNSIGNED_INT # geometry_group.type_array == Uint32Array ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT
10
+
11
+ # wireframe
12
+ if material.wireframe
13
+ @renderer.state.set_line_width(material.wireframe_linewidth * @pixel_ratio)
14
+
15
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry_group.line_buffer) if update_buffers
16
+ glDrawElements(GL_LINES, geometry_group.line_count, type, 0)
17
+
18
+ # triangles
19
+ else
20
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry_group.face_buffer) if update_buffers
21
+ glDrawElements(GL_TRIANGLES, geometry_group.face_count, type, 0)
22
+ end
23
+
24
+ @renderer.info[:render][:calls] += 1
25
+ @renderer.info[:render][:vertices] += geometry_group.face_count
26
+ @renderer.info[:render][:faces] += geometry_group.face_count / 3
27
+ end
28
+
29
+ def update
30
+ # check all geometry groubs
31
+ geometry = @mesh.geometry
32
+ geometry_impl = geometry.implementation(self)
33
+
34
+ material = nil
35
+ material_impl = nil
36
+ geometry_impl.groups.each do |geometry_group|
37
+ # TODO: place to put this???
38
+ # glBindVertexArray(geometry_group.vertex_array_object)
39
+ material = buffer_material(geometry_group)
40
+ material_impl = material.implementation(@renderer)
41
+
42
+ custom_attributes_dirty = material.attributes && material_impl.custom_attributes_dirty?
43
+
44
+ if geometry.vertices_need_update || geometry.morph_targets_need_update || geometry.elements_need_update || geometry.uvs_need_update || geometry.normals_need_update || geometry.colors_need_update || geometry.tangents_need_update || custom_attributes_dirty
45
+ geometry_group.set_mesh_buffers(@mesh, GL_DYNAMIC_DRAW, !geometry.dynamic, material)
46
+ end
47
+ end
48
+
49
+ geometry.vertices_need_update = false
50
+ geometry.morph_targets_need_update = false
51
+ geometry.elements_need_update = false
52
+ geometry.uvs_need_update = false
53
+ geometry.normals_need_update = false
54
+ geometry.colors_need_update = false
55
+ geometry.tangents_need_update = false
56
+
57
+ material.attributes && material_impl.clear_custom_attributes(material)
58
+ end
59
+
60
+ def init_geometry
61
+ @object.geometry.implementation(@renderer).init_geometry_groups(@object)
62
+ end
63
+
64
+ def add_opengl_object
65
+ geometry = @object.geometry
66
+ case geometry
67
+ when BufferGeometry
68
+ @renderer.add_opengl_object(geometry, @object)
69
+ when Geometry
70
+ geometry_impl = geometry.implementation(self)
71
+ geometry_impl.groups.each do |group|
72
+ @renderer.add_opengl_object(group, @object)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,5 @@
1
+ module Mittsu
2
+ class OpenGLBuffer < Struct.new(:buffer, :object, :material, :z)
3
+ attr_accessor :render, :transparent, :opaque
4
+ end
5
+ end
@@ -12,6 +12,21 @@ ERROR_STRINGS = {
12
12
  }
13
13
 
14
14
  module OpenGLDebug
15
+ class DebugShader
16
+ def initialize(handle)
17
+ @handle = handle
18
+ @uniforms = {}
19
+ end
20
+
21
+ def set_uniform(handle, name)
22
+ @uniforms[handle] = name
23
+ end
24
+
25
+ def get_uniform_name(handle)
26
+ @uniforms[handle]
27
+ end
28
+ end
29
+
15
30
  module OpenGLProxy
16
31
  extend OpenGL
17
32
  end
@@ -24,15 +39,42 @@ module OpenGLDebug
24
39
  const_set c, OpenGL.const_get(c)
25
40
  end
26
41
 
42
+ def call_debug_method m, *args
43
+ r = OpenGLProxy.send(m, *args)
44
+ if m.to_s.start_with?('glUniform')
45
+ uniform_name = @@current_shader.get_uniform_name(args.first)
46
+ call = "#{m}('#{uniform_name}',#{args[1..-1].map { |s| s.to_s[0..20] }.join(', ')})"
47
+ else
48
+ call = "#{m}(#{args.map { |s| s.to_s[0..20] }.join(', ')})"
49
+ end
50
+ ret = r.nil? ? '' : " => #{r}"
51
+ puts "#{call}#{ret} (#{caller[0]})"
52
+ e = OpenGLProxy.glGetError
53
+ raise "ERROR: #{m} => #{ERROR_STRINGS[e]}" unless e == OpenGL::GL_NO_ERROR
54
+ r
55
+ end
56
+
27
57
  OpenGL.instance_methods.each do |m|
28
58
  define_method m do |*args|
29
- r = OpenGLProxy.send(m, *args)
30
- call = "#{m}(#{args.map { |s| s.to_s[0..20] }.join(', ')})"
31
- ret = r.nil? ? '' : " => #{r}"
32
- puts "#{call}#{ret}"
33
- e = OpenGLProxy.glGetError
34
- raise "ERROR: #{m} => #{ERROR_STRINGS[e]}" unless e == OpenGL::GL_NO_ERROR
35
- r
59
+ self.call_debug_method(m, *args)
60
+ end
61
+ end
62
+
63
+ def glCreateProgram
64
+ call_debug_method(:glCreateProgram).tap do |handle|
65
+ @@shaders ||= {}
66
+ @@shaders[handle] = DebugShader.new(handle)
67
+ end
68
+ end
69
+
70
+ def glUseProgram(handle)
71
+ @@current_shader = @@shaders[handle]
72
+ call_debug_method(:glUseProgram, handle)
73
+ end
74
+
75
+ def glGetUniformLocation(program, name)
76
+ call_debug_method(:glGetUniformLocation, program, name).tap do |handle|
77
+ @@shaders[program].set_uniform(handle, name)
36
78
  end
37
79
  end
38
80
  end
@@ -0,0 +1,54 @@
1
+ module Mittsu
2
+ class OpenGLDefaultTarget
3
+ attr_accessor :viewport_width, :viewport_height, :viewport_x, :viewport_y
4
+ alias :width :viewport_width
5
+ alias :height :viewport_height
6
+
7
+ def initialize renderer
8
+ @renderer = renderer
9
+ @viewport_width = 0
10
+ @viewport_height = 0
11
+ @viewport_x = 0
12
+ @viewport_y = 0
13
+ end
14
+
15
+ def framebuffer
16
+ 0
17
+ end
18
+
19
+ def update_mipmap
20
+ # NOOP
21
+ end
22
+
23
+ def setup_buffers
24
+ # NOOP
25
+ end
26
+
27
+ def use
28
+ glBindFramebuffer(GL_FRAMEBUFFER, 0)
29
+ use_viewport
30
+ end
31
+
32
+ def use_viewport
33
+ glViewport(@viewport_x, @viewport_y, @viewport_width, @viewport_height)
34
+ end
35
+
36
+ def set_and_use_viewport(x, y, width, height)
37
+ set_viewport(x, y, width, height)
38
+ use_viewport
39
+ end
40
+
41
+ def set_viewport(x, y, width, height)
42
+ @viewport_x, @viewport_y = x, y
43
+ set_viewport_size(width, height)
44
+ end
45
+
46
+ def set_viewport_size(width, height)
47
+ @viewport_width, @viewport_height = width, height
48
+ end
49
+
50
+ def implementation(_)
51
+ self
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,763 @@
1
+ require 'mittsu/renderers/opengl/opengl_geometry_like'
2
+
3
+ module Mittsu
4
+ class OpenGLGeometryGroup
5
+ include OpenGLGeometryLike
6
+
7
+ attr_reader :id
8
+
9
+ alias :initted_arrays? :initted_arrays
10
+
11
+ def initialize material_index, num_morph_targets, num_morph_normals, renderer
12
+ @id = (@@id ||= 1).tap { @@id += 1 }
13
+
14
+ @faces3 = []
15
+ @num_vertices = 0
16
+
17
+ @material_index = material_index
18
+
19
+ @num_morph_targets = num_morph_targets
20
+ @num_morph_normals = num_morph_normals
21
+
22
+ @renderer = renderer
23
+ end
24
+
25
+ def create_mesh_buffers
26
+ @vertex_array_object = glCreateVertexArray
27
+
28
+ @vertex_buffer = glCreateBuffer
29
+ @normal_buffer = glCreateBuffer
30
+ @tangent_buffer = glCreateBuffer
31
+ @color_buffer = glCreateBuffer
32
+ @uv_buffer = glCreateBuffer
33
+ @uv2_buffer = glCreateBuffer
34
+
35
+ @skin_indices_buffer = glCreateBuffer
36
+ @skin_weights_buffer = glCreateBuffer
37
+
38
+ @face_buffer = glCreateBuffer
39
+ @line_buffer = glCreateBuffer
40
+
41
+ if !@num_morph_targets.nil?
42
+ @morph_targets_buffers = []
43
+
44
+ @num_morph_targets.times do |m|
45
+ @morph_targets_buffers << glCreateBuffer
46
+ end
47
+ end
48
+
49
+ if !@num_morph_normals.nil?
50
+ @morph_normals_buffers = []
51
+
52
+ @num_morph_normals.times do |m|
53
+ @morph_normals_buffers << glCreateBuffer
54
+ end
55
+ end
56
+ end
57
+
58
+ def init_mesh_buffers(object)
59
+ geometry = object.geometry
60
+ object_impl = object.implementation(@renderer)
61
+
62
+ nvertices = @faces3.length * 3
63
+ nvertices2 = nvertices * 2
64
+ nvertices3 = nvertices * 3
65
+ nvertices4 = nvertices * 4
66
+ ntris = @faces3.length * 1
67
+ nlines = @faces3.length * 3
68
+
69
+ material = object_impl.buffer_material(self)
70
+
71
+ @vertex_array = Array.new(nvertices3) # Float32Array
72
+ @normal_array = Array.new(nvertices3) # Float32Array
73
+ @color_array = Array.new(nvertices3) # Float32Array
74
+ @uv_array = Array.new(nvertices2) # Float32Array
75
+
76
+ if geometry.face_vertex_uvs.length > 1
77
+ @uv2_array = Array.new(nvertices2) # Float32Array
78
+ end
79
+
80
+ if geometry.has_tangents
81
+ @tangent_array = Array.new(nvertices4) # Float32Array
82
+ end
83
+
84
+ if !object.geometry.skin_weights.empty? && !object.geometry.skin_indices.empty?
85
+ @skin_indices_array = Array.new(nvertices4) # Float32Array
86
+ @skin_weight_array = Array.new(nvertices4)
87
+ end
88
+
89
+ # UintArray from OES_element_index_uint ???
90
+
91
+ @type_array = Array # UintArray ???
92
+ @face_array = Array.new(ntris * 3)
93
+ @line_array = Array.new(nlines * 2)
94
+
95
+ num_morph_targets = @num_morph_targets
96
+
97
+ if !num_morph_targets.zero?
98
+ @morph_targets_arrays = []
99
+
100
+ num_morph_targets.times do |m|
101
+ @morph_targets_arrays << Array.new(nvertices3) # Float32Array ???
102
+ end
103
+ end
104
+
105
+ num_morph_normals = @num_morph_normals
106
+
107
+ if !num_morph_targets.zero?
108
+ @morph_normals_arrays = []
109
+
110
+ num_morph_normals.times do |m|
111
+ @morph_normals_arrays << Array.new(nvertices3) # Float32Array ???
112
+ end
113
+ end
114
+
115
+ @face_count = ntris * 3
116
+ @line_count = nlines * 2
117
+
118
+ # custom attributes
119
+
120
+ if material.attributes
121
+ if @custom_attributes_list.nil?
122
+ @custom_attributes_list = []
123
+ end
124
+
125
+ material.attributes.each do |(name, original_attribute)|
126
+ attribute = {}
127
+ original_attribute.each do |(key, value)|
128
+ attribute[key] = value
129
+ end
130
+
131
+ if !attribute[:_opengl_initialized] || attribute[:create_unique_buffers]
132
+ attribute[:_opengl_initialized] = true
133
+
134
+ size = case attribute[:type]
135
+ when :v2 then 2
136
+ when :v3, :c then 3
137
+ when :v4 then 4
138
+ else 1 # :f and :i
139
+ end
140
+
141
+ attribute[:size] = size
142
+ attribute[:array] = Array.new(nvertices * size) # Float32Array
143
+
144
+ attribute[:buffer] = glCreateBuffer
145
+ attribute[:buffer_belongs_to_attribute] = name
146
+
147
+ original_attribute[:needs_update] = true
148
+ attribute[:_original] = original_attribute
149
+ end
150
+
151
+ @custom_attributes_list << attribute
152
+ end
153
+ end
154
+
155
+ @initted_arrays = true
156
+ end
157
+
158
+ def set_mesh_buffers(object, hint, should_dispose, material)
159
+ return unless @initted_arrays
160
+
161
+ geometry = object.geometry
162
+ material_impl = material.implementation(@renderer)
163
+
164
+ needs_face_normals = material_impl.needs_face_normals?
165
+
166
+ vertex_index = 0
167
+
168
+ offset = 0
169
+ offset_uv = 0
170
+ offset_uv2 = 0
171
+ offset_face = 0
172
+ offset_normal = 0
173
+ offset_tangent = 0
174
+ offset_line = 0
175
+ offset_color = 0
176
+ offset_skin = 0
177
+ offset_morph_target = 0
178
+ offset_custom = 0
179
+
180
+ vertices = geometry.vertices
181
+ obj_faces = geometry.faces
182
+
183
+ obj_uvs = geometry.face_vertex_uvs[0]
184
+ obj_uvs2 = geometry.face_vertex_uvs[1]
185
+
186
+ obj_skin_indices = geometry.skin_indices
187
+ obj_skin_weights = geometry.skin_weights
188
+
189
+ morph_targets = geometry.morph_targets
190
+ morph_normals = geometry.morph_normals
191
+
192
+ if geometry.vertices_need_update
193
+ @faces3.each do |chf|
194
+ face = obj_faces[chf]
195
+
196
+ v1 = vertices[face.a]
197
+ v2 = vertices[face.b]
198
+ v3 = vertices[face.c]
199
+
200
+ @vertex_array[offset] = v1.x
201
+ @vertex_array[offset + 1] = v1.y
202
+ @vertex_array[offset + 2] = v1.z
203
+
204
+ @vertex_array[offset + 3] = v2.x
205
+ @vertex_array[offset + 4] = v2.y
206
+ @vertex_array[offset + 5] = v2.z
207
+
208
+ @vertex_array[offset + 6] = v3.x
209
+ @vertex_array[offset + 7] = v3.y
210
+ @vertex_array[offset + 8] = v3.z
211
+
212
+ offset += 9
213
+ end
214
+
215
+ glBindBuffer(GL_ARRAY_BUFFER, @vertex_buffer)
216
+ glBufferData_easy(GL_ARRAY_BUFFER, @vertex_array, hint)
217
+ end
218
+
219
+ if geometry.morph_targets_need_update
220
+ morph_targets.each_index do |vk|
221
+ @faces3.each do |chf|
222
+ face = obj_faces[chf]
223
+
224
+ # morph positions
225
+
226
+ v1 = morph_targets[vk].vertices[face.a]
227
+ v2 = morph_targets[vk].vertices[face.b]
228
+ v3 = morph_targets[vk].vertices[face.c]
229
+
230
+ vka = @morph_targets_arrays[vk]
231
+
232
+ vka[offset_morph_target] = v1.x
233
+ vka[offset_morph_target + 1] = v1.y
234
+ vka[offset_morph_target + 2] = v1.z
235
+
236
+ vka[offset_morph_target + 3] = v2.x
237
+ vka[offset_morph_target + 4] = v2.y
238
+ vka[offset_morph_target + 5] = v2.z
239
+
240
+ vka[offset_morph_target + 6] = v3.x
241
+ vka[offset_morph_target + 7] = v3.y
242
+ vka[offset_morph_target + 8] = v3.z
243
+
244
+ # morph normals
245
+
246
+ if material.morph_normals
247
+ if needs_face_normals
248
+ n1 = morph_normals[vk].face_normals[chf]
249
+ n2 = n1
250
+ n3 = n1
251
+ else
252
+ face_vertex_normals = morph_normals[vk].vertex_normals[chf]
253
+
254
+ n1 = face_vertex_normals.a
255
+ n2 = face_vertex_normals.b
256
+ n3 = face_vertex_normals.c
257
+ end
258
+
259
+ nka = @morph_normals_arrays[vk]
260
+
261
+ nka[offset_morph_target] = n1.x
262
+ nka[offset_morph_target + 1] = n1.y
263
+ nka[offset_morph_target + 2] = n1.z
264
+
265
+ nka[offset_morph_target + 3] = n2.x
266
+ nka[offset_morph_target + 4] = n2.y
267
+ nka[offset_morph_target + 5] = n2.z
268
+
269
+ nka[offset_morph_target + 6] = n3.x
270
+ nka[offset_morph_target + 7] = n3.y
271
+ nka[offset_morph_target + 8] = n3.z
272
+ end
273
+
274
+ #
275
+
276
+ offset_morph_target += 9
277
+ end
278
+
279
+ glBindBuffer(GL_ARRAY_BUFFER, @morph_targets_buffers[vk])
280
+ glBufferData_easy(GL_ARRAY_BUFFER, @morph_targets_arrays[vk], hint)
281
+
282
+ if material.morph_normals
283
+ glBindBuffer(GL_ARRAY_BUFFER, @morph_normals_buffers[vk])
284
+ glBufferData_easy(GL_ARRAY_BUFFER, @morph_normals_arrays[vk], hint)
285
+ end
286
+ end
287
+ end
288
+
289
+ if !obj_skin_weights.empty?
290
+ @faces3.each do |chf|
291
+ face = obj_faces[chf]
292
+
293
+ # weights
294
+
295
+ sw1 = obj_skin_weights[face.a]
296
+ sw2 = obj_skin_weights[face.b]
297
+ sw3 = obj_skin_weights[face.c]
298
+
299
+ @skin_weight_array[offset_skin] = sw1.x
300
+ @skin_weight_array[offset_skin + 1] = sw1.y
301
+ @skin_weight_array[offset_skin + 2] = sw1.z
302
+ @skin_weight_array[offset_skin + 3] = sw1.w
303
+
304
+ @skin_weight_array[offset_skin + 4] = sw2.x
305
+ @skin_weight_array[offset_skin + 5] = sw2.y
306
+ @skin_weight_array[offset_skin + 6] = sw2.z
307
+ @skin_weight_array[offset_skin + 7] = sw2.w
308
+
309
+ @skin_weight_array[offset_skin + 8] = sw3.x
310
+ @skin_weight_array[offset_skin + 9] = sw3.y
311
+ @skin_weight_array[offset_skin + 10] = sw3.z
312
+ @skin_weight_array[offset_skin + 11] = sw3.w
313
+
314
+ # indices
315
+
316
+ si1 = obj_skin_indices[face.a]
317
+ si2 = obj_skin_indices[face.b]
318
+ si3 = obj_skin_indices[face.c]
319
+
320
+ @skin_indices_array[offset_skin] = si1.x
321
+ @skin_indices_array[offset_skin + 1] = si1.y
322
+ @skin_indices_array[offset_skin + 2] = si1.z
323
+ @skin_indices_array[offset_skin + 3] = si1.w
324
+
325
+ @skin_indices_array[offset_skin + 4] = si2.x
326
+ @skin_indices_array[offset_skin + 5] = si2.y
327
+ @skin_indices_array[offset_skin + 6] = si2.z
328
+ @skin_indices_array[offset_skin + 7] = si2.w
329
+
330
+ @skin_indices_array[offset_skin + 8] = si3.x
331
+ @skin_indices_array[offset_skin + 9] = si3.y
332
+ @skin_indices_array[offset_skin + 10] = si3.z
333
+ @skin_indices_array[offset_skin + 11] = si3.w
334
+
335
+ offset_skin += 12
336
+ end
337
+
338
+ if offset_skin > 0
339
+ glBindBuffer(GL_ARRAY_BUFFER, @skin_indices_buffer)
340
+ glBufferData_easy(GL_ARRAY_BUFFER, @skin_indices_array, hint)
341
+
342
+ glBindBuffer(GL_ARRAY_BUFFER, @skin_weights_buffer)
343
+ glBufferData_easy(GL_ARRAY_BUFFER, @skin_weight_array, hint)
344
+ end
345
+ end
346
+
347
+ if geometry.colors_need_update
348
+ @faces3.each do |chf|
349
+ face = obj_faces[chf]
350
+
351
+ face_vertex_colors = face.vertex_colors
352
+ face_color = face.color
353
+
354
+ if face_vertex_colors.length == 3 && material.vertex_colors == VertexColors
355
+ c1 = face_vertex_colors[0]
356
+ c2 = face_vertex_colors[1]
357
+ c3 = face_vertex_colors[2]
358
+ else
359
+ c1 = face_color
360
+ c2 = face_color
361
+ c3 = face_color
362
+ end
363
+
364
+ @color_array[offset_color] = c1.r
365
+ @color_array[offset_color + 1] = c1.g
366
+ @color_array[offset_color + 2] = c1.b
367
+
368
+ @color_array[offset_color + 3] = c2.r
369
+ @color_array[offset_color + 4] = c2.g
370
+ @color_array[offset_color + 5] = c2.b
371
+
372
+ @color_array[offset_color + 6] = c3.r
373
+ @color_array[offset_color + 7] = c3.g
374
+ @color_array[offset_color + 8] = c3.b
375
+
376
+ offset_color += 9
377
+ end
378
+
379
+ if offset_color > 0
380
+ glBindBuffer(GL_ARRAY_BUFFER, @color_buffer)
381
+ glBufferData_easy(GL_ARRAY_BUFFER, @color_array, hint)
382
+ end
383
+ end
384
+
385
+ if geometry.tangents_need_update && geometry.has_tangents
386
+ @faces3.each do |chf|
387
+ face = obj_faces[chf]
388
+
389
+ face_vertex_tangents = face.vertex_tangents
390
+
391
+ t1 = face_vertex_tangents[0]
392
+ t2 = face_vertex_tangents[1]
393
+ t3 = face_vertex_tangents[2]
394
+
395
+ @tangent_array[offset_tangent] = t1.x
396
+ @tangent_array[offset_tangent + 1] = t1.y
397
+ @tangent_array[offset_tangent + 2] = t1.z
398
+ @tangent_array[offset_tangent + 3] = t1.w
399
+
400
+ @tangent_array[offset_tangent + 4] = t2.x
401
+ @tangent_array[offset_tangent + 5] = t2.y
402
+ @tangent_array[offset_tangent + 6] = t2.z
403
+ @tangent_array[offset_tangent + 7] = t2.w
404
+
405
+ @tangent_array[offset_tangent + 8] = t3.x
406
+ @tangent_array[offset_tangent + 9] = t3.y
407
+ @tangent_array[offset_tangent + 10] = t3.z
408
+ @tangent_array[offset_tangent + 11] = t3.w
409
+
410
+ offset_tangent += 12
411
+ end
412
+
413
+ glBindBuffer(GL_ARRAY_BUFFER, @angent_buffer)
414
+ glBufferData_easy(GL_ARRAY_BUFFER, @tangent_array, hint)
415
+ end
416
+
417
+ if geometry.normals_need_update
418
+ @faces3.each do |chf|
419
+ face = obj_faces[chf]
420
+
421
+ face_vertex_normals = face.vertex_normals
422
+ face_normal = face.normal
423
+
424
+ if face_vertex_normals.length == 3 && !needs_face_normals
425
+ 3.times do |i|
426
+ vn = face_vertex_normals[i]
427
+
428
+ @normal_array[offset_normal] = vn.x
429
+ @normal_array[offset_normal + 1] = vn.y
430
+ @normal_array[offset_normal + 2] = vn.z
431
+
432
+ offset_normal += 3
433
+ end
434
+ else
435
+ 3.times do |i|
436
+ @normal_array[offset_normal] = face_normal.x
437
+ @normal_array[offset_normal + 1] = face_normal.y
438
+ @normal_array[offset_normal + 2] = face_normal.z
439
+
440
+ offset_normal += 3
441
+ end
442
+ end
443
+ end
444
+
445
+ glBindBuffer(GL_ARRAY_BUFFER, @normal_buffer)
446
+ glBufferData_easy(GL_ARRAY_BUFFER, @normal_array, hint)
447
+ end
448
+
449
+ if geometry.uvs_need_update && obj_uvs
450
+ @faces3.each do |fi|
451
+ uv = obj_uvs[fi]
452
+
453
+ next if uv.nil?
454
+
455
+ 3.times do |i|
456
+ uvi = uv[i]
457
+
458
+ @uv_array[offset_uv] = uvi.x
459
+ @uv_array[offset_uv + 1] = uvi.y
460
+
461
+ offset_uv += 2
462
+ end
463
+ end
464
+
465
+ if offset_uv > 0
466
+ glBindBuffer(GL_ARRAY_BUFFER, @uv_buffer)
467
+ glBufferData_easy(GL_ARRAY_BUFFER, @uv_array, hint)
468
+ end
469
+ end
470
+
471
+ if geometry.uvs_need_update && obj_uvs2
472
+ @faces3.each do |fi|
473
+ uv2 = obj_uvs2[fi]
474
+
475
+ next if uv2.nil?
476
+
477
+ 3.times do |i|
478
+ uv2i = uv2[i]
479
+
480
+ @uv2_array[offset_uv2] = uv2i.x
481
+ @uv2_array[offset_uv2 + 1] = uv2i.y
482
+
483
+ offset_uv2 += 2
484
+ end
485
+ end
486
+
487
+ if offset_uv2 > 0
488
+ glBindBuffer(GL_ARRAY_BUFFER, @uv2_buffer)
489
+ glBufferData_easy(GL_ARRAY_BUFFER, @uv2_array, hint)
490
+ end
491
+ end
492
+
493
+ if geometry.elements_need_update
494
+ @faces3.each do |chf|
495
+ @face_array[offset_face] = vertex_index
496
+ @face_array[offset_face + 1] = vertex_index + 1
497
+ @face_array[offset_face + 2] = vertex_index + 2
498
+
499
+ offset_face += 3
500
+
501
+ @line_array[offset_line] = vertex_index
502
+ @line_array[offset_line + 1] = vertex_index + 1
503
+
504
+ @line_array[offset_line + 2] = vertex_index
505
+ @line_array[offset_line + 3] = vertex_index + 2
506
+
507
+ @line_array[offset_line + 4] = vertex_index + 1
508
+ @line_array[offset_line + 5] = vertex_index + 2
509
+
510
+ offset_line += 6
511
+
512
+ vertex_index += 3
513
+ end
514
+
515
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, @face_buffer)
516
+ glBufferData_easy(GL_ELEMENT_ARRAY_BUFFER, @face_array, hint)
517
+
518
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, @line_buffer)
519
+ glBufferData_easy(GL_ELEMENT_ARRAY_BUFFER, @line_array, hint)
520
+ end
521
+
522
+ if @custom_attributes_list
523
+ @custom_attributes_list.each do |custom_attribute|
524
+ next if !custom_attribute[:_original][:needs_update]
525
+
526
+ offset_custom = 0
527
+
528
+ if custom_attribute[:size] == 1
529
+ if custom_attribute[:bound_to].nil? || custom_attribute[:bound_to] == :vertices
530
+ @faces3.each do |chf|
531
+ face = obj_faces[chf]
532
+
533
+ custom_attribute[:array][offset_custom] = custom_attribute[:value][face.a]
534
+ custom_attribute[:array][offset_custom + 1] = custom_attribute[:value][face.b]
535
+ custom_attribute[:array][offset_custom + 2] = custom_attribute[:value][face.c]
536
+
537
+ offset_custom += 3
538
+ end
539
+ elsif custom_attribute[:bound_to] == :faces
540
+ value = custom_attribute[:value][chf]
541
+
542
+ custom_attribute[:array][offset_custom] = value
543
+ custom_attribute[:array][offset_custom + 1] = value
544
+ custom_attribute[:array][offset_custom + 2] = value
545
+
546
+ offset_custom += 3
547
+ end
548
+ elsif custom_attribute[:size] == 2
549
+ if custom_attribute[:bound_to].nil? || custom_attribute[:bound_to] == :vertices
550
+ @faces3.each do |chf|
551
+ face = obj_faces[chf]
552
+
553
+ v1 = custom_attribute[:value][face.a]
554
+ v2 = custom_attribute[:value][face.b]
555
+ v3 = custom_attribute[:value][face.c]
556
+
557
+ custom_attribute[:array][offset_custom] = v1.x
558
+ custom_attribute[:array][offset_custom + 1] = v1.y
559
+
560
+ custom_attribute[:array][offset_custom + 2] = v2.x
561
+ custom_attribute[:array][offset_custom + 3] = v2.y
562
+
563
+ custom_attribute[:array][offset_custom + 4] = v3.x
564
+ custom_attribute[:array][offset_custom + 5] = v3.y
565
+
566
+ offset_custom += 6
567
+ end
568
+ elsif custom_attribute[:bound_to] == :faces
569
+ @faces3.each do |chf|
570
+ value = custom_attribute[:value][chf]
571
+
572
+ v1 = value
573
+ v2 = value
574
+ v3 = value
575
+
576
+ custom_attribute[:array][offset_custom] = v1.x
577
+ custom_attribute[:array][offset_custom + 1] = v1.y
578
+
579
+ custom_attribute[:array][offset_custom + 2] = v2.x
580
+ custom_attribute[:array][offset_custom + 3] = v2.y
581
+
582
+ custom_attribute[:array][offset_custom + 4] = v3.x
583
+ custom_attribute[:array][offset_custom + 5] = v3.y
584
+
585
+ offset_custom += 6
586
+ end
587
+ end
588
+ elsif custom_attribute[:size] == 3
589
+ if custom_attribute[:bound_to].nil? || custom_attribute[:bound_to] == :vertices
590
+ @faces3.each do |chf|
591
+ face = obj_faces[chf];
592
+
593
+ v1 = custom_attribute[:value][face.a]
594
+ v2 = custom_attribute[:value][face.b]
595
+ v3 = custom_attribute[:value][face.c]
596
+
597
+ custom_attribute[:array][offset_custom] = v1[0]
598
+ custom_attribute[:array][offset_custom + 1] = v1[1]
599
+ custom_attribute[:array][offset_custom + 2] = v1[2]
600
+
601
+ custom_attribute[:array][offset_custom + 3] = v2[0]
602
+ custom_attribute[:array][offset_custom + 4] = v2[1]
603
+ custom_attribute[:array][offset_custom + 5] = v2[2]
604
+
605
+ custom_attribute[:array][offset_custom + 6] = v3[0]
606
+ custom_attribute[:array][offset_custom + 7] = v3[1]
607
+ custom_attribute[:array][offset_custom + 8] = v3[2]
608
+
609
+ offset_custom += 9
610
+ end
611
+ elsif custom_attribute[:bound_to] == :faces
612
+ @faces3.each do |chf|
613
+ value = custom_attribute[:value][chf]
614
+
615
+ v1 = value
616
+ v2 = value
617
+ v3 = value
618
+
619
+ custom_attribute[:array][offset_custom] = v1[0]
620
+ custom_attribute[:array][offset_custom + 1] = v1[1]
621
+ custom_attribute[:array][offset_custom + 2] = v1[2]
622
+
623
+ custom_attribute[:array][offset_custom + 3] = v2[0]
624
+ custom_attribute[:array][offset_custom + 4] = v2[1]
625
+ custom_attribute[:array][offset_custom + 5] = v2[2]
626
+
627
+ custom_attribute[:array][offset_custom + 6] = v3[0]
628
+ custom_attribute[:array][offset_custom + 7] = v3[1]
629
+ custom_attribute[:array][offset_custom + 8] = v3[2]
630
+
631
+ offset_custom += 9
632
+ end
633
+ elsif custom_attribute[:bound_to] == :face_vertices
634
+ @faces3.each do |chf|
635
+ value = custom_attribute[:value][chf]
636
+
637
+ v1 = value[0]
638
+ v2 = value[1]
639
+ v3 = value[2]
640
+
641
+ custom_attribute[:array][offset_custom] = v1[0]
642
+ custom_attribute[:array][offset_custom + 1] = v1[1]
643
+ custom_attribute[:array][offset_custom + 2] = v1[2]
644
+
645
+ custom_attribute[:array][offset_custom + 3] = v2[0]
646
+ custom_attribute[:array][offset_custom + 4] = v2[1]
647
+ custom_attribute[:array][offset_custom + 5] = v2[2]
648
+
649
+ custom_attribute[:array][offset_custom + 6] = v3[0]
650
+ custom_attribute[:array][offset_custom + 7] = v3[1]
651
+ custom_attribute[:array][offset_custom + 8] = v3[2]
652
+
653
+ offset_custom += 9
654
+ end
655
+ end
656
+ elsif custom_attribute[:size] == 4
657
+ if custom_attribute[:bound_to].nil? || custom_attribute[:bound_to] == :vertices
658
+ @faces3.each do |chf|
659
+ face = obj_faces[chf]
660
+
661
+ v1 = custom_attribute[:value][face.a]
662
+ v2 = custom_attribute[:value][face.b]
663
+ v3 = custom_attribute[:value][face.c]
664
+
665
+ custom_attribute[:array][offset_custom] = v1.x
666
+ custom_attribute[:array][offset_custom + 1 ] = v1.y
667
+ custom_attribute[:array][offset_custom + 2 ] = v1.z
668
+ custom_attribute[:array][offset_custom + 3 ] = v1.w
669
+
670
+ custom_attribute[:array][offset_custom + 4 ] = v2.x
671
+ custom_attribute[:array][offset_custom + 5 ] = v2.y
672
+ custom_attribute[:array][offset_custom + 6 ] = v2.z
673
+ custom_attribute[:array][offset_custom + 7 ] = v2.w
674
+
675
+ custom_attribute[:array][offset_custom + 8 ] = v3.x
676
+ custom_attribute[:array][offset_custom + 9 ] = v3.y
677
+ custom_attribute[:array][offset_custom + 10] = v3.z
678
+ custom_attribute[:array][offset_custom + 11] = v3.w
679
+
680
+ offset_custom += 12
681
+ end
682
+ elsif custom_attribute[:bound_to] == :faces
683
+ @faces3.each do |chf|
684
+ value = custom_attribute[:value][chf]
685
+
686
+ v1 = value
687
+ v2 = value
688
+ v3 = value
689
+
690
+ custom_attribute[:array][offset_custom] = v1.x
691
+ custom_attribute[:array][offset_custom + 1 ] = v1.y
692
+ custom_attribute[:array][offset_custom + 2 ] = v1.z
693
+ custom_attribute[:array][offset_custom + 3 ] = v1.w
694
+
695
+ custom_attribute[:array][offset_custom + 4 ] = v2.x
696
+ custom_attribute[:array][offset_custom + 5 ] = v2.y
697
+ custom_attribute[:array][offset_custom + 6 ] = v2.z
698
+ custom_attribute[:array][offset_custom + 7 ] = v2.w
699
+
700
+ custom_attribute[:array][offset_custom + 8 ] = v3.x
701
+ custom_attribute[:array][offset_custom + 9 ] = v3.y
702
+ custom_attribute[:array][offset_custom + 10] = v3.z
703
+ custom_attribute[:array][offset_custom + 11] = v3.w
704
+
705
+ offset_custom += 12
706
+ end
707
+ elsif custom_attribute[:bound_to] == :face_vertices
708
+ @faces3.each do |chf|
709
+ value = custom_attribute[:value][chf]
710
+
711
+ v1 = value[0]
712
+ v2 = value[1]
713
+ v3 = value[2]
714
+
715
+ custom_attribute[:array][offset_custom] = v1.x
716
+ custom_attribute[:array][offset_custom + 1 ] = v1.y
717
+ custom_attribute[:array][offset_custom + 2 ] = v1.z
718
+ custom_attribute[:array][offset_custom + 3 ] = v1.w
719
+
720
+ custom_attribute[:array][offset_custom + 4 ] = v2.x
721
+ custom_attribute[:array][offset_custom + 5 ] = v2.y
722
+ custom_attribute[:array][offset_custom + 6 ] = v2.z
723
+ custom_attribute[:array][offset_custom + 7 ] = v2.w
724
+
725
+ custom_attribute[:array][offset_custom + 8 ] = v3.x
726
+ custom_attribute[:array][offset_custom + 9 ] = v3.y
727
+ custom_attribute[:array][offset_custom + 10] = v3.z
728
+ custom_attribute[:array][offset_custom + 11] = v3.w
729
+
730
+ offset_custom += 12
731
+ end
732
+ end
733
+ end
734
+
735
+ glBindBuffer(GL_ARRAY_BUFFER, custom_attribute[:buffer])
736
+ glBufferData_easy(GL_ARRAY_BUFFER, custom_attribute[:array], hint)
737
+ end
738
+ end
739
+
740
+ if should_dispose
741
+ self.dispose
742
+ end
743
+ end
744
+
745
+ def dispose
746
+ @initted_arrays = nil
747
+ @color_array = nil
748
+ @normal_array = nil
749
+ @tangent_array = nil
750
+ @uv_array = nil
751
+ @uv2_array = nil
752
+ @face_array = nil
753
+ @vertex_array = nil
754
+ @line_array = nil
755
+ @skin_index_array = nil
756
+ @skin_weight_array = nil
757
+ end
758
+
759
+ def implementation(_)
760
+ self
761
+ end
762
+ end
763
+ end