Obiectul Vertex Buffer
Vertex Buffer Object (VBO) este o caracteristică a OpenGL care furnizează metode de descărcare a datelor ( vârfuri , vectori normali , culori și așa mai departe) pe dispozitivul video pentru redare non-live. VBO-urile au oferit o creștere semnificativă a performanței față de modul de redare directă, în primul rând pentru că datele se află în memoria dispozitivului video, nu în RAM, și astfel pot fi redate direct de dispozitivul video.
Specificația Vertex Buffer Object a fost standardizată de OpenGL Architecture Review Board ca versiunea OpenGL 1.5 (în 2003). Funcționalități similare au fost disponibile înainte de standardizarea VBO-urilor prin extensiile Nvidia „Vertex Array Range” [1] și ATI „Vertex Array Object” [2] .
Principalele funcții ale VBO
Următoarele funcții formează baza accesului și manipulării VBO:
În OpenGL 1.4 :
GenBuffersARB (sizei n, uint *buffers)
Creează n VBO noi și returnează numărul lor de identificare ca un întreg nesemnat. ID-ul 0 este rezervat.
BindBufferARB (enum target, uint buffer)
Utilizează tamponul creat anterior ca VBO activ.
BufferDataARB (enum target, sizeiptrARB size, const void *data, enumerare utilizare)
Încarcă date în VBO activ.
DeleteBuffersARB (sizei n, const uint *buffers)
Elimină VBO-urile specificate din matrice sau ID-ul VBO.
În OpenGL 2.1 :
[3] , OpenGL 3.x
[4] și OpenGL 4.x, sufixul ARB poate fi omis din funcții:
[5]
GenBuffers (sizei n, uint *buffers)
Creează n VBO noi și returnează numărul lor de identificare ca un întreg nesemnat. ID-ul 0 este rezervat.
BindBuffer (enum target, uint buffer)
Utilizează tamponul creat anterior ca VBO activ.
BufferData (ținta enumerare, dimensiunea sizeiptrARB, const void *date, utilizarea enumerarii)
Încarcă date în VBO activ.
DeleteBuffers (sizei n, const uint *buffers)
Elimină VBO-urile specificate din matrice sau ID-ul VBO.
Exemplu în C și OpenGL 2.1
//Inițializarea VBO - făcută o dată, la pornirea programului
//Crearea unei variabile pentru a stoca identificatorul VBO
GLuint triangleVBO ;
// Vârfurile triunghiului (ocolire în sens invers acelor de ceasornic)
date flotante [] = { 1.0 , 0.0 , 1.0 , 0.0 , 0.0 , -1.0 , -1.0 , 0.0 , 1.0 };
//Creează un nou VBO și salvează ID-ul VBO
glGenBuffers ( 1 , & triangleVBO );
//Setează activitatea VBO
glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO );
//Încărcați date de vârf pe dispozitivul video
glBufferData ( GL_ARRAY_BUFFER , sizeof ( data ), data , GL_STATIC_DRAW );
//Desenarea triunghiului din VBO - se întâmplă de fiecare dată când fereastra, punctul de vedere sau datele se schimbă
//Setați 3 coordonate ale fiecărui vârf în trepte de 0 în această matrice; are nevoie
de glVertexPointer ( 3 , GL_FLOAT , 0 , NULL );
//Activați noul VBO. Repetați acest lucru dacă ați modificat de la inițializare
glBindBuffer ( GL_ARRAY_BUFFER , triangleVBO );
//Această matrice conține vârfuri (nu normale, culori, texturi etc.)
glEnableClientState ( GL_VERTEX_ARRAY );
//Desenați un triunghi specificând numărul de vârfuri
glDrawArrays ( GL_TRIANGLES , 0 , sizeof ( data ) / sizeof ( float ) / 3 );
//Instrucțiune pentru afișarea desenată imediat
glFlush ();
Exemplu în C și OpenGL 3.x sau OpenGL 4.x
O funcție care poate citi orice fișier text sau binar într-un buffer de octeți:
/* Funcție de citire a unui fișier text într-un buffer de caractere alocat */
char * filetobuf ( char * file )
{
FIȘIER * fptr ;
lungime mare ;
char * buf ;
fptr = fopen ( fișier , "rb" ); /* Deschide fișierul pentru citire */
if ( ! fptr ) /* Returnează NULL la eroare */
returnează NULL ;
fseek ( fptr , 0 , SEEK_END ); /* Găsiți sfârșitul fișierului */
lungime = ftell ( fptr ); /* Calculați dimensiunea fișierului în octeți */
buf = malloc ( lungime + 1 ); /* Alocați încă un buffer pentru fișier și pointer nul */
fseek ( fptr , 0 , SEEK_SET ); /* Sari înapoi la începutul fișierului */
fread ( buf , lungime , 1 , fptr ); /* Citiți conținutul fișierului în buffer */
fclose ( fptr ); /* Închide fișierul */
buf [ lungime ] = 0 ; /* Setați indicatorul nul ca marcator de sfârșit de buffer */
return buf ; /* Returnează tamponul primit */
}
Vertex shader:
/*----------------- "exempluVertexShader.vert" -----------------*/
#version 150 // Specificați versiunea de GLSL pe care o folosim.
// in_Position a fost asociat cu un atribut cu index 0 ("shaderAttribute")
în vec3 in_Position ;
void main ( void )
{
gl_Position = vec4 ( in_Position . x , in_Position . y , in_Position . z , 1.0 );
}
/*----------------------------------------------- --------------- ---------------*/
Fragment Shader:
/*---------------- "exampleFragmentShader.frag" ----------------*/
#version 150 // Specificați versiunea de GLSL pe care o folosim.
plutitor de precizie ; // Driverele plăcii video necesită acest lucru pentru ca următoarea linie să funcționeze corect
out vec4 fragColor ;
void main ( void )
{
fragColor = vec4 ( 1.0 , 1.0 , 1.0 , 1.0 ); //Setați culoarea fiecărui fragment la alb
}
/*-------------------------------------- ----------- -----------------------*/
Programul principal OpenGL:
/*--------------------- Programul principal OpenGL ---------------------*/
/* Creați o variabilă pentru a stoca identificatorul VBO */
GLuint triunghi VBO ;
/* Acesta este numele programului shader */
GLuint shaderProgram ;
/* Acești pointeri vor primi adrese în memoria codului sursă al shaderului */
GLchar * vertexSource , * fragmentSource ;
/* Aceste variabile sunt folosite pentru shadere */
GLuint vertexShader , fragmentShader ;
const unsigned int shaderAttribute = 0 ;
const float NUM_OF_VERTICES_IN_DATA = 3 ;
/* Vârfurile triunghiului (direcția transversală: în sens invers acelor de ceasornic) */
date float [ 3 ][ 3 ] = {
{ 0,0 , 1,0 , 0,0 },
{ -1,0 , -1,0 , 0,0 },
{ 1,0 , -1,0 , 0,0 }
};
/*--------------------- Inițializare VBO - (efectuat o dată, la pornirea programului) --------------- - -----*/
/* Creați un nou VBO și utilizați variabila „triangleVBO” pentru a stoca id-ul VBO */
glGenBuffers ( 1 , & triangleVBO );
/* Activează noul VBO */
glBindBuffer ( GL_ARRAY_BUFFER , triunghiVBO );
/* Încărcați date pe dispozitivul video */
glBufferData ( GL_ARRAY_BUFFER , NUM_OF_VERTICES_IN_DATA * 3 * sizeof ( float ), data , GL_STATIC_DRAW );
/* Specificați că datele noastre de coordonate din indexul de atribut sunt 0 (shaderAttribute) și conțin 3 floats per vârf */
glVertexAttribPointer ( shaderAttribute , 3 , GL_FLOAT , GL_FALSE , 0 , 0 );
/* Includeți indicele de atribut egal cu 0 (shaderAttribute) așa cum este utilizat */
glEnableVertexAttribArray ( shaderAttribute );
/* Activează noul VBO */
glBindBuffer ( GL_ARRAY_BUFFER , triunghiVBO );
/*------------------------------------------------ -------------------------------------------------- -----*/
/*--------------------- Încărcați Vertex și Fragment din fișiere și compilați-le ------------------ --*/
/* Citiți codul shader în bufferele alocate dinamic corespunzătoare */
vertexSource = filetobuf ( "exampleVertexShader.vert" );
fragmentSource = filetobuf ( "exampleFragmentShader.frag" );
/* Atribuiți „nume” managerilor noștri pentru noile obiecte shader */
vertexShader = glCreateShader ( GL_VERTEX_SHADER );
fragmentShader = glCreateShader ( GL_FRAGMENT_SHADER );
/* Îmbină buffer-urile sursei de shader cu handlerele lor respective */
glShaderSource ( vertexShader , 1 , ( const GLchar ** ) & vertexSource , 0 );
glShaderSource ( fragmentShader , 1 , ( const GLchar ** ) & fragmentSource , 0 );
/* Eliberează memoria alocată anterior */
liber ( sursa vertex );
gratuit ( fragmentSource );
/* Compilăm codurile noastre shader */
glCompileShader ( vertexShader );
glCompileShader ( fragmentShader );
/*------------------------------------------------ -------------------------------------------------- -----*/
/*-------------------- Crearea unui program shader, atașarea shader-ului la acesta și legarea ---------------- -- ---*/
/* Atribuiți un nume programului nostru de gestionare */
shaderProgram = glCreateProgram ();
/* Atașați shaderele noastre la programul shader */
glAttachShader ( shaderProgram , vertexShader );
glAttachShader ( shaderProgram , fragmentShader );
/* Asociați un index de atribut de 0 (shaderAttribute) cu in_Position */
/* „in_Position” va reprezenta matricea de date în vertex shader */
glBindAttribLocation ( shaderProgram , shaderAttribute , "in_Position" );
/* Conectați programul shader */
glLinkProgram ( shaderProgram );
/*------------------------------------------------ -------------------------------------------------- -----*/
/* Setați programul nostru de shader activ */
glUseProgram ( shaderProgram );
/* Setați fundalul la negru */
glClearColor ( 0,0 , 0,0 , 0,0 , 1,0 );
/* Culoarea de fundal clară */
glClear ( GL_COLOR_BUFFER_BIT );
/* Desenând un triunghi, numerele de vârfuri sunt transmise apelând glDrawArrays
spunând că triunghiurile noastre date și vrem să desenăm vârfurile 0-3
*/
glDrawArrays ( GL_TRIANGLES , 0 , 3 );
/*------------------------------------------------ ---------------*/
Vezi și
Note
- ↑ Cartea albă GL_NV_vertex_array_range . Arhivat din original pe 22 mai 2013. (nedefinit)
- ↑ ATI_vertex_array_object . Arhivat din original pe 22 mai 2013. (nedefinit)
- ↑ Referința funcției OpenGL 2.1 . Arhivat din original pe 22 mai 2013. (nedefinit)
- ↑ Referința funcției OpenGL 3.3 . Arhivat din original pe 22 mai 2013. (nedefinit)
- ↑ Referința funcției OpenGL 4.2 (link indisponibil) . Consultat la 5 mai 2013. Arhivat din original pe 22 mai 2013. (nedefinit)
Link -uri