プログラム生成機構

プログラムを作ろう

 この節は閑話休題ということで、プログラムの生成機構をメソッド化します。それだけです。まあ同じこと何回も書くのめんどくさいので...以降はこれを使うものとし、もうあの長ったらしい式は書きません。代わりにcommon.jsという新しいファイルを作り、そちらに委譲します。ただ同じものを作っても仕方ないのでちょっとだけ細工を追加したいと思います。

コード全文

作品4のリンク

プログラムの生成(復習)

 まず、pgのところはprogramに書き直しました。pgだけ略すのが不自然なので。復習するとまず、createShaderにターゲットを渡して2つのシェーダーを作ります。shaderSourceでそこに文字列のソースをアタッチします。コンパイルします。その際に失敗するとコンパイルステータスがおかしくなるのでそれをgetShaderParameterでチェックして、getShaderInfoLogで問題の内容を取得します。両方ともコンパイルができたら、プログラムをcreateProgramで作り、2枚のシェーダーをattachShaderでアタッチします。最後にlinkProgramで両者をリンクさせて完成です。完成したかどうかをgetProgramParameterでチェックします。問題があるようならば、getProgramInfoLogで内容をチェックします。おわり!
 ちなみにgetProgramParameterは、記事の注釈を読んだ人ならわかると思いますが、ユニフォームやアトリビュートの情報も取得できます。いずれこれを改変するつもりなので、そのときにまた登場するかと思います。

関数化する上での変更点

 まず第一引数がコンテクストになっています。WebGLはコンテクストが無いと何にもできないので、まあ必須ですね。で、次がパラメータになっています。この、どこまでを列挙引数としどこからをオブジェクト引数とするかの判断が関数の利便性に大きく影響するんですよね...やみくもに全部列挙にしてしまうと、並べる順番を間違えただけでめちゃくちゃなことになるのでそれを覚えないといけなくて面倒ですし、逆に全部オブジェクト引数にした場合、ちょっとしたことで呼び出したい場合であってもいちいち中括弧と、変数名と、コロンを書かないといけないわけです。面倒でしょう。なので、明らかに必須なものだけ列挙とし、残りのパラメータを基本的にオブジェクトにするやり方で自分としては作っています。オブジェクト形式はデフォルト引数を自由に使えるので列挙よりその辺の自由度は高いんですよね。
 パラメータはvs,fsでバーテックスシェーダ文字列とフラグメントシェーダ文字列としています。今現在他にないのでこれしか用意できないですね。

コンテキストのバリデーション

 まず、第一引数がきちんとコンテクストになってるかどうかを調べています。WebGL2のコンテキストでなければ弾くことにしました。私の記事ではWebGL2RenderingContextしか使いません。なぜならTFFやVAOを宣言無しで自由に使えるからです。今更WebGL1なんてまだるっこしくて使ってられないです。VAO無しのWebGLはほんとにきついです。やりたくないので。なおこれ以降もそうですが、その際のエラーメッセージを文字列として出力しています。つまり問題がある場合にはその内容が文字列で返されるわけです。一応それを調べるコードを書いています。

  const pg = createShaderProgram(gl, {vs:vs, fs:fs});
  if(typeof pg === 'string'){
    console.log(pg);
  }

ソースのバリデーション

 ついでにシェーダーソースのバリデーションもかけています。文字列でなければなりません。このくらいですね。

描画

 描画自体は特に難しいことはしていません。いつものようにTRIANGLE_STRIPで0,1,2,3に対し2枚の三角形を用意して、頂点ごとに違う色を割り当ててるだけです。

 おわりです。そうだ。次からはcommon.cssは省略してcommon.jsにしましょう。いちいち見に行くの面倒ですからね。
 しかしプログラムの生成過程を関数化するだけでここまで簡単になるんですね...WebGPUはこんな簡単にはならないので、いかにWebGLが(これでも!)単純な仕組みで動いてるかが分かるというものです。glslもC言語チックで分かりやすいですし。いいですね。