纯色三角形

咱们首先借助缓冲区绘制一个三角形:

残缺的代码如下:

<canvas width=200 height=200 style="outline:1px solid gray;">    十分道歉,您的浏览器不反对canvas!</canvas><!-- 顶点着色器 --><script type='x-shader/x-vertex' id='vs'>    attribute vec4 a_position;    void main(){        gl_Position=a_position;    }</script><!-- 片段着色器 --><script type='x-shader/x-fragment' id='fs'>    precision mediump float;    uniform vec4 u_color;    void main(){        gl_FragColor=u_color;    }</script><script>    var gl = document.getElementsByTagName('canvas')[0].getContext('webgl');    var loadShader = function (type, source) {        var shader = gl.createShader(type);        gl.shaderSource(shader, source);        gl.compileShader(shader);        return shader;    };    var vertexShader = loadShader(gl.VERTEX_SHADER, document.getElementById('vs').innerHTML),        fragmentShader = loadShader(gl.FRAGMENT_SHADER, document.getElementById('fs').innerHTML);    var glProgram = gl.createProgram();    gl.attachShader(glProgram, vertexShader);    gl.attachShader(glProgram, fragmentShader);    gl.linkProgram(glProgram);    gl.useProgram(glProgram);    // 设置三角形的色彩(红色)    var u_color = gl.getUniformLocation(glProgram, 'u_color');    gl.uniform4f(u_color, 1, 0, 0, 1);    // 创立缓冲区    var buffer = gl.createBuffer();    // 把缓冲区对象绑定到指标    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);    // 筹备好点的数据    var data = new Float32Array([        -0.7, -0.7, 0,        0.7, -0.7, 1,        0, 0.7, 0    ]);    // 写入数据到缓冲区    gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);    // 获取变量地位    var a_position = gl.getAttribLocation(glProgram, "a_position");    // 把缓冲区对象调配给指标变量    gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, data.BYTES_PER_ELEMENT * 3, 0);    // 连贯指标对象和缓冲区对象    gl.enableVertexAttribArray(a_position);    // 绘制一个三角形    gl.drawArrays(gl.TRIANGLES, 0, 3);</script>

接着,咱们未来解读下面这段代码。

着色器

三角形一共有3个点,因而不能再写死了,须要定义变量应用缓冲区进行传递,顶点着色器批改如下:

attribute vec4 a_position;void main(){    gl_Position=a_position;}

尽管三角形是纯色的,色彩能够写死,不过咱们想演示一下如何通过变量设置色彩,因而片元着色器也进行批改:

precision mediump float;uniform vec4 u_color;void main(){    gl_FragColor=u_color;}

设置单个色彩

和点不同,色彩就一个值,无需借助缓冲区,比较简单,咱们先看下具体代码:

var u_color = gl.getUniformLocation(glProgram, 'u_color');gl.uniform4f(u_color, 1, 0, 0, 1);

色彩值是rgba(1,0,0,1),也就是不通明的红色。

借助缓冲区设置点

首先,筹备好缓冲区对象:

var buffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

而后,筹备好数据,并写入缓冲区中:

var data = new Float32Array([    -0.7, -0.7, 0,    0.7, -0.7, 1,    0, 0.7, 0]);gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

最初,把缓冲区中的数据调配给点变量a_position即可:

var a_position = gl.getAttribLocation(glProgram, "a_position");gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, data.BYTES_PER_ELEMENT * 3, 0);gl.enableVertexAttribArray(a_position);

绘制

gl.drawArrays(gl.TRIANGLES, 0, 3);

如此,一个红色的三角形就画好了。那么,既然点能够传递3个,可不可以每个点的色彩也能够不一样?当然能够了。

渐变色三角形

当初,咱们再把这个三角形变成渐变色的,先看看最终成果:

同样的,先看看残缺代码,后续咱们一一进行必要的解释:

<canvas width=200 height=200 style="outline:1px solid gray;">    十分道歉,您的浏览器不反对canvas!</canvas><!-- 顶点着色器 --><script type='x-shader/x-vertex' id='vs'>    attribute vec4 a_position;    attribute vec4 a_color;    varying vec4 v_color;    void main(){        gl_Position=a_position;        v_color=a_color;    }</script><!-- 片段着色器 --><script type='x-shader/x-fragment' id='fs'>    precision mediump float;    varying vec4 v_color;    void main(){        gl_FragColor=v_color;    }</script><script>    var gl = document.getElementsByTagName('canvas')[0].getContext('webgl');    var loadShader = function (type, source) {        var shader = gl.createShader(type);        gl.shaderSource(shader, source);        gl.compileShader(shader);        return shader;    };    var vertexShader = loadShader(gl.VERTEX_SHADER, document.getElementById('vs').innerHTML),        fragmentShader = loadShader(gl.FRAGMENT_SHADER, document.getElementById('fs').innerHTML);    var glProgram = gl.createProgram();    gl.attachShader(glProgram, vertexShader);    gl.attachShader(glProgram, fragmentShader);    gl.linkProgram(glProgram);    gl.useProgram(glProgram);    var buffer = gl.createBuffer();    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);    // 筹备好点的数据    var data = new Float32Array([        -0.7, -0.7, 0, 1, 0, 0,        0.7, -0.7, 1, 0, 1, 0,        0, 0.7, 0, 0, 0, 1    ]);    // 写入数据到缓冲区    gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);    // 点的地位    var a_position = gl.getAttribLocation(glProgram, "a_position");    gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, data.BYTES_PER_ELEMENT * 6, 0);    gl.enableVertexAttribArray(a_position);    // 点的色彩    var a_color = gl.getAttribLocation(glProgram, "a_color");    gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, data.BYTES_PER_ELEMENT * 6, data.BYTES_PER_ELEMENT * 3);    gl.enableVertexAttribArray(a_color);    // 绘制一个三角形    gl.drawArrays(gl.TRIANGLES, 0, 3);</script>

应用缓冲区设置点的色彩

着色器

只有顶点着色器能够传递多个数据,因而,须要先革新顶点着色器后通过管道实现:

attribute vec4 a_position;attribute vec4 a_color;varying vec4 v_color;void main(){    gl_Position=a_position;    v_color=a_color;}

而后,片段着色器借助桥梁进行接管:

precision mediump float;varying vec4 v_color;void main(){    gl_FragColor=v_color;}
这里的varying类型的变量就相当于桥梁,当然,桥梁能够有多个。

借助缓冲区设置色彩

点的设置和之前一样,咱们只须要批改一下点色彩的设置即可:

var a_color = gl.getAttribLocation(glProgram, "a_color");gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, data.BYTES_PER_ELEMENT * 6, data.BYTES_PER_ELEMENT * 3);gl.enableVertexAttribArray(a_color);

余下的,就和之前一样了。