webgl繪製粗線段
阿新 • • 發佈:2018-12-23
webgl1不支援設定線段寬度,這就只好通過shader來實現了,參考了踏得網的例子,引用地址:http://wow.techbrood.com/fiddle/43140。先在此感謝踏得網創始人之一 Ryan.chen 陳曉峰。介紹一下踏得網,這是一個推廣交流webgl的網站,同學們可以去學習交流。由於本文程式碼完全抄用踏得網的例子,所以本文不是案例原創,但本文會將對借鑑程式碼的理解詳細分析。
我們先貼出shader著色器程式碼,來看一下。
<script id="vertex" type="x-shader"> attribute vec2 aVertexPosition;void main() { gl_Position = vec4(aVertexPosition, 0.0, 1.0); } </script> <script id="fragment" type="x-shader"> #ifdef GL_ES precision highp float; #endif uniform vec4 uColor;void main() { gl_FragColor = uColor; } </script>
首先我們來分析一下頂點著色器vertex,只有一個attribute引數,是vec2型別的引數 aVertexPosition,線段的兩個頂點座標。接下來看片段著色器fragment,也只有一個引數,uniform引數,引數型別vec4,是傳入的線段顏色引數。頂點著色器的主函式只是將gl_Position設定為線段的頂點座標,片段著色器的主函式也僅僅是將gl_FragColor設定成引數傳入的線段顏色。就是說線段上每一個position的頂點畫素的顏色都是引數傳入的線段顏色。
接下來我們來看js程式碼。
<script type="text/javascript"> function init(){ canvas = document.getElementById("mycanvas"); gl = canvas.getContext("experimental-webgl"); gl.viewport(0, 0, canvas.width, canvas.height); gl.clearColor(0, 0.5, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); var v = document.getElementById("vertex").firstChild.nodeValue; var f = document.getElementById("fragment").firstChild.nodeValue; var vs = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vs, v); gl.compileShader(vs); var fs = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fs, f); gl.compileShader(fs); program = gl.createProgram(); gl.attachShader(program, vs); gl.attachShader(program, fs); gl.linkProgram(program); if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) console.log(gl.getShaderInfoLog(vs)); if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) console.log(gl.getShaderInfoLog(fs)); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) console.log(gl.getProgramInfoLog(program)); var aspect = canvas.width / canvas.height; var vertices = new Float32Array([ -0.5, 0.1*aspect, 0.5, 0.1*aspect, 0.5,0.11*aspect, -0.5, 0.1*aspect, 0.5, 0.11*aspect, -0.5,0.11*aspect ]); vbuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); itemSize = 2; numItems = vertices.length / itemSize; gl.useProgram(program); program.uColor = gl.getUniformLocation(program, "uColor"); gl.uniform4fv(program.uColor, [1.0, 1.0, 0.0, 1.0]); program.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); gl.enableVertexAttribArray(program.aVertexPosition); gl.vertexAttribPointer(program.aVertexPosition, itemSize, gl.FLOAT, false, 0, 0); gl.drawArrays(gl.TRIANGLES, 0, numItems); } </script>
我們看到,線段的頂點是vertices,其中有6組頂點,線段的顏色是黃色,就是這段程式碼
program.uColor = gl.getUniformLocation(program, "uColor");
gl.uniform4fv(program.uColor, [1.0, 1.0, 0.0, 1.0]);
我們可以看一下結果,如下圖
我們看到,這條線段是2D的矩形,並不是3D意義上的粗線段,還有一種思路,可以畫一個圓柱代替線段。
以上就是踏得網的粗線段的例子。