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.



33
34
35
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
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 33

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.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def auto_clear
  @auto_clear
end

#auto_clear_colorObject

Returns the value of attribute auto_clear_color.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def auto_clear_color
  @auto_clear_color
end

#auto_clear_depthObject

Returns the value of attribute auto_clear_depth.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def auto_clear_depth
  @auto_clear_depth
end

#auto_clear_stencilObject

Returns the value of attribute auto_clear_stencil.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def auto_clear_stencil
  @auto_clear_stencil
end

#gamma_factorObject

Returns the value of attribute gamma_factor.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def gamma_factor
  @gamma_factor
end

#gamma_inputObject

Returns the value of attribute gamma_input.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def gamma_input
  @gamma_input
end

#gamma_outputObject

Returns the value of attribute gamma_output.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def gamma_output
  @gamma_output
end

#heightObject

Returns the value of attribute height.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def height
  @height
end

#infoObject

Returns the value of attribute info.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def info
  @info
end

#light_rendererObject (readonly)

Returns the value of attribute light_renderer.



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

def light_renderer
  @light_renderer
end

#logarithmic_depth_bufferObject (readonly)

Returns the value of attribute logarithmic_depth_buffer.



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

def logarithmic_depth_buffer
  @logarithmic_depth_buffer
end

#max_morph_normalsObject

Returns the value of attribute max_morph_normals.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def max_morph_normals
  @max_morph_normals
end

#max_morph_targetsObject

Returns the value of attribute max_morph_targets.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def max_morph_targets
  @max_morph_targets
end

#pixel_ratioObject

Returns the value of attribute pixel_ratio.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def pixel_ratio
  @pixel_ratio
end

#programsObject (readonly)

Returns the value of attribute programs.



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

def programs
  @programs
end

#proj_screen_matrixObject (readonly)

Returns the value of attribute proj_screen_matrix.



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

def proj_screen_matrix
  @proj_screen_matrix
end

#shadow_map_cascadeObject

Returns the value of attribute shadow_map_cascade.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def shadow_map_cascade
  @shadow_map_cascade
end

#shadow_map_cull_faceObject

Returns the value of attribute shadow_map_cull_face.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def shadow_map_cull_face
  @shadow_map_cull_face
end

#shadow_map_debugObject

Returns the value of attribute shadow_map_debug.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def shadow_map_debug
  @shadow_map_debug
end

#shadow_map_enabledObject

Returns the value of attribute shadow_map_enabled.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def shadow_map_enabled
  @shadow_map_enabled
end

#shadow_map_typeObject

Returns the value of attribute shadow_map_type.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def shadow_map_type
  @shadow_map_type
end

#sort_objectsObject

Returns the value of attribute sort_objects.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def sort_objects
  @sort_objects
end

#stateObject

Returns the value of attribute state.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def state
  @state
end

#widthObject

Returns the value of attribute width.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def width
  @width
end

#windowObject

Returns the value of attribute window.



29
30
31
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 29

def window
  @window
end

Instance Method Details

#add_opengl_object(buffer, object) ⇒ Object



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

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

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



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

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



149
150
151
152
153
154
155
156
157
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 149

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



159
160
161
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 159

def clear_depth
  glClear(GL_DEPTH_BUFFER_BIT)
end

#clear_stencilObject



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

def clear_stencil
  glClear(GL_STENCIL_BUFFER_BIT)
end

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



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

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

#compressed_texture_formatsObject



269
270
271
272
273
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 269

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

  @_compressed_texture_formats ||= []
end

#create_implementation(thing) ⇒ Object



311
312
313
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 311

def create_implementation(thing)
  OPENGL_IMPLEMENTATIONS[thing.class].new(thing, self)
end

#enable_scissor_test(enable) ⇒ Object



116
117
118
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 116

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

#get_clear_alphaObject



140
141
142
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 140

def get_clear_alpha
  @_clear_alpha
end

#get_clear_colorObject

clearing



130
131
132
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 130

def get_clear_color
  @_clear_color
end

#max_anisotropyObject

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



88
89
90
91
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 88

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

#object_in_frustum?(object) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#on_geometry_dispose(event) ⇒ Object



285
286
287
288
289
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 285

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



305
306
307
308
309
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 305

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



277
278
279
280
281
282
283
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 277

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



298
299
300
301
302
303
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 298

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



291
292
293
294
295
296
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 291

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



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

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

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



199
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
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 199

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.implementation(self).project
  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.implementation(self).update_mipmap

  ensure_depth_buffer_writing
end

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



233
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
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 233

def render_buffer(camera, lights, fog, material, geometry_group, object)
  return unless material.visible

  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.implementation(self).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



172
173
174
175
176
177
178
179
180
181
182
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 172

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



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

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



134
135
136
137
138
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 134

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



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

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



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

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

  render_target_impl = render_target.implementation(self)

  # TODO framebuffer logic for render target cube
  render_target_impl.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



107
108
109
110
111
112
113
114
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 107

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



93
94
95
96
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 93

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

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



98
99
100
101
102
103
104
105
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 98

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)


74
75
76
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 74

def shadow_map_enabled?
  @shadow_map_enabled
end

#sort_objects?Boolean

Returns:

  • (Boolean)


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

def sort_objects?
  @sort_objects
end

#supports_bone_textures?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 66

def supports_bone_textures?
  @_supports_bone_textures
end

#supports_vertex_textures?Boolean

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

Returns:

  • (Boolean)


81
82
83
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 81

def supports_vertex_textures?
  @_supports_vertex_textures
end