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.



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

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.



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

def auto_clear
  @auto_clear
end

#auto_clear_colorObject

Returns the value of attribute auto_clear_color.



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

def auto_clear_color
  @auto_clear_color
end

#auto_clear_depthObject

Returns the value of attribute auto_clear_depth.



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

def auto_clear_depth
  @auto_clear_depth
end

#auto_clear_stencilObject

Returns the value of attribute auto_clear_stencil.



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

def auto_clear_stencil
  @auto_clear_stencil
end

#gamma_factorObject

Returns the value of attribute gamma_factor.



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

def gamma_factor
  @gamma_factor
end

#gamma_inputObject

Returns the value of attribute gamma_input.



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

def gamma_input
  @gamma_input
end

#gamma_outputObject

Returns the value of attribute gamma_output.



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

def gamma_output
  @gamma_output
end

#heightObject

Returns the value of attribute height.



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

def height
  @height
end

#infoObject

Returns the value of attribute info.



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

def info
  @info
end

#light_rendererObject (readonly)

Returns the value of attribute light_renderer.



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

def light_renderer
  @light_renderer
end

#logarithmic_depth_bufferObject (readonly)

Returns the value of attribute logarithmic_depth_buffer.



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

def logarithmic_depth_buffer
  @logarithmic_depth_buffer
end

#max_morph_normalsObject

Returns the value of attribute max_morph_normals.



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

def max_morph_normals
  @max_morph_normals
end

#max_morph_targetsObject

Returns the value of attribute max_morph_targets.



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

def max_morph_targets
  @max_morph_targets
end

#pixel_ratioObject

Returns the value of attribute pixel_ratio.



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

def pixel_ratio
  @pixel_ratio
end

#programsObject (readonly)

Returns the value of attribute programs.



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

def programs
  @programs
end

#proj_screen_matrixObject (readonly)

Returns the value of attribute proj_screen_matrix.



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

def proj_screen_matrix
  @proj_screen_matrix
end

#shadow_map_cascadeObject

Returns the value of attribute shadow_map_cascade.



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

def shadow_map_cascade
  @shadow_map_cascade
end

#shadow_map_cull_faceObject

Returns the value of attribute shadow_map_cull_face.



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

def shadow_map_cull_face
  @shadow_map_cull_face
end

#shadow_map_debugObject

Returns the value of attribute shadow_map_debug.



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

def shadow_map_debug
  @shadow_map_debug
end

#shadow_map_enabledObject

Returns the value of attribute shadow_map_enabled.



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

def shadow_map_enabled
  @shadow_map_enabled
end

#shadow_map_typeObject

Returns the value of attribute shadow_map_type.



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

def shadow_map_type
  @shadow_map_type
end

#sort_objectsObject

Returns the value of attribute sort_objects.



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

def sort_objects
  @sort_objects
end

#stateObject

Returns the value of attribute state.



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

def state
  @state
end

#widthObject

Returns the value of attribute width.



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

def width
  @width
end

#windowObject

Returns the value of attribute window.



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

def window
  @window
end

Instance Method Details

#add_opengl_object(buffer, object) ⇒ Object



313
314
315
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 313

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

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



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

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



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

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



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

def clear_depth
  glClear(GL_DEPTH_BUFFER_BIT)
end

#clear_stencilObject



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

def clear_stencil
  glClear(GL_STENCIL_BUFFER_BIT)
end

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



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

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

#compressed_texture_formatsObject



261
262
263
264
265
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 261

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

  @_compressed_texture_formats ||= []
end

#enable_scissor_test(enable) ⇒ Object



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

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

#get_clear_alphaObject



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

def get_clear_alpha
  @_clear_alpha
end

#get_clear_colorObject

clearing



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

def get_clear_color
  @_clear_color
end

#max_anisotropyObject

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



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

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

#object_in_frustum?(object) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#on_geometry_dispose(event) ⇒ Object



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

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



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

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



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

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



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

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



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

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



317
318
319
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 317

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

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



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

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



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

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)
end

#reset_gl_stateObject



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

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



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

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



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

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



225
226
227
228
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 225

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



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

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



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

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



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

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

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



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

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)


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

def shadow_map_enabled?
  @shadow_map_enabled
end

#sort_objects?Boolean

Returns:

  • (Boolean)


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

def sort_objects?
  @sort_objects
end

#supports_bone_textures?Boolean

Returns:

  • (Boolean)


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

def supports_bone_textures?
  @_supports_bone_textures
end

#supports_vertex_textures?Boolean

Returns:

  • (Boolean)


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

def supports_vertex_textures?
  @_supports_vertex_textures
end