Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
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
490
2022 - COSCUP - 我想慢慢寫程式該怎麼辦?
elct9620
0
270
2022 - COSCUP - 打造高速 Ruby 專案開發流程
elct9620
0
300
Other Decks in Programming
See All in Programming
DevFest Android in Korea 2025 - 개발자 커뮤니티를 통해 얻는 가치
wisemuji
0
160
Microservices rules: What good looks like
cer
PRO
0
1.5k
著者と進める!『AIと個人開発したくなったらまずCursorで要件定義だ!』
yasunacoffee
0
150
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
190
マスタデータ問題、マイクロサービスでどう解くか
kts
0
110
Rediscover the Console - SymfonyCon Amsterdam 2025
chalasr
2
180
Socio-Technical Evolution: Growing an Architecture and Its Organization for Fast Flow
cer
PRO
0
370
脳の「省エネモード」をデバッグする ~System 1(直感)と System 2(論理)の切り替え~
panda728
PRO
0
100
Context is King? 〜Verifiability時代とコンテキスト設計 / Beyond "Context is King"
rkaga
10
1.3k
AIコーディングエージェント(skywork)
kondai24
0
180
tsgolintはいかにしてtypescript-goの非公開APIを呼び出しているのか
syumai
7
2.3k
リリース時」テストから「デイリー実行」へ!開発マネージャが取り組んだ、レガシー自動テストのモダン化戦略
goataka
0
130
Featured
See All Featured
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
500
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
2
2.7k
Site-Speed That Sticks
csswizardry
13
1k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
22
SEO for Brand Visibility & Recognition
aleyda
0
4.1k
30 Presentation Tips
portentint
PRO
1
160
Making the Leap to Tech Lead
cromwellryan
135
9.7k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
220
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
87
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
196
70k
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