unityController - WebGL¶
このセクションでは、WebGL の作成プロセスを取り扱います。
In This Section
gfx_draw3D¶
gfx_draw3D()
gfx_draw3D は、WebGL を使用して 3D 描画処理を行います。オブジェクトとともに移動する円を描画するため、フレームごとに呼び出します。
WebGL のコンテキストを取得して、古いフレームコンテンツを削除します。
描画コマンドを実行する前に、テクスチャを適切に設定します。
// Perform the 3d draw process let genvidWebGL = this.genvidWebGL; let gl = genvidWebGL.gl; genvidWebGL.clear(); let prog = this.gfx_prog; gl.useProgram(prog); // 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(prog, "tex"), 0); if (this.gfx_prog_data_viewproj) { gl.uniformMatrix4fv(this.gfx_prog_loc_viewproj, false, this.gfx_prog_data_viewproj); }
最後に、各オブジェクトに対してループ処理を実行し、オブジェクトの回りに輪を描画します。
// Draw commands.
let cmds: RenderCommand[] = [this.gfx_cmd_test, this.gfx_cmd_cubes];
for (let cmd of cmds) {
if (cmd.visible && cmd.vtx) {
gl.bindBuffer(gl.ARRAY_BUFFER, cmd.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, cmd.idx[0]);
gl.bindTexture(gl.TEXTURE_2D, cmd.tex);
genvidWebGL.checkGLError();
gl.drawElements(gl.TRIANGLES, cmd.idx[1], gl.UNSIGNED_SHORT, 0);
genvidWebGL.checkGLError();
}
}
gfx_initShaders¶
gfx_initShaders()
gfx_initShaders は、全体的な初期化プロセスにおいて、シェーダを初期化します。
// Web GL initalization of shaders
gfx_initShaders() {
let genvidWebGL = this.genvidWebGL;
let 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");
let 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.
// " gl_FragColor = color;", // Just the color.
// " gl_FragColor = texColor;", // Just the texture.
// " gl_FragColor = vec4(texCoord, 0.0, 1.0);", // The texture coordinate.
// " gl_FragColor = vec4(fract(texCoord), 0.0, 1.0);", // Repeating texture coordinate.
"}"
].join("\n");
let vsh = genvidWebGL.loadVertexShader(vShaderStr);
let fsh = genvidWebGL.loadFragmentShader(fShaderStr);
this.gfx_prog = genvidWebGL.loadProgram(vsh, fsh, ["g_Position", "g_TexCoord0"]);
this.gfx_prog_loc_viewproj = genvidWebGL.gl.getUniformLocation(this.gfx_prog, "g_ViewProjMat");
}
gfx_initRenderCommands¶
gfx_initRenderCommands()
gfx_initRenderCommands は、全体的な初期化プロセスにおいて、レンダーコマンドを初期化します。
// Web gl initialization of render command
gfx_initRenderCommands() {
let genvidWebGL = this.genvidWebGL;
let gl = 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);
// console.log("Enabling aniso filtering", max);
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max);
}
}
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
}
let onload = this.gfx_draw3D.bind(this);
{
let vertices: number[] = [];
this.makeCircleZ(vertices, 0, 0, 0, 0.5, genvidMath.vec4(1, 0, 0, 1));
let num_quads = vertices.length / (4 * 9);
let cmd = new RenderCommand();
let options = {
"wrap": gl.CLAMP_TO_EDGE,
"aniso": true,
};
cmd.vtx = genvidWebGL.createBuffer(new Float32Array(vertices));
cmd.idx = genvidWebGL.createIndexBufferForQuads(num_quads);
cmd.tex = gl.createTexture();
cmd.img = new Image();
cmd.img.onload = function () { handleTextureLoaded(cmd.img, cmd.tex, options); if (onload) onload(); };
cmd.img.src = "img/highlight_full_pa.png";
cmd.visible = false;
this.gfx_cmd_test = cmd;
}
// Cubes.
{
// Only prepare textures.
let cmd = new RenderCommand();
let options = {
"wrap": gl.CLAMP_TO_EDGE,
"aniso": true,
};
cmd.tex = gl.createTexture();
cmd.img = new Image();
cmd.img.onload = function () { handleTextureLoaded(cmd.img, cmd.tex, options); if (onload) onload(); };
cmd.img.src = "img/highlight_full_pa.png";
cmd.visible = true;
this.gfx_cmd_cubes = cmd;
}
this.gfx_draw3D();
}