Objeto de búfer de vértice

El objeto de búfer de vértices (VBO) es una función de OpenGL que proporciona métodos para volcar datos ( vértices , vectores normales , colores, etc.) al dispositivo de video para renderización no en vivo. Los VBO aumentaron significativamente el rendimiento en comparación con el modo de representación directa, principalmente porque los datos residen en la memoria del dispositivo de video, no en la RAM, por lo que el dispositivo de video puede procesarlos directamente.

La especificación Vertex Buffer Object fue estandarizada por OpenGL Architecture Review Board como OpenGL versión 1.5 (en 2003). Una funcionalidad similar estaba disponible antes de la estandarización de los VBO a través de las extensiones "Vertex Array Range" [1] de Nvidia y "Vertex Array Object" [2] de ATI .

Funciones principales de VBO

Las siguientes funciones forman la base del acceso y la manipulación de VBO:

En OpenGL 1.4 : GenBuffersARB (tamañoi n, uint *búferes) Crea n VBO nuevos y devuelve su número de identificación como un número entero sin signo. El ID 0 está reservado. BindBufferARB (objetivo de enumeración, búfer uint) Utiliza el búfer creado previamente como el VBO activo. BufferDataARB (objetivo de enumeración, tamaño sizeiptrARB, const void *datos, uso de enumeración) Carga datos al VBO activo. DeleteBuffersARB (tamaño, const uint *búferes) Elimina los VBO especificados de la matriz o ID de VBO. En OpenGL 2.1 : [3] , OpenGL 3.x [4] y OpenGL 4.x, el sufijo ARB se puede omitir de las funciones: [5] GenBuffers (tamañoi n, uint *buffers) Crea n VBO nuevos y devuelve su número de identificación como un número entero sin signo. El ID 0 está reservado. BindBuffer (destino de enumeración, búfer uint) Utiliza el búfer creado previamente como el VBO activo. BufferData (objetivo de enumeración, tamaño sizeiptrARB, const void *datos, uso de enumeración) Carga datos al VBO activo. DeleteBuffers (sizei n, const uint *buffers) Elimina los VBO especificados de la matriz o ID de VBO.

Ejemplo en C y OpenGL 2.1

//Inicialización de VBO - hecho una vez, al inicio del programa //Creación de una variable para almacenar el identificador de VBO GLuint TriangleVBO ; // Vértices de triángulo (bypass en sentido contrario a las agujas del reloj) float data [] = { 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , -1.0 , -1.0 , 0.0 , 1.0 }; //Cree un VBO nuevo y guarde el ID de VBO glGenBuffers ( 1 , & TriangleVBO ); // Establecer actividad VBO glBindBuffer ( GL_ARRAY_BUFFER , TriangleVBO ); //Cargar datos de vértice al dispositivo de video glBufferData ( GL_ARRAY_BUFFER , sizeof ( datos ), datos , GL_STATIC_DRAW ); //Dibujar un triángulo desde VBO: ocurre cada vez que cambia la ventana, el punto de vista o los datos //Establece 3 coordenadas de cada vértice en incrementos de 0 en esta matriz; necesita glVertexPointer ( 3 , GL_FLOAT , 0 , NULL ); //Hacer activo el nuevo VBO. Repita esto si cambió desde la inicialización glBindBuffer ( GL_ARRAY_BUFFER , TriangleVBO ); //Esta matriz contiene vértices (no normales, colores, texturas, etc.) glEnableClientState ( GL_VERTEX_ARRAY ); //Dibuja un triángulo especificando el número de vértices glDrawArrays ( GL_TRIANGLES , 0 , sizeof ( data ) / sizeof ( float ) / 3 ); //Instrucción para mostrar dibujado inmediatamente glFlush ();

Ejemplo en C y OpenGL 3.xo OpenGL 4.x

Una función que puede leer cualquier texto o archivo binario en un búfer de bytes:

/* Función para leer un archivo de texto en un búfer de caracteres asignado */ char * archivotobuf ( char * archivo ) { ARCHIVO * fptr ; longitud larga ; char * buf ; fptr = fopen ( archivo , "rb" ); /* Abrir archivo para lectura */ if ( ! fptr ) /* Devuelve NULL en caso de error */ devuelve NULL ; fbuscar ( fptr , 0 , SEEK_END ); /* Busca el final del archivo */ longitud = ftell ( fptr ); /* Calcula el tamaño del archivo en bytes */ buf = malloc ( longitud + 1 ); /* Asignar un búfer más para el archivo y el puntero nulo */ fbuscar ( fptr , 0 , SEEK_SET ); /* Saltar al principio del archivo */ fread ( buf , longitud , 1 , fptr ); /* Leer el contenido del archivo en el búfer */ fcerrar ( fptr ); /* Cierra el archivo */ buf [ longitud ] = 0 ; /* Establecer puntero nulo como marcador de fin de búfer */ volver buf ; /* Devuelve el búfer resultante */ }


Sombreador de vértices:

/*----------------- "ejemploVertexShader.vert" -----------------*/ #version 150 // Especifique la versión de GLSL que estamos usando. // in_Position se ha asociado con un atributo con índice 0 ("shaderAttribute") en vec3 in_Position ; void main ( void ) { gl_Position = vec4 ( in_Position . x , in_Position . y , in_Position . z , 1.0 ); } /*----------------------------------------------- ------ ---------------*/


Sombreador de fragmentos:

/*---------------- "ejemploFragmentShader.frag" ----------------*/ #version 150 // Especifique la versión de GLSL que estamos usando. flotador alto de precisión ; // Los controladores de la tarjeta de video requieren esto para que la siguiente línea funcione correctamente fuera vec4 fragColor ; vacío principal ( vacío ) { fragColor = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ); //Establecer el color de cada fragmento en blanco } /*------------------------------------- ----------- -----------------------*/


Programa principal de OpenGL:

/*--------------------- Programa principal OpenGL ---------------------*/ /* Crea una variable para almacenar el identificador VBO */ GLuint triángulo VBO ; /* Este es el nombre del programa shader */ GLuint shaderProgram ; /* Estos punteros obtendrán direcciones en la memoria del código fuente del shader */ GLchar * origen del vértice , * origen del fragmento ; /* Estas variables se usan para shaders */ GLuint vertexShader , fragmentShader ; const unsigned int shaderAttribute = 0 ; const float NUM_OF_VERTICES_IN_DATA = 3 ; /* Vértices del triángulo (sentido transversal: en sentido contrario a las agujas del reloj) */ datos flotantes [ 3 ][ 3 ] = { { 0.0 , 1.0 , 0.0 }, { -1.0 , -1.0 , 0.0 }, { 1.0 , -1.0 , 0.0 } }; /*--------------------------- Inicialización de VBO - (hecho una vez, al iniciar el programa) --------------- - -----*/ /* Cree un nuevo VBO y use la variable "triangleVBO" para almacenar la identificación de VBO */ glGenBuffers ( 1 , & triánguloVBO ); /* Activar el nuevo VBO */ glBindBuffer ( GL_ARRAY_BUFFER , triánguloVBO ); /* Subir datos al dispositivo de video */ glBufferData ( GL_ARRAY_BUFFER , NUM_OF_VERTICES_IN_DATA * 3 * sizeof ( float ), data , GL_STATIC_DRAW ); /* Especificar que nuestros datos de coordenadas en el índice de atributos son 0 (shaderAttribute) y contienen 3 flotantes por vértice */ glVertexAttribPointer ( shaderAttribute , 3 , GL_FLOAT , GL_FALSE , 0 , 0 ); /* Incluir índice de atributo igual a 0 (shaderAttribute) como se usa */ glEnableVertexAttribArray ( shaderAttribute ); /* Activar el nuevo VBO */ glBindBuffer ( GL_ARRAY_BUFFER , triánguloVBO ); /*------------------------------------------------ -------------------------------------------------- -----*/ /*---------------------- Cargar Vertex y Fragment desde archivos y compilarlos ------------------ --*/ /* Lee el código del sombreador en los búfer asignados dinámicamente apropiados */ vertexSource = filetobuf ( "exampleVertexShader.vert" ); fragmentSource = filetobuf ( "exampleFragmentShader.frag" ); /* Asignar "nombres" a nuestros manejadores para los nuevos objetos shader */ vertexShader = glCreateShader ( GL_VERTEX_SHADER ); fragmentShader = glCreateShader ( GL_FRAGMENT_SHADER ); /* Fusionar los búferes de origen del sombreador con sus respectivos controladores */ glShaderSource ( vertexShader , 1 , ( const GLchar ** ) & vertexSource , 0 ); glShaderSource ( fragmentShader , 1 , ( const GLchar ** ) & fragmentSource , 0 ); /* Liberar la memoria previamente asignada */ libre ( fuente del vértice ); libre ( fragmentoFuente ); /* Compilar nuestros códigos de sombreado */ glCompileShader ( vertexShader ); glCompileShader ( fragmentoShader ); /*------------------------------------------------ -------------------------------------------------- -----*/ /*-------------------- Creando un programa de sombreado, adjuntándole el sombreador y vinculando ---------------- -- ---*/ /* Asignar un nombre a nuestro programa controlador */ shaderProgram = glCreateProgram (); /* Adjuntar nuestros shaders al programa de shaders */ glAttachShader ( shaderProgram , vertexShader ); glAttachShader ( shaderProgram , fragmentShader ); /* Asociar un índice de atributo de 0 (shaderAttribute) con in_Position */ /* "in_Position" representará la matriz de datos en el sombreador de vértices */ glBindAttribLocation ( shaderProgram , shaderAttribute , "in_Position" ); /* Vincular el programa de sombreado */ glLinkProgram ( shaderProgram ); /*------------------------------------------------ -------------------------------------------------- -----*/ /* Activar nuestro programa de shaders */ glUseProgram ( shaderProgram ); /* Establecer el fondo en negro */ glClearColor ( 0.0 , 0.0 , 0.0 , 1.0 ); /* Borrar color de fondo */ glClear ( GL_COLOR_BUFFER_BIT ); /* Al dibujar un triángulo, los números de vértice se pasan llamando a glDrawArrays diciendo que nuestros triángulos dados y queremos dibujar los vértices 0-3 */ glDrawArrays ( GL_TRIANGLES , 0 , 3 ); /*------------------------------------------------ ---------------*/

Véase también

Notas

  1. Documento técnico de GL_NV_vertex_array_range . Archivado desde el original el 22 de mayo de 2013.
  2. ATI_vertex_array_object . Archivado desde el original el 22 de mayo de 2013.
  3. Referencia de la función OpenGL 2.1 . Archivado desde el original el 22 de mayo de 2013.
  4. Referencia de la función OpenGL 3.3 . Archivado desde el original el 22 de mayo de 2013.
  5. Referencia de la función OpenGL 4.2 (enlace no disponible) . Consultado el 5 de mayo de 2013. Archivado desde el original el 22 de mayo de 2013. 

Enlaces