module Mittsu class OpenGL::State def initialize @new_attributes = Array.new(16) # Uint8Array @enabled_attributes = Array.new(16) # Uint8Array @current_blending = nil @current_blend_equation = nil @current_blend_src = nil @current_blend_dst = nil @current_blend_equation_alpha = nil @current_blend_src_alpha = nil @current_blend_dst_alpha = nil @current_depth_test = nil @current_depth_write = nil @current_color_write = nil @current_double_sided = nil @current_flip_sided = nil @current_line_width = nil @current_polygon_offset = nil @current_polygon_offset_factor = nil @current_polygon_offset_units = nil end def init_attributes @new_attributes.length.times do |i| @new_attributes[i] = false end end def enable_attribute(attribute) GL.EnableVertexAttribArray(attribute) @new_attributes[attribute] = true if !@enabled_attributes[attribute] # GL.EnableVertexAttribArray(attribute) @enabled_attributes[attribute] = true end end def disable_unused_attributes @enabled_attributes.length.times do |i| if @enabled_attributes[i] && !@new_attributes[i] GL.DisableVertexAttribArray(i) @enabled_attributes[i] = false end end end def set_blending(blending, blend_equation = nil, blend_src = nil, blend_dst = nil, blend_equation_alpha = nil, blend_src_alpha = nil, blend_dst_alpha = nil) if blending != @current_blending case blending when NoBlending GL.Disable(GL::BLEND) when AdditiveBlending GL.Enable(GL::BLEND) GL.BlendEquation(GL::FUNC_ADD) GL.BlendFunc(GL::SRC_ALPHA, GL::ONE) when SubtractiveBlending # TODO: Find blendFuncSeparate() combination ??? GL.Enable(GL::BLEND) GL.BlendEquation(GL::FUNC_ADD) GL.BlendFunc(GL::ZERO, GL::ONE_MINUS_SRC_COLOR) when MultiplyBlending # TODO: Find blendFuncSeparate() combination ??? GL.Enable(GL::BLEND) GL.BlendEquation(GL::FUNC_ADD) GL.BlendFunc(GL::ZERO, GL::ONE_MINUS_SRC_COLOR) when CustomBlending GL.Enable(GL::BLEND) else GL.Enable(GL::BLEND) GL.BlendEquationSeparate(GL::FUNC_ADD, GL::FUNC_ADD) GL.BlendFuncSeparate(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA, GL::ONE, GL::ONE_MINUS_SRC_ALPHA) end @current_blending = blending end if blending == CustomBlending blend_equation_alpha ||= blend_equation blend_src_alpha ||= blend_src blend_dst_alpha ||= blend_dst if blend_equation != @current_blend_equation || blend_equation_alpha != @current_blend_equation_alpha GL.BlendEquationSeparate(GL::MITTSU_PARAMS[blend_equation], GL::MITTSU_PARAMS[blend_equation_alpha]) @current_blend_equation = blend_equation @current_blend_equation_alpha = blend_equation_alpha end if blend_src != @current_blend_src || blend_dst != @current_blend_dst || blend_src_alpha != @current_blend_src_alpha || blend_dst_alpha != @current_blend_dst_alpha GL.BlendFuncSeparate(GL::MITTSU_PARAMS[blend_src], GL::MITTSU_PARAMS[blend_dst], GL::MITTSU_PARAMS[blend_src_alpha], GL::MITTSU_PARAMS[blend_dst_alpha]) @current_blend_src = nil @current_blend_dst = nil @current_blend_src_alpha = nil @current_blend_dst_alpha = nil end else @current_blend_equation = nil @current_blend_src = nil @current_blend_dst = nil @current_blend_equation_alpha = nil @current_blend_src_alpha = nil @current_blend_dst_alpha = nil end end def set_depth_test(depth_test) if @current_depth_test != depth_test if depth_test GL.Enable(GL::DEPTH_TEST) else GL.Disable(GL::DEPTH_TEST) end @current_depth_test = depth_test end end def set_depth_write(depth_write) if @current_depth_write != depth_write GL.DepthMask(depth_write ? GL::TRUE : GL::FALSE) @current_depth_write = depth_write end end def set_color_write(color_write) if @current_color_write != color_write gl_color_write = color_write ? GL::TRUE : GL::FALSE GL.ColorMask(gl_color_write, gl_color_write, gl_color_write, gl_color_write) @current_color_write = color_write end end def set_double_sided(double_sided) if @current_double_sided != double_sided if double_sided GL.Disable(GL::CULL_FACE) else GL.Enable(GL::CULL_FACE) end @current_double_sided = double_sided end end def set_flip_sided(flip_sided) if @current_flip_sided != flip_sided if flip_sided GL.FrontFace(GL::CW) else GL.FrontFace(GL::CCW) end @current_flip_sided = flip_sided end end def set_line_width(width) if width != @current_line_width GL.LineWidth(width) @current_line_width = width end end def set_polygon_offset(polygon_offset, factor, units) if @current_polygon_offset != polygon_offset if polygon_offset GL.Enable(GL::POLYGON_OFFSET_FILL) else GL.Disable(GL::POLYGON_OFFSET_FILL) end @current_polygon_offset = polygon_offset end if polygon_offset && (@current_polygon_offset_factor != factor || @current_polygon_offset_units != units) GL.PolygonOffset(factor, units) @current_polygon_offset_factor = factor @current_polygon_offset_units = units end end def reset @enabled_attributes.length.times do |i| @enabled_attributes[i] = false end @current_blending = nil @current_depth_test = nil @current_depth_write = nil @current_color_write = nil @current_double_sided = nil @current_flip_sided = nil end end end