$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Play GLSL on mruby with OpenFrameworks
Search
蒼時弦や
September 08, 2016
Programming
0
1.1k
Play GLSL on mruby with OpenFrameworks
蒼時弦や
September 08, 2016
Tweet
Share
More Decks by 蒼時弦や
See All by 蒼時弦や
2024 - COSCUP - Clean Architecture in Rails
elct9620
2
180
2023 - RubyConfTW - Rethink Rails Architecture
elct9620
0
180
20230916 - DDDTW - 導入 Domain-Driven Design 的最佳時機
elct9620
0
440
2023 - WebConf - 選擇適合你的技能組合
elct9620
0
660
20230322 - Generative AI 小聚 ft. Happy Designer
elct9620
0
400
2022 - 默默會 - 重新學習 MVC 的 Model
elct9620
1
480
MOPCON 2022 - 從 Domain-Driven Design 看網站開發框架隱藏
elct9620
1
480
2022 - COSCUP - 我想慢慢寫程式該怎麼辦?
elct9620
0
270
2022 - COSCUP - 打造高速 Ruby 專案開發流程
elct9620
0
300
Other Decks in Programming
See All in Programming
【CA.ai #3】Google ADKを活用したAI Agent開発と運用知見
harappa80
0
300
Building AI Agents with TypeScript #TSKaigiHokuriku
izumin5210
6
1.3k
Full-Cycle Reactivity in Angular: SignalStore mit Signal Forms und Resources
manfredsteyer
PRO
0
210
組み合わせ爆発にのまれない - 責務分割 x テスト
halhorn
1
150
これだけで丸わかり!LangChain v1.0 アップデートまとめ
os1ma
6
1.8k
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
150
AIコーディングエージェント(skywork)
kondai24
0
160
認証・認可の基本を学ぼう前編
kouyuume
0
200
AtCoder Conference 2025「LLM時代のAHC」
imjk
2
440
Developing static sites with Ruby
okuramasafumi
0
270
新卒エンジニアのプルリクエスト with AI駆動
fukunaga2025
0
210
React Native New Architecture 移行実践報告
taminif
1
150
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.8k
The Cult of Friendly URLs
andyhume
79
6.7k
Git: the NoSQL Database
bkeepers
PRO
432
66k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
Making the Leap to Tech Lead
cromwellryan
135
9.7k
Navigating Team Friction
lara
191
16k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
34k
Transcript
Play GLSL on mruby with OpenFrameworks 襝儗䓚⛲
Web Developer Game Developer Major in Digital Media Design Taiwanese
who likes Anime, Manga, Game @elct9620 襝儗䓚⛲
None
https://www.flickr.com/photos/hsbt/21251922399/in/album-72157658244299230/
Demo First Talk What is OpenFrameworks and GLSL? Shader Generator
written in mruby Using mruby in C++
Learn some physics knowledge before demo
None
DEMO TIME!
Who use the OpenFrameworks? What is the Shader mean? What
is the GLSL? OpenFrameworks and GLSL
http://blog.bongiovi.tw/calligraphy-in-3d/ OpenFrameworks demo
The Shader Role
The Shader Role
Vertex Shader http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
Vertex Shader http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
Vertex Shader http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
Vertex Shader http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
Fragment Shader
Fragment Shader
“GLSL is a language OpenGL provide for us”
@5xruby @s_cat555
Open Class to extend C++ class How to convert Ruby
to GLSL The DSL limitation Arithmetic Problem Shader Generator
class Shader def vertex(&block) code = Code.new code.instance_eval(&block) self.vertex =
code.to_s end end Open Class
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
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
@5xruby @s_cat555
lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL
Convert to GLSL
lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL
=> #<Type:0x00ff8dc @type=“vec4” @arguments=[…]> Convert to GLSL
TYPES.each do |type, typename| define_method(type) { |*args| Type.new(type, *args) }
end Convert to GLSL
lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL
def is(*args) value = args value = args.first if args.first.is_a?(Array)
AssignNode.new(*value) end Convert to GLSL
=> #<AssignNode:0x0ff @type=#<Type:0xfb> @expression=#<ExpressionNode:0xfa>> Convert to GLSL
lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL
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
=> "vec4 lightIntensity = vec4(1, 1, 1, 1);" Convert to
GLSL
lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL
class Shader::AssignNode def initialize(type, *args) @type = type @expression =
args.shift unless type.is_a?(Type) &&
[email protected]
? @expression = @type @type = nil end end end Convert to GLSL
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
Convert to GLSL lightIntensity is Vec4 vec4(1, 1, 1, 1)
Convert to GLSL vec4(1, 1, 1, 1) => #<Type:0xff @name=“vec4”>
Convert to GLSL Vec4 [Argument] => [#<Type:0xfa>, #<Type:0xff>]
Convert to GLSL is [type, expression] => #<AssignNode @type=#<Type:0xfa> @expression=#<Type:0xff>>
Convert to GLSL lightIntensity [expression] => (Insert into Buffer)
lightIntensity(is(Vec4(vec4(1, 1, 1, 1)))) lightIntensity(is(clamp(lightIntensity.x, 0, 1)) Convert to GLSL
def method_missing(name, *args, &block) @suffix << name self end Convert
to GLSL
def to_s return "#{@name}" if @suffix.empty? "#{@name}.#{@suffix.join(".")}" end Convert to
GLSL
lightIntensity.x # => “lightIntensity.x" lightIntensity.x.z # => “lightIntensity.x.z" Convert to
GLSL
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
FUNCTIONS.each do |name| define_method(name) do |*args| FunctionCall.new(name, *args) end end
Convert to GLSL
“But, why not use = to assign variable?”
main do @variable = 1234 # Captured by class variable
= 1234 # Not captured end Limitation
main do vec4 @variable = vec4(1, 1, 1, 1) @variable
= vec4 vec4(1, 1, 1, 1) end Limitation
Limitation
main do variable is Vec4 vec4(1, 1, 1, 1) variable
is Vec4 vec4(1, 1, 1, 1) end Limitation
main do variable is vec4 vec4(1, 1, 1, 1) +
1 variable is Vec4 vec4(1) * normal end Arithmetic Problem
module Shader::Calculable def operation @operation ||= [] end def +(other)
operation.push("+", other) self end end Arithmetic Problem
module Shader::Calculable def to_expression return to_s if operation.empty? "#{to_s} #{operation.join("
")}" end end Arithmetic Problem
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
main do variable is Vec4 ( 1 - delta )
* normal end # => vec4 variable = 1 - delat * normal Arithmetic Problem
module Shader::Calculable def operation @operation ||= [] end def +(other)
operation.push("+", other) BracketsNode.new(self) end end Arithmetic Problem
main do variable is Vec4 ( 1 - delta )
* normal end # => vec4 variable = ((1 - delat) * normal) Arithmetic Problem
How to define a class in C++ Save data inside
ruby class in C++ Using mruby in C++
mrb_state* mrb = mrb_start(); RClass* klass = mrb_define_class(mrb, "Shader", mrb->object_class);
Define Class in C++
mrb_define_method(mrb, klass, "initialize", init, MRG_ARGS_NONE()); Define Class in C++
mrb_value init(mrb_state* mrb, mrb_value self) { // Do something return
self; } Define Class in C++
Let’s try create Shader class for Ruby
struct Shader { ofShader* instance; } Save data in Class
static struct mrb_data_type ShaderType { "Shader", freeShader } Save data
in Class
Shader* allocaShader(mrb_state* mrb) { return (Shader*) mrb_alloca(mrb, sizeof(struct Shader)); }
Save data in Class
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
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
OpenFrameworks + mruby https://github.com/elct9620/MRubyShader GLSL generator https://github.com/elct9620/mruby-shader- generator Github
None