1. 程式人生 > >webgl繪製粗線段

webgl繪製粗線段

  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意義上的粗線段,還有一種思路,可以畫一個圓柱代替線段。

  以上就是踏得網的粗線段的例子。