Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Play GLSL on mruby with OpenFrameworks

888339de9e7a88688b6acb30d33e66cd?s=47 蒼時弦や
September 08, 2016

Play GLSL on mruby with OpenFrameworks

888339de9e7a88688b6acb30d33e66cd?s=128

蒼時弦や

September 08, 2016
Tweet

More Decks by 蒼時弦や

Other Decks in Programming

Transcript

  1. Play GLSL on mruby with OpenFrameworks 襝儗䓚⛲

  2. Web Developer Game Developer Major in Digital Media Design Taiwanese

    who likes Anime, Manga, Game @elct9620 襝儗䓚⛲
  3. None
  4. https://www.flickr.com/photos/hsbt/21251922399/in/album-72157658244299230/

  5. Demo First Talk What is OpenFrameworks and GLSL? Shader Generator

    written in mruby Using mruby in C++
  6. Learn some physics knowledge before demo

  7. None
  8. DEMO TIME!

  9. Who use the OpenFrameworks? What is the Shader mean? What

    is the GLSL? OpenFrameworks and GLSL
  10. http://blog.bongiovi.tw/calligraphy-in-3d/ OpenFrameworks demo

  11. The Shader Role

  12. The Shader Role

  13. Vertex Shader http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

  14. Vertex Shader http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

  15. Vertex Shader http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

  16. Vertex Shader http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

  17. Fragment Shader

  18. Fragment Shader

  19. “GLSL is a language OpenGL provide for us”

  20. @5xruby @s_cat555

  21. Open Class to extend C++ class How to convert Ruby

    to GLSL The DSL limitation Arithmetic Problem Shader Generator
  22. class Shader def vertex(&block) code = Code.new code.instance_eval(&block) self.vertex =

    code.to_s end end Open Class
  23. mrb_define_method(mrb, klass, "draw", draw, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "vertex=", setVertexShader, MRB_ARGS_REQ(1));

    mrb_define_method(mrb, klass, "fragment=", setFragmentShader, MRB_ARGS_REQ(1)); mrb_define_method(mrb, klass, "bind", bind, MRB_ARGS_OPT(3)); mrb_define_method(mrb, klass, "apply", apply, MRB_ARGS_NONE()); Open Class
  24. vec4 lightIntensity = vec4(1, 1, 1, 1); lightIntensity = clamp(lightIntensity.x,

    0, 1); lightIntensity is Vec4 vec4(1, 1, 1, 1) lightIntensity is clamp(lightIntensity.x, 0, 1) Ruby Code GLSL Code Convert to GLSL
  25. @5xruby @s_cat555

  26. lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL

    Convert to GLSL
  27. lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL

  28. => #<Type:0x00ff8dc @type=“vec4” @arguments=[…]> Convert to GLSL

  29. TYPES.each do |type, typename| define_method(type) { |*args| Type.new(type, *args) }

    end Convert to GLSL
  30. lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL

  31. def is(*args) value = args value = args.first if args.first.is_a?(Array)

    AssignNode.new(*value) end Convert to GLSL
  32. => #<AssignNode:0x0ff @type=#<Type:0xfb> @expression=#<ExpressionNode:0xfa>> Convert to GLSL

  33. lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL

  34. def method_missing(name, *args, &block) value = args.first return assign(name, value)

    if value.is_a? (AssignNode) return [send(name.downcase), value] if is_const?(name) Variable.new(name) end Convert to GLSL
  35. => "vec4 lightIntensity = vec4(1, 1, 1, 1);" Convert to

    GLSL
  36. lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL

  37. class Shader::AssignNode def initialize(type, *args) @type = type @expression =

    args.shift unless type.is_a?(Type) && !@expression.nil? @expression = @type @type = nil end end end Convert to GLSL
  38. def to(name) name = "-#{name}" if @negative return "#{name} =

    #{expression};" if @type.nil? return "#{@type.to_typename} #{name} = #{expression};" unless is_const?(name) "const #{@type.to_typename} #{name} = #{expression};" end Convert to GLSL
  39. Convert to GLSL lightIntensity is Vec4 vec4(1, 1, 1, 1)

  40. Convert to GLSL vec4(1, 1, 1, 1) => #<Type:0xff @name=“vec4”>

  41. Convert to GLSL Vec4 [Argument] => [#<Type:0xfa>, #<Type:0xff>]

  42. Convert to GLSL is [type, expression] => #<AssignNode @type=#<Type:0xfa> @expression=#<Type:0xff>>

  43. Convert to GLSL lightIntensity [expression] => (Insert into Buffer)

  44. lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL

  45. def method_missing(name, *args, &block) @suffix << name self end Convert

    to GLSL
  46. def to_s return "#{@name}" if @suffix.empty? "#{@name}.#{@suffix.join(".")}" end Convert to

    GLSL
  47. lightIntensity.x # => “lightIntensity.x" lightIntensity.x.z # => “lightIntensity.x.z" Convert to

    GLSL
  48. class Shader::FunctionCall < Shader::Variable def initialize(name, *args) super(name) @args =

    args end def to_funtion "#{@name}(#{@args.join(", ")})" end def to_s return "#{to_funtion}" if @suffix.empty? "#{to_funtion}.#{@suffix.join(".")}" end end Convert to GLSL
  49. FUNCTIONS.each do |name| define_method(name) do |*args| FunctionCall.new(name, *args) end end

    Convert to GLSL
  50. “But, why not use = to assign variable?”

  51. main do @variable = 1234 # Captured by class variable

    = 1234 # Not captured end Limitation
  52. main do vec4 @variable = vec4(1, 1, 1, 1) @variable

    = vec4 vec4(1, 1, 1, 1) end Limitation
  53. Limitation

  54. main do variable is Vec4 vec4(1, 1, 1, 1) variable

    is Vec4 vec4(1, 1, 1, 1) end Limitation
  55. main do variable is vec4 vec4(1, 1, 1, 1) +

    1 variable is Vec4 vec4(1) * normal end Arithmetic Problem
  56. module Shader::Calculable def operation @operation ||= [] end def +(other)

    operation.push("+", other) self end end Arithmetic Problem
  57. module Shader::Calculable def to_expression return to_s if operation.empty? "#{to_s} #{operation.join("

    ")}" end end Arithmetic Problem
  58. module Shader::Calculable def expanded_operation operation.map do |node| if node.respond_to?(:to_expression) node.to_expression

    else node.to_s end end end end Arithmetic Problem
  59. main do variable is Vec4 ( 1 - delta )

    * normal end # => vec4 variable = 1 - delat * normal Arithmetic Problem
  60. module Shader::Calculable def operation @operation ||= [] end def +(other)

    operation.push("+", other) BracketsNode.new(self) end end Arithmetic Problem
  61. main do variable is Vec4 ( 1 - delta )

    * normal end # => vec4 variable = ((1 - delat) * normal) Arithmetic Problem
  62. How to define a class in C++ Save data inside

    ruby class in C++ Using mruby in C++
  63. mrb_state* mrb = mrb_start(); RClass* klass = mrb_define_class(mrb, "Shader", mrb->object_class);

    Define Class in C++
  64. mrb_define_method(mrb, klass, "initialize", init, MRG_ARGS_NONE()); Define Class in C++

  65. mrb_value init(mrb_state* mrb, mrb_value self) { // Do something return

    self; } Define Class in C++
  66. Let’s try create Shader class for Ruby

  67. struct Shader { ofShader* instance; } Save data in Class

  68. static struct mrb_data_type ShaderType { "Shader", freeShader } Save data

    in Class
  69. Shader* allocaShader(mrb_state* mrb) { return (Shader*) mrb_alloca(mrb, sizeof(struct Shader)); }

    Save data in Class
  70. void freeShader(mrb_state* mrb, void* ptr) { Shader* shader = static_cast<Shader*>(ptr);

    if(shader != NULL) { free(shader); } mrb_free(ptr); } Save data in Class
  71. mrb_value init(mrb_state* mrb, mrb_value self) { Shader* shader = (Shader*)

    DATA_PTR(self); if(shader) { mrb_free(mrb, shader); } DATA_TYPE(self) = &ShaderType; DATA_PTR(self) = NULL; shader = allocaShader(mrb); shader->instance = new ofShader; DATA_PTR(self) = shader; return self; } Save data in Class
  72. OpenFrameworks + mruby https://github.com/elct9620/MRubyShader GLSL generator https://github.com/elct9620/mruby-shader- generator Github

  73. None