dkellycollins
dkellycollins

Reputation: 497

What is the purpose of vertexAttribPointer?

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;
}

Upvotes: 10

Views: 9982

Answers (2)

ratchet freak
ratchet freak

Reputation: 48216

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.

Upvotes: 16

Arthur Visser
Arthur Visser

Reputation: 51

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.

Upvotes: 2

Related Questions