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


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

def auto_clear
  @auto_clear
end

#auto_clear_colorObject

Returns the value of attribute auto_clear_color


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

def auto_clear_color
  @auto_clear_color
end

#auto_clear_depthObject

Returns the value of attribute auto_clear_depth


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

def auto_clear_depth
  @auto_clear_depth
end

#auto_clear_stencilObject

Returns the value of attribute auto_clear_stencil


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

def auto_clear_stencil
  @auto_clear_stencil
end

#gamma_factorObject

Returns the value of attribute gamma_factor


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

def gamma_factor
  @gamma_factor
end

#gamma_inputObject

Returns the value of attribute gamma_input


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

def gamma_input
  @gamma_input
end

#gamma_outputObject

Returns the value of attribute gamma_output


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

def gamma_output
  @gamma_output
end

#heightObject

Returns the value of attribute height


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

def height
  @height
end

#infoObject

Returns the value of attribute info


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

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


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

def max_morph_normals
  @max_morph_normals
end

#max_morph_targetsObject

Returns the value of attribute max_morph_targets


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

def max_morph_targets
  @max_morph_targets
end

#pixel_ratioObject

Returns the value of attribute pixel_ratio


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

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


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

def shadow_map_cascade
  @shadow_map_cascade
end

#shadow_map_cull_faceObject

Returns the value of attribute shadow_map_cull_face


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

def shadow_map_cull_face
  @shadow_map_cull_face
end

#shadow_map_debugObject

Returns the value of attribute shadow_map_debug


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

def shadow_map_debug
  @shadow_map_debug
end

#shadow_map_enabledObject

Returns the value of attribute shadow_map_enabled


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

def shadow_map_enabled
  @shadow_map_enabled
end

#shadow_map_typeObject

Returns the value of attribute shadow_map_type


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

def shadow_map_type
  @shadow_map_type
end

#sort_objectsObject

Returns the value of attribute sort_objects


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

def sort_objects
  @sort_objects
end

#stateObject

Returns the value of attribute state


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

def state
  @state
end

#widthObject

Returns the value of attribute width


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

def width
  @width
end

#windowObject

Returns the value of attribute window


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

def window
  @window
end

Instance Method Details

#add_opengl_object(buffer, object) ⇒ Object


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

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

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


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

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


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

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


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

def clear_depth
  glClear(GL_DEPTH_BUFFER_BIT)
end

#clear_stencilObject


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

def clear_stencil
  glClear(GL_STENCIL_BUFFER_BIT)
end

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


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

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

#compressed_texture_formatsObject


266
267
268
269
270
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 266

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

  @_compressed_texture_formats ||= []
end

#enable_scissor_test(enable) ⇒ Object


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

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

#get_clear_alphaObject


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

def get_clear_alpha
  @_clear_alpha
end

#get_clear_colorObject

clearing


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

def get_clear_color
  @_clear_color
end

#max_anisotropyObject

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


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

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

#object_in_frustum?(object) ⇒ Boolean

Returns:

  • (Boolean)

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

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

#on_geometry_dispose(event) ⇒ Object


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

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


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

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


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

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


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

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


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

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


322
323
324
# File 'lib/mittsu/renderers/opengl_renderer.rb', line 322

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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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

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


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

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)

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

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

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

Returns:

  • (Boolean)

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

def supports_vertex_textures?
  @_supports_vertex_textures
end