2012-01-01 21 views
6
código

muestra:¿Se puede usar objetivos múltiples con un solo VBO?

1. glGenBuffers(1, &VboId); 
2. glBindBuffer(GL_ARRAY_BUFFER, VboId); 
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 

Así que generan un mango genérica VBO, y luego se unen usando "GL_ARRAY_BUFFER". La unión parece que tiene 2 propósitos:

  1. Debemos obligar a la memoria intermedia antes de poder copiar los datos a la GPU a través de glBufferData
  2. Debemos obligar a la memoria intermedia antes de que podamos añadir atributos a ella a través glVertexAttribPointer

Y creo que esas son las únicas 2 veces que necesita vincular el VBO. Mi pregunta es, ¿hay algún escenario en el que el objetivo (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER o GL_PIXEL_UNPACK_BUFFER) sea diferente en las líneas 2 y 3? ¿O quisiéramos volver a vincularlo a un objetivo diferente antes de la línea 4?

¿Podemos vincular múltiples destinos de almacenamiento intermedio a un solo VBO?

Respuesta

11

No enlaza objetivos a un objeto de búfer. Los objetivos son ubicaciones en el contexto de OpenGL a las que se pueden unir cosas (como objetos de búfer). Por lo tanto, vincula objetos de almacenamiento intermedio a objetivos, y no al revés.

A buffer object (no hay nada como un VBO. Simplemente hay objetos de memoria intermedia) es simplemente una matriz lineal no formateada de la memoria propiedad del controlador OpenGL. Puede usarlo como fuente para datos de matriz de vértices, vinculando el búfer al GL_ARRAY_BUFFER y llamando a una de las funciones gl*Pointer. Estas función solo funcionan con el búfer actualmente vinculado a GL_ARRAY_BUFFER. Puede usarlos como fuente de datos de índice vinculándolos al GL_ELEMENT_ARRAY_BUFFER y llamando a una de las funciones glDrawElements.

Las funciones utilizadas para modificar los contenidos de los objetos de un búfer (glBufferData, glMapBuffer, glBufferSubData, etc.) específicamente toman un objetivo para que sus operaciones funcionen. Por lo tanto, glBufferData(GL_ARRAY_BUFFER, ...) hace sus cosas en cualquier búfer actualmente vinculado a GL_ARRAY_BUFFER.

Existen dos tipos de funciones que afectan a los objetos del búfer: las que modifican su contenido y las que usan en las operaciones. Estos últimos son específicos de una fuente; glVertexAttribPointersiempre utiliza el búfer actualmente vinculado a GL_ARRAY_BUFFER. No puedes hacer que use un objetivo diferente. Del mismo modo, glReadPixels siempre utiliza el buffer vinculado a GL_PIXEL_PACK_BUFFER. Etcétera. Si una función hace cosas con objetos de búfer pero no toma un objetivo como parámetro, entonces su documentación le dirá a qué objetivo busca su búfer.

Nota: Las matrices de vértices son un poco raras. La asociación entre un atributo de vértice y un objeto de memoria intermedia se realiza llamando al glVertexAttribPointer. Lo que hace esta función es establecer los datos apropiados para ese atributo, utilizando el objeto de búfer que está actualmente vinculado a GL_ARRAY_BUFFER. Por "actualmente vinculado", me refiero al límite en el momento en que se llama a esta función. Entonces, inmediatamente después de llamar a esta función, puede llamar al glBindBuffer(GL_ARRAY_BUFFER, 0), y cambiará nada acerca de lo que sucede cuando se va a procesar. Va a rendir bien.

De esta manera, puede usar diferentes objetos de memoria para diferentes atributos. La información se conservará hasta que la cambie con otra llamada glVertexAttribPointer para ese atributo en particular.

+0

¡Oooh! ¡Gracias! Esto tiene mucho más sentido ahora. Fue mi pensamiento retrospectivo lo que me estaba tirando. – mpen

+0

En realidad, con respecto al párrafo 3, estás diciendo que 'glBufferData' toma un objetivo para que sus operaciones funcionen ... ¿entonces estás diciendo que esencialmente está usando 'GL_ARRAY_BUFFER' como un búfer de trabajo temporal? ¿Por qué tenemos que vincular el objeto buffer al objetivo y luego especificar el objetivo nuevamente en 'glBufferData'? Básicamente intenté cambiar las líneas 2 y 3 en mi pregunta, y el programa ya no funciona. Intento entender por qué tendrías que especificar el objetivo dos veces, a menos que estén haciendo algo diferente. – mpen

+1

No importa ... Creo que lo descubrí. Vinculamos el objeto del búfer al objetivo y, luego, alimentamos esencialmente los datos a ese objetivo y, por lo tanto, indirectamente al objeto del búfer. Entonces ambos son necesarios. ¿Estoy pensando en esto correctamente? Los datos se vinculan al objeto de memoria intermedia, por lo que podemos borrar 'GL_ARRAY_BUFFER' inmediatamente después de llamar a glBufferData sin perder nada. Supongo que funciona igual que los punteros de atributo. – mpen

Cuestiones relacionadas