我从一个示例WebGL程序开始,该程序在页面上显示了一个多维数据集。示例代码不使用类。
我希望能够绘制多个可以独立移动的立方体。因此,我添加了一个“多维数据集”类。此类的每个实例都使用其自己的“程序”。我创建了两个对象,但只绘制了第一个对象。不幸的是,显示了后来实例化的对象。例如。在“ ground”下面的代码中显示,而不是“ cube1”。
代码的相关部分在下面。您能看到任何问题吗?我该如何解决?
...
////
class Cube {
constructor(gl, color) {
this.gl = gl;
this.program = initShaders(gl, "vertex-shader", "fragment-shader");
//// Model buffers and attributes
[this.pointsArray, this.colorsArray] = cubePointsAndColors(color);
this.numVertices = 36;
this.initAttributeBuffers();
//// Camera Related Uniforms Matrices
this.modelViewMatrixLoc = gl.getUniformLocation(
this.program,
"modelViewMatrix"
);
this.projectionMatrixLoc = gl.getUniformLocation(
this.program,
"projectionMatrix"
);
}
draw() {
this.gl.drawArrays(this.gl.TRIANGLES, 0, this.numVertices);
}
initAttributeBuffers() {
// arrange cube color data stuff
var cBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, cBuffer);
this.gl.bufferData(
this.gl.ARRAY_BUFFER,
flatten(this.colorsArray),
this.gl.STATIC_DRAW
);
var vColor = this.gl.getAttribLocation(this.program, "vColor");
this.gl.vertexAttribPointer(vColor, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(vColor);
// arrange cube vertex data stuff
var vBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vBuffer);
this.gl.bufferData(
this.gl.ARRAY_BUFFER,
flatten(this.pointsArray),
this.gl.STATIC_DRAW
);
var vPosition = this.gl.getAttribLocation(this.program, "vPosition");
this.gl.vertexAttribPointer(vPosition, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(vPosition);
}
}
window.onload = function init() {
//// initialize WebGl System
const canvas = document.getElementById("gl-canvas");
const gl = WebGLUtils.setupWebGL(canvas);
if (!gl) {
alert("WebGL isn't available");
}
gl.viewport(0, 0, canvas.width, canvas.height);
aspect = canvas.width / canvas.height;
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.enable(gl.DEPTH_TEST);
//// Initialize game objects
var cube1 = new Cube(gl, vec4(1.0, 0.0, 0.0, 1.0));
var ground = new Cube(gl, vec4(0.0, 1.0, 0.0, 1.0));
let gameObjects = [cube1];
// sliders for viewing parameters
readGUI();
render(gl, gameObjects);
};
////
var render = function(gl, gameObjects) {
//// clear the background
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//// camera settings
eye = vec3(
radius * Math.sin(theta) * Math.cos(phi),
radius * Math.sin(theta) * Math.sin(phi),
radius * Math.cos(theta)
);
modelViewMatrix = lookAt(eye, at, up);
projectionMatrix = perspective(fovy, aspect, near, far);
//// draw all objects
for (let objectI = 0; objectI < gameObjects.length; objectI++) {
const gameObject = gameObjects[objectI];
gl.useProgram(gameObject.program);
gl.uniformMatrix4fv(
gameObject.modelViewMatrixLoc,
false,
flatten(modelViewMatrix)
);
gl.uniformMatrix4fv(
gameObject.projectionMatrixLoc,
false,
flatten(projectionMatrix)
);
gameObject.draw();
}
requestAnimFrame(() => render(gl, gameObjects));
};
...
答案 0 :(得分:1)
在WebGL 1.0 drawArrays
中,使用当前由vertexAttribPointer
指定并由enableVertexAttribArray
启用的顶点。
使用属性存储缓冲区对象(this.cBuffer
,this.vBuffer
)和属性索引(this.vColor
,this.vPosition
):
initAttributeBuffers() {
// arrange cube color data stuff
this.cBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.cBuffer);
this.gl.bufferData(
this.gl.ARRAY_BUFFER,
flatten(this.colorsArray),
this.gl.STATIC_DRAW
);
this.vColor = this.gl.getAttribLocation(this.program, "vColor");
// arrange cube vertex data stuff
this.vBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vBuffer);
this.gl.bufferData(
this.gl.ARRAY_BUFFER,
flatten(this.pointsArray),
this.gl.STATIC_DRAW
);
this.vPosition = this.gl.getAttribLocation(this.program, "vPosition");
}
在绘制调用之前指定并启用通用顶点属性数据的数组:
draw() {
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.cBuffer);
this.gl.vertexAttribPointer(this.vColor, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.vColor);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vBuffer);
this.gl.vertexAttribPointer(this.vPosition, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(this.vPosition);
this.gl.drawArrays(this.gl.TRIANGLES, 0, this.numVertices);
}
在WebGL 2.0中(或通过使用扩展名OES_vertex_array_object),可以通过使用 WebGLVertexArrayObject s来简化。
顶点规范在顶点数组对象中声明:
initAttributeBuffers() {
// create vertex array object
this.vao = this.gl.createVertexArray();
this.gl.bindVertexArray(this.vao);
// arrange cube color data stuff
var cBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, cBuffer);
this.gl.bufferData(
this.gl.ARRAY_BUFFER,
flatten(this.colorsArray),
this.gl.STATIC_DRAW
);
var vColor = this.gl.getAttribLocation(this.program, "vColor");
this.gl.vertexAttribPointer(vColor, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(vColor);
// arrange cube vertex data stuff
var vBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vBuffer);
this.gl.bufferData(
this.gl.ARRAY_BUFFER,
flatten(this.pointsArray),
this.gl.STATIC_DRAW
);
var vPosition = this.gl.getAttribLocation(this.program, "vPosition");
this.gl.vertexAttribPointer(vPosition, 4, this.gl.FLOAT, false, 0, 0);
this.gl.enableVertexAttribArray(vPosition);
}
在绘制调用之前绑定顶点数组就足够了:
draw() {
this.gl.bindVertexArray(this.vao);
this.gl.drawArrays(this.gl.TRIANGLES, 0, this.numVertices);
}