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
EmscriptenのOpenGLと純粋なWebGLと共存させる黒魔術
Search
ueshita
July 05, 2017
Programming
1
5k
EmscriptenのOpenGLと純粋なWebGLと共存させる黒魔術
Emscripten Night!! #4 LTのスライド資料です
ueshita
July 05, 2017
Tweet
Share
More Decks by ueshita
See All by ueshita
こわくない!! たのしい!! GDExtension
ueshita
0
2.2k
Godot Engine完全に理解したかった
ueshita
1
660
UnmanagedThreadノススメ
ueshita
2
8.3k
Unityで3Dツールを作って開発を加速する
ueshita
3
3.7k
asm.js 減量やってみた
ueshita
0
1k
Other Decks in Programming
See All in Programming
ファインチューニングせずメインコンペを解く方法
pokutuna
0
220
野球解説AI Agentを開発してみた - 2026/02/27 LayerX社内LT会資料
shinyorke
PRO
0
370
モダンOBSプラグイン開発
umireon
0
190
RailsのValidatesをSwift Macrosで再現してみた
hokuron
0
140
Feature Toggle は捨てやすく使おう
gennei
0
390
車輪の再発明をしよう!PHP で実装して学ぶ、Web サーバーの仕組みと HTTP の正体
h1r0
2
440
一度始めたらやめられない開発効率向上術 / Findy あなたのdotfilesを教えて!
k0kubun
3
2.3k
テレメトリーシグナルが導くパフォーマンス最適化 / Performance Optimization Driven by Telemetry Signals
seike460
PRO
2
190
Symfonyの特性(設計思想)を手軽に活かす特性(trait)
ickx
0
100
今年もTECHSCOREブログを書き続けます!
hiraoku101
0
200
Strategy for Finding a Problem for OSS: With Real Examples
kibitan
0
120
How to stabilize UI tests using XCTest
akkeylab
0
150
Featured
See All Featured
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
610
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
420
Site-Speed That Sticks
csswizardry
13
1.1k
It's Worth the Effort
3n
188
29k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.1k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
53k
For a Future-Friendly Web
brad_frost
183
10k
Chasing Engaging Ingredients in Design
codingconduct
0
150
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.7k
How to build a perfect <img>
jonoalderson
1
5.3k
Statistics for Hackers
jakevdp
799
230k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
330
Transcript
EmscriptenのOpenGLと 純粋なWebGLと共存させる黒魔術 Emscripten Night !! #4
自己紹介 うえした (@ueshita) 同人ゲームを作ります Emscripten好き Emscripten Night!! で 何回かLTやってます Effekseerのコントリビュータ
エフェクトツール Effekseer エフェクト作成編集ツール - パーティクルやリボン、リングの アニメーションを簡単に作れるツール。 - オープンソースで無料! エフェクト実行ライブラリ -
リアルタイムにアニメーションを計算してレンダリング - C++で実装されている - レンダラー: DirectX9,11, OpenGL2~, OpenGL ES 2.0~ - サウンド: XAudio2, OpenAL
OpenGLなライブラリをWebGLに Effekseerの実行ライブラリ(C++)をWebで動かしたい! そうだEmscriptenを使おう! OpenGL ES 2.0, OpenALがそのまま使える JavaScriptのWebGLフレームワークと共存したい Three.jsやGrimoire.js等 Webのいいところは活用したい
画像のロードはDOMのimgを使いたい libpngやlibjpegはリンクしたくない
OpenGLのWebGLと共存 普通のOpenGLアプリケーションの場合 OpenGL Contextを自分で作って描画する。 EGL(GLES)やWGL(win), AGL(mac), glut, glfw 等 WebGLの場合
CanvasからWebGLRenderingContextを取得して描画する。 WebGLとOpenGL(Emscripten)が共存するには WebGLRenderingContextを使用して、 JS側からOpenGLコンテキストを作成して描画する。
そしてEmscriptenの裏側へ… ( ˘⊖˘) 。o( OpenGLContextをJSから作成するにはどうしたら・・・ ) Emscriptenのソースコードを見よう! 三┏( ^o^)┛ -
/emscripten/1.37.9/src/library_egl.js - /emscripten/1.37.9/src/library_gl.js ( ◠‿◠ )☛ EGLのJS実装 - eglCreateContext: function(display, config, hmm, contextAttribs) - eglMakeCurrent: function(display, draw, read, context) Emscriptenはソースコードに全て書いてある! ▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂
EmscriptenのOpenGL ネイティブのOpenGLの仕組み グローバル空間にOpenGLのContextがおり、 ステート変更、ドロー等のコマンドをGPUに送る EmscriptenのOpenGLもだいたい同じ グローバル空間にOpenGLのContextがおり、 JSのWebGLRenderingContextとやりとりをする。 Application OpenGL Context
GPU Driver WebGLContext GPU Driver glDrawArrays: function(mode, first, count) { GLctx.drawArrays(mode, first, count); }, Emscripten OpenGLの実装
WebGLRenderingContextを外部から渡す GL.registerContext(context, attributes)を呼べばOKらしい // CanvasのDOMを取得 var canvas = document.getElementById(“canvas”); //
CanvasからWebGLRenderingContextを取得 var context = canvas.getContext(“webgl”); // EmscriptenのOpenGLにWebGLRenderingContextを渡す GL.registerContext(context, { majorVersion: “1”, minorVersion: “0”, // WebGLのバージョン enableExtensionsByDefault: true // GL拡張のAPIをONに });
WebGLとOpenGLの違い WebGLのオブジェクトは’Object’、OpenGLのオブジェクトは’GLuint’(数値) JavaScriptのObjectはEmscriptenメモリ空間に存在できない! WebGL OpenGL Texture WebGLTexture GLuint Buffer WebGLBuffer
GLuint Program WebGLProgram GLuint
テクスチャ読み込みの違い できればWebブラウザの画像ロード機能は使いたい・・・ var img = new Image(); // 画像ロード完了 img.onload
= function() { // テクスチャを作成して画像を転送 var texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); }; // ロード開始 img.src = “texture.png”; // 画像をロードする GLsizei width, height; void* imageData = LoadImage(“texture.png”, &width, &height); // 自作ロード関数 // テクスチャを作成して画像を転送 GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); WebGL OpenGL
Emscriptenではどう扱っているのか library_gl.jsを見てみる - GLctx: WebGLRenderingContext - target: GL_TEXTURE_2D - texture:
GLuint - GL.textures: WebGLTextureのArray(たぶん) glBindTexture: function(target, texture) { GLctx.bindTexture(target, texture ? GL.textures[texture] : null); }, // ↑↑↑
DOMのimgを使ったテクスチャロード関数 GLuint LoadTexture(const char* path) { // テクスチャをロードするCの関数 GLuint texture;
glGenTextures(1, &texture); // (1) C側でテクスチャは作る EM_ASM_INT({ var img = new Image(); img.onload = function() { // (3) 画像ロード完了イベント GLctx.bindTexture(GLctx.TEXTURE_2D, GL.textures[$1]); GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, GLctx.RGBA, GLctx.UNSIGNED_BYTE, img); // (4) img指定ロード GLctx.bindTexture(GLctx.TEXTURE_2D, null); }; img.src = Pointer_stringify($0); // C文字列をJavaScript文字列に変換 }, path, texture); // (2) インラインJavaScriptに作成したテクスチャを渡す return texture; }
まとめ GL.registerContext(context, attributes) でOpenGL Contextは作れる (EGLいじるより簡単かも。各種イベントはハンドリングする必要あり) テクスチャはGL.texturesのArrayに存在している。GLuintはindex。 バッファはGL.buffers、シェーダプログラムはGL.programsにいた Emscriptenのソースコードはドキュメント 黒魔術はたのしい
参考Github: https://github.com/effekseer/EffekseerForWebGL