原生WebGL基礎學習(二) 用WebGL繪製一個三角形
阿新 • • 發佈:2018-12-14
在開始之前,需要知道著色器的相關知識,可以參考:webgl介紹裡面的著色器介紹,本文的demo 用到的著色器為:
<script id="vertex-shader" type="x-shader/x-vertex"> attribute vec4 a_position; void main() { gl_Position = a_position; } </script> <script id="fragment-shader" type="x-shader/x-fragment"> precision mediump float;//將精度設定為中等精度 void main() { gl_FragColor = vec4(1, 0, 0.5, 1); } </script>
其中的attribute定義了一個vec4四維變數,用於表示每個頂點的位置資訊,gl_Position代表頂點的位置, a_position是著色器用於接收來自JavaScript程式碼的頂點位置資訊的入口。gl_FragColor代表每個片元的顏色,通俗的理解是用於設定幾何顏色。
首先,在HTML文件裡建立一個用於畫圖的canvas(畫布):
<canvas id="triangle" width="800" height="600"></canvas>
獲取canvas元素:
let canvas = document.getElementById('triangle');
判斷瀏覽器是否支援WebGL,其中,antialias表示是否開啟抗鋸齒, depth表明繪製緩衝區包含一個深度至少為16位的緩衝區:
let gl = canvas.getContext('webgl', {antialias: true, depth: false});
if (!gl) {
console.log("您的瀏覽器不支援webgl!");
}
根據id獲取著色器文字,並建立、編譯和連結著色器:
//獲取GLSL文字 let vShaderSource = document.getElementById('vertex-shader').text; let fShaderSource = document.getElementById('fragment-shader').text; //建立、編譯和連結著色器 let program = initShader(gl, vShaderSource, fShaderSource);
在著色器中尋找attribute變數的位置:
let positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
建立緩衝區,並繫結資料:
//建立緩衝區
let positionBuffer = gl.createBuffer();
//將它繫結到ARRAY_BUFFER(將其視為ARRAY_BUFFER = positionBuffer)
//繫結緩衝區
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
//三個頂點構成一個三角形
let positions = [
-0.25, 0,
0, 0.5,
0.25, 0
];
//通過繫結點向緩衝區繫結資料
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
最後進行畫圖:
//使畫布的畫素數和顯示大小匹配
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
//設定視口
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
//清除canvas
gl.clearColor(0, 0, 0, 1);//設定背景顏色
gl.clear(gl.COLOR_BUFFER_BIT);
//應用著色器
gl.useProgram(program);
//建立著色器中attribute變數與緩衝區之間的連線
gl.enableVertexAttribArray(positionAttributeLocation);
const size = 2;//2維座標:每次迭代執行提取兩個單位資料
const type = gl.FLOAT;//每個單位的資料型別是32位浮點型
const normalize = false;//不需要歸一化資料
const stride = 0;//每次迭代前進大小* sizeof(型別)以獲得下一個位置
const offset1 = 0;//從緩衝起始位置開始讀取
//從緩衝區取出資料
gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset1);
let primitiveType = gl.TRIANGLES;//繪製三角形
let offset2 = 0;//從第一個頂點開始
let count = 3;//畫圖所頂點次數
gl.drawArrays(primitiveType, offset2, count);//畫圖
顯示效果: