Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
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.9k
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.1k
Godot Engine完全に理解したかった
ueshita
1
650
UnmanagedThreadノススメ
ueshita
2
8.3k
Unityで3Dツールを作って開発を加速する
ueshita
3
3.6k
asm.js 減量やってみた
ueshita
0
1k
Other Decks in Programming
See All in Programming
sbt 2
xuwei_k
0
260
Context is King? 〜Verifiability時代とコンテキスト設計 / Beyond "Context is King"
rkaga
6
1k
안드로이드 9년차 개발자, 프론트엔드 주니어로 커리어 리셋하기
maryang
1
110
20 years of Symfony, what's next?
fabpot
2
350
WebRTC、 綺麗に見るか滑らかに見るか
sublimer
1
160
俺流レスポンシブコーディング 2025
tak_dcxi
14
8.5k
無秩序からの脱却 / Emergence from chaos
nrslib
2
13k
tparseでgo testの出力を見やすくする
utgwkk
1
180
ViewファーストなRailsアプリ開発のたのしさ
sugiwe
0
430
UIデザインに役立つ 2025年の最新CSS / The Latest CSS for UI Design 2025
clockmaker
18
7.2k
テストやOSS開発に役立つSetup PHP Action
matsuo_atsushi
0
150
複数人でのCLI/Infrastructure as Codeの暮らしを良くする
shmokmt
5
2.2k
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
527
40k
The Art of Programming - Codeland 2020
erikaheidi
56
14k
We Have a Design System, Now What?
morganepeng
54
7.9k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.6k
A Tale of Four Properties
chriscoyier
162
23k
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.1k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
Visualization
eitanlees
150
16k
Music & Morning Musume
bryan
46
7k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
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