欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

WebGL画一个彩色矩形

程序员文章站 2022-05-23 14:03:31
...

     今天和大家分享一个用WebGL画矩形(rectangle)的小Demo,也可用来绘制三角形(triangle)。本文适用于初学者掌握WebGL的基本绘图知识,WebGL是OpenGL的Web版本,所以它的绘图过程与OpenGL是一样的,这里不赘述,大家自行百度。

     今天分享的是绘制一个二维的图形--矩形;二维是三维的基础,二维图像的Z=0,由此,先掌握二维图像的绘制,再向三维拓展,自然水到渠成。废话不多说,直接进入正题。  

     首先,webgl不能直接画彩色矩形的,但webgl可以直接画三角形,画三角形有三种画法,分别是:gl.TRIANGLES、gl.TRIANGLE_STRIP、gl.TRIANGLE_FAN,如下图所示。

WebGL画一个彩色矩形

         本文用到的的是第二种绘制三角形的方法gl.TRIANGLE_STRIP,一定要特别注意,其绘制的顶点顺序为(v0,v1,v2),(v2,v1,v3),由此得到两个三角形拼凑成一个矩形。详细过程示意图如下图:

WebGL画一个彩色矩形

     第三种方法gl.TRIANGLE_FAN也可以达到目的,但顶点的顺序要稍微调整一下,(v0,v1,v2),(v0,v2,v3)。

程序运行结果如下图:

WebGL画一个彩色矩形

上面是相关原理和运行结果,接下来直接上代码:

triangle.js

/**
 * Created by wjh on 2017/6/26.
 */

var canvas;
var gl;

function init(){
    canvas = document.getElementById("Rectangle");//获取canvas元素
    gl = WebGLUtils.setupWebGL(canvas);
    //判断浏览器是否支持webgl
    if(!gl){
        alert("您的浏览器不支持WebGL!")
    }

    //矩形的定点数组,共4个(x,y,r,g,b)
    var verticescolor = new Float32Array([
        -0.5,0.0, 0.0,1.0,0.0,
        0.0,-0.5, 0.0,0.0,1.0,//r,g,b,为颜色信息
        0.0,0.5, 1.0,0.0,0.0,
        0.5,0.0, 0.0,0.0,0.0
    ]);

    //顶点顺序索引
    var indexV = new Uint8Array([
        0,1,2,
        2,1,3
    ]);

    //设置窗口大小
    gl.viewport(0,0,canvas.width,canvas.height);
    gl.clearColor(0.0,0.0,0.0,1.0);

    //初始化着色器
    var program = initShaders(gl,"v-shader","f-shader");
    gl.useProgram(program);

    //创建缓存
    var tBuffer = gl.createBuffer()//为矩形顶点创建的缓存
    var iBuffer = gl.createBuffer();//为顶点索引创建的缓存

    gl.bindBuffer(gl.ARRAY_BUFFER,tBuffer);//绑定缓冲区
    gl.bufferData(gl.ARRAY_BUFFER,flatten(verticescolor),gl.STATIC_DRAW);//向缓冲区写入顶点数据

    //获取顶点着色器中attribute变量位置
    var a_Position = gl.getAttribLocation(program,"a_Position");

    var SIZE = verticescolor.BYTES_PER_ELEMENT;
    //建立a_Position与顶点着色器attribute变量“a_Position”的关联
    gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,SIZE*5,0);
    gl.enableVertexAttribArray(a_Position);

    var a_Color = gl.getAttribLocation(program,"a_Color");
    gl.vertexAttribPointer(a_Color,3,gl.FLOAT,false,SIZE*5,SIZE*2);
    gl.enableVertexAttribArray(a_Color);

    gl.bindBuffer(gl.ARRAY_BUFFER,iBuffer);//绑定缓冲区
    gl.bufferData(gl.ARRAY_BUFFER,flatten(indexV),gl.STATIC_DRAW);//向缓冲区写入索引数据


    render();//执行画图函数
}

function render(){
    gl.clear(gl.COLOR_BUFFER_BIT);//清除屏幕
  gl.drawArrays(gl.TRIANGLE_STRIP,0,4)//画三角形,两个三角形拼凑成一个矩形

}
window.onload = init;//window加载init函数,最终显示矩形

html文档如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <title>Rectangle</title>
    <!--顶点着色器-->
    <script id="v-shader" type="x-shader/x-vertex">
        attribute vec4 a_Position;
        attribute vec4 a_Color;
        varying vec4 v_Color;
        void main()
        {
        gl_Position = a_Position;
        v_Color = a_Color;
        }
    </script>
    <!--片元着色器-->
    <script id="f-shader" type="x-shader/x-fragment">
        precision mediump float;
        varying vec4 v_Color;
        void main()
        {
        gl_FragColor = v_Color;
        }
    </script>
    <!--调用js文件-->
    <script type="text/javascript" src="../../libs/webgl-utils.js"></script>
    <script type="text/javascript" src="../../libs/MV.js"></script>
    <script type="text/javascript" src="../../libs/initShaders.js"></script>
    <script type="text/javascript" src="triangle.js"></script>
</head>
<body>
<!--定义canvas ID-->
<canvas id="Rectangle" width="618" height="618">
</canvas>
</body>
</html>