C-WebGL: グローバルステートの実装
前回 列挙したステートを1つ1つ実装していく。
たとえば、 LINE_WIDTH であれば、
-
getParameterメソッドによる取得 -
lineWidthメソッドによる設定 - 設定時に
ALIASED_LINE_WIDTH_RANGEに収まっているかどうかのチェック
が必要になる。 ...はずなんだけど、 そもそもGLES2の仕様書にチェックしろと書いてない (記憶が正しければ LINE_WIDTH が唯一で、この点はGLES3で修正されている) という問題がある。
また EXTENSIONS のようにWebGLでは削除されているステートもあるため、それらもチェックしつつ実装を埋めていく必要がある。
実装定数 その1 (表6.18)
最初は実装定数を用意していく。これらは定数で lineWidth のような設定APIを持たない。(特に言及は無いが)WebGLの場合はWebGLコンテキストを生成したタイミングで決定され、以降変更されないということになる。
この中だと要注意なのは COMPRESSED_TEXTURE_FORMATS だろう。
- WebGL1はGLES2と異なり圧縮テクスチャを一切仕様化していない。というわけで規格上はゼロ長の配列になる。
- ただし、事実上全ての実装は圧縮テクスチャを実装していて、その場合は実装している圧縮テクスチャを含めて返却する必要がある → C-WebGLとしては常にゼロとは仮定できない
- WebGLでは、
NUM_COMPRESSED_TEXTURE_FORMATSは存在しない(配列を返却するため)。
最後の NUM_ 問題があるのはGLES2では他に(WebGL1では不要な)Shader binaryしか無いため、 COMPRESSED_TEXTURE_FORMATS だけ特別あつかいする方向にする。
BLEND_COLOR が規格書に無い
... 何故。。?
とりあえず偶然気付いたのでWebGLの getParameter でクエリできるものは全部埋めておくことにした。
見落し防止のため数が多いのを先に処理する。
getParameter
すごい量だ。。
GLESでは glGet〜 APIとなっているが、WebGLではJavaScriptの動的型を活かして getParameter に纏められている。C-WebGLではそれをC言語に落とすために型ごとに再度バラすというちょっと不毛なことになっている。
enable 、 disable と isEnabled
WebGLにもGLESにも isEnabled というコマンドが存在し、WebGLで言うところの getParameter のサブセットに相当する動作をする。 ...じゃぁ getParameter だけで良くない。。?
とりあえずグローバルステートは実装し終えた。。
depthRange はWebGLでは制約される
前のVulkanの調査 ではMetalのdepthRangeに制約があるという話を書いたけど、何とWebGLも同様の制約を入れていた。まぁ入れても良いんだけどMetal機材って最初からOpenGLだと思うんだけど何故この制約が。。
The WebGL API does not support depth ranges with where the near plane is mapped to a value greater than that of the far plane. A call to
depthRangewill generate anINVALID_OPERATIONerror ifzNearis greater thanzFar.
OpenGLの getError はエラーが消えるまで呼びつづけないといけない
これ知らなかった。。
Thus,
glGetErrorshould always be called in a loop, until it returnsGL_NO_ERROR, if all error flags are to be reset.