WebController - WebGL

このセクションでは、WebGL の作成プロセスを取り扱います。

gfxDraw3D

gfxDraw3D()

gfxDraw3D 関数は、WebGL を使用して 3D 描画処理を行います。オブジェクトとともに移動する円を描画するため、フレームごとに呼び出します。

  1. WebGL のコンテキストを取得して、古いフレームコンテンツを削除します。

  2. 描画コマンドを実行する前に、テクスチャを適切に設定します。

            // Performs the 3d draw process
            const gl = this.genvidWebGL.gl;
    
            this.genvidWebGL.clear();
    
            gl.useProgram(this.gfxProg);
    
            // We prepare the program only once (good thing we have a single material).
            gl.enableVertexAttribArray(0);
            gl.enableVertexAttribArray(1);
            gl.enableVertexAttribArray(2);
            gl.activeTexture(gl.TEXTURE0);
            gl.uniform1i(gl.getUniformLocation(this.gfxProg, "tex"), 0);
    
            if (this.gfxProgDataViewproj) {
                gl.uniformMatrix4fv(this.gfxProgLocViewproj, false, this.gfxProgDataViewproj);
            }
    
  3. 最後にサークルを描画します。

        // Draws commands.
        if (this.gfxCmdCubes.visible && this.gfxCmdCubes.vtx) {
            gl.bindBuffer(gl.ARRAY_BUFFER, this.gfxCmdCubes.vtx[0]);
            gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 9 * 4, 0 * 4); // Position.
            gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 9 * 4, 3 * 4); // TexCoord.
            gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 9 * 4, 5 * 4); // Color.
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.gfxCmdCubes.idx[0]);
            gl.bindTexture(gl.TEXTURE_2D, this.gfxCmdCubes.tex);
            this.genvidWebGL.checkGLError();

            gl.drawElements(gl.TRIANGLES, this.gfxCmdCubes.idx[1], gl.UNSIGNED_SHORT, 0);
            this.genvidWebGL.checkGLError();
        }

gfxInitShaders

gfxInitShaders()

gfxInitShaders 関数は、全体的な初期化プロセスにおいて、シェーダを初期化します。

    // Web GL initalization of shaders
    gfxInitShaders() {
        const vShaderStr = [
            "uniform mat4 g_ViewProjMat;",
            "attribute vec3 g_Position;",
            "attribute vec2 g_TexCoord0;",
            "attribute vec4 g_Color0;",
            "varying vec2 texCoord;",
            "varying vec4 color;",
            "void main()",
            "{",
            "   gl_Position = g_ViewProjMat * vec4(g_Position, 1.0);",
            "   texCoord = g_TexCoord0;",
            "   color = g_Color0;",
            "}"
        ].join("\n");
        const fShaderStr = [
            "precision mediump float;",
            "uniform sampler2D tex;",
            "varying vec2 texCoord;",
            "varying vec4 color;",
            "void main()",
            "{",
            "   vec4 texColor = texture2D(tex, texCoord);",
            "   gl_FragColor = texColor * color;", // Texture with color.
            "}"
        ].join("\n");

        const vsh = this.genvidWebGL.loadVertexShader(vShaderStr);
        const fsh = this.genvidWebGL.loadFragmentShader(fShaderStr);
        this.gfxProg = this.genvidWebGL.loadProgram(vsh, fsh, ["g_Position", "g_TexCoord0"]);
        this.gfxProgLocViewproj = this.genvidWebGL.gl.getUniformLocation(this.gfxProg, "g_ViewProjMat");
    }

gfxInitRenderCommands

gfxInitRenderCommands()

gfxInitRenderCommands 関数は、全体的な初期化プロセスにおいて、レンダーコマンドを初期化します。

    // Web gl initialization of render command
    gfxInitRenderCommands() {
        let gl = this.genvidWebGL.gl;

        // Utility function.
        function handleTextureLoaded(image, texture, options) {
            options = options || {};
            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
            if (options.wrap) {
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, options.wrap);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, options.wrap);
            }
            if (options.aniso) {
                let ext = (
                    gl.getExtension("EXT_texture_filter_anisotropic") ||
                    gl.getExtension("MOZ_EXT_texture_filter_anisotropic") ||
                    gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic")
                );
                if (ext) {
                    let max = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
                    gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max);
                }
            }
            gl.generateMipmap(gl.TEXTURE_2D);
            gl.bindTexture(gl.TEXTURE_2D, null);
        }

        // Cubes.
        {
            // Only prepares textures.
            this.gfxCmdCubes = {
                tex: gl.createTexture(),
                img: new Image(),
                visible: true,
            };
            this.gfxCmdCubes.img.onload = () => {
                handleTextureLoaded(this.gfxCmdCubes.img, this.gfxCmdCubes.tex, {
                    "wrap": gl.CLAMP_TO_EDGE,
                    "aniso": true,
                });
                if (this.gfxDraw3D) this.gfxDraw3D();
            };
            this.gfxCmdCubes.img.src = "img/highlight_full_pa.png";
        }

        this.gfxDraw3D();
    }