LoginSignup
0
0

More than 3 years have passed since last update.

Flash Advent Calendar 9日目 - WebGL導入への道のり02 -

Posted at

基礎部分はできたので、実際にシェーダーにデーターを渡していこうかと思います。
サンプルとしてdrawImage関数を作ってみようかと思います。

利用するイメージ

context.fillStyle = [1, 1, 1, 1];
context.setTransform(1, 0, 0, 1, 0, 0);
context.drawImage(texture, 0, 0, width, height);

シェーダーの準備

今回は色とmatrixも使ってdrawImageを実装していきます。

頂点シェーダー

const TEXTURE_VERTEX_SHADER = "\
precision highp float;\n\
attribute vec2 a_coord;\n\
varying vec2 v_coord;\n\
uniform vec2 u_position;\n\
uniform vec2 u_size;\n\
uniform vec2 u_viewport;\n\
uniform mat3 u_transform;\n\
void main() {\n\
    v_coord = a_coord;\n\
    vec3 pos = u_transform * vec3(u_position + vec2(a_coord.x, 1.0 - a_coord.y) * u_size, 1.0);\n\
    pos.x = (2.0 * pos.x / u_viewport.x) - 1.0;\n\
    pos.y = -((2.0 * pos.y / u_viewport.y) - 1.0);\n\
    gl_Position = vec4(pos.xy, 0.0, 1.0);\n\
}";

フラグメントシェーダー

const TEXTURE_FRAGMENT_SHADER = "\
precision highp float;\n\
uniform sampler2D u_texture;\n\
uniform vec4 u_color;\n\
varying vec2 v_coord;\n\
void main() {\n\
    gl_FragColor = texture2D(u_texture, v_coord) * u_color;\n\
}";

drawImageを実装


/**
 * @param  {array} uniforms
 * @return {void}
 * @public
 */
updateUniforms (uniforms) 
{
    var length = uniforms.length;
    for (let idx = 0; idx < length; idx++) {

        const uniform = uniforms[idx];

        var value = uniform.value;
        if (Util.$isArray(value)) {
            value = new Float32Array(value);
        }

        var info = this.uniformInfo[uniform.name];
        if (!info.location) {
            info.location = this.gl.getUniformLocation(this.program, uniform.name);
        }

        switch (info.type) {

            case gl.FLOAT_MAT2:
            case gl.FLOAT_MAT3:
            case gl.FLOAT_MAT4:
                info.method.call(this.gl, info.location, false, value);
                break;
            // ...他の関数も同様に値をセットしてコールする

        }
    }
}


/**
 * @praram {WebGLTexture} texture
 * @praram {number} x
 * @praram {number} y
 * @praram {number} width
 * @praram {number} height
 * @return {void}
 * @public
 */
drawImage (texture, x, y, width, height) 
{
    // 生成したプログラムをセット
    this.gl.useProgram(this.program);

    // 描画したいtextureをbind
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, texture);

    // 変数データを送る
    this.updateUniforms ([
        { "name": "u_size",      "value": [x, y] },
        { "name": "u_position",  "value": [width, height] },
        { "name": "u_transform", "value": this.matrix },
        { "name": "u_color",     "value": this.color },
        // ...今回は他の変数は割愛
    ]) 

    // buffer objectやattributeは長くなるので、今回は割愛します。

    gl.drawArrays(gl.TRIANGLES, 0, 6);
}

っという感じで、一番最初はCanvas2Dで出来上がったcanvasデータをtextureに変換してWebGLで描画する事からはじめました。

次はlineToやquadraticCurveToのパス情報について書こうと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0