参照代码样例:

 // This function takes in a vertex, color, index and type array
// And does the initialization for an object.
// The partner function below it draws the object
void initobject(GLuint object, GLfloat * vert, GLint sizevert, GLfloat * col, GLint sizecol, GLubyte * inds, GLint sizeind, GLenum type){
int offset = object * numperobj;
// make the new GL_ARRAY_BUFFER active
// 将VAO绑定到当前的context上
glBindVertexArray(VAOs[object]); // 将颜色数据绑定到VBO上
glBindBuffer(GL_ARRAY_BUFFER, buffers[Colors+offset]) ;
glBufferData(GL_ARRAY_BUFFER, sizecol, col,GL_STATIC_DRAW);
// 用于关联 shader (location = 1) color
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(GLfloat), ); // 将顶点数据绑定到VBO上 // 将这个buffer关联到 GL_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, buffers[Vertices+offset]);
// 将数据传送到这个buffer
glBufferData(GL_ARRAY_BUFFER, sizevert, vert,GL_STATIC_DRAW);
// 用于关联 shader (location = 0) vertex
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(GLfloat), );    // 将三角形序列绑定到VBO上
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[Elements+offset]) ;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeind, inds,GL_STATIC_DRAW);
PrimType[object] = type;
NumElems[object] = sizeind;
// Prevent further modification of this VAO by unbinding it
glBindVertexArray();
} void drawobject(GLuint object) {
glBindVertexArray(VAOs[object]);
glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNED_BYTE, );
glBindVertexArray();
}

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

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

vertex shader

 # version  core
// Do not modify the above version directive to anything older than 330, as
// modern OpenGL will not work properly due to it not being core at the time. // Shader inputs
layout (location = ) in vec3 position;
layout (location = ) in vec3 color; // Shader outputs, if any
out vec3 Color; // Uniform variables
uniform mat4 modelview;
uniform mat4 projection; void main() {
gl_Position = projection * modelview * vec4(position, 1.0f);
Color = color; // Just forward this color to the fragment shader
}

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

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

1. 创建物体

先看initobject函数(见上文),可以看到函数内部代码大致分成了4块,我们分别解释。

代码就不重复复制了。

offset那个变量不用管,那个是用于区分当前初始化的是第一个物体还是第二个物体的,你们可以默认这个程序只有一个物体然后忽视掉代码中的所有offset。

(1). 将VAO绑定到context

可以简单的将VAO理解为一个我们将要显示的物体。这个物体有许多属性,比如所有顶点,颜色,三角形的顶点序列。而这些属性都又由VBO来表示。

将其绑定到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();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(GLfloat), );

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

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

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

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

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

绑定的过程与上面一样,不过由于shader中并不需要这个数据,因此我们不用将其暴露给shader


2. 显示物体

创建完物体,我们可以显示出来了

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

 glBindVertexArray(VAOs[object]);
glDrawElements(PrimType[object], NumElems[object], GL_UNSIGNED_BYTE, );
glBindVertexArray();

第一行说明我们现在开始操作物体1

第二行让OpenGL画出物体1(为什么不是物体2?因为我们上一步已经说明了现在的context是物体1)

第三行解绑物体1

OpenGL VAO, VBO 使用简介的更多相关文章

  1. opengl VAO ,VBO

    A Vertex Array Object (VAO) is an object which contains one or more Vertex Buffer Objects and is des ...

  2. OpenGL ES 2: debugging, and improvements to VAO, VBO

    OpenGL ES 2: debugging, and improvements to VAO, VBO http://www.altdevblogaday.com/2013/10/12/opengl ...

  3. opengl中VAO,VBO,IBO用法小结(zz) 【转】

    http://cowboy.1988.blog.163.com/blog/static/751057982014380251300/ opengl中VAO,VBO,IBO用法小结 这三个玩意全面取代旧 ...

  4. opengl中VAO,VBO,IBO用法小结【转】

    http://cowboy.1988.blog.163.com/blog/static/751057982014380251300/ opengl中VAO,VBO,IBO用法小结 这三个玩意全面取代旧 ...

  5. OpenGL渲染管道,Shader,VAO&VBO&EBO

    OpenGL渲染管线 (也就是)OpenGL渲染一帧图形的流程 以下列举最简单的,渲染一个三角形的流程,你可以将它视为 精简版OpenGL渲染管线 更复杂的流程也仅仅就是:在此基础上的各个流程中 添加 ...

  6. VAO VBO IBO大乱炖

    最近对程序中绘制卡顿的问题忍无可忍,终于决定下手处理了.程序涉及的绘制比较多,除了点.线.三角形.多边形.圆柱体之外,还有自组格式模型.开始想全部采用显示列表优化,毕竟效率最高,虽然显示列表存在编译之 ...

  7. [转]OpenGL通过VBO实现顶点数组绘制顶点

    #include "stdlib.h" #include <OpenGL/glext.h> #include <GLUT/GLUT.h> #define B ...

  8. 第15.46节、PyQt显示部件:OpenGL Widget部件功能简介及使用案例

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 OpenGL Widget部件是一个Op ...

  9. OpenGL中VA,VAO,VBO和EBO的区别

    1,顶点数组(Vertex Array) VA,顶点数组也是收集好所有的顶点,一次性发送给GPU.不过数据不是存储于GPU中的,绘制速度上没有显示列表快,优点是可以修改数据. 4.VBO(Vertex ...

随机推荐

  1. 不常见使用的css

    flex和white-space等属性 1.flex属性让所有弹性盒模型对象的子元素都有相同的长度,忽略它们内部的内容.style={{flex:5}},该元素占父元素的六分之五. 2. white- ...

  2. 在VS2010下使用AppFace

    AppFace的介绍网上一大堆,此文仅为自己作个记录,方便以后查看. 一.需要的文件:1.AppFace.h  2.appface.lib 3.appface.dll 4.macosx_af.urf ...

  3. The type exists in both DLLs

    2>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\c0b37647\aaceda91\Ap ...

  4. 【180】IDL 读写 HDF 文件

    HDF(Hierarchical Data Formats)数据格式由 NCSA 开发.HDF 提供了大量的数据模式,包括多维数组.表格.图像.注解和调色板.在下面的章节中,将描述 HDF 科学数据系 ...

  5. winform 窗体设置成无边框、可拖拽、四周圆角

    最近做一个及时通讯系统的登录界面,现在将界面用到的无边框.可拖拽.四周圆角的方法分享如下: 1.无边框的窗体: 把FormBorderStyle的属性设置为none 2.可拖拽:private Poi ...

  6. poj 2699 The Maximum Number of Strong Kings【最大流+枚举】

    因为n很小所以从大到小枚举答案.(从小到大先排个序,因为显然胜利场次越多越容易成为strong king.然后对于每个枚举出来的ans建图.点分别表示人和比赛.s向所有人连接流量为胜利场次的边,所有比 ...

  7. SAMP论文学习

    SAMP:稀疏度自适应匹配追踪 实际应用中信号通常是可压缩的而不一定为稀疏的,而且稀疏信号的稀疏度我们通常也会不了解的.论文中提到过高或者过低估计了信号的稀疏度,都会对信号的重构造成影响.如果过低估计 ...

  8. _bzoj1798 [Ahoi2009]Seq 维护序列seq【线段树 lazy tag】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 注意,应保证当前节点维护的值是正确的,lazy tag只是一个下传标记,在下传时应即时 ...

  9. 【洛谷4769】[NOI2018] 冒泡排序(动态规划_组合数学)

    题目: 洛谷 4769 博客页面左下角的嘴嘴瓜封神之战中的题目 分析: 一个排列交换次数为 \(\frac{1}{2}\sum_{i=1}^{n}|i-p_i|\) 的充要条件是这个排列不存在长度为 ...

  10. AC自动机 HDOJ 2222 Keywords Search

    题目链接 题意:每个文本串的出现次数 分析:入门题,注意重复的关键字算不同的关键字,还有之前加过的清零.   新模板,加上last跑快一倍 #include <bits/stdc++.h> ...