Class: Mittsu::OpenGLRenderer

Inherits:
Object
  • Object
show all
Defined in:
lib/mittsu/renderers/opengl_renderer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parameters = {}) ⇒ OpenGLRenderer

Returns a new instance of OpenGLRenderer.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 36

def initialize(parameters = {})
  puts "OpenGLRenderer (Revision #{REVISION})"

  fetch_parameters(parameters)

  @pixel_ratio = 1.0
  @sort_objects = true

  init_collections
  init_clearing
  init_gamma
  init_shadow_properties
  init_morphs
  init_info
  init_state_cache
  init_camera_matrix_cache

  @light_renderer = OpenGLLightRenderer.new(self)

  create_window

  @state = OpenGLState.new

  # TODO: load extensions??

  reset_gl_state
  set_default_gl_state

  get_gpu_capabilities

  init_plugins
end

Instance Attribute Details

#auto_clearObject

Returns the value of attribute auto_clear.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def auto_clear
  @auto_clear
end

#auto_clear_colorObject

Returns the value of attribute auto_clear_color.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def auto_clear_color
  @auto_clear_color
end

#auto_clear_depthObject

Returns the value of attribute auto_clear_depth.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def auto_clear_depth
  @auto_clear_depth
end

#auto_clear_stencilObject

Returns the value of attribute auto_clear_stencil.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def auto_clear_stencil
  @auto_clear_stencil
end

#gamma_factorObject

Returns the value of attribute gamma_factor.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def gamma_factor
  @gamma_factor
end

#gamma_inputObject

Returns the value of attribute gamma_input.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def gamma_input
  @gamma_input
end

#gamma_outputObject

Returns the value of attribute gamma_output.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def gamma_output
  @gamma_output
end

#heightObject

Returns the value of attribute height.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def height
  @height
end

#infoObject

Returns the value of attribute info.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def info
  @info
end

#light_rendererObject (readonly)

Returns the value of attribute light_renderer.



34
35
36
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 34

def light_renderer
  @light_renderer
end

#logarithmic_depth_bufferObject (readonly)

Returns the value of attribute logarithmic_depth_buffer.



34
35
36
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 34

def logarithmic_depth_buffer
  @logarithmic_depth_buffer
end

#max_morph_normalsObject

Returns the value of attribute max_morph_normals.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def max_morph_normals
  @max_morph_normals
end

#max_morph_targetsObject

Returns the value of attribute max_morph_targets.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def max_morph_targets
  @max_morph_targets
end

#pixel_ratioObject

Returns the value of attribute pixel_ratio.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def pixel_ratio
  @pixel_ratio
end

#programsObject (readonly)

Returns the value of attribute programs.



34
35
36
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 34

def programs
  @programs
end

#proj_screen_matrixObject (readonly)

Returns the value of attribute proj_screen_matrix.



34
35
36
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 34

def proj_screen_matrix
  @proj_screen_matrix
end

#shadow_map_cascadeObject

Returns the value of attribute shadow_map_cascade.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def shadow_map_cascade
  @shadow_map_cascade
end

#shadow_map_cull_faceObject

Returns the value of attribute shadow_map_cull_face.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def shadow_map_cull_face
  @shadow_map_cull_face
end

#shadow_map_debugObject

Returns the value of attribute shadow_map_debug.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def shadow_map_debug
  @shadow_map_debug
end

#shadow_map_enabledObject

Returns the value of attribute shadow_map_enabled.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def shadow_map_enabled
  @shadow_map_enabled
end

#shadow_map_typeObject

Returns the value of attribute shadow_map_type.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def shadow_map_type
  @shadow_map_type
end

#sort_objectsObject

Returns the value of attribute sort_objects.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def sort_objects
  @sort_objects
end

#stateObject

Returns the value of attribute state.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def state
  @state
end

#widthObject

Returns the value of attribute width.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def width
  @width
end

#windowObject

Returns the value of attribute window.



32
33
34
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 32

def window
  @window
end

Instance Method Details

#add_opengl_object(buffer, object) ⇒ Object



324
325
326
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 324

def add_opengl_object(buffer, object)
  add_buffer(@_opengl_objects, buffer, object)
end

#clamp_to_max_size(image, max_size = @_max_texture_size) ⇒ Object



314
315
316
317
318
319
320
321
322
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 314

def clamp_to_max_size(image, max_size = @_max_texture_size)
  width, height = image.width, image.height
  if width > max_size || height > max_size
    # TODO: scale the image ...

    puts "WARNING: Mittsu::OpenGLRenderer: image is too big (#{width} x #{height}). Resized to #{@_max_texture_size} x #{@_max_texture_size}"
  end
  image
end

#clear(color = true, depth = true, stencil = true) ⇒ Object



152
153
154
155
156
157
158
159
160
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 152

def clear(color = true, depth = true, stencil = true)
  bits = 0

  bits |= GL_COLOR_BUFFER_BIT if color
  bits |= GL_DEPTH_BUFFER_BIT if depth
  bits |= GL_STENCIL_BUFFER_BIT if stencil

  glClear(bits)
end

#clear_depthObject



162
163
164
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 162

def clear_depth
  glClear(GL_DEPTH_BUFFER_BIT)
end

#clear_stencilObject



166
167
168
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 166

def clear_stencil
  glClear(GL_STENCIL_BUFFER_BIT)
end

#clear_target(render_target, color, depth, stencil) ⇒ Object



170
171
172
173
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 170

def clear_target(render_target, color, depth, stencil)
  set_render_target(render_target)
  clear(color, depth, stencil)
end

#compressed_texture_formatsObject



272
273
274
275
276
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 272

def compressed_texture_formats
  # TODO: needs extensions.get ...

  @_compressed_texture_formats ||= []
end

#enable_scissor_test(enable) ⇒ Object



119
120
121
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 119

def enable_scissor_test(enable)
  enable ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST)
end

#get_clear_alphaObject



143
144
145
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 143

def get_clear_alpha
  @_clear_alpha
end

#get_clear_colorObject

clearing



133
134
135
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 133

def get_clear_color
  @_clear_color
end

#max_anisotropyObject

TODO: supports_float_textures? ??? TODO: supports[half|standard|compressed|blend min max] … ???



91
92
93
94
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 91

def max_anisotropy
  @_max_anisotropy ||= nil
  # TODO: get max anisotropy ????
end

#object_in_frustum?(object) ⇒ Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 123

def object_in_frustum?(object)
  @_frustum.intersects_object?(object)
end

#on_geometry_dispose(event) ⇒ Object



288
289
290
291
292
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 288

def on_geometry_dispose(event)
  geometry = event.target
  geometry.remove_event_listener(:dispose, method(:on_geometry_dispose))
  deallocate_geometry(geometry)
end

#on_material_dispose(event) ⇒ Object



308
309
310
311
312
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 308

def on_material_dispose(event)
  material = event.target
  material.remove_event_listener(:dispose, method(:on_material_dispose))
  deallocate_material(material)
end

#on_object_removed(event) ⇒ Object

Events



280
281
282
283
284
285
286
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 280

def on_object_removed(event)
  object = event.target
  object.traverse do |child|
    child.remove_event_listener(:remove, method(:on_object_removed))
    remove_child(child)
  end
end

#on_render_target_dispose(event) ⇒ Object



301
302
303
304
305
306
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 301

def on_render_target_dispose(event)
  render_target = event.target
  render_target.remove_event_listener(:dispose, method(:on_render_target_dispose))
  deallocate_render_target(render_target)
  @info[:memory][:textures] -= 1
end

#on_texture_dispose(event) ⇒ Object



294
295
296
297
298
299
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 294

def on_texture_dispose(event)
  texture = event.target
  texture.remove_event_listener(:dispose, method(:on_texture_dispose))
  deallocate_texture(texture)
  @info[:memory][:textures] -= 1
end

#remove_opengl_object(object) ⇒ Object



328
329
330
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 328

def remove_opengl_object(object)
  @_opengl_objects.delete(object.id)
end

#render(scene, camera, render_target = default_target, force_clear = false) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 200

def render(scene, camera, render_target = default_target, force_clear = false)
  raise "ERROR: Mittsu::OpenGLRenderer#render: camera is not an instance of Mittsu::Camera" unless camera.is_a?(Camera)

  reset_cache_for_this_frame

  scene.update_matrix_world if scene.auto_update
  camera.update_matrix_world if camera.parent.nil?

  update_skeleton_objects(scene)

  update_screen_projection(camera)
  scene.project(self)
  sort_objects_for_render if @sort_objects

  render_custom_plugins_pre_pass(scene, camera)

  set_matrices_for_immediate_objects(camera)

  set_render_target(render_target)
  perform_auto_clear if @auto_clear || force_clear
  render_main_pass(scene, camera)

  render_custom_plugins_post_pass(scene, camera)

  render_target.update_mipmap

  ensure_depth_buffer_writing
end

#render_buffer(camera, lights, fog, material, geometry_group, object) ⇒ Object



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 234

def render_buffer(camera, lights, fog, material, geometry_group, object)
  puts "--- RENDER #{object.name}" if DEBUG
  return unless material.visible

  geometry_group.renderer = self
  geometry_group.bind_vertex_array_object

  update_object(object)

  program = set_program(camera, lights, fog, material, object)
  attributes = program.attributes
  buffers_need_update = switch_geometry_program(program, material, geometry_group)

  @state.init_attributes if buffers_need_update

  if !material.morph_targets && attributes['position'] && attributes['position'] >= 0
    geometry_group.update_vertex_buffer(attributes['position']) if buffers_need_update
  elsif object.morph_target_base
    # TODO: when morphing is implemented
    # setup_morph_targets(material, geometry_group, object)
  end

  if buffers_need_update
    geometry_group.update_other_buffers(object, material, attributes)
  end

  @state.disable_unused_attributes

  object.render_buffer(camera, lights, fog, material, geometry_group, buffers_need_update)

  # TODO: render particles
  # when PointCloud
  #   glDrawArrays(GL_POINTS, 0, geometry_group.particle_count)
  #
  #   @info[:render][:calls] += 1
  #   @info[:render][:points] += geometry_group.particle_count
end

#reset_gl_stateObject



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 175

def reset_gl_state
  @_current_program = nil
  @_current_camera = nil

  @_current_geometry_program = ''
  @_current_material_id = -1

  @light_renderer.reset

  @state.reset
end

#set_clear_alpha(alpha) ⇒ Object



147
148
149
150
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 147

def set_clear_alpha(alpha)
  @_clear_alpha = alpha
  clear_color(@_clear_color.r, @_clear_color.g, @_clear_color.b, @_clear_alpha)
end

#set_clear_color(color, alpha = 1.0) ⇒ Object



137
138
139
140
141
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 137

def set_clear_color(color, alpha = 1.0)
  @_clear_color.set(color)
  @_clear_alpha = alpha
  clear_color(@_clear_color.r, @_clear_color.g, @_clear_color.b, @_clear_alpha)
end

#set_material_faces(material) ⇒ Object



229
230
231
232
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 229

def set_material_faces(material)
  @state.set_double_sided(material.side == DoubleSide)
  @state.set_flip_sided(material.side == BackSide)
end

#set_render_target(render_target = default_target) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 187

def set_render_target(render_target = default_target)
  # TODO: when OpenGLRenderTargetCube exists
  # is_cube = render_target.is_a? OpenGLRenderTargetCube

  # TODO framebuffer logic for render target cube
  render_target.setup_buffers

  if render_target != @_current_render_target
    render_target.use
    @_current_render_target = render_target
  end
end

#set_scissor(x, y, width, height) ⇒ Object



110
111
112
113
114
115
116
117
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 110

def set_scissor(x, y, width, height)
  glScissor(
    x * pixel_ratio,
    y * pixel_ratio,
    width * pixel_ratio,
    height * pixel_ratio
  )
end

#set_size(width, height) ⇒ Object



96
97
98
99
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 96

def set_size(width, height)
  @width, @height = width, height
  self.set_viewport(0, 0, width, height)
end

#set_viewport(x, y, width, height) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 101

def set_viewport(x, y, width, height)
  default_target.set_and_use_viewport(
    x * pixel_ratio,
    y * pixel_ratio,
    width * pixel_ratio,
    height * pixel_ratio
  )
end

#shadow_map_enabled?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 77

def shadow_map_enabled?
  @shadow_map_enabled
end

#sort_objects?Boolean

Returns:

  • (Boolean)


127
128
129
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 127

def sort_objects?
  @sort_objects
end

#supports_bone_textures?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 69

def supports_bone_textures?
  @_supports_bone_textures
end

#supports_vertex_textures?Boolean

TODO: get_context ??? TODO: force_context_loss ???

Returns:

  • (Boolean)


84
85
86
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 84

def supports_vertex_textures?
  @_supports_vertex_textures
end