Reputation: 125
I have to draw multiple shapes in a simple WebGL program and there occurs a problem which seems unplausible for me. If I try to draw only a single shape, everything works fine.
In the "main" function I create the following instances and render them
_coneInstance = new Cone();
_coneInstance.initCone();
_cylinderInstance = new Cylinder();
_cylinderInstance.initCylinder();
_sphereInstance = new Sphere();
_sphereInstance.initSphere();
renderAll();
This leads to the problem, that all three objets looks like shapes
In renderAll() the render function of each object is called - these functions are shown below.
This looks like, that all vertices from the cone and the cylinder are overwritten by the sphere. Since each object drawn separately is correctly working, I will not post the vertex-building process.
function Cone()
{
...
this.vertexBuffer = 0;
this.initCone = function()
{
this.generateCone();
this.initBuffers();
}
this.generateCone = function()
{
...
}
this.initBuffers = function()
{
this.vertexBuffer = gl.createBuffer();
this.bind();
gl.bufferData(gl.ARRAY_BUFFER, flatten(this.triangleList), gl.STATIC_DRAW);
gl.enableVertexAttribArray(vPosition);
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
this.unbind();
}
this.render = function()
{
this.bind();
gl.drawArrays(gl.TRIANGLE_FAN, 0, this.numTrianglesUpperPart);
gl.drawArrays(gl.TRIANGLE_FAN, this.numTrianglesUpperPart, this.numTrianglesLowerPart);
this.unbind();
}
this.bind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
console.log(gl.isBuffer(this.vertexBuffer ));
}
this.unbind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
}
function Cylinder()
{
...
this.vertexBuffer = 0;
this.initCylinder = function()
{
this.generateCylinder();
this.initCylinderBuffers();
}
this.generateCylinder = function()
{
...
}
this.initCylinderBuffers = function()
{
this.vertexBuffer = gl.createBuffer();
this.bind();
gl.bufferData(gl.ARRAY_BUFFER, flatten(this.cylinderVertexList), gl.STATIC_DRAW);
gl.enableVertexAttribArray(vPosition);
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
this.unbind();
}
this.render = function()
{
this.bind();
gl.drawArrays(gl.TRIANGLE_FAN, 0, this.cylinderNumTrianglesUpperPart);
gl.drawArrays(gl.TRIANGLE_FAN, this.cylinderNumTrianglesUpperPart, this.cylinderNumTrianglesLowerPart);
gl.drawArrays(gl.TRIANGLES, this.cylinderNumTrianglesUpperPart+this.cylinderNumTrianglesLowerPart, this.cylinderNumTrianglesMiddlePart);
this.unbind();
}
this.bind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
console.log(gl.isBuffer(this.vertexBuffer ));
}
this.unbind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
}
function Sphere()
{
...
this.vertexBuffer = 0;
this.initSphere = function()
{
this.generateSphere();
this.initSphereBuffers();
}
this.generateSphere = function()
{
...
}
this.initSphereBuffers = function()
{
this.vertexBuffer = gl.createBuffer();
this.bind();
gl.bufferData(gl.ARRAY_BUFFER, flatten(this.unindexedVertices), gl.STATIC_DRAW);
gl.enableVertexAttribArray(vPosition);
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
this.unbind();
}
this.render = function()
{
this.bind();
gl.drawArrays(gl.TRIANGLES, 0, this.numTriangles);
this.unbind();
}
this.bind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
console.log(gl.isBuffer(this.vertexBuffer ));
}
this.unbind = function()
{
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
}
Upvotes: 0
Views: 410
Reputation: 8153
You have to update the attribute pointers to the buffer every time.
When binding a vertex attribute pointer you're setting a global pointer to the buffer currently bound. Having a bound buffer is a prerequisite for that, but it does not store any state in regards to vertex attribute pointers. So you have to either move the pointer setup into your render method or use the OES_vertex_array_object extension.
Your initBuffers
functions need to be split
This part is "initing" a buffer and only needs to happen at init time
this.vertexBuffer = gl.createBuffer();
this.bind();
gl.bufferData(gl.ARRAY_BUFFER, flatten(this.unindexedVertices), gl.STATIC_DRAW);
This part needs to happen every time before you render
this.bind();
gl.enableVertexAttribArray(vPosition);
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
Upvotes: 1