lib/mittsu/opengl/geometry_like.rb
module Mittsu
module OpenGL::GeometryLike
CONST_BUFFER_NAMES = [
:vertex,
:color,
:normal,
:tangent,
:uv,
:uv2,
:skin_indices,
:skin_weight,
:line_distance,
:face,
:line
]
attr_accessor(*CONST_BUFFER_NAMES.map(&:to_s).map { |name| "#{name}_buffer" }.map(&:to_sym))
attr_accessor(*CONST_BUFFER_NAMES.map(&:to_s).map { |name| "#{name}_array" }.map(&:to_sym))
attr_accessor :vertex_array_object,
:num_morph_targets,
:num_morph_normals,
:morph_targets_buffers,
:morph_normals_buffers,
:morph_targets_arrays,
:morph_normals_arrays,
:faces3,
:type_array,
:face_count,
:line_count,
:particle_count,
:initted_arrays,
:custom_attributes_list,
:num_vertices,
:renderer
def bind_vertex_array_object
GL.BindVertexArray(@vertex_array_object) if @vertex_array_object
end
def update_vertex_buffer(attribute)
GL.BindBuffer(GL::ARRAY_BUFFER, @vertex_buffer)
@renderer.state.enable_attribute(attribute)
GL.VertexAttribPointer(attribute, 3, GL::FLOAT, GL::FALSE, 0, 0)
end
def update_other_buffers(object, material, attributes)
update_custom_attributes(attributes)
update_color_buffer(attributes['color'], object, material)
update_normal_buffer(attributes['normal'])
update_tangent_buffer(attributes['tangent'])
update_uv_buffers(attributes['uv'], attributes['uv2'], object, material)
if material.skinning
update_skin_buffers(attributes['skin_index'], attributes['skin_weight'])
end
update_line_distances_buffer(attributes['line_distances'])
end
private
def attribute_exists?(attribute)
attribute && attribute >= 0
end
def update_color_buffer(attribute, object, material)
return unless attribute_exists?(attribute)
if object.geometry.colors.length > 0 || object.geometry.faces.length > 0
update_attribute(attribute, @color_buffer, 3)
elsif material.default_attribute_values
GL.VertexAttrib3fv(attribute, material.default_attribute_values.color)
end
end
def update_normal_buffer(attribute)
return unless attribute_exists?(attribute)
update_attribute(attribute, @normal_buffer, 3)
end
def update_tangent_buffer(attribute)
return unless attribute_exists?(attribute)
update_attribute(attribute, @tangent_buffer, 4)
end
def update_uv_buffers(uv_attribute, uv2_attribute, object, material)
update_uv_buffer(uv_attribute, @uv_buffer, object, 0)
update_uv_buffer(uv2_attribute, @uv2_buffer, object, 1)
end
def update_uv_buffer(attribute, buffer, object, index)
return unless attribute_exists?(attribute)
if object.geometry.face_vertex_uvs[index]
update_attribute(attribute, buffer, 2)
else
# TODO default_attribute_value ???
# GL.VertexAttrib2fv(attribute, default_attribute_value)
end
end
def update_skin_buffers(index_attribute, weight_attribute)
return unless attribute_exists?(index_attribute) && attribute_exists?(weight_attribute)
update_attribute(attribute, @skin_indices_buffer, 4)
update_attribute(attribute, @skin_weight_buffer, 4)
end
def update_line_distances_buffer(attribute)
return unless attribute_exists?(attribute)
update_attribute(attribute, @line_distance_buffer, 1)
end
def update_custom_attributes(attributes)
if @custom_attributes_list
@custom_attributes_list.each do |custom_attribute|
belongs_to_attribute = attributes[custom_attribute.buffer.belongs_to_attribute]
update_custom_attribute(custom_attribute, belongs_to_attribute)
end
end
end
def update_custom_attribute(custom_attribute, belongs_to_attribute)
return unless attribute_exists?(belongs_to_attribute)
update_attribute(attribute, custom_attribute.buffer, custom_attribute.size)
end
def update_attribute(attribute, buffer, size)
GL.BindBuffer(GL::ARRAY_BUFFER, buffer)
@renderer.state.enable_attribute(attribute)
GL.VertexAttribPointer(attribute, size, GL::FLOAT, GL::FALSE, 0, 0)
end
end
end