Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 290
dkellycollins Avatar asked Oct 31 '14 15:10

dkellycollins


2 Answers

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.

like image 173
ratchet freak Avatar answered Oct 15 '22 15:10

ratchet freak


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.

like image 45
Arthur Visser Avatar answered Oct 15 '22 16:10

Arthur Visser