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
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
430
2023 - WebConf - 選擇適合你的技能組合
elct9620
0
650
20230322 - Generative AI 小聚 ft. Happy Designer
elct9620
0
400
2022 - 默默會 - 重新學習 MVC 的 Model
elct9620
1
470
MOPCON 2022 - 從 Domain-Driven Design 看網站開發框架隱藏
elct9620
1
480
2022 - COSCUP - 我想慢慢寫程式該怎麼辦?
elct9620
0
260
2022 - COSCUP - 打造高速 Ruby 專案開發流程
elct9620
0
290
Other Decks in Programming
See All in Programming
競馬で学ぶ機械学習の基本と実践 / Machine Learning with Horse Racing
shoheimitani
14
13k
TVerのWeb内製化 - 開発スピードと品質を両立させるまでの道のり
techtver
PRO
3
1.2k
Claude Code on the Web を超える!? Codex Cloud の実践テク5選
sunagaku
0
590
モビリティSaaSにおけるデータ利活用の発展
nealle
0
560
GraalVM Native Image トラブルシューティング機能の最新状況(2025年版)
ntt_dsol_java
0
160
Java_プロセスのメモリ監視の落とし穴_NMT_で見抜けない_glibc_キャッシュ問題_.pdf
ntt_dsol_java
0
220
30分でDoctrineの仕組みと使い方を完全にマスターする / phpconkagawa 2025 Doctrine
ttskch
1
150
目的で駆動する、AI時代のアーキテクチャ設計 / purpose-driven-architecture
minodriven
9
3k
AI時代もSEOを頑張っている話
shirahama_x
0
130
「10分以内に機能を消せる状態」 の実現のためにやっていること
togishima
1
530
「正規表現をつくる」をつくる / make "make regex"
makenowjust
1
700
OSS開発者の憂鬱
yusukebe
12
5.5k
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.8k
Code Reviewing Like a Champion
maltzj
527
40k
How to train your dragon (web standard)
notwaldorf
97
6.4k
Site-Speed That Sticks
csswizardry
13
970
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
How GitHub (no longer) Works
holman
315
140k
Fireside Chat
paigeccino
41
3.7k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
192
56k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
Practical Orchestrator
shlominoach
190
11k
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