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
@@ -1,8 +1,6 @@
1
1
  module Mittsu
2
2
  class OpenGLState
3
- def initialize(param_mittsu_to_gl)
4
- @param_mittsu_to_gl = param_mittsu_to_gl
5
-
3
+ def initialize
6
4
  @new_attributes = Array.new(16) # Uint8Array
7
5
  @enabled_attributes = Array.new(16) # Uint8Array
8
6
 
@@ -90,14 +88,14 @@ module Mittsu
90
88
  blend_dst_alpha ||= blend_dst
91
89
 
92
90
  if blend_equation != @current_blend_equation || blend_equation_alpha != @current_blend_equation_alpha
93
- glBlendEquationSeparate(@param_mittsu_to_gl[blend_equation], @param_mittsu_to_gl[blend_equation_alpha])
91
+ glBlendEquationSeparate(GL_MITTSU_PARAMS[blend_equation], GL_MITTSU_PARAMS[blend_equation_alpha])
94
92
 
95
93
  @current_blend_equation = blend_equation
96
94
  @current_blend_equation_alpha = blend_equation_alpha
97
95
  end
98
96
 
99
97
  if blend_src != @current_blend_src || blend_dst != @current_blend_dst || blend_src_alpha != @current_blend_src_alpha || blend_dst_alpha != @current_blend_dst_alpha
100
- glBlendFuncSeparate(@param_mittsu_to_gl[blend_src], @param_mittsu_to_gl[blend_dst], @param_mittsu_to_gl[blend_src_alpha], @param_mittsu_to_gl[blend_dst_alpha])
98
+ glBlendFuncSeparate(GL_MITTSU_PARAMS[blend_src], GL_MITTSU_PARAMS[blend_dst], GL_MITTSU_PARAMS[blend_src_alpha], GL_MITTSU_PARAMS[blend_dst_alpha])
101
99
 
102
100
  @current_blend_src = nil
103
101
  @current_blend_dst = nil
@@ -49,10 +49,10 @@ module Mittsu
49
49
  skinning: true
50
50
  )
51
51
 
52
- @depth_material[:_shadow_pass] = true
53
- @depth_material_morph[:_shadow_pass] = true
54
- @depth_material_skin[:_shadow_pass] = true
55
- @depth_material_morph_skin[:_shadow_pass] = true
52
+ @depth_material.implementation(renderer).shadow_pass = true
53
+ @depth_material_morph.implementation(renderer).shadow_pass = true
54
+ @depth_material_skin.implementation(renderer).shadow_pass = true
55
+ @depth_material_morph_skin.implementation(renderer).shadow_pass = true
56
56
  end
57
57
 
58
58
  def render(scene, camera)
@@ -142,9 +142,10 @@ module Mittsu
142
142
  scene.update_matrix_world if scene.auto_update
143
143
  end
144
144
 
145
- if light.shadow_camera_visible && !light[:camera_helper]
146
- light[:camera_helper] = CameraHelper.new(light.shadow_camera)
147
- scene.add(light[:camera_helper])
145
+ light_impl = light.implementation(@renderer)
146
+ if light.shadow_camera_visible && !light_impl.camera_helper
147
+ light_impl.camera_helper = CameraHelper.new(light.shadow_camera)
148
+ scene.add(light_impl.camera_helper)
148
149
  end
149
150
 
150
151
  if light.virtual? && virtual_light.original_camera == camera
@@ -167,8 +168,8 @@ module Mittsu
167
168
  #
168
169
 
169
170
 
170
- light[:camera_helper].visible = light.shadow_camera_visible if light[:camera_helper]
171
- light[:camera_helper].update if light.shadow_camera_visible
171
+ light_impl.camera_helper.visible = light.shadow_camera_visible if light_impl.camera_helper
172
+ light_impl.camera_helper.update if light.shadow_camera_visible
172
173
 
173
174
  # compute shadow matrix
174
175
 
@@ -273,7 +274,8 @@ module Mittsu
273
274
 
274
275
  if opengl_objects && object.cast_shadow && (object.frustum_culled == false || @frustum.intersects_object?(object) == true)
275
276
  opengl_objects.each do |opengl_object|
276
- object[:_model_view_matrix].multiply_matrices(shadow_camera.matrix_world_inverse, object.matrix_world)
277
+ object_impl = object.implementation(@renderer)
278
+ object_impl.model_view_matrix.multiply_matrices(shadow_camera.matrix_world_inverse, object.matrix_world)
277
279
  @render_list << opengl_object
278
280
  end
279
281
  end
@@ -0,0 +1,8 @@
1
+ module Mittsu
2
+ class OpenGLScene < OpenGLObject3D
3
+ def project
4
+ return unless @object.visible
5
+ project_children
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ module Mittsu
2
+ class OpenGLCompressedTexture < OpenGLTexture
3
+ def update_specific
4
+ gl_format = GL_MITTSU_PARAMS[@texture.format]
5
+ gl_type = GL_MITTSU_PARAMS[@texture.type]
6
+ mipmaps = @texture.mipmaps
7
+
8
+ mipmaps.each_with_index do |mipmap, i|
9
+ if @texture.format != RGBAFormat && @texture.format != RGBFormat
10
+ if @renderer.compressed_texture_formats.include?(gl_format)
11
+ glCompressedTexImage2D(GL_TEXTURE_2D, i, gl_format, mipmap.width, mipmap.height, 0, mipmap.data)
12
+ else
13
+ puts 'WARNING: Mittsu::OpenGLTexture: Attempt to load unsupported compressed texture format in #update_texture'
14
+ end
15
+ else
16
+ glTexImage2D(GL_TEXTURE_2D, i, gl_format, mipmap.width, mipmap.height, 0, gl_format, gl_type, mipmap.data)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,75 @@
1
+ module Mittsu
2
+ class OpenGLCubeTexture < OpenGLTexture
3
+ def set(slot)
4
+ if @texture.image.length == 6
5
+ if @texture.needs_update?
6
+ if !@texture.image[:_opengl_texture_cube]
7
+ @texture.add_event_listener(:dispose, @renderer.method(:on_texture_dispose))
8
+ @texture.image[:_opengl_texture_cube] = glCreateTexture
9
+ @renderer.info[:memory][:textures] += 1
10
+ end
11
+
12
+ glActiveTexture(GL_TEXTURE0 + slot)
13
+ glBindTexture(GL_TEXTURE_CUBE_MAP, @texture.image[:_opengl_texture_cube])
14
+
15
+ # glPixelStorei(GL_UNPACK_FLIP_Y_WEBGL, texture.flip_y)
16
+
17
+ is_compressed = @texture.is_a?(CompressedTexture)
18
+ is_data_texture = @texture.image[0].is_a?(DataTexture)
19
+
20
+ cube_image = [];
21
+
22
+ 6.times do |i|
23
+ if @auto_scale_cubemaps && !is_compressed && !is_data_texture
24
+ cube_image[i] = clamp_to_max_size(@texture.image[i], @_max_cubemap_size)
25
+ else
26
+ cube_image[i] = is_data_texture ? @texture.image[i].image : @texture.image[i];
27
+ end
28
+ end
29
+
30
+ image = cube_image[0]
31
+ is_image_power_of_two = Math.power_of_two?(image.width) && Math.power_of_two?(image.height)
32
+ gl_format = GL_MITTSU_PARAMS[@texture.format]
33
+ gl_type = GL_MITTSU_PARAMS[@texture.type]
34
+
35
+ set_parameters(GL_TEXTURE_CUBE_MAP, is_image_power_of_two)
36
+
37
+ 6.times do |i|
38
+ if !is_compressed
39
+ if is_data_texture
40
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl_format, cube_image[i].width, cube_image[i].height, 0, gl_format, gl_type, cube_image[i].data)
41
+ else
42
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl_format, cube_image[i].width, cube_image[i].height, 0, gl_format, gl_type, cube_image[i].data)
43
+ end
44
+ else
45
+ mipmaps = cube_image[i].mipmaps
46
+
47
+ mipmaps.each_with_index do |mipmap, j|
48
+ if @texture.format != RGBAFormat && @texture.format != RGBFormat
49
+ if @renderer.compressed_texture_formats.include?(gl_format)
50
+ glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, j, gl_format, mipmap.width, mipmap.height, 0, mipmap.data)
51
+ else
52
+ puts "WARNING: Mittsu::OpenGLCubeTexture: Attempt to load unsupported compressed texture format in #set"
53
+ end
54
+ else
55
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, j, gl_format, mipmap.width, mipmap.height, 0, gl_format, gl_type, mipmap.data)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ if @texture.generate_mipmaps && is_image_power_of_two
62
+ glGenerateMipmap(GL_TEXTURE_CUBE_MAP)
63
+ end
64
+
65
+ @texture.needs_update = false
66
+
67
+ @texture.on_update.call if @texture.on_update
68
+ else
69
+ glActiveTexture(GL_TEXTURE0 + slot)
70
+ glBindTexture(GL_TEXTURE_CUBE_MAP, @texture.image[:_opengl_texture_cube])
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,23 @@
1
+ module Mittsu
2
+ class OpenGLDataTexture < OpenGLTexture
3
+ def update_specific
4
+ gl_format = GL_MITTSU_PARAMS[@texture.format]
5
+ gl_type = GL_MITTSU_PARAMS[@texture.type]
6
+ mipmaps = @texture.mipmaps
7
+ image = @texture.image
8
+ is_image_power_of_two = Math.power_of_two?(image.width) && Math.power_of_two?(image.height)
9
+
10
+ # use manually created mipmaps if available
11
+ # if there are no manual mipmaps
12
+ # set 0 level mipmap and then use GL to generate other mipmap levels
13
+
14
+ if !mipmaps.empty? && is_image_power_of_two
15
+ mipmaps.each_with_index do |mipmap, i|
16
+ glTexImage2D(GL_TEXTURE_2D, i, gl_format, mipmap.width, mipmap.height, 0, gl_format, gl_type, mipmap.data)
17
+ end
18
+ else
19
+ glTexImage2D(GL_TEXTURE_2D, 0, gl_format, image.width, image.height, 0, gl_format, gl_type, image.data)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,111 @@
1
+ module Mittsu
2
+ class OpenGLTexture
3
+ attr_reader :opengl_texture
4
+
5
+ def initialize(texture, renderer)
6
+ @texture = texture
7
+ @renderer = renderer
8
+ @initted = false
9
+ end
10
+
11
+ def set(slot)
12
+ glActiveTexture(GL_TEXTURE0 + slot)
13
+
14
+ if @texture.needs_update?
15
+ update
16
+ else
17
+ glBindTexture(GL_TEXTURE_2D, @opengl_texture)
18
+ end
19
+ end
20
+
21
+ def update
22
+ if !@initted
23
+ @initted = true
24
+ @texture.add_event_listener(:dispose, @renderer.method(:on_texture_dispose))
25
+ @opengl_texture = glCreateTexture
26
+ @renderer.info[:memory][:textures] += 1
27
+ end
28
+
29
+ glBindTexture(GL_TEXTURE_2D, @opengl_texture)
30
+
31
+ # glPixelStorei(GL_UNPACK_FLIP_Y_WEBGL, texture.flip_y) ???
32
+ # glPixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiply_alpha) ???
33
+ glPixelStorei(GL_UNPACK_ALIGNMENT, @texture.unpack_alignment)
34
+
35
+ image = @texture.image = @renderer.clamp_to_max_size(@texture.image)
36
+
37
+ is_image_power_of_two = Math.power_of_two?(image.width) && Math.power_of_two?(image.height)
38
+
39
+ set_parameters(GL_TEXTURE_2D, is_image_power_of_two)
40
+
41
+ update_specific
42
+
43
+ if @texture.generate_mipmaps && is_image_power_of_two
44
+ glGenerateMipmap(GL_TEXTURE_2D)
45
+ end
46
+
47
+ @texture.needs_update = false
48
+
49
+ @texture.on_update.call if @texture.on_update
50
+ end
51
+
52
+ protected
53
+
54
+ def set_parameters(texture_type, is_image_power_of_two)
55
+ if is_image_power_of_two
56
+ glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, GL_MITTSU_PARAMS[@texture.wrap_s])
57
+ glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, GL_MITTSU_PARAMS[@texture.wrap_t])
58
+
59
+ glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, GL_MITTSU_PARAMS[@texture.mag_filter])
60
+ glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, GL_MITTSU_PARAMS[@texture.min_filter])
61
+ else
62
+ glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
63
+ glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
64
+
65
+ if @texture.wrap_s != ClampToEdgeWrapping || @texture.wrap_t != ClampToEdgeWrapping
66
+ puts "WARNING: Mittsu::OpenGLTexture: Texture is not power of two. Texture.wrap_s and Texture.wrap_t should be set to Mittsu::ClampToEdgeWrapping. (#{texture.source_file})"
67
+ end
68
+
69
+ glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, filter_fallback(@texture.mag_filter))
70
+ glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, filter_fallback(@texture.min_filter))
71
+
72
+ if @texture.min_filter != NearestFilter && @texture.min_filter != LinearFilter
73
+ puts "WARNING: Mittsu::OpenGLTexture: Texture is not a power of two. Texture.min_filter should be set to Mittsu::NearestFilter or Mittsu::LinearFilter. (#{texture.source_file})"
74
+ end
75
+
76
+ # TODO: anisotropic extension ???
77
+ end
78
+ end
79
+
80
+ # Fallback filters for non-power-of-2 textures
81
+ def filter_fallback(filter)
82
+ if filter == NearestFilter || filter == NearestMipMapNearestFilter || f == NearestMipMapLinearFilter
83
+ GL_NEAREST
84
+ end
85
+
86
+ GL_LINEAR
87
+ end
88
+
89
+ def update_specific
90
+ gl_format = GL_MITTSU_PARAMS[@texture.format]
91
+ gl_type = GL_MITTSU_PARAMS[@texture.type]
92
+ mipmaps = @texture.mipmaps
93
+ image = @texture.image
94
+ is_image_power_of_two = Math.power_of_two?(image.width) && Math.power_of_two?(image.height)
95
+
96
+ # use manually created mipmaps if available
97
+ # if there are no manual mipmaps
98
+ # set 0 level mipmap and then use GL to generate other mipmap levels
99
+
100
+ if !mipmaps.empty? && is_image_power_of_two
101
+ mipmaps.each_with_index do |mipmap, i|
102
+ glTexImage2D(GL_TEXTURE_2D, i, gl_format, mipmap.width, mipmap.height, 0, gl_format, gl_type, mipmap.data)
103
+ end
104
+
105
+ @texture.generate_mipmaps = false
106
+ else
107
+ glTexImage2D(GL_TEXTURE_2D, 0, gl_format, @texture.image.width, @texture.image.height, 0, gl_format, gl_type, @texture.image.data)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -1,5 +1,5 @@
1
1
  module Mittsu
2
- class OpenGLRenderTarget < HashObject
2
+ class OpenGLRenderTarget < OpenGLTexture
3
3
  include EventDispatcher
4
4
 
5
5
  attr_accessor :width,
@@ -18,8 +18,10 @@ module Mittsu
18
18
  :generate_mipmaps,
19
19
  :share_depth_from
20
20
 
21
+ attr_reader :framebuffer
22
+
21
23
  def initialize(width, height, options = {})
22
- super()
24
+ super(self, nil)
23
25
 
24
26
  @width = width
25
27
  @height = height
@@ -80,8 +82,121 @@ module Mittsu
80
82
  end
81
83
  end
82
84
 
85
+ def setup_buffers
86
+ return unless @framebuffer.nil?
87
+
88
+ # TODO: when OpenGLRenderTargetCube exists
89
+ is_cube = false # render_target.is_a? OpenGLRenderTargetCube
90
+
91
+ @depth_buffer = true if @depth_buffer.nil?
92
+ @stencil_buffer = true if @stencil_buffer.nil?
93
+
94
+ add_event_listener(:dispose, @renderer.method(:on_render_target_dispose))
95
+
96
+ @opengl_texture = glCreateTexture
97
+
98
+ @renderer.info[:memory][:textures] += 1
99
+
100
+ # Setup texture, create render and frame buffers
101
+
102
+ is_target_power_of_two = Math.power_of_two?(@width) && Math.power_of_two?(@height)
103
+ gl_format = GL_MITTSU_PARAMS[@format]
104
+ gl_type = GL_MITTSU_PARAMS[@type]
105
+
106
+ if is_cube
107
+ # TODO
108
+ else
109
+ @framebuffer = glCreateFramebuffer
110
+
111
+ if @share_depth_from
112
+ @renderbuffer = share_depth_from.renderbuffer
113
+ else
114
+ @renderbuffer = glCreateRenderbuffer
115
+ end
116
+
117
+ glBindTexture(GL_TEXTURE_2D, @opengl_texture)
118
+ set_parameters(GL_TEXTURE_2D, is_target_power_of_two)
119
+
120
+ glTexImage2D(GL_TEXTURE_2D, 0, gl_format, @width, @height, 0, gl_format, gl_type, nil)
121
+
122
+ setup_framebuffer(GL_TEXTURE_2D)
123
+
124
+ if @share_depth_from
125
+ if @depth_buffer && !@stencil_buffer
126
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, @renderbuffer)
127
+ elsif @depth_buffer && @stencil_buffer
128
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, @renderbuffer)
129
+ end
130
+ else
131
+ setup_renderbuffer
132
+ end
133
+
134
+ glGenerateMipmap(GL_TEXTURE_2D) if is_target_power_of_two
135
+ end
136
+
137
+ # Release everything
138
+
139
+ if is_cube
140
+ # TODO
141
+ else
142
+ glBindTexture(GL_TEXTURE_2D, 0)
143
+ end
144
+
145
+ glBindRenderbuffer(GL_RENDERBUFFER, 0)
146
+ glBindFramebuffer(GL_FRAMEBUFFER, 0)
147
+ end
148
+
149
+ def use
150
+ glBindFramebuffer(GL_FRAMEBUFFER, @framebuffer)
151
+ glViewport(0, 0, @width, @height)
152
+ end
153
+
83
154
  def dispose
84
155
  dispatch_event(type: :dispose)
85
156
  end
157
+
158
+ def implementation(renderer)
159
+ @renderer = renderer
160
+ self
161
+ end
162
+
163
+ def update_mipmap
164
+ return if !@generate_mipmaps || @min_filter == NearestFilter || @min_filter == LinearFilter
165
+ # TODO: when OpenGLRenderTargetCube exists
166
+ # glBindTexture(GL_TEXTURE_CUBE_MAP, @opengl_texture)
167
+ # glGenerateMipmap(GL_TEXTURE_CUBE_MAP)
168
+ # glBindTexture(GL_TEXTURE_CUBE_MAP, nil)
169
+ glBindTexture(GL_TEXTURE_2D, @opengl_texture)
170
+ glGenerateMipmap(GL_TEXTURE_2D)
171
+ glBindTexture(GL_TEXTURE_2D, nil)
172
+ end
173
+
174
+ private
175
+
176
+ def setup_framebuffer(texture_target)
177
+ glBindFramebuffer(GL_FRAMEBUFFER, @framebuffer)
178
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, @opengl_texture, 0)
179
+ end
180
+
181
+ def setup_renderbuffer
182
+ glBindRenderbuffer(GL_RENDERBUFFER, @renderbuffer)
183
+
184
+ if @depth_buffer && !@stencil_buffer
185
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, @width, @height)
186
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, @renderbuffer)
187
+
188
+ # TODO: investigate this (?):
189
+ # THREE.js - For some reason this is not working. Defaulting to RGBA4.
190
+ # } else if ( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
191
+ #
192
+ # _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
193
+ # _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
194
+ elsif @depth_buffer && @stencil_buffer
195
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, @width, @height)
196
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, @renderbuffer)
197
+ else
198
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, @width, @height)
199
+ end
200
+ end
86
201
  end
87
202
  end