WebGL(TypeScript)--- 三角形描画
今回はWebGLを用いてcanvasに三角形を描画してみたいと思います。
ライブラリを用いず、一から実装してみます。
HTMLの準備
表示のため、下記htmlを用意しました。
<!DOCTYPE html> <html> <body> <canvas id="gl_canvas" width="100" height="100"></canvas> <script src="script.js"></script> </body> </html>
Shader作成関数
Vertex ShaderのコードとFragment Shaderのコードから、WebGLProgramを作成する関数を準備します。
function createProgram(gl : WebGLRenderingContext, vertexCode : string, fragmentCode : string) : WebGLProgram { // Vertex Shader コンパイル const vertexShader = gl.createShader(gl.VERTEX_SHADER)!; compileShader(gl, vertexShader, vertexCode); // Fragment Shader コンパイル const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)!; compileShader(gl, fragmentShader, fragmentCode); // Program作成 const program = gl.createProgram()!; gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); // エラー確認 console.log(gl.getProgramInfoLog(program)); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) throw new Error("program error"); return program; }
上記で利用しているcompileShaderは次のようになります。
function compileShader(gl : WebGLRenderingContext, shader : WebGLShader, code : string) : void { gl.shaderSource(shader, code); gl.compileShader(shader); // エラー確認 console.log(gl.getShaderInfoLog(shader)); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) throw new Error("compile error"); }
VertexBuffer作成関数
頂点データの配列からWebGLBufferを作成する関数を準備します。
function createVertexBuffer(gl : WebGLRenderingContext, vertices : number[]) : WebGLBuffer { const buffer = gl.createBuffer()!; gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); return buffer; }
main関数
三角形を描画する関数は下記の様になります。
canvasにはこのように描画されます。
let gl : WebGLRenderingContext; function main() : void { const canvas = <HTMLCanvasElement>document.getElementById("gl_canvas"); gl = canvas.getContext("webgl")!; const vertexCode = ` attribute vec4 position; void main() { gl_Position = position; } `; const fragmentCode = ` void main() { gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); } `; const program = createProgram(gl, vertexCode, fragmentCode); const vertices = [ 0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, ]; const vertexBuffer = createVertexBuffer(gl, vertices); gl.useProgram(program); const positionAttrib = gl.getAttribLocation(program, "position"); gl.enableVertexAttribArray(positionAttrib); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.vertexAttribPointer(positionAttrib, 3, gl.FLOAT, false, 0, 0); gl.clearColor(0.3, 0.3, 0.3, 1); gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, 3); } main();