I am writing a game engine using javascript and webgl. To test it out I have written a program that draws a cube. For this program to work vertexAttribPointer must be called after I have called bind buffers but before I call draw triangles. I was wondering what exactly this method did and why I have to call these methods in this order?
My best guess is that it initializes the attribute but I don't understand why it must be called on the client side if that is the case.
I have include some of the source below. Everything is written in typescript. For the full source see github.com/dkellycollins/nemesis
Setting up the shader:
var cubeShader = new shaderProgram();
cubeShader.addShader(shaders.colorVertexShader);
cubeShader.addShader(shaders.colorFragmentShader);
cubeShader.init();
cubeShader.enableAttrib("position", 3, 4 * (3 + 3), 0);
cubeShader.enableAttrib("color", 3, 4 * (3 + 3), 3 * 4);
ShaderProgram:
class shaderProgram {
constructor() {
this.Id = gl.createProgram();
}
public Id;
public addShader(shader:WebGLShader[]):void {
if(shader instanceof Array) {
shader.forEach(s => {
gl.attachShader(this.Id, s);
});
} else {
gl.attachShader(this.Id, shader);
}
}
public init():void {
gl.linkProgram(this.Id);
}
public setActive() {
gl.useProgram(this.Id);
}
public enableAttrib(attribName: string, index: number, stride:number, offset: number) {
var attrib = gl.getAttribLocation(this.Id, attribName);
gl.enableVertexAttribArray(attrib);
gl.vertexAttribPointer(attrib, index, gl.FLOAT, false, stride, offset);
}
public setFloatAttrib(attribName:string, value:number) {
var attrib = gl.getAttribLocation(this.Id, attribName);
gl.vertexAttrib1f(attrib, value);
}
public setMatrix(uniName: string, value: number[]) {
var uniform = gl.getUniformLocation(this.Id, uniName);
gl.uniformMatrix4fv(uniform, false, value);
}
}
Rendering the cube:
public render():void {
gl.drawElements(gl.TRIANGLES, this._triangles, gl.UNSIGNED_SHORT, 0);
}
Vertex shader source:
attribute vec3 position; //the position of the point
uniform mat4 Pmatrix;
uniform mat4 Vmatrix;
uniform mat4 Mmatrix;
attribute vec3 color; //the color of the point
varying vec3 vColor;
void main(void) { //pre-built function
gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(position, 1.); //0. is the z, and 1 is w
vColor=color;
}
it tells WebgL how to interpret the data:
gl.vertexAttribPointer(attrib, index, gl.FLOAT, false, stride, offset);
this means: for attribute attrib
there are index
components of type gl.FLOAT
that are not
normalized starting at offset
and stride
apart in the gl.ARRAY_BUFFER
bound at the time of this call.
The client is free to set its data anyway it wishes as long as they can be described as above.
According to this WebGl2 Fundamentals tutorial this is necessary to specify how to pull the data out. Also:
A hidden part of gl.vertexAttribPointer is that it binds the current ARRAY_BUFFER to the attribute. In other words now this attribute is bound to positionBuffer. That means we're free to bind something else to the ARRAY_BUFFER bind point. The attribute will continue to use positionBuffer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With