Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

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

基礎部分はできたので、実際にシェーダーにデーターを渡していこうかと思います。
サンプルとして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のパス情報について書こうと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?