HTML5 WEBGL学习2 实时3D渲染

本系列学习资源来自《HTML5 与WebGL编程》 中国工信出版集团 人民邮电出版社

中文教程地址:
http://www.hiwebgl.com/?p=42
项目开源地址:
https://github.com/tparisi/Programming3DApplications

WEB GL不属于HTML5官方标准,但绝大多数支持HTML5的浏览器都支持WebGL。

  • WebGL是一套底层绘图API,它通过解析数据和着色器阵列来进行绘制。
  • WebGL基于OpenGL Es2.0,ES代表嵌入式系统。
  • WebGL可以与其它Web页面元素相结合。
  • WebGL为创建动态Web应用而生
  • WebGL是跨平台的
  • WebGL是免费的。

WebGL应用剖析

为了在页面中渲染WebGL,一个应用至少应当执行以下步骤:

  1. 创建一个Canvas元素
  2. 获取Canvas元素中的绘图上下文
  3. 初始化视口
  4. 创建一个或多个包含待渲染数据(通常是顶点数据)的缓冲
  5. 创建一个或多个定义顶点缓冲到屏幕空间转换规则的矩阵
  6. 创建一个或多个实现绘制算法的着色器
  7. 使用各项参数初始化着色器
  8. 绘制

简单的WebGL示例

这里写图片描述

1. 从Canvas获得WebGL上下文
    function initWebGL(canvas) {
        var gl = null;
        var msg = "Your browser does not support WebGL, " +
            "or it is not enabled by default.";
        try 
        {
            gl = canvas.getContext("experimental-webgl");
        } 
        catch (e)
        {
            msg = "Error creating WebGL Context!: " + e.toString();
        }

        if (!gl)
        {
            alert(msg);
            throw new Error(msg);
        }
        return gl;        
     }
2. 视口
    function initViewport(gl, canvas)
    {
        gl.viewport(0, 0, canvas.width, canvas.height);
    }
3. 缓冲、缓冲数组和类型化数组

WebGL基于图元(primitive)进行图像绘制。图元以数组的形式存储数据,这个数组被称为缓冲(buffer),待绘制的顶点数据在缓冲中被定义。
创建一个1*1正方形顶点缓冲:

    function createSquare(gl) {
        var vertexBuffer;
        vertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        var verts = [
             .5,  .5,  0.0,
            -.5,  .5,  0.0,
             .5, -.5,  0.0,
            -.5, -.5,  0.0
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
        var square = {buffer:vertexBuffer, vertSize:3, nVerts:4, primtype:gl.TRIANGLE_STRIP};
        return square;
    }

Float32Array,是一种浏览器专门为WebGL引入的新数据类型。Float32Array是一类缓冲数组(ArrayBuffer),也称为类型化数组(typed array)。它是一种以二进制方式存储的JavaScript类型。

4. 矩阵

在绘制正方形前,首先要创建一对矩阵。一个矩阵用于定义正方形在3D坐标系统中的位置(相对于相机),这个矩阵被称为模型-视图矩阵,因为它同时包含模型矩阵和视图矩阵的信息。
第二个矩阵被称为投影矩阵,着色器使用它来执行从3D空间坐标到2D视口绘制空间坐标的转换。

    var projectionMatrix, modelViewMatrix;
    function initMatrices(canvas)
    {
        // Create a model view matrix with object at 0, 0, -3.333
        modelViewMatrix = mat4.create();
        mat4.translate(modelViewMatrix, modelViewMatrix, [0, 0, -3.333]);
        // Create a project matrix with 45 degree field of view
        projectionMatrix = mat4.create();
        mat4.perspective(projectionMatrix, Math.PI / 4, canvas.width / canvas.height, 1, 10000);
    }
5. 着色器

着色器是一段使用GLSL编写的简短程序。

    function createShader(gl, str, type) {
        var shader;
        if (type == "fragment") {
            shader = gl.createShader(gl.FRAGMENT_SHADER);
        } else if (type == "vertex") {
            shader = gl.createShader(gl.VERTEX_SHADER);
        } else {
            return null;
        }
        gl.shaderSource(shader, str);
        gl.compileShader(shader);
        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            alert(gl.getShaderInfoLog(shader));
            return null;
        }
        return shader;
    }

着色器代码以JavaScript字符串的形式定义,存储在全局变量中。

    var vertexShaderSource =

        "    attribute vec3 vertexPos;\n" +
        "    uniform mat4 modelViewMatrix;\n" +
        "    uniform mat4 projectionMatrix;\n" +
        "    void main(void) {\n" +
        "       // Return the transformed and projected vertex value\n" +
        "        gl_Position = projectionMatrix * modelViewMatrix * \n" +
        "            vec4(vertexPos, 1.0);\n" +
        "    }\n";
    var fragmentShaderSource = 
        "    void main(void) {\n" +
        "    // Return the pixel color: always output white\n" +
        "    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
        "}\n";

当着色器的各个部分被编译完成,需要调用WebGL中的gl.createProgram() gl.attachShader()以及gl.linkProgram()方法将它们链接到同一段程序中。随便需要调用 gl.getAttribLocation()和gl.getUniformLocation()函数获取GLSL程序中定义的各个变量的句柄,从而可以用JavaScript 定义的数值来初始化这些变量。

6. 绘制图元
   function draw(gl, obj) {
       // clear the background (with black)
       gl.clearColor(0.0, 0.0, 0.0, 1.0);
       gl.clear(gl.COLOR_BUFFER_BIT);
       // set the shader to use
       gl.useProgram(shaderProgram);
       // connect up the shader parameters: vertex position and projection/model matrices
       // set the vertex buffer to be drawn
       gl.bindBuffer(gl.ARRAY_BUFFER, obj.buffer);
       gl.vertexAttribPointer(shaderVertexPositionAttribute, obj.vertSize, gl.FLOAT, false, 0, 0);
       gl.uniformMatrix4fv(shaderProjectionMatrixUniform, false, projectionMatrix);
       gl.uniformMatrix4fv(shaderModelViewMatrixUniform, false, modelViewMatrix);
       // draw the object
       gl.drawArrays(obj.primtype, 0, obj.nVerts);
    }

完整源代码可以在
https://github.com/tparisi/Programming3DApplications
看到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程圈子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值