Open4

WebGL1のAPIレビュー(3周目)

okuokuokuoku

prev: https://zenn.dev/okuoku/scraps/a8ffaa73862409
next: https://zenn.dev/okuoku/scraps/99fa92f6aae12e

CWGL → WebGL wrapperを作る

目的 : WebGLをC言語で実装したライブラリを作る

いきなりGLES2を実装するのは大変なので単なるwrapper、つまりGLES2実装を呼ぶだけのコードを用意する。

これマジで面白くない(直球)... 1日1章目標で1週間ちょっとか。。

単純なwrapではダメなところはWebGL仕様の Differences Between WebGL and OpenGL ES 2.0 に記述がある。この辺はとりあえず無視する。

okuokuokuoku

Wrapの基本方針

CWGL_API cwgl_enum_t 
cwgl_getError(cwgl_ctx_t* ctx){
    cwgl_enum_t r;
    CTX_ENTER(ctx);
    r = (cwgl_enum_t)glGetError();
    CTX_LEAVE(ctx);
    return r;
}

基本的には CTX_ENTER CTX_LEAVE で囲んで元のAPIを呼ぶだけ。コレをWebGLの全インターフェースに対して手書きする。。

CWGL_API cwgl_UniformLocation_t* 
cwgl_getUniformLocation(cwgl_ctx_t* ctx, cwgl_Program_t* program, 
                        const char* name){
    GLint nameu;
    GLuint namep;
    cwgl_UniformLocation_t* r;
    CTX_ENTER(ctx);
    namep = CTX_GETNAME(ctx, program);
    nameu = glGetUniformLocation(namep, name);
    if(nameu == -1){
        r = NULL;
    }else{
        r = CTX_ALLOC(ctx, UniformLocation);
        CTX_SETNAME(ctx, r, nameu);
    }
    CTX_LEAVE(ctx);
    return r;
}

OpenGL的なハンドルはwrapする。 CTX_ALLOC で確保、 CTX_GETNAME CTX_SETNAME がgetter/setter。

開発環境

PowerVRのOpenGL ES2エミュレータを使うことにした。APIトレースとかが付いてくるため。

https://zenn.dev/okuoku/articles/dccb1d0587ba57

内製のトレーサでも良いんだけどトレーサのデバッグまではやりたくない。。

okuokuokuoku

2章 (一部飛ばした)

https://github.com/okuoku/cwgl-proto/blob/749a52db10fcc921f6367162a3a0f64a34ee060e/src-gles2/cwgl-gles2-s2.c

GetattribとUniformはちょっと自信無いので飛ばした。Uniform系はAPIを省略しない方が良いかな。。

https://github.com/okuoku/cwgl-proto/issues/3

https://github.com/okuoku/cwgl-proto/issues/2

あと、WebGLではVertexAttribPointerなどホスト側のポインタを取る操作で、ポインタがGPUに渡るものの殆どは実ポインタを取れないのでそのチェックをどこかに追加する必要がある。

https://github.com/okuoku/cwgl-proto/issues/1

実際APIを int32_t にしちゃってるので必ずキャストされることになる。

    glVertexAttribPointer(indx, size, type, normalized,
                          stride, (void*)(uintptr_t)offset);

明かに実メモリは取れないよね。なので実際にポインタを渡してついうっかり動いてしまうということはそんなに無い(WebAssemblyを通る段階でアドレスはマングルされてしまう -- ということはFFIで混成ポインタを扱う必要がたぶん無いはず。要確認 ★ 。)

okuokuokuoku

3 〜 6章 (いっぱい飛ばした)

https://github.com/okuoku/cwgl-proto/tree/c9a63a0582295cd87efff88284bed860731c58a9/src-gles2

... 飽きたんではなく、そもそもJavaScript側からWebGLにセットしたオブジェクトをクエリした場合、 == なオブジェクトを返却しないと不味いんではないかという気がしてきたので。。これを実現するためには、JavaScript側からセットしたオブジェクトはJavaScript側で 折り返す 実装にするしかない。つまり、そもそもC APIとして出す必要がない。

そして、常識的なプログラムは、そもそもWebGLに渡した値をクエリして再取得したりしない。どっちにせよ遅い。別にConformantなWebブラウザを作りたいわけではないので、この辺は割り切ってしまうことにした。