WebGL编程笔记1

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

  

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 @ 2020-03-28 08:47  Rain Man  阅读(444)  评论(0编辑  收藏  举报