Skip to content

Files

Latest commit

author
fangshufeng
May 23, 2019
31984bc · May 23, 2019

History

History
211 lines (129 loc) · 5.23 KB

02.DrawPrimitive.md

File metadata and controls

211 lines (129 loc) · 5.23 KB

基本图元绘制

请先阅读你好,三角形

OpenGL中绘制一个图形的话大致分为以下几步

  1. 准备顶点数据
  2. 将数据送到GPU内存;
  3. 告诉OpenGL如何解析那段内存
  4. 绑定VAO
  5. 构造着色器程序
  6. 绘制

一、准备顶点数据

根据想画的图形的形状来定义顶点,坐标系为[-1,1]之间

现在想画个三角形

float vertices[] = {
   -0.5f, -0.5f, 0.0f, // left
   0.5f, -0.5f, 0.0f, // right
   0.0f,  0.5f, 0.0f  // top
};

二、将数据送到GPU内存

上面的顶点数据是cpu内存里面的,要想把数据送到GPU内存,需要用到VBO

unsigned int VBO;
glGenBuffers(1,&VBO);// 创建一个索引

glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW); // 将顶点数据放到GPU内存

三、告诉OpenGL如何解析那段内存

上面只是在GPU中开辟了一段内存空间,但是现在OpenGL并不知道如何使用那段内存,由于在你好三角形中已经有了详细的解释,这里不做过多的解释了

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

内存本身没有任何意义,我们通过glVertexAttribPointer赋予每隔一段内存以特殊的含义

四、绑定VAO

OpenGL为了简化渲染部分的代码,引入了VAO,它的结构如下,本来想重新画的,但是这张图已经画的很好了

使用如下

unsigned int VAO;
glGenVertexArrays(1,&VAO);

glBindVertexArray(VAO);
 

五、构造着色器程序

这个感觉没什么可说的,大家看下你好三角形就能看懂了

六、绘制

  1. 顶点数组绘制
  2. 索引绘制

6.1 顶点数组绘制

 glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES,0,3);

6.2 索引绘制

glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)

七、扫盲

7.1 为什么在VAO里面可以解绑VBO,却不能解绑EBO呢?

这个问题主要和VBOEBO的存放位置有关,VBO的数据和VAO没有关系,尽管引入了VAO,但是数据任然放在VBO中,但是EBO的数据是和VAO是有关系的,可以理解为

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);

伪代码的数据结构(实际上复杂的多,可以hooper查看下GLEngine(对应mac的/System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle)这个文件,我已经放到了02-基本图元绘制文件夹下)

 struct VertexArrayObject  {  
        BufferObject *pElementArrayBufferObject = NULL;  
        VertexAttribute attributes[GL_MAX_VERTEX_ATTRIB];  
}  

glBindBuffer方法类似与

void glBindBuffer(enum target, uint buffer)  {

if (target ==  GL_ELEMENT_ARRAY_BUFFER)  {
    vao->pElementArrayBufferObject = pBuffer;
}

}

实际是操作VAO中执行EBO的数据的,所以不能在VAO解绑之前解绑EBO,也就是下面这段代码的解释

// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

如何在VAO解绑之前解绑EBO就相当于将vao->pElementArrayBufferObject = 0;,所以到绘制的时候取得的vao->pElementArrayBufferObject为0。

八、常见图元

枚举值 含义
GL_POINTS
GL_TRAINGLES 三角形
GL_LINE_STRIP 线带
GL_LINE_LOOP 循环线带
GL_TRAINGLE_STRIP 连续填充三角形线带
GL_TRAINGLE_FAN 以第一个顶点为中三角形线带

GL_POINTS

glPointSize(80.0f);
glUniform4f(location,0.0f,1.0f,0.0f,1.0f);
glDrawArrays(GL_POINTS,0,1);

GL_LINE_STRIP

glDrawArrays(GL_LINE_STRIP,1,6);

GL_LINE_LOOP

glUniform4f(location,0.0f,0.0f,1.0f,1.0f);
glDrawArrays(GL_LINE_LOOP,7,4);

三角形相关的请自行测试下

image

代码请参考Primitive_line_strip.cpp