最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - What is the purpose of vertexAttribPointer? - Stack Overflow

programmeradmin3浏览0评论

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

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;
}
Share Improve this question edited Oct 31, 2014 at 15:39 genpfault 52.1k12 gold badges91 silver badges148 bronze badges asked Oct 31, 2014 at 15:02 dkellycollinsdkellycollins 4976 silver badges17 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 16

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.

发布评论

评论列表(0)

  1. 暂无评论