OpenGL VAO, VBO 使用简介

参照代码样例:数组

 1 // This function takes in a vertex, color, index and type array 
 2 // And does the initialization for an object.  
 3 // The partner function below it draws the object 
 4 void initobject(GLuint object, GLfloat * vert, GLint sizevert, GLfloat * col, GLint sizecol, GLubyte * inds, GLint sizeind, GLenum type){
 5     int offset = object * numperobj;
 6     // make the new GL_ARRAY_BUFFER active
 7     // 将VAO绑定到当前的context上
 8     glBindVertexArray(VAOs[object]);
 9 
10 
11     // 将颜色数据绑定到VBO上
12     glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors+offset]) ; 
13     glBufferData(GL_ARRAY_BUFFER, sizecol, col,GL_STATIC_DRAW);
14     // 用于关联 shader (location = 1) color
15     glEnableVertexAttribArray(1);
16     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
17 
18 
19     // 将顶点数据绑定到VBO上20     // 将这个buffer关联到 GL_ARRAY_BUFFER
21     glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]);
22     // 将数据传送到这个buffer 
23     glBufferData(GL_ARRAY_BUFFER, sizevert, vert,GL_STATIC_DRAW);
24     // 用于关联 shader (location = 0) vertex
25     glEnableVertexAttribArray(0);
27     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
28 
29    // 将三角形序列绑定到VBO上
30     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ; 
31     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeind, inds,GL_STATIC_DRAW);
32     PrimType[object] = type;
33     NumElems[object] = sizeind;
34     // Prevent further modification of this VAO by unbinding it
35     glBindVertexArray(0);
36 }
37 
38 void drawobject(GLuint object) {
39     glBindVertexArray(VAOs[object]);
40     glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNED_BYTE, 0); 
41     glBindVertexArray(0);
42 }

 

程序的部分相关初始化代码:函数

 1 // Now create the buffer objects to be used in the scene later
 2 // Remember to delete all the VAOs and VBOs when the program terminates!
 3 glGenVertexArrays(numobjects, VAOs);
 4 glGenBuffers(numperobj*numobjects, buffers);
 5 
 6 // Initialize the floors
 7 initobject(FLOOR, (GLfloat *) floorverts, sizeof(floorverts), (GLfloat *) floorcol, sizeof (floorcol), (GLubyte *) floorinds, sizeof (floorinds), GL_TRIANGLES) ; 
 8 initobject(FLOOR2, (GLfloat *) floorverts2, sizeof(floorverts2), (GLfloat *) floorcol2, sizeof (floorcol2), (GLubyte *) floorinds2, sizeof (floorinds2), GL_TRIANGLES) ;
 9 

 

vertex shaderui

 1 # version 330 core
 2 // Do not modify the above version directive to anything older than 330, as
 3 // modern OpenGL will not work properly due to it not being core at the time.
 4 
 5 // Shader inputs
 6 layout (location = 0) in vec3 position;
 7 layout (location = 1) in vec3 color;
 8 
 9 // Shader outputs, if any
10 out vec3 Color;
11 
12 // Uniform variables
13 uniform mat4 modelview;
14 uniform mat4 projection;
15 
16 void main() {
17     gl_Position = projection * modelview * vec4(position, 1.0f);
18     Color = color; // Just forward this color to the fragment shader
19 }

 

 


 

OpenGL有着许多使人捉摸不着的概念,其中比较重要的即是Vertex Array Object 以及 Vertex Buffer Object。为了理解这两个概念,还须要注意另外一个叫作context(上下文)的概念,由于OpenGL用C写的,没有C++那种面向对象的特性,所以在遇到涉及状态保存的时候(好比为当前物体(而不是其余什么物体)赋值),就须要用context来储存临时状态(好比“我如今编辑的对象是物体1,而不是物体2”)。this

 

牢记context这个概念的存在,让咱们看看如何使用代码建立一个物体并显示。spa

 

1. 建立物体

先看initobject函数(见上文),能够看到函数内部代码大体分红了4块,咱们分别解释。code

代码就不重复复制了。orm

offset那个变量不用管,那个是用于区分当前初始化的是第一个物体仍是第二个物体的,大家能够默认这个程序只有一个物体而后忽视掉代码中的全部offset。对象

 

(1). 将VAO绑定到contextblog

能够简单的将VAO理解为一个咱们将要显示的物体。这个物体有许多属性,好比全部顶点,颜色,三角形的顶点序列。而这些属性都又由VBO来表示。input

将其绑定到context这一动做表示:我接下来操做的对象都是1号物体了。

 

(2). 将颜色绑定到VBO上

glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors+offset]) ; 
glBufferData(GL_ARRAY_BUFFER, sizecol, col, GL_STATIC_DRAW);

这两行代码应该一块儿使用,能够将其做用理解为:将col这个数组的数据绑定到buffers[colors] (此处忽略了offset)

也就是说,咱们将颜色数据链接到一个VBO上,这样之后OpenGL即可以经过这个VBO读取这个颜色数据。

 

因为咱们须要在shader中访问颜色数据,所以咱们还须要将其暴露给shader,经过如下代码。

// 用于关联 shader (location = 1) color
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);

以上代码说明shader中的 1 号(能够是任何未使用过的数字) location 处的数据将是咱们刚刚绑定的颜色信息

 

(3). 将顶点绑定到VBO上

这一步与绑定颜色的作法重复,先是将咱们的顶点数据绑定到一个VBO,而后将其暴露给shader的0号位置。

 

(4). 将三角形序列绑定到VBO

这里就不解释三角形序列是什么了,这个名字我可能叫错了。。。总之这个数据定义了那些顶点用来组成三角形。

绑定的过程与上面同样,不过因为shader中并不须要这个数据,所以咱们不用将其暴露给shader

 


 

 

2. 显示物体

建立完物体,咱们能够显示出来了

在丢给glutDisplayFunc的那个display函数中加上如下代码

1 glBindVertexArray(VAOs[object]);
2 glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNED_BYTE, 0); 
3 glBindVertexArray(0);

第一行说明咱们如今开始操做物体1

第二行让OpenGL画出物体1(为何不是物体2?由于咱们上一步已经说明了如今的context是物体1)

第三行解绑物体1

相关文章
相关标签/搜索