Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
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
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
140
2023 - RubyConfTW - Rethink Rails Architecture
elct9620
0
110
20230916 - DDDTW - 導入 Domain-Driven Design 的最佳時機
elct9620
0
380
2023 - WebConf - 選擇適合你的技能組合
elct9620
0
600
20230322 - Generative AI 小聚 ft. Happy Designer
elct9620
0
320
2022 - 默默會 - 重新學習 MVC 的 Model
elct9620
1
420
MOPCON 2022 - 從 Domain-Driven Design 看網站開發框架隱藏
elct9620
1
440
2022 - COSCUP - 我想慢慢寫程式該怎麼辦?
elct9620
0
220
2022 - COSCUP - 打造高速 Ruby 專案開發流程
elct9620
0
250
Other Decks in Programming
See All in Programming
仕様変更に耐えるための"今の"DRY原則を考える / Rethinking the "Don't repeat yourself" for resilience to specification changes
mkmk884
0
160
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
900
GitHub Actions × RAGでコードレビューの検証の結果
sho_000
0
260
ペアーズでの、Langfuseを中心とした評価ドリブンなリリースサイクルのご紹介
fukubaka0825
2
320
Grafana Cloudとソラカメ
devoc
0
170
Honoのおもしろいミドルウェアをみてみよう
yusukebe
1
210
AIの力でお手軽Chrome拡張機能作り
taiseiue
0
170
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
6
4k
Ruby on cygwin 2025-02
fd0
0
140
2024年のkintone API振り返りと2025年 / kintone API look back in 2024
tasshi
0
220
Writing documentation can be fun with plugin system
okuramasafumi
0
120
定理証明プラットフォーム lapisla.net
abap34
1
1.8k
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.4k
Documentation Writing (for coders)
carmenintech
67
4.6k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.5k
Rebuilding a faster, lazier Slack
samanthasiow
80
8.8k
Visualization
eitanlees
146
15k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
9
440
A Philosophy of Restraint
colly
203
16k
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Writing Fast Ruby
sferik
628
61k
Why Our Code Smells
bkeepers
PRO
336
57k
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