2014-10-31 30 views
5

Piszę silnik gry przy użyciu javascript i webgl. Aby przetestować to, napisałem program, który rysuje kostkę. Aby ten program działał, vertexAttribPointer musi zostać wywołany po wywołaniu buforów powiązań, ale zanim wezwę trójkąty rysowania. Zastanawiałem się, co dokładnie ta metoda zrobiła i dlaczego muszę nazwać te metody w tej kolejności?Jaki jest cel vertexAttribPointer?

Moje najlepsze przypuszczenie jest takie, że inicjuje atrybut, ale nie rozumiem, dlaczego musi on być wywołany po stronie klienta, jeśli tak jest.

Mam zawierać niektóre źródła poniżej. Wszystko jest napisane maszynowo. Dla pełnego źródła zobaczyć github.com/dkellycollins/nemesis

Konfigurowanie shadera:

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 kostkę:

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

Vertex źródło shader:

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

Odpowiedz

8

mówi WebGL jak interpretować dane:

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

to znaczy: dla atrybutu attrib istnieją index składniki typu gl.FLOAT które są not znormalizowane już od offset i stride siebie w aktualnie związany gl.ARRAY_BUFFER.

Klient może dowolnie konfigurować swoje dane, o ile można je opisać powyżej.

+0

Dlaczego więc należy to zrobić dla atrybutów? Mundury nie muszą tego robić. Czy webgl nie powinien być w stanie określić indeksu, przesunięcia i kroku od faktu, że atrybut jest vec3, czy też czegoś brakuje? – dkellycollins

+1

Nie można określić kroku (zależy to całkowicie od tego, w jaki sposób programista przeplótł dane, istnieje domyślna wartość 0 dla ciasno spakowanych), a niektórzy używają półwipów lub liczb całkowitych lub szortów dla danych (i bufor przechowuje tylko sekwencję bajtów bez informacji o typie) –

+0

Myślę, że teraz rozumiem. Nie składałem, że wszystkie atrybuty pobierają dane z bufora tablicowego. Dziękuję za pomoc! – dkellycollins