【OpenGL】理解VAO、VBO、EBO和 shader中vertex、fragment交互。

1:首先了解GPU和渲染管道工作原理。

 

 2:解释VAO、VBO、EBO

  • 顶点数组对象:Vertex Array Object,VAO
  • 顶点缓冲对象:Vertex Buffer Object,VBO
  • 元素缓冲对象:Element Buffer Object

        在定义VBO时我们一般绑定一组顶点数据或者顶点信息。举例:

float vertices[] = {
		// positions          // normals           // texture coords
		-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
		 0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 0.0f,
		 0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
		 0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
		-0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 1.0f,
		-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
        ......
}
//绑定数据到VBO
    //定义VBO
    unsigned int VBO;
//生成缓冲区-----数量-名称
    glGenBuffers(1, &VBO);
//牵扯到上下文切换,绑定此处的VBO为当前环境中的VBO,同一时间只能存在一种状态
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
//将数据绑定到VBO中,推送至缓冲区
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        接下来就是VAO,VAO使用的是VBO中的数据,但是VAO可以有很多种读取方式,举例:

unsigned int lightCubeVAO, cubeVAO;
//---------------物体--------
//绑定VBO(切换上下文)
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//绑定VAO
    glGenVertexArrays(1, &cubeVAO);
    glBindVertexArray(cubeVAO);
	// 位置数据信息
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);

	// 法线信息
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);
    //光照贴图信息
	glVertexAttribPointer(2, 2, GL_FLOAT,GL_FALSE, 8*sizeof(float), (void*)(6 * sizeof(float)));
	glEnableVertexAttribArray(2);
//-----------------灯光-------
//只使用位置信息
//绑定VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//绑定VAO
glGenVertexArrays(1, &lightCubeVAO);
	glBindVertexArray(lightCubeVAO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);

        最后就是EBO,EBO就是让多个重复的点重合在一起,节省资源,例如:

//三角形顶点信息
 float vertices[] = {
         0.5f,  0.5f, 0.0f,  // top right
         0.5f, -0.5f, 0.0f,  // bottom right
        -0.5f, -0.5f, 0.0f,  // bottom left
        -0.5f,  0.5f, 0.0f   // top left 
    };
//每个三角形顶点数据信息
unsigned int indices[] = {  // note that we start from 0!
        0, 1, 3,  // first Triangle
        1, 2, 3   // second Triangle
    };

    unsigned int EBO;
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//画图时根据索引绘制
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

3:理解 vertex、fragment

好我们已经将顶点数据准备好了,接下来我们需要写shader了,一般有2个文件要写,第一个是顶点着色器(vertex),一个是片段着色器(fragment)。

        首先是Vertex文件,举例说明:

//版本信息
#version 330 core
//接受VAO输入的值
layout (location = 0) in vec3 aPos;
//脚本和shader交互传值用uniform
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
	//将顶点值输出--------渲染管道进行顶点变化
	gl_Position = projection * view * model * vec4(aPos, 1.0);

}

         然后是fragment,举例说明:

#version 330 core
//out接收数据 in输出数据
out vec4 FragColor;


void main()
{
    FragColor = vec4(1.0); // set alle 4 vector values to 1.0
    
}

4:总结

        其实我们的效果主要在shader中实现,在脚本代码中主要准备的数据信息,和一些其他信息,比如纹理贴图、光照贴图、法线贴图等。在shader中实现渲染管道的实现,渲染设置,其中脚本和shader也可以用uniform交互。其实很容易实现。 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值