Cuando leo el documento en webGL u OpenGL, se pueden ver algunos patrones en cómo se usan los nombres de funciones y objetos. Pero no puedo entender la diferencia entre el objeto de búfer y una matriz.
Hay "objetos de búfer de vértices", "objetos de matriz de vértices" e incluso algún tipo de "matriz de búfer" o "matriz de búfer".
En el contexto de OpenGL, ¿cuándo algo es "matriz" y cuándo debería llamarse "buffer"?
char* buffer = socketRead();
(pseudocódigo). El registro, por otro lado, vive a través de todo el ciclo de vida de la aplicación. Entonces, crea una matriz en algún lugar y comienza a leer el socket, cada vez que obtiene datos, escribe esa porción en la matriz, lo que le brinda una lista ordenada de todos los datos que recibió.Respuestas:
La denominación de Vertex Array Object es algo desafortunada. Hay tres cosas diferentes que aparecen (solían aparecer) en / con / alrededor de su aplicación, y que (históricamente) se nombraron de manera diferente, con "matriz" o "buffer" en el nombre (bueno, también hay objetos framebuffer, pero lo ignoraré)
La intención de esto era hacer que el acceso fuera más eficiente, ya que OpenGL podría copiar todo de una vez en un momento bien definido cuando prometió que los datos eran consistentes y pasarlos a AGP o lo que sea en un bloque. Esto ya no existe.
OpenGL puede mover estos datos más o menos libremente, y solo se le permite / puede copiar al / desde el búfer a través de la API correspondiente o acceder a los datos mientras se está asignando. Eso es lo que se llama un objeto de búfer ( objeto de búfer de vértices si contiene vértices, pero realmente no tiene que ser así, podrían ser datos de imagen o uniformes, solo los vértices fueron los primeros en ser apoyados, alguna vez).
La intención de esto es garantizar que OpenGL pueda (en principio) hacer lo que quiera, incluso puede empujar el búfer sobre PCIe especulativamente incluso antes de dibujar. Eso funciona porque no posee los datos (¡OpenGL sí!) Y solo puede acceder a ellos a través de la API dada, por lo que se sabe en todo momento que los datos son válidos. El controlador incluso puede optar por desechar la memoria intermedia en la tarjeta gráfica cuando necesita memoria para algo diferente y luego restaurarla desde su copia secreta cuando sea necesario.
Ahora, la intención del objeto de matriz de vértices es reducir el número de llamadas API y reducir el número de comprobaciones de consistencia que OpenGL debe hacer internamente y, por supuesto, para usar el hardware tal como funciona. Si enlaza 5 buffers, cada uno debe pasar por algunas comprobaciones posiblemente costosas, y cada uno es candidato para errores de caché en el controlador, además de que cada uno requiere comunicarse con la tarjeta gráfica para cambiar un descriptor, etc., etc. enlazar un VAO, el controlador puede (a menudo) simplemente cambiar el conjunto de descriptores en la tarjeta gráfica, y listo.
fuente
(sacado de khronos )
Cada búfer tiende a constituir un atributo de una matriz de vértices (objeto). Un VAO puede contener muchos atributos de vértice (por ejemplo, posición, color, UV). Cada uno puede mantenerse en su propio búfer, donde el búfer indica una serie sin formato de bytes contiguos, y donde necesita especificar explícitamente el tamaño (tipo) por elemento de búfer para las llamadas OpenGL del lado de la CPU y el trabajo del sombreador del lado de la GPU.
Esa es una forma. Las otras formas en que esto puede funcionar son:
El siguiente diagrama ilustra estos dos últimos casos.
En pocas palabras: si la frase "matriz de vértices" se usa sin calificar en OpenGL, puede suponer que significa VAO, lo que, en un contexto de OpenGL (específicamente) es una cosa muy diferente de un búfer.
EDITAR re su comentario:
GL_ARRAY_BUFFER
indica una intención de usar ese objeto de búfer para los datos de atributos de vértice, como se describió anteriormente. Esto se debe a que los búferes no se usan solo para los atributos de vértice. Sin embargo, como es el caso de uso más común y usted está preguntando acerca de VAO, no entraré en los otros; Sin embargo, aquí hay una lista de los otros tipos de buffers que se pueden configurar.fuente
struct
tipo. Los datos pueden estar intercalados o ser completamente uniformes, por búfer. Puede indexarlos, al igual que con una matriz C tradicional en la CPU. Arregle objetos (¡use esta terminología correcta o termine confundiéndose!) ... (continúa a continuación)Esta terminología se basa en la historia de OpenGL. Lo que es importante recordar es que, para la mayoría de las versiones de GL que son relevantes aquí, OpenGL evolucionó gradualmente y al agregar nuevas funcionalidades a una API ya existente en lugar de cambiar la API.
La primera versión de OpenGL no tenía ninguno de estos tipos de objetos. El dibujo se logró mediante la emisión de múltiples llamadas glBegin / glEnd, y un problema con este modelo fue que era muy ineficiente, en términos de sobrecarga de llamadas de función.
OpenGL 1.1 dio los primeros pasos para abordar esto mediante la introducción de matrices de vértices. En lugar de especificar directamente los datos de vértice, ahora puede obtenerlos de matrices C / C ++, de ahí el nombre. Entonces, una matriz de vértices es solo eso: una matriz de vértices y el estado GL requerido para especificarlos.
La siguiente evolución importante vino con GL 1.5 y permitió almacenar datos de matriz de vértices en la memoria de la GPU en lugar de en la memoria del sistema ("lado del cliente"). Una debilidad de la especificación de matriz de vértices GL 1.1 era que el conjunto completo de datos de vértices tenía que transferirse a la GPU cada vez que deseaba usarlo; si ya estaba en la GPU, entonces esta transferencia podría evitarse y se podrían lograr ganancias potenciales de rendimiento.
Por lo tanto, se creó un nuevo tipo de objeto GL para permitir el almacenamiento de estos datos en la GPU. Al igual que un objeto de textura se usa para almacenar datos de textura, un objeto de búfer de vértice almacena datos de vértice. En realidad, esto es solo un caso especial de un tipo de objeto de almacenamiento intermedio más general que puede almacenar datos no específicos.
La API para usar objetos de búfer de vértices estaba respaldada en la API de matrices de vértices ya existente, por lo que ve cosas extrañas como convertir desplazamientos de bytes en punteros. Entonces, ahora tenemos una API de matrices de vértices que solo almacena el estado, y los datos se obtienen de objetos de búfer en lugar de matrices en memoria.
Esto nos lleva casi al final de nuestra historia. La API resultante fue bastante detallada a la hora de especificar el estado de la matriz de vértices, por lo que otra vía de optimización fue crear un nuevo tipo de objeto que reuniera todo este estado, permitiera múltiples cambios de estado de la matriz de vértices en una sola llamada de API y permitió GPU potencialmente realizar optimizaciones debido a poder saber qué estado se iba a utilizar antes de tiempo.
Ingrese el objeto de matriz de vértices, que recopila todo esto junto.
Entonces, para resumir, una matriz de vértices comenzó como una colección de estado y datos (almacenados en una matriz) para dibujar. Un búfer de vértices reemplaza el almacenamiento de la matriz en memoria con un tipo de objeto GL, dejando la matriz de vértices solo en estado. Un objeto de matriz de vértices es solo un objeto contenedor para este estado, lo que permite cambiarlo más fácilmente y con menos llamadas a la API.
fuente
Hace tiempo que no trabajo con OpenGL, por lo que solo podría tener la mitad de la razón. En términos generales: los almacenamientos intermedios almacenan una matriz de memoria sin formato. Una matriz es un término general de memoria contigua.
Un búfer debe estar vinculado al contexto, mientras que una matriz es solo una matriz de datos. Si recuerdo correctamente, los datos en el búfer deben copiarse en la tarjeta gráfica (de ahí el enlace).
Espero que esto ayude un poco
fuente