WebGL使用36个索引绘制一个立方体

时间:2019-02-24 19:07:48

标签: webgl

我正在尝试使用在three.js cube中使用的相同的indicesvertices来绘制BoxGeometry。我感觉顶点很好,但是以某种方式获得索引后,我就无法使其正常工作。

指数

[0,2,1,2,3,1,4,6,5,6,7,5,8,10,9,10,11,9,12,14,13,14,15,13,16,18,17,18,19,17,20,22,21,22,23,21] 

顶点

[
    0.5,0.5,0.5,
    0.5,0.5,-0.5,
    0.5,-0.5,0.5,
    0.5,-0.5,-0.5,
    -0.5,0.5,-0.5,
    -0.5,0.5,0.5,
    -0.5,-0.5,-0.5,
    -0.5,-0.5,0.5,
    -0.5,0.5,-0.5,
    0.5,0.5,-0.5,
    -0.5,0.5,0.5,
    0.5,0.5,0.5,
    -0.5,-0.5,0.5,
    0.5,-0.5,0.5,
    -0.5,-0.5,-0.5,
    0.5,-0.5,-0.5,
    -0.5,0.5,0.5,
    0.5,0.5,0.5,
    -0.5,-0.5,0.5,
    0.5,-0.5,0.5,
    0.5,0.5,-0.5,
    -0.5,0.5,-0.5,
    0.5,-0.5,-0.5,
    -0.5,-0.5,-0.5
] 

这是代码

let canvas = document.querySelector("canvas");
let gl = canvas.getContext("webgl");

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

const vsSource = `
    attribute vec4 position;
    uniform mat4 modelViewMatrix;
    varying vec4 vColor;
    void main(void) {
      gl_Position = position;
    }
  `;

const fsSource = `  
    precision mediump float;
    varying vec4 vColor;
    void main(void) {
      gl_FragColor = vec4(1.0,0.0,1.0,1.0);
    }
  `;

// Shader setup

let vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);

if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
    var log = gl.getShaderInfoLog(vertexShader);
    throw "Shader compilation failed\n\n" + log + "\n\n";
}

var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);

if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
    var log = gl.getShaderInfoLog(fragmentShader);
    throw "Shader compilation failed\n\n" + log + "\n\n";
}

let program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);

gl.linkProgram(program);
gl.validateProgram(program);

if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    var log = gl.getProgramInfoLog(program);
    throw "Program link failed\n\n" + log;
}

gl.useProgram(program);

let modelViewMatrix = gl.getUniformLocation(program, "modelViewMatrix");

let model = mat4.create();

gl.uniformMatrix4fv(modelViewMatrix, false, model);

var vertices = new Float32Array([
    0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    -0.5,
    0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    -0.5,
    -0.5,
    0.5,
    -0.5,
    0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    0.5,
    -0.5,
    0.5,
    0.5,
    0.5,
    -0.5,
    -0.5,
    0.5,
    -0.5,
    0.5,
    -0.5,
    -0.5,
    -0.5,
    -0.5,
    -0.5
]);

var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

let position = gl.getAttribLocation(program, "position");

gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(position);

var indices = new Uint16Array([
    0,
    2,
    1,
    2,
    3,
    1,
    4,
    6,
    5,
    6,
    7,
    5,
    8,
    10,
    9,
    10,
    11,
    9,
    12,
    14,
    13,
    14,
    15,
    13,
    16,
    18,
    17,
    18,
    19,
    17,
    20,
    22,
    21,
    22,
    23,
    21
]);

var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);
<canvas></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>

1 个答案:

答案 0 :(得分:2)

对于索引缓冲区,您使用了数组数据类型Uint16Array

  

var index = new Uint16Array([...]);

因此您必须对数据类型参数使用枚举常量gl.UNSIGNED_SHORT而不是gl.UNSIGNED_BYTE

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);

由于最大索引小于256,因此可以使用数组数据类型Uint8Array而不是Uint16Array,但请保持枚举数为常量gl.UNSIGNED_BYTE

var indices = new Uint8Array([...]);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);