2014-10-31 11 views
5

Ich schreibe eine Spielengine mit JavaScript und Webgl. Um es zu testen, habe ich ein Programm geschrieben, das einen Würfel zeichnet. Damit dieses Programm funktioniert, muss vertexAttribPointer aufgerufen werden, nachdem ich Bindungspuffer aufgerufen habe, aber bevor ich Draw-Dreiecke aufruft. Ich habe mich gefragt, was genau diese Methode gemacht hat und warum ich diese Methoden in dieser Reihenfolge aufrufen muss?Was ist der Zweck von VertexAttribPointer?

Meine beste Schätzung ist, dass es das Attribut initialisiert, aber ich verstehe nicht, warum es auf der Client-Seite aufgerufen werden muss, wenn das der Fall ist.

Ich habe einige der folgenden Quellen enthalten. Alles ist in Maschinenschrift geschrieben. sehen für die volle Quelle github.com/dkellycollins/nemesis

Einrichten des 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 Cube:

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

Vertex-Shader-Quelle:

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

Antwort

8

es sagt WebGL, wie die Daten zu interpretieren:

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

bedeutet dies: für das Attribut attrib gibt es index Komponenten des Typs gl.FLOAT die not normalisierte Ausgang bei offset und stride auseinander in den aktuell gebundenen gl.ARRAY_BUFFER sind.

Der Client kann seine Daten beliebig einstellen, solange sie wie oben beschrieben beschrieben werden können.

+0

Also warum muss das für Attribute getan werden? Uniformen müssen das nicht tun. Sollte webgl nicht in der Lage sein, den Index, Offset und Schritt zu ermitteln, nur weil das Attribut ein vec3 ist oder fehlt mir etwas? – dkellycollins

+1

Es wäre nicht in der Lage, Schritt zu verstehen (das hängt ganz davon ab, wie der Programmierer die Daten interleaved, es gibt einen Standard 0 Wert für dicht gepackte), und einige Leute verwenden Halbschwimmer oder ganze Zahlen oder Kurzschlüsse für die Daten (und der Puffer speichert nur eine Sequenz von Bytes ohne Typ Informationen) –

+0

Ich glaube, ich verstehe jetzt. Ich stellte nicht zusammen, dass alle Attribute ihre Daten aus dem Array-Puffer erhalten. Danke für die Hilfe! – dkellycollins