tutorial descargar actualizar opengl

descargar - opengl intel



OpenGL, VAOs y mĂșltiples buffers (1)

Estoy escribiendo un pequeño motor gráfico utilizando OpenGL (a través de OpenTK con C #).

Para definir atributos de vértice, tengo una clase VertexDeclaration con una matriz de estructuras VertexElement que están asignadas a las llamadas glEnableVertexAttribArray / glVertexAttribPointer.

Además, para admitir múltiples flujos de vértices, tengo una estructura especial que contiene un búfer de vértice, declaración de vértice, desplazamiento de vértice y frecuencia de instancia (como la estructura VertexBufferBinding de XNA).

Actualmente, cada vez que se invoca una llamada de dibujo, recorro todas las secuencias de vértices establecidas y ato sus buffers de vértice, aplico declaraciones de vértice, deshabilito los atributos de vértice no utilizados y dibuja los primitivos.

Me gustaría usar VAOs para almacenar en caché las llamadas a glEnableVertexAttribArray, y cada vez que se aplique un flujo de vértice, vincule VAO y cambie su enlace de búfer de matriz.

¿Es ese un uso correcto de VAOs?


¿Es ese un uso correcto de VAOs?

No 1 .

glVertexAttribPointer utiliza el objeto de búfer que estaba vinculado a GL_ARRAY_BUFFER en el momento en que se llamó a la función . Así que no puedes hacer esto:

glVertexAttribPointer(...); glBindBuffer(GL_ARRAY_BUFFER, bufferObject); glDrawArrays(...);

Esto no utilizará bufferObject ; utilizará todo lo que estaba vinculado a GL_ARRAY_BUFFER cuando se llamó originalmente glVertexAttribPointer .

Los VAO capturan este estado. Por lo tanto, la VAO, para cada atributo de vértice, almacenará cualquier objeto de búfer que se haya vinculado a GL_ARRAY_BUFFER cuando fue llamado. Esto te permite hacer cosas como esta:

glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, buffer1); glVertexAttribPointer(0, ...); glVertexAttribPointer(1, ...); glBindBuffer(GL_ARRAY_BUFFER, buffer2); glVertexAttribPointer(2, ...);

Los atributos 0 y 1 provendrán de buffer1 , y los atributos 2 provendrán de buffer2 . VAO ahora captura todo ese estado. Para renderizar, simplemente haz esto:

glBindVertexArray(VAO); glDraw*();

En resumen, si desea cambiar de dónde proviene el almacenamiento de un atributo en OpenGL, también debe cambiar su formato . Incluso si es el mismo formato, debe llamar a glVertexAttribPointer nuevamente.

1 : Esta discusión asume que no estás usando el nuevo ARB_vertex_attrib_binding . O, como se sabe, " Exactamente cómo Direct3D realiza el enlace de atributo de vértice " . Si está usando una implementación que ofrece esta extensión, puede hacer lo que está hablando, ya que el formato del atributo no está vinculado a el almacenamiento del objeto buffer. Además, la lógica torturada de glVertexAttribPointer se ha ido.

En general, la forma en que resolvemos esto en el mundo OpenGL es poner tantas cosas como sea posible en el mismo objeto de búfer. Si esto falla, solo usa un VAO para cada objeto.