WebGL编程笔记1

    1
    <canvas id="myCanvas" width="600" height="300" style="border: 1px solid red"></canvas>

      

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    function createProgram(webgl, vertex, fragment) {
        // 创建程序
        let shader_vertex = webgl.createShader(webgl.VERTEX_SHADER);
        let shader_fragment = webgl.createShader(webgl.FRAGMENT_SHADER);
        webgl.shaderSource(shader_vertex, vertex);
        webgl.shaderSource(shader_fragment, fragment);
        // 编译源码
        webgl.compileShader(shader_vertex);
        webgl.compileShader(shader_fragment);
        if (webgl.getShaderParameter(shader_vertex, webgl.COMPILE_STATUS) === false) {
            console.error('Compile Shader Error: shader_vertex,' + webgl.getShaderInfoLog(shader_vertex));
        }
        if (webgl.getShaderParameter(shader_fragment, webgl.COMPILE_STATUS) === false) {
            console.error('Compile Shader Error: shader_fragment,' + webgl.getShaderInfoLog(shader_fragment));
        }
        // 创建执行程序
        let program = webgl.createProgram();
        webgl.attachShader(program, shader_vertex);
        webgl.attachShader(program, shader_fragment);
     
        // 连接context和program
        webgl.linkProgram(program);
        if(webgl.getProgramParameter(program, webgl.LINK_STATUS) === false) {
            console.error(webgl.getProgramInfoLog(program));
        }
        webgl.useProgram(program);
        return program;
    }
    function bindBufferWidthData(webgl, target, data) {
        let buffer = webgl.createBuffer();
        webgl.bindBuffer(target, buffer);
        webgl.bufferData(target, data, webgl.STATIC_DRAW);  // 内存数据传入显存
    }
    function bindVertexAttributePointer(webgl, program, varName, varSize, varType, normalized, stride, offset) {
        var pointer = webgl.getAttribLocation(program, varName);
        webgl.vertexAttribPointer(pointer, varSize, varType, normalized, stride, offset);
        webgl.enableVertexAttribArray(pointer);
        return pointer;
    }
     
    const vertex = `
        precision lowp float;
        attribute vec3 vertexPosition;
        attribute vec4 inColor;
        varying   vec4 outcolor;
        void main(void) {
            outcolor = inColor;
            gl_Position = vec4(vertexPosition, 1.0);
        }
    `;
    const fragment = `
        precision lowp float;
        varying   vec4 outcolor;
        void main(void) {       
            gl_FragColor = vec4(outcolor);
        }
    `;
     
    let canvas = document.getElementById('myCanvas');
    let webgl = canvas.getContext('webgl');
    const data_position = new Float32Array([
       // x       y      z        r       g       b       a
        -0.5,    0.5,    0.0,    0.9,    0.0,    0.0,    1.0,
        +0.5,    0.5,    0.0,    0.0,    0.8,    0.0,    1.0,
        +0.5,   -0.5,    0.0,    0.0,    0.0,    1.0,    1.0,
        -0.5,   -0.5,    0.0,    1.0,    1.0,    1.0,    1.0
    ]);
    const data_index = new Uint16Array([
        0, 1, 2,
        0, 2, 3
    ]);
    const FSIZE = data_position.BYTES_PER_ELEMENT;
     
    webgl.clearColor(0, 1, 0, 1);
    webgl.clear(webgl.COLOR_BUFFER_BIT);
     
    // 第一步:编译Shader程序,并创建program
    let program = createProgram(webgl, vertex, fragment);
     
    // 第二步:创建数据缓冲区和索引缓冲区
    let buffer_position = bindBufferWidthData(webgl, webgl.ARRAY_BUFFER, data_position);    // 将顶点数据写入数据缓冲区并启用
    let buffer_index = bindBufferWidthData(webgl, webgl.ELEMENT_ARRAY_BUFFER, data_index);  // 将索引数据写入冲区并启用
     
    // 第三步: 未Shader中的输入变量定义指针的,并分配取数位置
    let vertexPosition = bindVertexAttributePointer(webgl, program, "vertexPosition", 3, webgl.FLOAT, false, FSIZE * 7, 0); // 每次从buffer中取28个字节,从这一段字节中的offset=0字节开始取3个浮点数
    let inColor = bindVertexAttributePointer(webgl, program, "inColor", 4, webgl.FLOAT, false, FSIZE * 7, FSIZE * 3);       // 每次从buffer中取28个字节,从这一段字节中的offset=12字节开始取4个浮点数作为inColor
     
    // 开始绘制
    webgl.drawElements(webgl.TRIANGLES, 6, webgl.UNSIGNED_SHORT, 0);
     
     
    // 定义从buffer中取得次数,3次,从0开始
    // webgl.drawArrays(webgl.TRIANGLES, 0, 3);
    // draw函数中的count参数指的是从buffer中取几次数据
    // drawArrays直接从数据缓冲区中取数据,每次取多少字节,多少偏移由vertexAttribPointer函数决定
    // drawElements先从索引缓冲区中取出索引index,然后从数据缓冲区对应的index中取数据,每次取多少字节,多少偏移由vertexAttribPointer函数决定

      

    posted @   Rain Man  阅读(446)  评论(0编辑  收藏  举报
    编辑推荐:
    · 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
    · .NET Core 中如何实现缓存的预热?
    · 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
    · AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
    · 基于Microsoft.Extensions.AI核心库实现RAG应用
    阅读排行:
    · 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
    · 地球OL攻略 —— 某应届生求职总结
    · 提示词工程——AI应用必不可少的技术
    · Open-Sora 2.0 重磅开源!
    · 字符编码:从基础到乱码解决
    点击右上角即可分享
    微信分享提示