vertexAttribPointer的目的是什么?

时间:2014-10-31 15:02:17

标签: javascript opengl-es typescript webgl

我正在使用javascript和webgl编写游戏引擎。为了测试它,我编写了一个绘制立方体的程序。要使这个程序工作,我必须在调用绑定缓冲区之后但在调用绘制三角形之前调用vertexAttribPointer。我想知道这个方法究竟是做了什么以及为什么我必须按此顺序调用这些方法?

我最好的猜测是它初始化了属性,但我不明白为什么必须在客户端调用它,如果是这种情况。

我在下面列出了一些来源。一切都是用打字稿写的。有关完整来源,请参阅github.com/dkellycollins/nemesis

设置着色器:

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

渲染立方体:

public render():void {
    gl.drawElements(gl.TRIANGLES, this._triangles, gl.UNSIGNED_SHORT, 0);
}

顶点着色器源:

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

2 个答案:

答案 0 :(得分:8)

它告诉WebgL如何解释数据:

gl.vertexAttribPointer(attrib, index, gl.FLOAT, false, stride, offset);

这意味着:对于属性attribindex类型的gl.FLOATnot成分从offset开始stride归一化,gl.ARRAY_BUFFER分开在当前绑定的{{1}}。

客户可以随意设置数据,只要它们可以如上所述。

答案 1 :(得分:1)

根据this WebGl2 Fundamentals tutorial,这是指定如何提取数据所必需的。还有:

<块引用>

gl.vertexAttribPointer 的一个隐藏部分是它将当前 ARRAY_BUFFER 绑定到属性。换句话说,现在这个属性绑定到 positionBuffer。这意味着我们可以自由地将其他内容绑定到 ARRAY_BUFFER 绑定点。该属性将继续使用 positionBuffer。