WebGL绘制多个对象

问题描述 投票:2回答:1

我正在使用WebGL,并且我制作了一些类来简化渲染。问题在于,只有第一类可以渲染,而所有其他类都不能渲染。我寻找每个数组缓冲区,并在需要时绑定和取消绑定它们,但是仍然无法正常工作。这是我的triangleElementCluster类:

function TriangleElementCluster(vertices, uvs, normals, indices, indicesLenght, shader, gl) {
  shader.use();

  var verticesBuffer = new ArrayBufferFloat(vertices, gl);
  var verticesAttribLocation = new VertexAttribPointerFloat(shader.getProgram(), "vertex", 3, 3, 0, gl);

  var uvsBuffer = new ArrayBufferFloat(uvs, gl);
  var uvsAttribLocation = new VertexAttribPointerFloat(shader.getProgram(), "uv", 2, 2, 0, gl);

  var normalsBuffer = new ArrayBufferFloat(normals, gl);
  var normalsAttribLocation = new VertexAttribPointerFloat(shader.getProgram(), "normal", 3, 3, 0, gl);

  var indicesBuffer = new ElementArrayBuffer16(indices, gl);

  verticesBuffer.unbind();
  verticesAttribLocation.unbind();
  uvsBuffer.unbind();
  uvsAttribLocation.unbind();
  normalsBuffer.unbind();
  normalsAttribLocation.unbind();
  indicesBuffer.unbind();




  this.setTexture = function(texture) {
    this.texture = texture;
  }

  this.render = function() {
    verticesBuffer.bind();
    verticesAttribLocation.bind();
    uvsBuffer.bind();
    uvsAttribLocation.bind();
    normalsBuffer.bind();
    normalsAttribLocation.bind();

    indicesBuffer.bind();

    this.texture.activate(gl.TEXTURE0);

    gl.drawElements(gl.TRIANGLES, indicesLenght, gl.UNSIGNED_SHORT, 0);

    verticesBuffer.unbind();
    verticesAttribLocation.unbind();
    uvsBuffer.unbind();
    uvsAttribLocation.unbind();
    normalsBuffer.unbind();
    normalsAttribLocation.unbind();
    indicesBuffer.unbind();
  }
}

这些是ArrayBuffers和VertexAttribPoints的类:

function ArrayBufferFloat(array, gl) {
    this.arrayBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, this.arrayBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(array), gl.STATIC_DRAW);

    this.unbind = function() {
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
    }

    this.bind = function() {
        gl.bindBuffer(gl.ARRAY_BUFFER, this.arrayBuffer);
    }
}

function VertexAttribPointerFloat(shaderProgram, shaderVariableName, elementLenght, stepSize, offset, gl) {
    var attribLocation = gl.getAttribLocation(shaderProgram, shaderVariableName);
    gl.vertexAttribPointer(attribLocation, elementLenght, gl.FLOAT, gl.FALSE, stepSize * Float32Array.BYTES_PER_ELEMENT, offset);
    gl.enableVertexAttribArray(attribLocation);

    console.log(attribLocation);

    this.bind = function() {
        gl.enableVertexAttribArray(attribLocation);
    }

    this.unbind = function() {
        gl.disableVertexAttribArray(attribLocation);
    }
}

[您可能已经注意到我打印了VertexAttribPointer的ID并得到:2 0 1 2 0 1我有两个类,并且两个类都使用相同的指针,这不应该发生,这可能导致什么?

根据我对OpenGL的理解,绘制了三角形后,每个缓冲区等都被停用。仅导致绘制第一类的错误在哪里?

javascript webgl
1个回答
2
投票

function VertexAttribPointerFloat(shaderProgram, shaderVariableName, elementLenght, stepSize, offset, gl) {
    var attribLocation = gl.getAttribLocation(shaderProgram, shaderVariableName);
    gl.vertexAttribPointer(attribLocation, elementLenght, gl.FLOAT, gl.FALSE, stepSize * Float32Array.BYTES_PER_ELEMENT, offset);
    gl.enableVertexAttribArray(attribLocation);

    console.log(attribLocation);

    this.bind = function() {
        gl.enableVertexAttribArray(attribLocation);
    }

    this.unbind = function() {
        gl.disableVertexAttribArray(attribLocation);
    }
}

需要这个

function VertexAttribPointerFloat(shaderProgram, shaderVariableName, elementLenght, stepSize, offset, gl) {
    var attribLocation = gl.getAttribLocation(shaderProgram, shaderVariableName);

    this.bind = function() {
        gl.enableVertexAttribArray(attribLocation);
        gl.vertexAttribPointer(attribLocation, elementLenght, gl.FLOAT, gl.FALSE, stepSize * Float32Array.BYTES_PER_ELEMENT, offset);
    }

    this.unbind = function() {
        gl.disableVertexAttribArray(attribLocation);
    }
}

并且您的程序用法需要移动到呈现状态

function TriangleElementCluster(vertices, uvs, normals, indices, indicesLenght, shader, gl) {


  this.render = function() {
    shader.use();
    ...

  }
}

您实际上并不需要任何解除绑定的BTW

您可以认为bind与设置全局变量相似。

const state = {
 temp1: 0,
 temp2: 0,
 temp3: 0,
 result: 0,
};

function add() { state.result = state.temp1 + state.temp2; }
function sub() { state.result = state.temp1 - state.temp2; }
function sum() { state.result = state.temp1 + state.temp2 + state.temp3; }

function bind(id, value) { state[id] = value; }
function get(id)         { return state[id]; }

bind('temp1', 1);
bind('temp2', 2);
bind('temp3', 3);
sum();
console.log('sum:', get('result'));
bind('temp1', 4);
bind('temp2', 5);
add();
console.log('add:', get('result'));

注意,我没有解除绑定。我只是bind运行下一个功能所需的东西。在WebGL中是相同的,尽管the state is more complicated

© www.soinside.com 2019 - 2024. All rights reserved.