WebGL入门系列二

来源:互联网 发布:if you中文网络歌手 编辑:程序博客网 时间:2024/05/20 13:09

获取webgl上下文

获取webgl上下文示例代码如下:

var gl = canvas.getContext('webgl');

这里介绍getContext()的语法:

canvas.getContext(contextType, contextAttributes);

上面webgl作为contentType。contextAttributes参数是可选的,此参数接受布尔值,如下表所示:
这里写图片描述

带参数的webgl上下文示例代码如下:

var gl = canvas.getContext('webgl', { antialias: false, stencil: true });

WebGL编程步骤

1、着色器编程

存储着色器(顶点着色器和片段着色器),以顶点着色器为例:

//顶点着色器程序var VSHADER_SOURCE =    "attribute vec4 a_Position;" +    "void main() {" +        //设置坐标    "gl_Position = a_Position; " +    "} ";

2、编译着色器
先创建Shader对象,然后将写好的着色器附加到Shader上,最后编译Shader。过程示例代码如下:

//编译着色器var vertShader = gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertShader, VSHADER_SOURCE);gl.compileShader(vertShader);

2、合并编程

存储和编译着色器程序后,你需要创建完整的程序使用着色器。步骤一般如下:

1、创建一个程序对象

var shaderProgram = gl.createProgram();

2、附加着色器

附加的着色器的使用 attachShader()方法创建的程序对象。它的语法如下:

attachShader(Object program, Object shader);

此方法接受两个参数 -
● Program − 通过创建空的程序对象作为一个参数
● Shader − 传递的着色器编译程序中的一个(顶点着色器,片段着色器)
注 - 需要附加两者都使用这种方法的着色器。

3、链接着色器

使用linkProgram()方法链接着色器。通过传递到所附加的着色器程序对象。它的语法如下:

linkProgram(shaderProgram);

4、使用程序

WebGL提供了一个名为useProgram()方法。需要链接程序时向它传递。它的语法如下 :

useProgram(shaderProgram);

下面的代码片段展示了如何创建,连接和使用组合着色器程序。

//创建一个程序对象var shaderProgram = gl.createProgram();//附加着色器gl.attachShader(shaderProgram, vertShader);gl.attachShader(shaderProgram, fragShader);//链接着色器gl.linkProgram(shaderProgram);//使用程序gl.useProgram(shaderProgram); 

示例演示

绘制一个红色的三角形,JavaScript代码如下:

//顶点着色器程序var VSHADER_SOURCE =    "attribute vec4 a_Position;" +    "void main() {" +        //设置坐标    "gl_Position = a_Position; " +    "} ";//片元着色器var FSHADER_SOURCE =    "void main() {" +        //设置颜色    "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" +    "}";//获取canvas元素var canvas = document.getElementById('canvas');//获取绘制二维上下文var gl = canvas.getContext('webgl');if (!gl) {    console.log("Failed");}//编译着色器var vertShader = gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertShader, VSHADER_SOURCE);gl.compileShader(vertShader);var fragShader = gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragShader, FSHADER_SOURCE);gl.compileShader(fragShader);//合并程序var shaderProgram = gl.createProgram();gl.attachShader(shaderProgram, vertShader);gl.attachShader(shaderProgram, fragShader);gl.linkProgram(shaderProgram);gl.useProgram(shaderProgram);//获取坐标点var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');if (a_Position < 0) {    console.log('Failed to get the storage location of a_Position');}var n = initBuffers(gl,shaderProgram);if(n<0){    console.log('Failed to set the positions');}// 清除指定<画布>的颜色gl.clearColor(0.0, 0.0, 0.0, 1.0);// 清空 <canvas>gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLES, 0, n);function initBuffers(gl,shaderProgram) {    var vertices = new Float32Array([        0.0, 0.5, -0.5, -0.5, 0.5, -0.5    ]);    var n = 3;//点的个数    //创建缓冲区对象    var vertexBuffer = gl.createBuffer();    if(!vertexBuffer){        console.log("Failed to create the butter object");        return -1;    }     //将缓冲区对象绑定到目标    gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);    //向缓冲区写入数据    gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);    //获取坐标点    var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');    //将缓冲区对象分配给a_Position变量    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);    //连接a_Position变量与分配给它的缓冲区对象    gl.enableVertexAttribArray(a_Position);  //顶点着色器程序    var VSHADER_SOURCE =        "attribute vec4 a_Position;" +        "void main() {" +            //设置坐标        "gl_Position = a_Position; " +        "} ";    //片元着色器    var FSHADER_SOURCE =        "void main() {" +            //设置颜色        "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);" +        "}";    //获取canvas元素    var canvas = document.getElementById('myCanvas');    //获取绘制二维上下文    var gl = canvas.getContext('experimental-webgl');    if (!gl) {        console.log("Failed");        return;    }    //编译着色器    var vertShader = gl.createShader(gl.VERTEX_SHADER);    gl.shaderSource(vertShader, VSHADER_SOURCE);    gl.compileShader(vertShader);    var fragShader = gl.createShader(gl.FRAGMENT_SHADER);    gl.shaderSource(fragShader, FSHADER_SOURCE);    gl.compileShader(fragShader);    //合并程序    var shaderProgram = gl.createProgram();    gl.attachShader(shaderProgram, vertShader);    gl.attachShader(shaderProgram, fragShader);    gl.linkProgram(shaderProgram);    gl.useProgram(shaderProgram);    //获取坐标点    var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');    if (a_Position < 0) {        console.log('Failed to get the storage location of a_Position');        return;    }    var n = initBuffers(gl,shaderProgram);    if(n<0){        console.log('Failed to set the positions');        return;    }    // 清除指定<画布>的颜色    gl.clearColor(0.0, 0.0, 0.0, 1.0);    // 清空 <canvas>    gl.clear(gl.COLOR_BUFFER_BIT);    gl.drawArrays(gl.TRIANGLES, 0, n);}function initBuffers(gl,shaderProgram) {    var vertices = new Float32Array([        0.0, 0.5, -0.5, -0.5, 0.5, -0.5    ]);    var n = 3;//点的个数    //创建缓冲区对象    var vertexBuffer = gl.createBuffer();    if(!vertexBuffer){        console.log("Failed to create the butter object");        return -1;    }     //将缓冲区对象绑定到目标    gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);    //向缓冲区写入数据    gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);    //获取坐标点    var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');    //将缓冲区对象分配给a_Position变量    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);    //连接a_Position变量与分配给它的缓冲区对象    gl.enableVertexAttribArray(a_Position);    return n;}

运行结果:

这里写图片描述

参考资料:

http://www.yiibai.com/webgl/webgl_shaders.html
http://www.cnblogs.com/bsman/p/6146343.html