OpenGL扫盲入门

本文详细介绍了OpenGL开发环境,包括使用glad加载函数、glfw管理窗口和OpenGL上下文,以及关键概念如VBO、VAO、EBO、顶点着色器和不同光照模型的实现。着重讲解了状态机、顶点数据结构和OpenGL中的bind操作,以及如何配置VAO和VBO以支持多边形渲染。
摘要由CSDN通过智能技术生成

Opengl开发环境

glad

因为OpenGL只是一个标准/规范,具体的实现是由驱动开发商针对特定显卡实现的。由于OpenGL驱动版本众多,它大多数函数的位置都无法在编译时确定下来,需要在运行时查询。所以任务就落在了开发者身上,开发者需要在运行时获取函数地址并将其保存在一个函数指针中供以后使用。取得地址的方法因平台而异,在Windows上会是类似这样:

//glad 加载函数
typedef void (*GL_GENBUFFERS)(GLsizei, GLuint*);
GL_GENBUFFERS glGenBuffers =(GL_GENBUFFERS)glfwGetProcAddress("glGenBuffers"); //window下 调用wglGetProcAddress
GLuint buffer;
glGenBuffers(100, &buffer); 

glfw

用glfw创建并管理窗口和 OpenGL 上下文

OpenGL状态机

opengl是一个状态机,opengl的上下文context定义了状态

渲染管线

顶点着色器

将顶点三维坐标,转换为标准化设备坐标。

  • 顶点数组对象:Vertex Array Object,VAO
  • 顶点缓冲对象:Vertex Buffer Object,VBO
  • 元素缓冲对象:Element Buffer Object,EBO 或 索引缓冲对象 Index Buffer Object,IBO

VBO是位于GPU上的缓存,可以一次性发送大量顶点数据,需要定义OpenGL如何解释这些内存。创建VBO的步骤:

unsigned int VBO;
glGenBuffers(1, &VBO);

一些重要概念

vertex attribute : 包括positions,colors,纹理坐标等

vertex data:由vertex attributes组成。

vertex buffer objects(VBO):GPU中存储vertex data的空间。

vertex attribute pointer:用于解释vertex data。可以看做“格式”一类的概念。

element buffer objects(EBO):存储vertex data的索引。

vertex attribute objects(VAO):可以看做一个数组,其中元素为EBO,VBO与其对应的vertex attribute pointer。vertex shader从VAO中拿取数据并按其格式渲染。

bind:在VBO和VAO中都存在glBind*这类操作。

OpenGL中的bind有两种用法。

第一种,表示对全局变量的赋值。如“glBindBuffer(GL_ARRAY_BUFFER, &VBO)”就是将“VBO”这个名字赋值给GL_ARRAY_BUFFER这个全局变量。正因如此,在渲染loop中才需要随着场景的变化不断重新bind,即不断给各种全局变量赋新的值。

第二种,表示将数据提交给渲染管线。比如“glBindVertexArray(VAO)”就是将该VAO中的数据提交给vertex shader。

VAO和VBO使用流程

//定义和创建VAO VBO
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);

// 绑定VAO ,VBO 
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

//设置VBO数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

//配置顶点属性
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

//启用顶点属性
glEnableVertexAttribArray(0);

多个VAO

float firstTriangle[] = {
-0.9f, -0.5f, 0.0f,  // left 
-0.0f, -0.5f, 0.0f,  // right
-0.45f, 0.5f, 0.0f,  // top 
};
float secondTriangle[] = {
0.0f, -0.5f, 0.0f,  // left
0.9f, -0.5f, 0.0f,  // right
0.45f, 0.5f, 0.0f   // top 
};

VAO和VBO配置部分

(1).创建VAO和VBO

(2).对每一个VAO进行单独的配置,流程如下:

绑定VAO(glBindVertexArray)

写入VBO数据(glBufferData)

规定VBO数据解析规则(glVertexAttribPointer)

启动应用(glEnableVertexAttribArray)

	//创建VAO
	unsigned int VAOs[2];
	glGenVertexArrays(2, VAOs);

	//创建VBO
	unsigned int VBOs[2];
	glGenBuffers(2, VBOs);

	//绑定VAO
	//配置VAO[0];
	glBindVertexArray(VAOs[0]);
	glBindBuffer(GL_ARRAY_BUFFER,VBOs[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(firstTriangle), firstTriangle, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	//glEnableVertexAttribArray表示启用该配置,0表示顶点属性位置值
	glEnableVertexAttribArray(0);

	//配置VAO[1];
	glBindVertexArray(VAOs[1]);
	glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(secondTriangle), secondTriangle, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	//glEnableVertexAttribArray表示启用该配置,0表示顶点属性位置值
	glEnableVertexAttribArray(0);

OpenGl基本图元

GL_TRIANGLE

GL_TRIANGLE_STRIP

三角形条带

光照模型

颜色基本理论

看到的物体的颜色,是物体反射的光的颜色

  • 白光RGB(1,1,1)
  • 黑色光RGB(0,0,0)
  • 物体颜色RGB(1.0f, 0.5f, 0.31f)
glm::vec3 lightColor(1.0f, 1.0f, 1.0f);
glm::vec3 toyColor(1.0f, 0.5f, 0.31f);
glm::vec3 result = lightColor * toyColor; // = (1.0f, 0.5f, 0.31f);

Phone Lighting model

源自对物理世界最朴素的认知和模拟:

环境光照:没有绝对的黑,总会有一点光照

void main()
{
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;

    vec3 result = ambient * objectColor;
    FragColor = vec4(result, 1.0);
}

漫反射光照:正对着光线的地方,光照最强

需要计算光线和平面的法向,所有渲染的时候需要顶点法向

float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;

镜面光照:沿着光反射的方向看最亮,从观察者的角度

需要计算相机方向(视角方向)和光线反射方向的夹角

float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); //这个32是高光的反光度(Shininess)
vec3 specular = specularStrength * spec * lightColor;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值