WebGL 绘制多个对象
WebGL draw multiple objects
我正在研究 WebGL,我做了一些 classes 来简化渲染。问题是,只有第一个 class 可以呈现,而所有其他 class 都不会呈现。我查找了每个数组缓冲区并在需要时绑定和取消绑定它们,但它仍然不起作用。这是我的 class 的 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 的 classes:
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
我有两个 classes 并且它们都使用相同的指针,这不应该发生, 什么会导致这种情况?
根据我对 OpenGL 的理解,每个缓冲区等在绘制三角形后都会被停用。导致只绘制第一个 class 的错误在哪里?
这个
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();
...
}
}
你实际上并不需要任何解除绑定的东西顺便说一句
你可以认为绑定类似于设置全局变量。
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'));
注意我没有解绑任何东西。我只是 绑定 下一个功能所需的东西到 运行。尽管在 WebGL 中是相同的 the state is more complicated
我正在研究 WebGL,我做了一些 classes 来简化渲染。问题是,只有第一个 class 可以呈现,而所有其他 class 都不会呈现。我查找了每个数组缓冲区并在需要时绑定和取消绑定它们,但它仍然不起作用。这是我的 class 的 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 的 classes:
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
我有两个 classes 并且它们都使用相同的指针,这不应该发生, 什么会导致这种情况?
根据我对 OpenGL 的理解,每个缓冲区等在绘制三角形后都会被停用。导致只绘制第一个 class 的错误在哪里?
这个
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();
...
}
}
你实际上并不需要任何解除绑定的东西顺便说一句
你可以认为绑定类似于设置全局变量。
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'));
注意我没有解绑任何东西。我只是 绑定 下一个功能所需的东西到 运行。尽管在 WebGL 中是相同的 the state is more complicated