webgl之helloworld

从今天开始,正式进入webgl的世界,正式由一个写C++,C#,java的码农转变成写前端的码农。还是有那么一点点兴奋。

这是webgl的第一篇博客,主要通过webgl绘制一个三角形。

调用流程:

1获取webgl上下文
2获取着色器字符串
3创建,加载,编译着色器
4

给着色器的变量赋值

5绘制图形

 

效果图:

 详细步骤:

步骤一:获取webgl上下文,并告诉webgl作用的空间大小,设置画布的默认值为黑色

        // 获取WebGL上下文
        var canvas = document.getElementById("canvas");
        var gl = canvas.getContext("webgl");
        if (!gl) {
            return;
        }

        // 告诉WebGL怎样把提供的gl_Position裁剪空间坐标对应到画布像素坐标(屏幕空间)
        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

        // 清空画布
        gl.clearColor(0, 0, 0, 1);
        gl.clear(gl.COLOR_BUFFER_BIT);

步骤二:获取着色器字符串,这里主要分为两个阶段,第一个阶段,定义着色器,第二个阶段 获取着色器字符串

着色器需要定义定点着色器和片元着色器

定点着色器定义如下:主要实现对坐标点位置的设置

<script id="2d-vertex-shader" type="notjs">

    // 一个属性值,将会从缓冲中获取数据
    attribute vec4 a_position;
  
    // 所有着色器都有一个main方法
    void main() {
  
      // gl_Position 是一个顶点着色器主要设置的变量
      gl_Position = a_position;
    }
  </script>

 片元着色器定义如下,主要设置渲染的颜色

  <script id="2d-fragment-shader" type="notjs">

    // 片断着色器没有默认精度,所以我们需要设置一个精度
    // mediump是一个不错的默认值,代表“medium precision”(中等精度)
    precision mediump float;
    
    void main() {
        // gl_FragColor是一个片断着色器主要设置的变量
        gl_FragColor = vec4(1, 0, 0.5, 1); // 返回“瑞迪施紫色”
    }
  </script>

 最后在js代码里面,获取着色器字符串

        // 获取着色器字符串
        var vertexShaderSource = document.getElementById("2d-vertex-shader").text;
        var fragmentShaderSource = document.getElementById("2d-fragment-shader").text;

 步骤三:创建程序,加载,编译,连接着色器

创建一个着色器的公共函数:

    function createShader(gl, type, source) {
        var shader = gl.createShader(type);// 创建着色器对象
        gl.shaderSource(shader, source);// 提供数据源
        gl.compileShader(shader);// 编译 -> 生成着色器
        var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
        if (success) {
            return shader;
        }

        console.log(gl.getShaderInfoLog(shader));
        gl.deleteShader(shader);
    }

创建定点着色器和片元着色器

        // 创建,加载,编译着色器
        var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
        var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);

 

把定点着色器和片元着色器link到着色程序,这里写成一个公共函数

        // 然后我们将这两个着色器 link(链接)到一个 program(着色程序)
        function createProgram(gl, vertexShader, fragmentShader) {
        var program = gl.createProgram();//创建着色程序
        gl.attachShader(program, vertexShader);// 附加顶点着色器
        gl.attachShader(program, fragmentShader);// 附加片元着色器
        gl.linkProgram(program);//链接到着色程序
        var success = gl.getProgramParameter(program, gl.LINK_STATUS);//判断着色程序是否创建成功
        if (success) {
            return program;
        }

        console.log(gl.getProgramInfoLog(program));
        gl.deleteProgram(program);
    }

在js代码中,链接到着色程序以及告诉webgl使用这个着色程序

        // 链接连个着色器到着色程序
        var program = createProgram(gl, vertexShader, fragmentShader);

        // 告诉它用我们之前写好的着色程序(一个着色器对)
        gl.useProgram(program);

 

第四步:给着色器的变量赋值,这里主要是给定点变量赋值

下面代码功能为:获取变量a_position,定义一个数组,有3个点,再把数据放置到webgl的缓冲区,通过函数vertexAttribPointer告诉程序如何从缓冲区获取数据。最后启用属性

        // 从刚才创建的GLSL着色程序中找到a_position属性值所在的位置
        var positionAttributeLocation = gl.getAttribLocation(program, "a_position");


        // 三个二维点坐标
        var positions = new Float32Array(
            [0, 0, 
            0, 0.5,
            0.7, 0,]
        );

        // 属性值从缓冲中获取数据,所以我们创建一个缓冲
        var positionBuffer = gl.createBuffer();

        // 绑定位置信息缓冲(下面的绑定点就是ARRAY_BUFFER)
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
       
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);


        // 告诉属性怎么从positionBuffer中读取数据 (ARRAY_BUFFER)
        var size = 2;          // 每次迭代运行提取两个单位数据
        var type = gl.FLOAT;   // 每个单位的数据类型是32位浮点型
        var normalize = false; // 不需要归一化数据
        var stride = positions.BYTES_PER_ELEMENT*2;        // 0 = 移动单位数量 * 每个单位占用内存(sizeof(type))每次迭代运行运动多少内存到下一个数据开始点
        var offset = 0;        // 从缓冲起始位置开始读取
        gl.vertexAttribPointer(
            positionAttributeLocation, size, type, normalize, stride, offset);

        // 启用对应属性
        gl.enableVertexAttribArray(positionAttributeLocation);

 

第五步:绘制图像,这里绘制一个三角形,一共3个点。

        // 绘制
        var primitiveType = gl.TRIANGLES;
        var offset = 0;
        var count = 3;
        gl.drawArrays(primitiveType, offset, count);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值