glDrawArrays vs glDrawElements

Ok, todavía estoy luchando para que esto funcione. Las partes importantes de mi código son:

def __init__(self, vertices, normals, triangles):
    self.bufferVertices = glGenBuffersARB(1)
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(vertices), ADT.voidDataPointer(vertices), GL_STATIC_DRAW_ARB)
    self.vertices = vertices
    self.bufferNormals = glGenBuffersARB(1)
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(normals), ADT.voidDataPointer(normals), GL_STATIC_DRAW_ARB)
    self.normals = normals
    self.bufferTriangles = glGenBuffersARB(1)

    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)
    glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ADT.arrayByteCount(triangles), ADT.voidDataPointer(triangles), GL_STATIC_DRAW_ARB)

    self.triangles = triangles
    glDisableClientState(GL_VERTEX_ARRAY) **(Not sure if any of the following influence in any way)** 
    glDisableClientState(GL_NORMAL_ARRAY)
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)

No creo que haya nada malo aquí por lo que he leído hasta ahora sobre los VBO. Así que ahora tengo mis búferes de vértices, normales (aún no utilizados) e índices de triángulos. Ahora para el sorteo real:

def draw(self, type):
    glDisableClientState(GL_VERTEX_ARRAY)  
    glDisableClientState(GL_NORMAL_ARRAY)
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)
    **Again above line not sure if they have any use.**        
    glEnableClientState(GL_VERTEX_ARRAY)         
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
    glVertexPointer(3, GL_FLOAT, 0, None)

    glEnableClientState(GL_NORMAL_ARRAY);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
    glNormalPointer(GL_FLOAT, 0, None)

    if type == GL_POINTS:    
        #glDrawArrays( GL_POINTS, 0, len(self.vertices) );    
        glDrawElements(type, len(self.vertices), GL_UNSIGNED_SHORT, 0)
    else:
        #glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)**(If I uncomment this doesnt seem to make any difference?!)**
        #glDrawArrays( GL_TRIANGLES, 0, len(self.triangles) );  
        glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, 0)**(What does it draw now since GL_ELEMENT_ARRAY_BUFFER_ARB is binded to 0 ?!)**

Ahora funciona glDrawArrays. Pero en el caso de que tenga que dibujar mis triángulos, no dibuja los triángulos que he definido en bufferTriangles (esto es normal por lo que he leído ya que drawArrays no usa índices? ¿O me equivoco aquí?). El problema es que si trato de usar glDrawElements, todo falla con:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000003150ebbc
Crashed Thread:  0

Thread 0 Crashed:
0   com.apple.GeForce8xxxGLDriver   0x1a3e7050 gldGetTextureLevel + 743600
1   com.apple.GeForce8xxxGLDriver   0x1a3e7563 gldGetTextureLevel + 744899
2   GLEngine                        0x1a206eee gleDrawArraysOrElements_VBO_Exec + 1950

Ahora, ¿qué me estoy perdiendo aquí? Por lo que puedo entender, ¿probablemente estoy pasando un mal puntero en alguna parte? Tenga en cuenta que incluso si trato de usar glDrawElements (type, 24, GL_UNSIGNED_INT, 0) todavía se bloquea aunque el número de triángulos definidos es mucho más grande, así que no creo que tenga nada que ver con el tamaño.

Regards, Bogdan

EDITAR Ok, ahora he hecho algunas comprobaciones adicionales y aquí está mi situación actual: he cambiado el len (triángulos) a ADT.byteCount, todavía no hay solución. Así que verifiqué todos los datos que estaba obteniendo y es así: la matriz de vértices contiene ~ 60000 * 3 = 180000 entradas de vértices de tipo GL_Float, al igual que la matriz de normales. Como solo hay <62535 vértices, estoy usando un corto sin signo para los triángulos. Entonces tengo len (triángulos) es ~ 135000. También he cambiado los glDrawElements (GL_TRIANGLES, len (self.triangles), GL_UNSIGNED_SHORT, 0) .También he verificado y todos los datos de la matriz de triángulos están entre 0 y 62534, ya que estaba pensando que tal vez algún índice que está fuera de rango se deslizó. ¿Qué más podría estar mal aquí? Ah, y ¿cómo funciona glDrawElements (GL_POINTS, ...)? ¿También necesita algún tipo de índices?

EDIT2 He actualizado el código anterior y, como dije allí, ahora dibujar elementos dibuja mis GL_POINTS, pero no estoy seguro de dónde obtiene los índices. ¿O no son necesarios en caso de GL_POINTS? Y para GL_TRIANGLES, funciona así, con glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles) comentado, pero de nuevo, ¿qué tipo de índices se necesitan ahora que el elemento buffer está vinculado a 0? Y otra cosa es que glDrawElements no dibujará todos los puntos que hace glDrawArrays. Para explicar mejor:

glDrawArrays( GL_POINTS, 0, len(self.vertices) );

Esto dibuja todos mis puntos correctamente:

glDrawElements(type, len(self.vertices), GL_UNSIGNED_SHORT, 0)

Esto parece dibujar muchos menos puntos que glDrawArrays. Ahora lo curioso es que si paso como tamaño algo así como 10 * len (self.vertices) para dibujar elementos, dibujará todos los puntos (algunos tal vez dos veces o más; ¿puedo verificar esto?) Pero ¿no supondría que se bloqueara? @

Saludo

EDIT3

Algunas informaciones más precisas sobre las matrices:

vertices - una serie de carrozas,

len (vértices) = 180000 byteCount (vértices) = 720000

triangles: una matriz de numpy.uint16

len (triángulos) = 353439 byteCount (triángulos) = 706878 min (triángulos) = 0 max (triángulos) = 59999, por lo que deberían apuntar a vértices válidos

El dibujo está hecho:

glDrawElements (GL_TRIANGLES, len (self.triangles), GL_UNSIGNED_SHORT, 0)

ACTUALIZA

k, justo cuando pensaba que entendía cómo debería funcionar esto, traté de omitir el VBO para los elementos y solo dije:

glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, ADT.voidDataPointer(self.triangles))

Ahora no solo funciona y dibuja todos mis triángulos a la perfección, sino que el FPS es mejor. ¿No debería ser el VBO más rápido? Y qué podría hacer que el enfoque anterior funcione, pero que se bloquee lo siguiente:

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ADT.arrayByteCount(triangles), ADT.voidDataPointer(triangles), GL_STATIC_DRAW_ARB)
glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, 0)

Respuestas a la pregunta(3)

Su respuesta a la pregunta