mittsu-opengl 0.5.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 (145) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +18 -0
  3. data/.github/workflows/build-workflow.yml +67 -0
  4. data/.gitignore +12 -0
  5. data/.rubocop.yml +1158 -0
  6. data/CODE_OF_CONDUCT.md +13 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +195 -0
  10. data/Rakefile +8 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +7 -0
  13. data/install-glfw.ps1 +13 -0
  14. data/lib/mittsu/generic_lib.rb +116 -0
  15. data/lib/mittsu/glfw/lib.rb +58 -0
  16. data/lib/mittsu/glfw/window.rb +231 -0
  17. data/lib/mittsu/opengl/buffer.rb +13 -0
  18. data/lib/mittsu/opengl/default_target.rb +50 -0
  19. data/lib/mittsu/opengl/geometry_group.rb +758 -0
  20. data/lib/mittsu/opengl/geometry_like.rb +132 -0
  21. data/lib/mittsu/opengl/gl_debug.rb +85 -0
  22. data/lib/mittsu/opengl/gl_extensions.rb +42 -0
  23. data/lib/mittsu/opengl/gl_mittsu_params.rb +53 -0
  24. data/lib/mittsu/opengl/helper.rb +120 -0
  25. data/lib/mittsu/opengl/implementation.rb +31 -0
  26. data/lib/mittsu/opengl/lib.rb +19 -0
  27. data/lib/mittsu/opengl/light_renderer.rb +43 -0
  28. data/lib/mittsu/opengl/material_basics.rb +57 -0
  29. data/lib/mittsu/opengl/plugins/shadow_map_plugin.rb +416 -0
  30. data/lib/mittsu/opengl/plugins/sprite_fragment.glsl +38 -0
  31. data/lib/mittsu/opengl/plugins/sprite_plugin.rb +250 -0
  32. data/lib/mittsu/opengl/plugins/sprite_vertex.glsl +31 -0
  33. data/lib/mittsu/opengl/program.rb +250 -0
  34. data/lib/mittsu/opengl/renderer.rb +1028 -0
  35. data/lib/mittsu/opengl/shader/chunk.rb +11 -0
  36. data/lib/mittsu/opengl/shader/chunks/alphamap_fragment.glsl +5 -0
  37. data/lib/mittsu/opengl/shader/chunks/alphamap_pars_fragment.glsl +5 -0
  38. data/lib/mittsu/opengl/shader/chunks/alphatest_fragment.glsl +5 -0
  39. data/lib/mittsu/opengl/shader/chunks/bumpmap_pars_fragment.glsl +40 -0
  40. data/lib/mittsu/opengl/shader/chunks/color_fragment.glsl +5 -0
  41. data/lib/mittsu/opengl/shader/chunks/color_pars_fragment.glsl +5 -0
  42. data/lib/mittsu/opengl/shader/chunks/color_pars_vertex.glsl +5 -0
  43. data/lib/mittsu/opengl/shader/chunks/color_vertex.glsl +5 -0
  44. data/lib/mittsu/opengl/shader/chunks/common.glsl +60 -0
  45. data/lib/mittsu/opengl/shader/chunks/default_vertex.glsl +15 -0
  46. data/lib/mittsu/opengl/shader/chunks/defaultnormal_vertex.glsl +21 -0
  47. data/lib/mittsu/opengl/shader/chunks/envmap_fragment.glsl +62 -0
  48. data/lib/mittsu/opengl/shader/chunks/envmap_pars_fragment.glsl +21 -0
  49. data/lib/mittsu/opengl/shader/chunks/envmap_pars_vertex.glsl +7 -0
  50. data/lib/mittsu/opengl/shader/chunks/envmap_vertex.glsl +17 -0
  51. data/lib/mittsu/opengl/shader/chunks/fog_fragment.glsl +26 -0
  52. data/lib/mittsu/opengl/shader/chunks/fog_pars_fragment.glsl +15 -0
  53. data/lib/mittsu/opengl/shader/chunks/lightmap_fragment.glsl +5 -0
  54. data/lib/mittsu/opengl/shader/chunks/lightmap_pars_fragment.glsl +6 -0
  55. data/lib/mittsu/opengl/shader/chunks/lightmap_pars_vertex.glsl +5 -0
  56. data/lib/mittsu/opengl/shader/chunks/lightmap_vertex.glsl +5 -0
  57. data/lib/mittsu/opengl/shader/chunks/lights_lambert_pars_vertex.glsl +43 -0
  58. data/lib/mittsu/opengl/shader/chunks/lights_lambert_vertex.glsl +196 -0
  59. data/lib/mittsu/opengl/shader/chunks/lights_phong_fragment.glsl +243 -0
  60. data/lib/mittsu/opengl/shader/chunks/lights_phong_pars_fragment.glsl +58 -0
  61. data/lib/mittsu/opengl/shader/chunks/lights_phong_pars_vertex.glsl +5 -0
  62. data/lib/mittsu/opengl/shader/chunks/lights_phong_vertex.glsl +5 -0
  63. data/lib/mittsu/opengl/shader/chunks/linear_to_gamma_fragment.glsl +2 -0
  64. data/lib/mittsu/opengl/shader/chunks/logdepthbuf_fragment.glsl +5 -0
  65. data/lib/mittsu/opengl/shader/chunks/logdepthbuf_pars_fragment.glsl +12 -0
  66. data/lib/mittsu/opengl/shader/chunks/logdepthbuf_pars_vertex.glsl +11 -0
  67. data/lib/mittsu/opengl/shader/chunks/logdepthbuf_vertex.glsl +15 -0
  68. data/lib/mittsu/opengl/shader/chunks/map_fragment.glsl +9 -0
  69. data/lib/mittsu/opengl/shader/chunks/map_pars_fragment.glsl +11 -0
  70. data/lib/mittsu/opengl/shader/chunks/map_pars_vertex.glsl +6 -0
  71. data/lib/mittsu/opengl/shader/chunks/map_particle_fragment.glsl +5 -0
  72. data/lib/mittsu/opengl/shader/chunks/map_particle_pars_fragment.glsl +6 -0
  73. data/lib/mittsu/opengl/shader/chunks/map_vertex.glsl +5 -0
  74. data/lib/mittsu/opengl/shader/chunks/morphnormal_vertex.glsl +12 -0
  75. data/lib/mittsu/opengl/shader/chunks/morphtarget_pars_vertex.glsl +13 -0
  76. data/lib/mittsu/opengl/shader/chunks/morphtarget_vertex.glsl +20 -0
  77. data/lib/mittsu/opengl/shader/chunks/normalmap_pars_fragment.glsl +27 -0
  78. data/lib/mittsu/opengl/shader/chunks/shadowmap_fragment.glsl +216 -0
  79. data/lib/mittsu/opengl/shader/chunks/shadowmap_pars_fragment.glsl +19 -0
  80. data/lib/mittsu/opengl/shader/chunks/shadowmap_pars_vertex.glsl +6 -0
  81. data/lib/mittsu/opengl/shader/chunks/shadowmap_vertex.glsl +9 -0
  82. data/lib/mittsu/opengl/shader/chunks/skinbase_vertex.glsl +8 -0
  83. data/lib/mittsu/opengl/shader/chunks/skinning_pars_vertex.glsl +47 -0
  84. data/lib/mittsu/opengl/shader/chunks/skinning_vertex.glsl +20 -0
  85. data/lib/mittsu/opengl/shader/chunks/skinnormal_vertex.glsl +20 -0
  86. data/lib/mittsu/opengl/shader/chunks/specularmap_fragment.glsl +12 -0
  87. data/lib/mittsu/opengl/shader/chunks/specularmap_pars_fragment.glsl +5 -0
  88. data/lib/mittsu/opengl/shader/chunks/worldpos_vertex.glsl +17 -0
  89. data/lib/mittsu/opengl/shader/lib/basic/basic_fragment.rbsl +37 -0
  90. data/lib/mittsu/opengl/shader/lib/basic/basic_uniforms.rbslu +3 -0
  91. data/lib/mittsu/opengl/shader/lib/basic/basic_vertex.rbsl +33 -0
  92. data/lib/mittsu/opengl/shader/lib/cube/cube_fragment.rbsl +12 -0
  93. data/lib/mittsu/opengl/shader/lib/cube/cube_uniforms.rbslu +2 -0
  94. data/lib/mittsu/opengl/shader/lib/cube/cube_vertex.rbsl +12 -0
  95. data/lib/mittsu/opengl/shader/lib/depth_rgba/depth_rgba_fragment.rbsl +26 -0
  96. data/lib/mittsu/opengl/shader/lib/depth_rgba/depth_rgba_uniforms.rbslu +0 -0
  97. data/lib/mittsu/opengl/shader/lib/depth_rgba/depth_rgba_vertex.rbsl +12 -0
  98. data/lib/mittsu/opengl/shader/lib/lambert/lambert_fragment.rbsl +56 -0
  99. data/lib/mittsu/opengl/shader/lib/lambert/lambert_uniforms.rbslu +7 -0
  100. data/lib/mittsu/opengl/shader/lib/lambert/lambert_vertex.rbsl +37 -0
  101. data/lib/mittsu/opengl/shader/lib/particle_basic/particle_basic_fragment.rbsl +27 -0
  102. data/lib/mittsu/opengl/shader/lib/particle_basic/particle_basic_uniforms.rbslu +2 -0
  103. data/lib/mittsu/opengl/shader/lib/particle_basic/particle_basic_vertex.rbsl +25 -0
  104. data/lib/mittsu/opengl/shader/lib/phong/phong_fragment.rbsl +45 -0
  105. data/lib/mittsu/opengl/shader/lib/phong/phong_uniforms.rbslu +11 -0
  106. data/lib/mittsu/opengl/shader/lib/phong/phong_vertex.rbsl +43 -0
  107. data/lib/mittsu/opengl/shader/lib.rb +45 -0
  108. data/lib/mittsu/opengl/shader/rbsl_loader.rb +168 -0
  109. data/lib/mittsu/opengl/shader/templates/fragment.glsl.erb +105 -0
  110. data/lib/mittsu/opengl/shader/templates/vertex.glsl.erb +143 -0
  111. data/lib/mittsu/opengl/shader/uniforms_lib.rb +86 -0
  112. data/lib/mittsu/opengl/shader/uniforms_utils.rb +31 -0
  113. data/lib/mittsu/opengl/shader.rb +56 -0
  114. data/lib/mittsu/opengl/state.rb +205 -0
  115. data/lib/mittsu/opengl/version.rb +5 -0
  116. data/lib/mittsu/opengl.rb +2 -0
  117. data/lib/mittsu/opengl_implementation/core/buffer_geometry.rb +11 -0
  118. data/lib/mittsu/opengl_implementation/core/geometry.rb +346 -0
  119. data/lib/mittsu/opengl_implementation/core/object_3d.rb +134 -0
  120. data/lib/mittsu/opengl_implementation/lights/ambient_light.rb +26 -0
  121. data/lib/mittsu/opengl_implementation/lights/directional_light.rb +35 -0
  122. data/lib/mittsu/opengl_implementation/lights/hemisphere_light.rb +39 -0
  123. data/lib/mittsu/opengl_implementation/lights/light.rb +55 -0
  124. data/lib/mittsu/opengl_implementation/lights/point_light.rb +36 -0
  125. data/lib/mittsu/opengl_implementation/lights/spot_light.rb +47 -0
  126. data/lib/mittsu/opengl_implementation/materials/line_basic_material.rb +16 -0
  127. data/lib/mittsu/opengl_implementation/materials/material.rb +274 -0
  128. data/lib/mittsu/opengl_implementation/materials/mesh_basic_material.rb +21 -0
  129. data/lib/mittsu/opengl_implementation/materials/mesh_lambert_material.rb +33 -0
  130. data/lib/mittsu/opengl_implementation/materials/mesh_phong_material.rb +44 -0
  131. data/lib/mittsu/opengl_implementation/materials/point_cloud_material.rb +27 -0
  132. data/lib/mittsu/opengl_implementation/materials/shader_material.rb +11 -0
  133. data/lib/mittsu/opengl_implementation/objects/group.rb +9 -0
  134. data/lib/mittsu/opengl_implementation/objects/line.rb +45 -0
  135. data/lib/mittsu/opengl_implementation/objects/mesh.rb +70 -0
  136. data/lib/mittsu/opengl_implementation/objects/point_cloud.rb +39 -0
  137. data/lib/mittsu/opengl_implementation/objects/sprite.rb +12 -0
  138. data/lib/mittsu/opengl_implementation/scenes/scene.rb +9 -0
  139. data/lib/mittsu/opengl_implementation/textures/compressed_texture.rb +20 -0
  140. data/lib/mittsu/opengl_implementation/textures/cube_texture.rb +77 -0
  141. data/lib/mittsu/opengl_implementation/textures/data_texture.rb +21 -0
  142. data/lib/mittsu/opengl_implementation/textures/render_target.rb +124 -0
  143. data/lib/mittsu/opengl_implementation/textures/texture.rb +107 -0
  144. data/mittsu-opengl.gemspec +36 -0
  145. metadata +314 -0
@@ -0,0 +1,1028 @@
1
+ require 'opengl'
2
+ require 'glfw'
3
+ require 'fiddle'
4
+
5
+ require 'mittsu/opengl/version'
6
+ require 'mittsu/opengl/lib'
7
+ opengl_lib = Mittsu::OpenGL::Lib.discover
8
+ GL.load_lib(ENV["MITTSU_LIBGL_PATH"] || opengl_lib.path, Mittsu.debug?)
9
+
10
+ require 'mittsu/glfw/window'
11
+ require 'mittsu/opengl/gl_debug' if ENV['DEBUG']
12
+ require 'mittsu/opengl/implementation'
13
+ require 'mittsu/opengl/gl_extensions'
14
+ require 'mittsu/opengl/helper'
15
+ require 'mittsu/opengl/program'
16
+ require 'mittsu/opengl/state'
17
+ require 'mittsu/opengl/geometry_group'
18
+ require 'mittsu/opengl/light_renderer'
19
+ require 'mittsu/opengl/default_target'
20
+ require 'mittsu/opengl/buffer'
21
+ require 'mittsu/opengl/plugins/shadow_map_plugin'
22
+ require 'mittsu/opengl/plugins/sprite_plugin'
23
+ require 'mittsu/opengl/shader/lib'
24
+ require 'mittsu/opengl/shader/uniforms_utils'
25
+ include Mittsu::OpenGL::Helper
26
+
27
+ require 'mittsu/opengl/gl_mittsu_params'
28
+
29
+ module Mittsu
30
+ class OpenGL::Renderer
31
+ attr_accessor :auto_clear, :auto_clear_color, :auto_clear_depth, :auto_clear_stencil, :sort_objects, :gamma_factor, :gamma_input,
32
+ :gamma_output, :shadow_map_enabled, :shadow_map_type, :shadow_map_cull_face, :shadow_map_debug, :shadow_map_cascade,
33
+ :max_morph_targets, :max_morph_normals, :info, :pixel_ratio, :window, :width, :height, :state
34
+
35
+ attr_reader :logarithmic_depth_buffer, :programs, :light_renderer, :proj_screen_matrix
36
+
37
+ def initialize(parameters = {})
38
+ puts "Mittsu OpenGL Renderer #{VERSION}"
39
+
40
+ fetch_parameters(parameters)
41
+
42
+ @pixel_ratio = 1.0
43
+ @sort_objects = true
44
+
45
+ init_collections
46
+ init_clearing
47
+ init_gamma
48
+ init_shadow_properties
49
+ init_morphs
50
+ init_info
51
+ init_state_cache
52
+ init_camera_matrix_cache
53
+
54
+ @light_renderer = OpenGL::LightRenderer.new(self)
55
+
56
+ create_window
57
+
58
+ @state = OpenGL::State.new
59
+
60
+ # TODO: load extensions??
61
+
62
+ reset_gl_state
63
+ set_default_gl_state
64
+
65
+ get_gpu_capabilities
66
+
67
+ init_plugins
68
+ end
69
+
70
+ def supports_bone_textures?
71
+ @_supports_bone_textures
72
+ end
73
+
74
+ def supports_vertex_textures?
75
+ @_supports_vertex_textures
76
+ end
77
+
78
+ def shadow_map_enabled?
79
+ @shadow_map_enabled
80
+ end
81
+
82
+ # TODO: get_context ???
83
+ # TODO: force_context_loss ???
84
+ # TODO: supports_float_textures? ???
85
+ # TODO: supports[half|standard|compressed|blend min max] ... ???
86
+
87
+ def max_anisotropy
88
+ @_max_anisotropy ||= nil
89
+ # TODO: get max anisotropy ????
90
+ end
91
+
92
+ def set_size(width, height)
93
+ @width, @height = width, height
94
+ self.set_viewport(0, 0, width, height)
95
+ end
96
+
97
+ def set_viewport(x, y, width, height)
98
+ default_target.set_and_use_viewport(
99
+ x * pixel_ratio,
100
+ y * pixel_ratio,
101
+ width * pixel_ratio,
102
+ height * pixel_ratio
103
+ )
104
+ end
105
+
106
+ def set_scissor(x, y, width, height)
107
+ GL.Scissor(
108
+ x * pixel_ratio,
109
+ y * pixel_ratio,
110
+ width * pixel_ratio,
111
+ height * pixel_ratio
112
+ )
113
+ end
114
+
115
+ def enable_scissor_test(enable)
116
+ enable ? GL.Enable(GL::SCISSOR_TEST) : GL.Disable(GL::SCISSOR_TEST)
117
+ end
118
+
119
+ def object_in_frustum?(object)
120
+ @_frustum.intersects_object?(object)
121
+ end
122
+
123
+ def sort_objects?
124
+ @sort_objects
125
+ end
126
+
127
+ # clearing
128
+
129
+ def get_clear_color
130
+ @_clear_color
131
+ end
132
+
133
+ def set_clear_color(color, alpha = 1.0)
134
+ @_clear_color.set(color)
135
+ @_clear_alpha = alpha
136
+ clear_color(@_clear_color.r, @_clear_color.g, @_clear_color.b, @_clear_alpha)
137
+ end
138
+
139
+ def get_clear_alpha
140
+ @_clear_alpha
141
+ end
142
+
143
+ def set_clear_alpha(alpha)
144
+ @_clear_alpha = alpha
145
+ clear_color(@_clear_color.r, @_clear_color.g, @_clear_color.b, @_clear_alpha)
146
+ end
147
+
148
+ def clear(color = true, depth = true, stencil = true)
149
+ bits = 0
150
+
151
+ bits |= GL::COLOR_BUFFER_BIT if color
152
+ bits |= GL::DEPTH_BUFFER_BIT if depth
153
+ bits |= GL::STENCIL_BUFFER_BIT if stencil
154
+
155
+ GL.Clear(bits)
156
+ end
157
+
158
+ def clear_depth
159
+ GL.Clear(GL::DEPTH_BUFFER_BIT)
160
+ end
161
+
162
+ def clear_stencil
163
+ GL.Clear(GL::STENCIL_BUFFER_BIT)
164
+ end
165
+
166
+ def clear_target(render_target, color, depth, stencil)
167
+ set_render_target(render_target)
168
+ clear(color, depth, stencil)
169
+ end
170
+
171
+ def reset_gl_state
172
+ @_current_program = nil
173
+ @_current_camera = nil
174
+
175
+ @_current_geometry_program = ''
176
+ @_current_material_id = -1
177
+
178
+ @light_renderer.reset
179
+
180
+ @state.reset
181
+ end
182
+
183
+ def set_render_target(render_target = default_target)
184
+ # TODO: when OpenGLRenderTargetCube exists
185
+ # is_cube = render_target.is_a? OpenGLRenderTargetCube
186
+
187
+ # TODO framebuffer logic for render target cube
188
+ render_target.setup_buffers
189
+
190
+ if render_target != @_current_render_target
191
+ render_target.use
192
+ @_current_render_target = render_target
193
+ end
194
+ end
195
+
196
+ def render(scene, camera, render_target = default_target, force_clear = false)
197
+ raise "ERROR: Mittsu::OpenGL::Renderer#render: camera is not an instance of Mittsu::Camera" unless camera.is_a?(Camera)
198
+
199
+ reset_cache_for_this_frame
200
+
201
+ scene.update_matrix_world if scene.auto_update
202
+ camera.update_matrix_world if camera.parent.nil?
203
+
204
+ update_skeleton_objects(scene)
205
+
206
+ update_screen_projection(camera)
207
+ scene.project(self)
208
+ sort_objects_for_render if @sort_objects
209
+
210
+ render_custom_plugins_pre_pass(scene, camera)
211
+
212
+ set_matrices_for_immediate_objects(camera)
213
+
214
+ set_render_target(render_target)
215
+ perform_auto_clear if @auto_clear || force_clear
216
+ render_main_pass(scene, camera)
217
+
218
+ render_custom_plugins_post_pass(scene, camera)
219
+
220
+ render_target.update_mipmap
221
+
222
+ ensure_depth_buffer_writing
223
+ end
224
+
225
+ def set_material_faces(material)
226
+ @state.set_double_sided(material.side == DoubleSide)
227
+ @state.set_flip_sided(material.side == BackSide)
228
+ end
229
+
230
+ def render_buffer(camera, lights, fog, material, geometry_group, object)
231
+ puts "--- RENDER #{object.name}" if DEBUG
232
+ return unless material.visible
233
+
234
+ geometry_group.renderer = self
235
+ geometry_group.bind_vertex_array_object
236
+
237
+ update_object(object)
238
+
239
+ program = set_program(camera, lights, fog, material, object)
240
+ attributes = program.attributes
241
+ buffers_need_update = switch_geometry_program(program, material, geometry_group)
242
+
243
+ @state.init_attributes if buffers_need_update
244
+
245
+ if !material.morph_targets && attributes['position'] && attributes['position'] >= 0
246
+ geometry_group.update_vertex_buffer(attributes['position']) if buffers_need_update
247
+ elsif object.morph_target_base
248
+ # TODO: when morphing is implemented
249
+ # setup_morph_targets(material, geometry_group, object)
250
+ end
251
+
252
+ if buffers_need_update
253
+ geometry_group.update_other_buffers(object, material, attributes)
254
+ end
255
+
256
+ @state.disable_unused_attributes
257
+
258
+ object.render_buffer(camera, lights, fog, material, geometry_group, buffers_need_update)
259
+ end
260
+
261
+ def compressed_texture_formats
262
+ # TODO: needs extensions.get ...
263
+
264
+ @_compressed_texture_formats ||= []
265
+ end
266
+
267
+ # Events
268
+
269
+ def on_object_removed(event)
270
+ object = event.target
271
+ object.traverse do |child|
272
+ child.remove_event_listener(:remove, method(:on_object_removed))
273
+ remove_child(child)
274
+ end
275
+ end
276
+
277
+ def on_geometry_dispose(event)
278
+ geometry = event.target
279
+ geometry.remove_event_listener(:dispose, method(:on_geometry_dispose))
280
+ deallocate_geometry(geometry)
281
+ end
282
+
283
+ def on_texture_dispose(event)
284
+ texture = event.target
285
+ texture.remove_event_listener(:dispose, method(:on_texture_dispose))
286
+ deallocate_texture(texture)
287
+ @info[:memory][:textures] -= 1
288
+ end
289
+
290
+ def on_render_target_dispose(event)
291
+ render_target = event.target
292
+ render_target.remove_event_listener(:dispose, method(:on_render_target_dispose))
293
+ deallocate_render_target(render_target)
294
+ @info[:memory][:textures] -= 1
295
+ end
296
+
297
+ def on_material_dispose(event)
298
+ material = event.target
299
+ material.remove_event_listener(:dispose, method(:on_material_dispose))
300
+ deallocate_material(material)
301
+ end
302
+
303
+ def clamp_to_max_size(image, max_size = @_max_texture_size)
304
+ width, height = image.width, image.height
305
+ if width > max_size || height > max_size
306
+ # TODO: scale the image ...
307
+
308
+ puts "WARNING: Mittsu::OpenGL::Renderer: image is too big (#{width} x #{height}). Resized to #{@_max_texture_size} x #{@_max_texture_size}"
309
+ end
310
+ image
311
+ end
312
+
313
+ def add_opengl_object(buffer, object)
314
+ add_buffer(@_opengl_objects, buffer, object)
315
+ end
316
+
317
+ def remove_opengl_object(object)
318
+ @_opengl_objects.delete(object.id)
319
+ end
320
+
321
+ private
322
+
323
+ def clear_color(r, g, b, a)
324
+ if (@_premultiplied_alpha)
325
+ r *= a; g *= a; b *= a
326
+ end
327
+
328
+ GL.ClearColor(r, g, b, a)
329
+ end
330
+
331
+ def set_default_gl_state
332
+ GL.ClearColor(0.0, 0.0, 0.0, 1.0)
333
+ GL.ClearDepth(1)
334
+ GL.ClearStencil(0)
335
+
336
+ GL.Enable(GL::DEPTH_TEST)
337
+ GL.DepthFunc(GL::LEQUAL)
338
+
339
+ GL.FrontFace(GL::CCW)
340
+ GL.CullFace(GL::BACK)
341
+ GL.Enable(GL::CULL_FACE)
342
+
343
+ GL.Enable(GL::BLEND)
344
+ GL.BlendEquation(GL::FUNC_ADD)
345
+ GL.BlendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA)
346
+
347
+ default_target.use_viewport
348
+
349
+ clear_color(@_clear_color.r, @_clear_color.g, @_clear_color.b, @_clear_alpha)
350
+ end
351
+
352
+ def render_objects(render_list, camera, lights, fog, override_material)
353
+ material = nil
354
+ render_list.each do |opengl_object|
355
+ puts "-- RENDER_OBJECT #{opengl_object.name}" if DEBUG
356
+ object = opengl_object.object
357
+ buffer = opengl_object.buffer
358
+
359
+ object.setup_matrices(camera)
360
+
361
+ if override_material
362
+ material = override_material
363
+ else
364
+ material = opengl_object.material
365
+ next unless material
366
+ material.set(self)
367
+ end
368
+
369
+ set_material_faces(material)
370
+ if buffer.is_a? BufferGeometry
371
+ # TODO
372
+ # render_buffer_direct(camera, lights, fog, material, buffer, object)
373
+ else
374
+ puts "-- RENDER COLOR #{material.color}" if DEBUG
375
+ render_buffer(camera, lights, fog, material, buffer, object)
376
+ end
377
+ end
378
+ end
379
+
380
+ def render_objects_immediate(render_list, material_type, camera, lights, fog, override_material)
381
+ material = nil
382
+ render_list.each do |opengl_object|
383
+ object = opengl_object.object
384
+ if object.visible
385
+ if override_material
386
+ material = override_material
387
+ else
388
+ material = case material_type
389
+ when :transparent then opengl_object.transparent
390
+ when :opaque then opengl_object.opaque
391
+ else nil
392
+ end
393
+ next unless material
394
+ material.set(self)
395
+ end
396
+ render_immediate_object(camera, lights, fog, material, object)
397
+ end
398
+ end
399
+ end
400
+
401
+ def add_buffer(objlist, buffer, object)
402
+ id = object.id
403
+ (objlist[id] ||= []) << OpenGL::Buffer.new(
404
+ buffer, object, nil, 0
405
+ )
406
+ end
407
+
408
+ def unroll_immediate_buffer_material(opengl_object)
409
+ object = opengl_object.object
410
+ material = object.material
411
+
412
+ if material.transparent
413
+ opengl_object.transparent
414
+ opengl_object.opaque = nil
415
+ else
416
+ opengl_object.opaque = material
417
+ opengl_object.transparent = nil
418
+ end
419
+ end
420
+
421
+ def unroll_buffer_material(opengl_object)
422
+ object = opengl_object.object
423
+ buffer = opengl_object.buffer
424
+
425
+ geometry = object.geometry
426
+ material = object.material
427
+
428
+ if material
429
+ puts "--- UNROLL #{opengl_object.name}" if DEBUG
430
+ if material.is_a? MeshFaceMaterial
431
+ material_index = geometry.is_a?(BufferGeometry) ? 0 : buffer.material_index
432
+ material = material.materials[material_index]
433
+ end
434
+
435
+ opengl_object.material = material
436
+
437
+ if material.transparent
438
+ @transparent_objects << opengl_object
439
+ else
440
+ @opaque_objects << opengl_object
441
+ end
442
+ end
443
+ end
444
+
445
+ # FIXME: refactor
446
+ def update_object(object)
447
+ geometry = object.geometry
448
+
449
+ if geometry.is_a? BufferGeometry
450
+ # TODO: geometry vertex array ?????
451
+ # GL.BindVertexArray geometry.vertex_array
452
+
453
+ geometry.attributes.each do |(key, attribute)|
454
+ buffer_type = (key == 'index') ? GL::ELEMENT_ARRAY_BUFFER : GL::ARRAY_BUFFER
455
+
456
+ if attribute.buffer.nil?
457
+ attribute.buffer = GL.CreateBuffer
458
+ GL.BindBuffer(buffer_type, attribute.buffer)
459
+ GL.BufferData_easy(buffer_type, attribute.array, (attribute.is_a? DynamicBufferAttribute) ? GL::DYNAMIC_DRAW : GL::STATIC_DRAW)
460
+
461
+ attribute.needs_update = false
462
+ elsif attribute.needs_update
463
+ GL.BindBuffer(buffer_type, attribute.buffer)
464
+ if attribute.update_range.nil? || attribute.update_range.count == -1 # Not using update ranged
465
+ GL.BufferSubData(buffer_type, 0, attribute.array)
466
+ elsif attribute.udpate_range.count.zero?
467
+ puts 'ERROR: Mittsu::OpenGL::Renderer#update_object: using update_range for Mittsu::DynamicBufferAttribute and marked as needs_update but count is 0, ensure you are using set methods or updating manually.'
468
+ else
469
+ # TODO: make a GL.BufferSubData_easy method
470
+ GL.BufferSubData(buffer_type, attribute.update_range.offset * attribute.array.BYTES_PER_ELEMENT, attribute.array.subarray(attribute.update_range.offset, attribute.update_range.offset + attribute.update_range.count))
471
+ attribute.update_range.count = 0 # reset range
472
+ end
473
+
474
+ attribute.needs_update = false
475
+ end
476
+ end
477
+ else
478
+ object.update
479
+ end
480
+ end
481
+
482
+ # FIXME: refactor
483
+ def set_program(camera, lights, fog, material, object)
484
+ @_used_texture_units = 0
485
+ if material.needs_update?
486
+ deallocate_material(material) if material.program
487
+
488
+ material.init(lights, fog, object, self)
489
+ material.needs_update = false
490
+ end
491
+
492
+ if material.morph_targets
493
+ if !object.morph_target_influences
494
+ object.morph_target_influences = Array.new(@max_morph_targets) # Float32Array
495
+ end
496
+ end
497
+
498
+ refresh_program = false
499
+ refresh_material = false
500
+ refresh_lights = false
501
+
502
+ program = material.program
503
+ program_uniforms = program.uniforms
504
+ material_uniforms = material.shader[:uniforms]
505
+
506
+ if program.id != @_current_program
507
+ GL.UseProgram(program.program)
508
+ @_current_program = program.id
509
+
510
+ refresh_program = true
511
+ refresh_material = true
512
+ refresh_lights = true
513
+ end
514
+
515
+ if material.id != @_current_material_id
516
+ refresh_lights = true if @_current_material_id == -1
517
+ @_current_material_id = material.id
518
+
519
+ refresh_material = true
520
+ end
521
+
522
+ if refresh_program || camera != @_current_camera
523
+ @_current_camera = camera
524
+ update_camera_uniforms(program_uniforms, camera, material)
525
+ end
526
+
527
+ if material.skinning
528
+ # TODO: when skinning is implemented. Then also refactor
529
+ # if object.bind_matrix && !program_uniforms['bindMatrix'].nil?
530
+ # GL.UniformMatrix4fv(program_uniforms['bindMatrix'], GL::FALSE, object.bind_matrix.elements)
531
+ # end
532
+ #
533
+ # if object.bind_matrix_inverse && !program_uniforms['bindMatrixInverse'].nil?
534
+ # GL.UniformMatrix4fv(program_uniforms['bindMatrixInverse'], GL::FALSE, object.bind_matrix_inverse.elements)
535
+ # end
536
+ #
537
+ # if @_supports_bone_textures && object.skeleton && object.skeleton.use_vertex_texture
538
+ # if !program_uniforms['boneTexture'].nil?
539
+ # texture_unit = get_texture_unit
540
+ #
541
+ # GL.Uniform1i(program_uniforms['boneTexture'], texture_unit)
542
+ # object.skeleton.bone_texture.set(texture_unit, self)
543
+ # end
544
+ #
545
+ # if !program_uniforms['boneTextureWidth'].nil?
546
+ # GL.Uniform1i(program_uniforms['boneTextureWidth'], object.skeleton.bone_texture_width)
547
+ # end
548
+ #
549
+ # if !program_uniforms['boneTextureHeight'].nil?
550
+ # GL.Uniform1i(program_uniforms['boneTextureHeight'], object.skeleton.bone_texture_height)
551
+ # end
552
+ # elsif object.skeleton && object.skeleton.bone_matrices
553
+ # if !program_uniforms['boneGlobalMatrices'].nil?
554
+ # GL.UniformMatrix4fv(program_uniforms['boneGlobalMatrices'], GL::FALSE, object.skeleton.bone_matrices)
555
+ # end
556
+ # end
557
+ end
558
+
559
+ if refresh_material
560
+ # TODO: when fog is implemented
561
+ # refresh_uniforms_fog(material_uniforms, fog) if fog && material.fog
562
+
563
+ if material.needs_lights?
564
+ if @light_renderer.lights_need_update
565
+ refresh_lights = true
566
+ @light_renderer.setup(lights)
567
+ end
568
+
569
+ if refresh_lights
570
+ OpenGL::Helper.refresh_uniforms_lights(material_uniforms, @light_renderer.cache)
571
+ end
572
+
573
+ OpenGL::Helper.mark_uniforms_lights_needs_update(material_uniforms, refresh_lights)
574
+ end
575
+
576
+ material.refresh_uniforms(material_uniforms)
577
+
578
+ # TODO: when all of these things exist
579
+ # when LineDashedMaterial
580
+ # refresh_uniforms_line(material_uniforms, material)
581
+ # refresh_uniforms_dash(material_uniforms, material)
582
+ # when MeshDepthMaterial
583
+ # material_uniforms.m_near.value = camera.near
584
+ # material_uniforms.m_far.value = camera.far
585
+ # material_uniforms.opacity.value = material.opacity
586
+ # when MeshNormalMaterial
587
+ # material_uniforms.opactity.value = material.opacity
588
+
589
+ if object.receive_shadow && !material.shadow_pass
590
+ OpenGL::Helper.refresh_uniforms_shadow(material_uniforms, lights)
591
+ end
592
+
593
+ load_uniforms_generic(material.uniforms_list)
594
+ end
595
+
596
+ object.load_uniforms_matrices(program_uniforms)
597
+
598
+ if !program_uniforms['modelMatrix'].nil?
599
+ GL.UniformMatrix4fv(program_uniforms['modelMatrix'], 1, GL::FALSE, array_to_ptr_easy(object.matrix_world.elements))
600
+ end
601
+
602
+ program
603
+ end
604
+
605
+ # FIXME: REFACTOR!?!?!?!?!???
606
+ # MASSIVE CASE STATEMENT OMG!!!
607
+ def load_uniforms_generic(uniforms)
608
+ uniforms.each do |(uniform, location)|
609
+ # needs_update property is not added to all uniforms.
610
+ next if uniform.needs_update == false || location == -1
611
+
612
+ type = uniform.type
613
+ value = uniform.value
614
+
615
+ # AAAAAHHHHH!!!!! \o/ *flips table*
616
+ case type
617
+ when :int
618
+ GL.Uniform1i(location, value)
619
+ when :ivec2
620
+ GL.Uniform2i(location, value[0], value[1])
621
+ when :ivec3
622
+ GL.Uniform3i(location, value[0], value[1], value[2])
623
+ when :ivec4
624
+ GL.Uniform4i(location, value[0], value[1], value[2], value[3])
625
+ when :float
626
+ GL.Uniform1f(location, value)
627
+ when :vec2
628
+ GL.Uniform2f(location, value[0], value[1])
629
+ when :vec3, :color
630
+ GL.Uniform3f(location, value[0], value[1], value[2])
631
+ when :vec4
632
+ GL.Uniform4f(location, value[0], value[1], value[2], value[3])
633
+ when :'int[]'
634
+ GL.Uniform1iv(location, value.length, array_to_ptr_easy(value))
635
+ when :'ivec2[]'
636
+ GL.Uniform2iv(location, value.length / 2, array_to_ptr_easy(value))
637
+ when :'ivec3[]'
638
+ GL.Uniform3iv(location, value.length / 3, array_to_ptr_easy(value))
639
+ when :'ivec4[]'
640
+ GL.Uniform4iv(location, value.length / 4, array_to_ptr_easy(value))
641
+ when :'float[]'
642
+ GL.Uniform1fv(location, value.length, array_to_ptr_easy(value))
643
+ when :'vec2[]'
644
+ if value[0].is_a? Vector2
645
+ uniform.array ||= value.flat_map(&:to_a) # TODO: Float32Array
646
+ GL.Uniform2fv(location, value.length, array_to_ptr_easy(uniform.array))
647
+ else
648
+ GL.Uniform2fv(location, value.length / 2, array_to_ptr_easy(value))
649
+ end
650
+ when :'vec3[]', :'color[]'
651
+ if value.first.is_a?(Vector3) || value.first.is_a?(Color)
652
+ uniform.array ||= value.flat_map(&:to_a) # TODO: Float32Array
653
+ GL.Uniform3fv(location, value.length, array_to_ptr_easy(uniform.array))
654
+ else
655
+ GL.Uniform3fv(location, value.length / 3, array_to_ptr_easy(value))
656
+ end
657
+ when :'vec4[]'
658
+ if value.first.is_a? Vector4
659
+ uniform.array ||= value.flat_map(&:to_a) # TODO: Float32Array
660
+ GL.Uniform4fv(location, value.length, array_to_ptr_easy(uniform.array))
661
+ else
662
+ GL.Uniform4fv(location, value.length / 4, array_to_ptr_easy(value))
663
+ end
664
+ when :mat3
665
+ GL.UniformMatrix3fv(location, 1, GL::FALSE, array_to_ptr_easy(value.to_a))
666
+ when :mat4
667
+ GL.UniformMatrix4fv(location, 1, GL::FALSE, array_to_ptr_easy(value.to_a))
668
+ when :'mat3[]'
669
+ if value.first.is_a? Matrix3
670
+ uniform.array ||= Array.new(9 * value.length) # Float32Array
671
+
672
+ value.each_with_index do |v, i|
673
+ value[i].flatten_to_array_offset(uniform.array, i * 9)
674
+ end
675
+
676
+ GL.UniformMatrix3fv(location, value.length, GL::FALSE, array_to_ptr_easy(uniform.array))
677
+ else
678
+ GL.UniformMatrix3fv(location, value.length / 9, GL::FALSE, array_to_ptr_easy(value))
679
+ end
680
+ when :'mat4[]'
681
+ if value.first.is_a? Matrix4
682
+ uniform.array ||= Array.new(16 * value.length) # Float32Array
683
+
684
+ value.each_with_index do |v, i|
685
+ value[i].flatten_to_array_offset(uniform.array, i * 16)
686
+ end
687
+
688
+ GL.UniformMatrix4fv(location, value.length, GL::FALSE, array_to_ptr_easy(uniform.array))
689
+ else
690
+ GL.UniformMatrix4fv(location, value.length / 16, GL::FALSE, array_to_ptr_easy(value))
691
+ end
692
+ when :texture
693
+ # single Mittsu::Texture (2d or cube)
694
+ texture = value
695
+ texture_unit = get_texture_unit
696
+
697
+ GL.Uniform1i(location, texture_unit)
698
+
699
+ next unless texture
700
+
701
+ texture.set(texture_unit, self)
702
+ # TODO: when OpenGLRenderTargetCube is defined
703
+ # elsif texture.is_a?(OpenGLRenderTargetCube)
704
+ # set_cube_texture_dynamic(texture, texture_unit)
705
+ when :'texture[]'
706
+ # array of Mittsu::Texture (2d)
707
+ uniform.array ||= []
708
+
709
+ uniform.value.each_index do |i|
710
+ uniform.array[i] = get_texture_unit
711
+ end
712
+
713
+ GL.Uniform1iv(location, uniform.array.length, array_to_ptr_easy(uniform.array))
714
+
715
+ uniform.value.each_with_index do |tex, i|
716
+ tex_unit = uniform.array[i]
717
+
718
+ next unless tex
719
+
720
+ tex.set(tex_unit, self)
721
+ end
722
+ else
723
+ puts "WARNING: Mittsu::OpenGL::Renderer: Unknown uniform type: #{type}"
724
+ end
725
+ end
726
+ end
727
+
728
+ def get_texture_unit
729
+ texture_unit = @_used_texture_units
730
+
731
+ if texture_unit >= @_max_textures
732
+ puts "WARNING: OpenGL::Renderer: trying to use #{texture_unit} texture units while this GPU supports only #{@_max_textures}"
733
+ end
734
+
735
+ @_used_texture_units += 1
736
+ texture_unit
737
+ end
738
+
739
+ def ensure_depth_buffer_writing
740
+ @state.set_depth_test(true)
741
+ @state.set_depth_write(true)
742
+ @state.set_color_write(true)
743
+ end
744
+
745
+ def reset_cache
746
+ @_current_geometry_program = ''
747
+ @_current_material_id = -1
748
+ @_current_camera = nil
749
+ @light_renderer.reset
750
+ end
751
+
752
+ def reset_objects_cache
753
+ @lights.clear
754
+ @opaque_objects.clear
755
+ @transparent_objects.clear
756
+ @sprites.clear
757
+ @lens_flares.clear
758
+ end
759
+
760
+ def reset_info
761
+ @info[:render][:calls] = 0
762
+ @info[:render][:vertices] = 0
763
+ @info[:render][:faces] = 0
764
+ @info[:render][:points] = 0
765
+ end
766
+
767
+ def reset_cache_for_this_frame
768
+ reset_cache
769
+ reset_objects_cache
770
+ reset_info
771
+ end
772
+
773
+ def update_screen_projection(camera)
774
+ camera.matrix_world_inverse.inverse(camera.matrix_world)
775
+
776
+ @proj_screen_matrix.multiply_matrices(camera.projection_matrix, camera.matrix_world_inverse)
777
+ @_frustum.set_from_matrix(@proj_screen_matrix)
778
+ end
779
+
780
+ def sort_objects_for_render
781
+ @opaque_objects.sort! { |a,b| OpenGL::Helper.painter_sort_stable(a,b) }
782
+ @transparent_objects.sort! { |a,b| OpenGL::Helper.reverse_painter_sort_stable(a,b) }
783
+ end
784
+
785
+ def set_matrices_for_immediate_objects(camera)
786
+ @_opengl_objects_immediate.each do |opengl_object|
787
+ object = opengl_object.object
788
+
789
+ if object.visible
790
+ object.setup_matrices(camera)
791
+ unroll_immediate_buffer_material(opengl_object)
792
+ end
793
+ end
794
+ end
795
+
796
+ def render_main_pass(scene, camera)
797
+ if scene.override_material
798
+ render_with_override_material(scene, camera)
799
+ else
800
+ render_with_default_materials(scene, camera)
801
+ end
802
+ end
803
+
804
+ def render_with_override_material(scene, camera)
805
+ override_material = scene.override_material
806
+
807
+ override_material.set(self)
808
+
809
+ render_objects(@opaque_objects, camera, @lights, scene.fog, override_material)
810
+ render_objects(@transparent_objects, camera, @lights, scene.fog, override_material)
811
+ render_objects_immediate(@_opengl_objects_immediate, nil, camera, @lights, scene.fog, override_material)
812
+ end
813
+
814
+ def render_with_default_materials(scene, camera)
815
+ render_opaque_pass(scene, camera)
816
+ render_transparent_pass(scene, camera)
817
+ end
818
+
819
+ def render_opaque_pass(scene, camera)
820
+ # front-to-back order
821
+ @state.set_blending(NoBlending)
822
+
823
+ render_objects(@opaque_objects, camera, @lights, scene.fog, nil)
824
+ render_objects_immediate(@_opengl_objects_immediate, :opaque, camera, @lights, scene.fog, nil)
825
+ end
826
+
827
+ def render_transparent_pass(scene, camera)
828
+ # back-to-front-order
829
+ render_objects(@transparent_objects, camera, @lights, scene.fog, nil)
830
+ render_objects_immediate(@_opengl_objects_immediate, :transparent, camera, @lights, scene.fog, nil)
831
+ end
832
+
833
+ def render_custom_plugins_pre_pass(scene, camera)
834
+ @shadow_map_plugin.render(scene, camera)
835
+ end
836
+
837
+ def render_custom_plugins_post_pass(scene, camera)
838
+ @sprite_plugin.render(scene, camera)
839
+
840
+ # TODO: when these custom plugins are implemented
841
+ # lens_flare_plugin.render(scene, camera, @_current_render_target.width, @_current_render_target.height)
842
+ end
843
+
844
+ def update_skeleton_objects(scene)
845
+ # TODO: when SkinnedMesh is defined
846
+ # scene.traverse do |object|
847
+ # if object.is_a? SkinnedMesh
848
+ # object.skeleton.update
849
+ # end
850
+ # end
851
+ end
852
+
853
+ def perform_auto_clear
854
+ clear(@auto_clear_color, @auto_clear_depth, @auto_clear_stencil)
855
+ end
856
+
857
+ def init_clearing
858
+ @_clear_color = Color.new(0x000000)
859
+ @_clear_alpha = 0.0
860
+
861
+ @auto_clear = true
862
+ @auto_clear_color = true
863
+ @auto_clear_depth = true
864
+ @auto_clear_stencil = true
865
+ end
866
+
867
+ def init_gamma
868
+ @gamma_factor = 2.0 # backwards compat???
869
+ @gamma_input = false
870
+ @gamma_output = false
871
+ end
872
+
873
+ def init_shadow_properties
874
+ @shadow_map_enabled = false
875
+ @shadow_map_type = PCFShadowMap
876
+ @shadow_map_cull_face = CullFaceFront
877
+ @shadow_map_debug = false
878
+ @shadow_map_cascade = false
879
+ end
880
+
881
+ def init_morphs
882
+ @max_morph_targets = 8
883
+ @max_morph_normals = 4
884
+ end
885
+
886
+ def init_collections
887
+ @lights = []
888
+ @sprites = []
889
+
890
+ @_opengl_objects = {}
891
+ @_opengl_objects_immediate = []
892
+
893
+ @opaque_objects = []
894
+ @transparent_objects = []
895
+
896
+ @sprites = []
897
+ @lens_flares = []
898
+
899
+ @programs = []
900
+ end
901
+
902
+ def init_info
903
+ @info = {
904
+ memory: {
905
+ programs: 0,
906
+ geometries: 0,
907
+ textures: 0
908
+ },
909
+ render: {
910
+ calls: 0,
911
+ vertices: 0,
912
+ faces: 0,
913
+ points: 0
914
+ }
915
+ }
916
+ end
917
+
918
+ def init_state_cache
919
+ @_current_program = nil
920
+ @_current_render_target = default_target
921
+ @_current_material_id = -1
922
+ @_current_geometry_program = ''
923
+ @_current_camera = nil
924
+
925
+ @_used_texture_units = 0
926
+ end
927
+
928
+ def init_camera_matrix_cache
929
+ @_frustum = Frustum.new
930
+ @proj_screen_matrix = Matrix4.new
931
+ @_vector3 = Vector3.new
932
+ end
933
+
934
+ def fetch_parameters(parameters)
935
+ @_alpha = parameters.fetch(:alpha, false)
936
+ @_depth = parameters.fetch(:depth, true)
937
+ @_stencil = parameters.fetch(:stencil, true)
938
+ @_premultiplied_alpha = parameters.fetch(:premultiplied_alpha, true)
939
+ @_preserve_drawing_buffer = parameters.fetch(:preserve_drawing_buffer, false)
940
+ @logarithmic_depth_buffer = parameters.fetch(:logarithmic_depth_buffer, false)
941
+
942
+ @width = parameters.fetch(:width, 800)
943
+ @height = parameters.fetch(:height, 600)
944
+ @title = parameters.fetch(:title, "Mittsu #{VERSION}")
945
+ @antialias = parameters.fetch(:antialias, 0)
946
+ end
947
+
948
+ def get_gpu_capabilities
949
+ @_max_textures = GL.GetParameter(GL::MAX_TEXTURE_IMAGE_UNITS)
950
+ @_max_vertex_textures = GL.GetParameter(GL::MAX_VERTEX_TEXTURE_IMAGE_UNITS)
951
+ @_max_texture_size = GL.GetParameter(GL::MAX_TEXTURE_SIZE)
952
+ @_max_cubemap_size = GL.GetParameter(GL::MAX_CUBE_MAP_TEXTURE_SIZE)
953
+
954
+ @_supports_vertex_textures = @_max_vertex_textures > 0
955
+ @_supports_bone_textures = @_supports_vertex_textures && false # TODO: extensions.get('OES_texture_float') ????
956
+ end
957
+
958
+ def init_plugins
959
+ @shadow_map_plugin = ShadowMapPlugin.new(self, @lights, @_opengl_objects, @_opengl_objects_immediate)
960
+
961
+ @sprite_plugin = SpritePlugin.new(self, @sprites)
962
+
963
+ # TODO: when these custom plugins are implemented
964
+ # @lens_flare_plugin = LensFlarePlugin.new(self, @lens_flares)
965
+ end
966
+
967
+ def create_window
968
+ # attributes = {
969
+ # alpha: _alpha,
970
+ # depth: _depth,
971
+ # stencil: _stencil,
972
+ # antialias: _antialias,
973
+ # premultiplied_alpha: _premultiplied_alpha,
974
+ # preserve_drawing_buffer: _preserve_drawing_buffer
975
+ # }
976
+
977
+ @window = GLFW::Window.new(@width, @height, @title, antialias: @antialias)
978
+
979
+ default_target.set_viewport_size(*(@window.framebuffer_size))
980
+
981
+ # TODO: handle losing opengl context??
982
+ end
983
+
984
+ def switch_geometry_program(program, material, geometry_group)
985
+ wireframe_bit = material.wireframe ? 1 : 0
986
+ geometry_program = "#{geometry_group.id}_#{program.id}_#{wireframe_bit}"
987
+
988
+ if geometry_program != @_current_geometry_program
989
+ @_current_geometry_program = geometry_program
990
+ true
991
+ else
992
+ false
993
+ end
994
+ end
995
+
996
+ def default_target
997
+ @_defualt_target ||= OpenGL::DefaultTarget.new(self)
998
+ end
999
+
1000
+ def update_camera_uniforms(uniforms, camera, material)
1001
+ GL.UniformMatrix4fv(uniforms['projectionMatrix'], 1, GL::FALSE, array_to_ptr_easy(camera.projection_matrix.elements))
1002
+
1003
+ if @logarithmic_depth_buffer
1004
+ GL.Uniform1f(uniforms['logDepthBuffFC'], 2.0 / ::Math.log(camera.far + 1.0) / Math::LN2)
1005
+ end
1006
+
1007
+ if material.needs_camera_position_uniform? && !uniforms['cameraPosition'].nil?
1008
+ @_vector3.set_from_matrix_position(camera.matrix_world)
1009
+ GL.Uniform3f(uniforms['cameraPosition'], @_vector3.x, @_vector3.y, @_vector3.z)
1010
+ end
1011
+
1012
+ if material.needs_view_matrix_uniform? && !uniforms['viewMatrix'].nil?
1013
+ GL.UniformMatrix4fv(uniforms['viewMatrix'], 1, GL::FALSE, array_to_ptr_easy(camera.matrix_world_inverse.elements))
1014
+ end
1015
+ end
1016
+
1017
+ def remove_child(object)
1018
+ if object.is_a?(Mesh) || object.is_a?(PointCloud) || object.is_a?(Line)
1019
+ @_opengl_objects.delete(object.id)
1020
+
1021
+ # elsif object.is_a?(ImmediateRenderObject) || object.immediate_render_callback
1022
+ # removeInstances( _webGL.ObjectsImmediate, object );
1023
+ end
1024
+
1025
+ object.deinit
1026
+ end
1027
+ end
1028
+ end