WebGL初學:構建一個多彩三角形與矩形

利用WebGL需要使用著色器,這裡不多介紹。

1.從HTML頁面獲取canvas元素的上下文,這裡主要要獲取到gl對象:

function initWebGL(canvas) { var gl; try { gl = canvas.getContext("webgl"); gl.viewport(0, 0, canvas.width, canvas.height); } catch (e) { var msg = "無法從canvas中獲取webgl!" + e.toString(); alert(msg); throw Error(msg); } return gl;}

2.著色器源碼:

// =======================================// 頂點著色器和片元著色器// =======================================var vsSource = `attribute vec3 a_Position;attribute vec4 a_Color;varying vec4 v_Color;void main() { gl_Position = vec4(a_Position, 1.0); v_Color = a_Color;}`;var fsSource = `#ifdef GL_ESprecision mediump float;#endifvarying vec4 v_Color;void main() { gl_FragColor = v_Color;}`;

3.需要對著色器進行編譯及使用:

function loadShader(gl, type, source) { // 1.創建著色器對象 var shader; if(type === "vertex") { shader = gl.createShader(gl.VERTEX_SHADER); } else if(type === "fragment") { shader = gl.createShader(gl.FRAGMENT_SHADER); } // 2.向著色器對象中填充著色器程序的源代碼 gl.shaderSource(shader, source); // 3.編譯著色器 gl.compileShader(shader); var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); if (!compiled) { var error = gl.getShaderInfoLog(shader); console.log('Failed to compile shader: ' + error); gl.deleteShader(shader); return -1; } // 4.返回著色器對象 return shader;}function initShader(gl, vertSource, fragSource) { // 加載頂點著色器和片元著色器 var vertShader = loadShader(gl, "vertex", vertSource); var fragShader = loadShader(gl, "fragment", fragSource); if(!vertShader || !fragShader) { return null; } // 1.創建著色器程序 var shaderProgram = gl.createProgram();  // 2.為程序對象分配著色器 gl.attachShader(shaderProgram, vertShader); gl.attachShader(shaderProgram, fragShader); // 3.連接程序對象 gl.linkProgram(shaderProgram); // 創建失敗, alert if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert('無法初始化著色器程序: ' + gl.getProgramInfoLog(shaderProgram)); console.log(gl.getProgramInfoLog(shaderProgram)); return null; } // 4.使用程序對象 gl.useProgram(shaderProgram); gl.program = shaderProgram; return true;}

4.創建三角形對象:

function createTriangle(gl) { var verts = new Float32Array([ 0.0, 0.5, -0.5, -0.5, 0.5, -0.5, ]);  var colors = new Float32Array([ 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, ]); var vSIZE = verts.BYTES_PER_ELEMENT; var vertexBuffer = gl.createBuffer(); var cSIZE = colors.BYTES_PER_ELEMENT; var colorBuffer = gl.createBuffer(); var triangle = { vertsArray: verts, colorsArray: colors, vertBuffer: vertexBuffer, colorBuffer: colorBuffer, vSIZE: vSIZE, cSIZE: cSIZE, nVert: 3, primType: gl.TRIANGLES }; return triangle;}

5.類似地,創建矩形對象:

function createSquare(gl) { var verts = new Float32Array([ 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5 ]);  var colors = new Float32Array([ 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 ]); var vSIZE = verts.BYTES_PER_ELEMENT; var vertexBuffer = gl.createBuffer(); var cSIZE = colors.BYTES_PER_ELEMENT; var colorBuffer = gl.createBuffer(); var square = { vertsArray: verts, colorsArray: colors, vertBuffer: vertexBuffer, colorBuffer: colorBuffer, vSIZE: vSIZE, cSIZE: cSIZE, nVert: 4, primType: gl.TRIANGLE_STRIP }; return square;}

6.初始化緩存:

function initBuffer(gl, obj) { gl.bindBuffer(gl.ARRAY_BUFFER, obj.vertBuffer); gl.bufferData(gl.ARRAY_BUFFER, obj.vertsArray, gl.STATIC_DRAW); var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, obj.vSIZE * 2 , 0); gl.enableVertexAttribArray(a_Position); gl.bindBuffer(gl.ARRAY_BUFFER, obj.colorBuffer); gl.bufferData(gl.ARRAY_BUFFER, obj.colorsArray, gl.STATIC_DRAW); var a_Color = gl.getAttribLocation(gl.program, 'a_Color'); gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, obj.cSIZE * 3 , 0); gl.enableVertexAttribArray(a_Color);}

7.主程序入口:

window.onload = function main() { var canvas1 = document.getElementById('webgl-1'); var gl1 = initWebGL(canvas1); initShader(gl1, vsSource, fsSource); var obj1 = createSquare(gl1); initBuffer(gl1, obj1); drawScene(canvas1, gl1, obj1);  var canvas2 = document.getElementById('webgl-2'); var gl2 = initWebGL(canvas2); initShader(gl2, vsSource, fsSource); var obj2 = createTriangle(gl2); initBuffer(gl2, obj2); drawScene(canvas2, gl2, obj2);};

8.完成!


分享到:


相關文章: