2013-06-27 8 views
5

Ich verwende OpenGL3.2 Core Profile unter OSX. Und ich möchte instanced Zeichnung (glDrawArraysInstanced), wo ich eine Matrix für jede Instanz übergeben.Verwenden einer Matrix als Vertex-Attribut in OpenGL3-Core-Profil

Mein Vertex-Shader baut gerade fein:

#version 150 
in mediump vec4 position; 
in mediump mat4 trf; 
in lowp vec4 rgb; 
out lowp vec4 colour; 
uniform highp mat4 modelcamviewprojmat; 
void main() 
{ 
    mediump vec4 tpos = trf * position; 
    gl_Position = modelcamviewprojmat * tpos; 
    colour = rgb; 
} 

Die Bindung von 'trf' ging gut:

glBindAttribLocation(program, ATTRIB_TRF, "trf"); 

Aber wie kann ich meine Daten weitergeben? glVertexAttribPointer kann keine Werte übergeben, die größer als 4 Floats sind. So dieser Aufruf fehlschlägt:

glVertexAttribPointer(ATTRIB_TRF, 16, GL_FLOAT, 0, 16 * sizeof(float), ...); 

Ich vermute, dass ich es mit 4 Anrufen glVertexAttribPointer, jeden 4 Schwimmer ersetzen muß. Aber welchen Wert könnte ich für 'Index' (erster Parm) verwenden? Muss ich stattdessen 4 Vektorattribute verwenden und die vier Vektoren im GLSL-Vertex-Shader zusammenstellen? Wenn ja, welche Art von GLSL-Code erfüllt dies? Oder kann ich den Rückgabewert von BindAttribLocation verwenden und val + 0, val + 1, val + 2 und val + 3 für alle Zeilen verwenden?

Antwort

8

Nach meiner this page und meine aktuelle Implementierung von Hardware-Instancierung in meinem Spiel, ist die richtige Art und Weise es getan ist, dass ein mat4 Attribut 4 Attribut Standorten. Die eine, die Sie binden und die 3 folgenden.

int pos = glGetAttribLocation(shader_instancedarrays.program, "transformmatrix"); 
int pos1 = pos + 0; 
int pos2 = pos + 1; 
int pos3 = pos + 2; 
int pos4 = pos + 3; 
glEnableVertexAttribArray(pos1); 
glEnableVertexAttribArray(pos2); 
glEnableVertexAttribArray(pos3); 
glEnableVertexAttribArray(pos4); 
glBindBuffer(GL_ARRAY_BUFFER, VBO_containing_matrices); 
glVertexAttribPointer(pos1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(0)); 
glVertexAttribPointer(pos2, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 4)); 
glVertexAttribPointer(pos3, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 8)); 
glVertexAttribPointer(pos4, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4 * 4, (void*)(sizeof(float) * 12)); 
glVertexAttribDivisor(pos1, 1); 
glVertexAttribDivisor(pos2, 1); 
glVertexAttribDivisor(pos3, 1); 
glVertexAttribDivisor(pos4, 1); 
+0

Ja, funktioniert für mich. Vielen Dank. – Bram

+0

Ich sah für immer, dass die Lösung für mein Problem nur die fehlenden Aufrufe von glVertexAttribDivisor waren. Ich danke dir sehr! – ThePadawan