2013-06-27 22 views
5

Używam profilu rdzeniowego OpenGL3.2 na OSX. I chcę wykonać instancyjny rysunek (glDrawArraysInstanced), gdzie przekazuję macierz dla każdej instancji.Używanie macierzy jako atrybutu wierzchołka w profilu OpenGL3 Core

Moja vertex shader buduje dobrze:

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

Wiązanie '' TRF poszło dobrze:

glBindAttribLocation(program, ATTRIB_TRF, "trf"); 

Ale jak mogę przekazać w moich danych? glVertexAttribPointer nie może przekazać wartości większych niż 4 pływaki. Więc ta rozmowa kończy się niepowodzeniem:

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

Podejrzewam, że muszę go zastąpić 4 wywołań glVertexAttribPointer, każdą mijającą 4 pływaków. Ale jakiej wartości mógłbym użyć dla "indeksu" (pierwszy parm)? Czy zamiast tego muszę użyć 4 atrybutów wektorowych i złożyć cztery wektory w module cieniującym GLSL? Jeśli tak, jaki rodzaj kodu GLSL to osiąga? Czy mogę użyć wartości zwracanej z BindAttribLocation i użyć wartości val + 0, val + 1, val + 2 i val + 3 dla wszystkich wierszy?

Odpowiedz

8

Zgodnie z moją aktualną implementacją instancji sprzętowej w mojej grze, prawidłowym sposobem jest to, że atrybut mat4 zajmuje 4 lokalizacje atrybutów. Ten, który powiążesz i 3 następujące.

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

Tak, działa dla mnie. Dzięki. – Bram

+0

Spojrzałem na zawsze, aby znaleźć rozwiązanie mojego problemu tylko brakujące wywołania glVertexAttribDivisor. Dziękuję bardzo! – ThePadawan