最近は TypeScrip を使わないと生き残っていけないな。なんて思って最近は WebGL でプロトタイプとか作るときも TypeScript 使ってるんですよね。まあ、けっこう適当な感じなんですけれど。
そんで、TypeScript といったら型ですよね。それで初めて気づいたんですけれど、WebGL って独自に型を定義してるってことに。存在する型が以下にまとまっていました。
いやー、全然わからん。仕方ないから調べますかとうことで、とりあえず自分なりにまとめてみることにしました。
Web IDL について
まず Web IDL type というカラムが気になります。
調べてみると、以下にサイトにて定義されていました。
https://triple-underscore.github.io/WebIDL-ja.html
要約を抜粋してみます。
この文書は、 interface 定義言語, Web IDL を定義する — それは、 Web ブラウザが実装するものと意図される interface を記述するために利用できる。 Web IDL は,IDL の変種であり、[ Web プラットフォームにおいて共通なスクリプトオブジェクトに対し,そのふるまいを より容易に指定できるようにする ]ための,いくつもの特能を備える。 この文書では、[ Web IDL で記述される interface が,ECMAScript 実行環境の構成子にどう対応するか ]についても,詳細に述べられる。 この文書は、[ 既に発行済みの仕様 / 新たに発行され, この文書を参照する仕様 ]に適合している interface の実装が相互運用可能になるための,実装者向けの手引きになるものと期待されている。
一言でいえば Web プラットフォームにおける interface 定義言語ということですかね。
WebGL で使われている Web IDL type は、Boolean 以外では整数型や浮動小数点数型になり、以下に定義されています。
整数型
符号あり/符号なし 整数型や,とり得る値の範囲
浮動小数点数型
整数型でない数量型 — に対応する値の範囲
とのこと。JavaScript の数値型といえば Number ですね。符号があろうがなかろうが、浮動小数点でもコミコミで Number です。まあ、 BigInt なんてもありますが、まだサポートされているブラウザが少ないですね。
あと TypedArray というオブジェクトがあります。これは型付き配列というものでその総称です。配列内の数値は Web IDL で定義されている整数型や浮動小数点数型のようなものがあります。パフォーマンス向上のため、WebGL ではこの TypedArray をよく使います。
Type の種類について
Web IDL type が大体わかったところで、それぞれの Type についてみていきましょう。
GLenum
Web IDL type: unsigned long
これは enum 型です。 設定する定数は WebGL constants にあります。
つまり、 WebGL constants の値はすべて unsigned long ということになりますね。
例えば WebGLRenderingContext.drawArrays() の mode で使います。描画するプリミティブの種類とかですね。WebGL ではこういった形で定数をよく使いますので、GLenum は最もよく使う型かもしれません。
GLboolean
Web IDL type: boolean
真偽値です。
A Boolean.
潔い説明ですね。JavaScript の Boolean まんまなので、だったらそのまま使えばよいじゃないって感じです。意地でもはってるのでしょうか?まあ、おそらくですが OpenGL から派生したものだから、それに合わせて interface を定義しているのかなと思いました。
例えば WebGLRenderingContext.vertexAttribPointer() の normalized とかですね。まあ、真偽値があれば GLboolean だと思っておけばよいのではないでしょうか。
GLbitfield
Web IDL type: unsigned long
直訳すると「複数の論理ビットを格納するビットフィールド」とのことですが、なにを言っているのかわからない。このあたりの低レベルなメモリ操作とか全然しないんでなかなか理解できない。まあ、分かる人にわかるはずですし、とりあえずスルーします。
例えば WebGLRenderingContext.clear() で使われているとのことです。描画をクリアするときに指定する gl.COLOR_BUFFER_BIT などの定数が unsigned long であるということですね。
GLbyte
Web IDL type: byte
ここからしばらくは比較的わかりやすいですね。Web IDL の型をそのまま定義している形です。
8 ビットの範囲で -128 ~ 127 の整数を扱えます。
探したんですが、使われているところが見つからない・・・。
果たして使い所はあるのだろうか?
GLshort
Web IDL type: short
16 ビットの範囲で -32,768 ~ 32,767 の整数を扱えます。
そしてコレも探したんですが、使われているところが見つからない・・・。
byte もそうなんですが、定数では BYTE や SHORT と名のつくものは定義されているのんですよね。たまたま enum 以外では byte や short を使うところが無かった感じなんでしょうか?
GLint
Web IDL type: long
名前の通り、いわゆる一般的な int 型ですね。
32 ビットの範囲で -2,147,483,648 ~ 2,147,483,647 の整数を扱えます。
例えば WebGLRenderingContext.drawArrays() の first で使われています。頂点配列の開始位置のオフセットですね。頂点の情報を扱うだけあって大きな数値も扱えるようになっているのでしょう。
GLsizei
Web IDL type: long
サイズ関連に使われる型とのことです。
例えば WebGLRenderingContext.texImage2D() の width や height などのサイズに使われています。また、 WebGLRenderingContext.drawArrays() の count にも使われています。これは頂点の数ですね。これまた符号いらなくないとか思っちゃいましたが、まあ、それは置いておいて、余裕で 10 億以上いけますね。凄いパーティクルができそうです。マシンスペックさえ足りればですけれど。
GLintptr
Web IDL type: long long
これはポインタ用の型とのことです。JavaScript を書いていてポインタなんて聞くとは思っていませんでした。正直あまり理解してないですが、そいうことだそうです。
long long は初めてでてきましたね。
64 ビットの範囲で -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,80 の整数を扱えます。桁を数える気をなくすほどデカい。
例えば WebGLRenderingContext.vertexAttribPointer() の offset などに使われています。インターリーブ配列の際にバイト数でオフセットを設定するものです。バイト数でってところが、ポインタ用ということと関係しているのでしょうか?
GLsizeiptr
Web IDL type: long long
これはポインタ用の型とのことです。説明が GLintptr と全く同じなんですよね。Web IDL type も一緒だし。説明責任を果たして欲しい。まあ、名前からすると GLsizei のようにサイズ関連に使うものかと思う。
例えば WebGLRenderingContext.bufferData() の size などに使われています。まさにサイズ用って感じですね。バッファのデータサイズをバイト単位で設定するところですが、たいていの場合は TypedArray をそのまま入れちゃってるんじゃないでしょうか?他に使ってる箇所もピンこなかったのであまり縁はなさそうですが、バイトでサイズなら GLsizeiptr と覚えておくと良いかもです。
GLubyte
Web IDL type: octet
なにげに octet って初めて知りました。聞いたことすらない。
8 ビットの範囲で 0 ~ 255 の整数を扱えます。
つまりは 1 バイトですかね。ってことを考えると凄く馴染み深いかも。RGB とか。
そんでコレも何に使われているかわからないです。んー、short 以下のは扱えないけどとりあえず定義してるとかなかなぁ?
GLushort
Web IDL type: unsigned short
これは GLshort の符号なしバージョンです。
16 ビットの範囲で 0 ~ 65,535 の整数を扱えます。
この数値なんか見覚えあるなと思ったのですが、特定のパターンでスタックオーバーフロー起こすときの数ですね。つまりその箇所は unsigned short になっているということかな?
まあ、予想通りというか使われている箇所をみつけられなかったです。
GLuint
Web IDL type: unsigned long
これは GLint の符号なしバージョンです。
32 ビットの範囲で 0 ~ 4,294,967,295 の整数を扱えます。
例えば WebGLRenderingContext.enableVertexAttribArray() の index に使われています。attribute を有効化するインデックスを指定します。
GLfloat
Web IDL type: unrestricted float
こらは浮動小数点型ですね。Web IDL の説明を抜粋します。
可能なすべての有限, 非有限[ 単精度 32 ビット IEEE 754 浮動小数点数 ]の集合に “非数( not a number )” ( 各種 NaN )を加えた集合
気になるのは IEEE 754 ですかね。浮動小数点の計算の規格です。JavaScript でもなく、Web IDL でもなく別で制定されている規格です。多くの言語などで採用されています。
単精度浮動小数点数 についてはリンク先をみてくださいませ。
例えば WebGLRenderingContext.uniformMatrix[234]fv() の value に使われています。普段は Float32Array を指定していますが、GLfloat をシーケンスとして指定できるそうです。シーケンスってなんだろ?
GLclampf
Web IDL type: unrestricted float
こちらも GLfloat と同じく、単精度浮動小数点数です。
ただクランプされているそうなんですが、どういうことなのか分からないです。
調べてみると WebGLRenderingContext.blendColor() に使われていますね。RGBA のそれぞれの値とのこと。0 ~ 1 の範囲なのでクランプされているのはその範囲なのかもしれないです。一応、他に使わている箇所をみても
GLint64 (WebGL 2)
Web IDL type: long long
WebGL 2 で追加された型です。
64 ビットの範囲で -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 の整数を扱えます。
long long 型はさきほども出てきましたが、ちょっと意味分かんないくらいの桁数ですね。正の数だけで 900 京以上あります。GLintptr と GLsizeiptr はポインタ用だから、それ以外で long long 型を使う用がなかったので追加したとうところでしょうか?
WebGLRenderingContext.getParameter()の pname つまり、パラメータ定数の一部で使われています。WebGL 2 用の gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL とかで他にもいくつかありました。タイムアウトに関する内容のようなのですが、細かいことはわからなかったです。ただ、時間を扱うから大きな数を必要とするのかもしれませんね。
GLuint64EXT (extensions)
Web IDL type: long long
これは拡張機能で使えるようです。
GLint64 が実装される前に拡張機能で追加されたのかな?と思いましたが、説明をみると符号なしなんですよね。でも Web IDL type は unsigned long long ではなくて long long です。どういうことでしょうか?わからん。
こちらも同じ様に WebGLRenderingContext.getParameter() の pname に使われています。対象のパラメータ定数は ext.TIMESTAMP_EXT だけでした。これは現在時刻とのことですので、やはり時間に関するものは 64 ビットが良いのかもしれません。
調べてみて
もともと型には強くないので、数値型の規格から学ぶ形になりました。なんとく知っていた部分もありましたが、ある程度ちゃんと知ることができてとても良い機会になったなと思います。
WebGL の型については結局ちゃんと分からないままの部分も多くて、ちょっと悔しい感じです。僕が分からなかった部分や曖昧に説明してる部分について、何か分かるようであれば教えてもらえると嬉しいです。あと、間違ってる部分もありそうなのでマサカリ待ってます。