OpenGL学习笔记(0)

配置OpenGL 以及第一个程序。

Mac下配置OpenGL

  1. 安装homebrew

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

  2. 安装GLEW与GLFW

    brew install glew

    brew install glfw

  3. 新建Xcode的Command Line C++项目,在build settings中设置Header Search PathLibrary Search Path,在其中添加对应的glewglfw的头文件(include)与库文件(lib)路径。

  4. build Phases中添加库文件屏幕快照 2018-07-28 下午5.27.39

(在对应的文件夹中将两个/.dylib的文件直接拖拽进来)

  1. 配置GLAD:
    1. 打开在线服务,API选择3.3及以上,Profile选择Core,勾选Options中的Generate a loader,点击GENERATE,会生成一个压缩包,下载。
    2. 将子目录中的/include/glad与/include/KHR复制到/usr/Local/include文件夹下。(如果/usr文件夹隐藏,可用快捷键command+shift+G输入访问)
    3. 将/src中的glad.c复制到Xcode工程文件夹下。
    4. build settings中添加路径/usr/local/include
  2. 此时如果不出意外的话,你的第一个测试程序已经可以运行了,点击测试代码,复制到自己的.cpp文件中执行,会出现一个黑色窗口。

图形渲染管线(Graphics PipeLines)

​ 图形渲染管线接受一组3D坐标,然后转换成屏幕上的2D像素。

  1. 顶点着色器:以数组的形式传递3个3D坐标作为图形渲染管线的输入,用来表示一个三角形,这个数组称为顶点数据(Vertex Data)。顶点数据是一系列顶点的集合,一个顶点是一个3D坐标的数据的集合。顶点数据由顶点属性表示。顶点着色器将一种3D坐标转换成另一种3D坐标,同时对顶点属性做出一些处理。
  2. 图元装配:将顶点着色器输出的所有顶点作为输入,将所有顶点装配成制定形状的图元。
  3. 几何着色器:把图元形式的一系列顶点集合作为输入,通过产生新的顶点构造出新的图元来产生其他形状。
  4. 光栅化阶段:把图元映射为最终屏幕上的像素,生成供片段着色器使用的片段,在片段着色器使用之前进行裁剪,丢弃视图之外的所有像素,以提升执行效率。
  5. 片段着色器:计算一个像素的最终颜色。
  6. Alpha 测试与混合阶段。

对象:

顶点缓冲对象(Vertex Buffer Objects,VBO):

​ 普通的顶点数组的传输,需要在绘制的时候频繁的从CPU向GPU传送数据,这种做法效率低下,为了加快显示速度,显卡增加了一个扩展,用于管理内存,在GPU内存中存储大量顶点数据,这样大大减少了从CPU到GPU的数据拷贝开销,从而提升了程序运行的效率。

1
2
3
4
5
void glGenBuffers(GLsizei n,GLuint* buffers);	// 返回n个当前未使用的缓存对象名称,并保存到buffers数组中

void glBindBuffer(GLenum target,GLuint buffer); // 指定当前激活的缓存对象,target表示指定绑定的目标类型,buffer为要绑定的缓存对象的名称

void glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); // 把用户定义的数据复制到当前绑定缓冲:target目标缓冲的类型,size指定传输数据的大小,data希望发送的实际数据,usage表示希望显卡如何使用该数据
  • usage的可选内容及意义:
    • GL_STATIC_DRAW :数据不会或几乎不会改变。
    • GL_DYNAMIC_DRAW:数据会被改变很多。
    • GL_STREAM_DRAW :数据每次绘制时都会改变。

顶点数组对象(Vertex Array Object,VAO):

​ 每当我们绘制一个几何体时,我们需要重复同样的工作(首先绑定缓冲区、然后设置顶点属性)。当需要绘制的物体很多时,这个过程就显得有些耗时。VAO将所有顶点绘制过程中的这些设置与绑定过程集中存储在一起,当配置顶点属性指针时,只需要将那些调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。这使在不同顶点数据和属性配置之间切换变得非常简单,只需要绑定不同的VAO就行了。刚刚设置的所有状态都将存储在VAO中。VAO可以看作一个容器,包含了多个VBO。

一个顶点数组对象会储存以下这些内容:

  • glEnableVertexAttribArray和glDisableVertexAttribArray的调用。
  • 通过glVertexAttribPointer设置的顶点属性配置。
  • 通过glVertexAttribPointer调用与顶点属性关联的顶点缓冲对象。

索引缓冲对象(Element Buffer Object,EBO):

​ 和顶点缓冲对象一样,EBO也是一个缓冲,它专门储存索引,OpenGL调用这些顶点的索引来决定该绘制哪个顶点。

​ glDrawElements函数从当前绑定到GL_ELEMENT_ARRAY_BUFFER目标的EBO中获取索引。这意味着我们必须在每次要用索引渲染一个物体时绑定相应的EBO,这还是有点麻烦。不过顶点数组对象同样可以保存索引缓冲对象的绑定状态。VAO绑定时正在绑定的索引缓冲对象会被保存为VAO的元素缓冲对象。绑定VAO的同时也会自动绑定EBO。

​ 当目标是GL_ELEMENT_ARRAY_BUFFER的时候,VAO会储存glBindBuffer的函数调用。这也意味着它也会储存解绑调用,所以确保你没有在解绑VAO之前解绑索引数组缓冲,否则它就没有这个EBO配置了。