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
4.8k
EmscriptenのOpenGLと純粋なWebGLと共存させる黒魔術
Emscripten Night!! #4 LTのスライド資料です
ueshita
July 05, 2017
Tweet
Share
More Decks by ueshita
See All by ueshita
こわくない!! たのしい!! GDExtension
ueshita
0
2k
Godot Engine完全に理解したかった
ueshita
1
630
UnmanagedThreadノススメ
ueshita
2
8.3k
Unityで3Dツールを作って開発を加速する
ueshita
3
3.6k
asm.js 減量やってみた
ueshita
0
980
Other Decks in Programming
See All in Programming
20250704_教育事業におけるアジャイルなデータ基盤構築
hanon52_
5
790
PostgreSQLのRow Level SecurityをPHPのORMで扱う Eloquent vs Doctrine #phpcon #track2
77web
2
530
AI時代の『改訂新版 良いコード/悪いコードで学ぶ設計入門』 / ai-good-code-bad-code
minodriven
13
3.7k
Webの外へ飛び出せ NativePHPが切り拓くPHPの未来
takuyakatsusa
2
550
AIと”コードの評価関数”を共有する / Share the "code evaluation function" with AI
euglena1215
1
160
NPOでのDevinの活用
codeforeveryone
0
830
Composerが「依存解決」のためにどんな工夫をしているか #phpcon
o0h
PRO
1
260
生成AI時代のコンポーネントライブラリの作り方
touyou
1
210
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
250
すべてのコンテキストを、 ユーザー価値に変える
applism118
3
1.3k
0626 Findy Product Manager LT Night_高田スライド_speaker deck用
mana_takada
0
170
地方に住むエンジニアの残酷な現実とキャリア論
ichimichi
5
1.5k
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
Building Applications with DynamoDB
mza
95
6.5k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.4k
Site-Speed That Sticks
csswizardry
10
690
A Modern Web Designer's Workflow
chriscoyier
695
190k
The Cult of Friendly URLs
andyhume
79
6.5k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Side Projects
sachag
455
42k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
820
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
GitHub's CSS Performance
jonrohan
1031
460k
Speed Design
sergeychernyshev
32
1k
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