WebController - WebGL¶
このセクションでは、WebGL の作成プロセスを取り扱います。
In This Section
gfxDraw3D¶
gfxDraw3D()
gfxDraw3D 関数は、WebGL を使用して 3D 描画処理を行います。オブジェクトとともに移動する円を描画するため、フレームごとに呼び出します。
WebGL のコンテキストを取得して、古いフレームコンテンツを削除します。
描画コマンドを実行する前に、テクスチャを適切に設定します。
// 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); }
最後にサークルを描画します。
// 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();
}