初始化
glfwInit()
:初始化GLFWglfwWindowHint()
:设置窗口版本glfwCreateWindow()
:新建一个窗口glfwGetFramebufferSize()
:获得实际占用的帧缓存大小glfwMakeContextCurrent()
:指定当前线程所使用的上下文glViewport()
:设置视口的大小glfwWindowShouldClose()
:检测窗口是否关闭glfwPollEvents()
:检查并处理与窗口、键盘、鼠标等相关的所有事件,并触发相应的回调函数glClearColor()
:清空颜色缓冲区,并设置颜色glClear()
:清空屏幕,并给每个像素画上背景色glfwSwapBuffers()
:打开双缓存模式glfwTerminate()
:关闭GLFW
着色器
设置顶点
GLfloat vertices_1[] =
{
0.0f, 0.5f, 0.0f, // 上顶点
-0.5f, -0.5f, 0.0f, // 左顶点
0.5f, -0.5f, 0.0f, // 右顶点
};
### 编写顶点着色器
- 设置顶点着色器源码(后面详细讲解)
// 顶点着色器
const GLchar* vertexCode_1 = "#version 330 core\n" // 3.30版本(版本申明)
"layout(location = 0) in vec3 position_1;\n" // 三个浮点数 vector 向量表示位置。position是变量,并储存了这三个向量
"void main()\n"
"{\n"
"gl_Position = vec4(position_1, 1.0f);\n" // 核心函数(位置信息赋值)
"}\n";
glCreateShader()
:创建顶点着色器对象glShaderSource()
:将着色器源码附加到着色器对象上glCompileShader()
:编译着色器glGetShaderiv()
:获取编译状态glGetShaderInfoLog()
:获取错误消息
编写片元着色器
- 过程和编写顶点着色器相同
const GLchar* fragmentCode_1 = "#version 330 core\n" // 版本信息3.3
"out vec4 FragColor_1;\n" // 输出是四个浮点数构成的一个向量 RGB+aerfa
"void main()\n"
"{\n"
"FragColor_1 = vec4(0.5f, 0.75f, 0.25f, 1.0f);\n" // 核心函数(颜色信息赋值)
"}\n";
GLuint fragmentShader_1 = glCreateShader(GL_FRAGMENT_SHADER); // 创建片元着色器对象
glShaderSource(fragmentShader_1, 1, &fragmentCode_1, NULL); // 将片元着色器的内容传进来
glCompileShader(fragmentShader_1); // 编译顶点着色器
GLint flag; // 用于判断编译是否成功的标识符
GLchar infoLog[512]; // 我用的512个字符来装错误信息(如果出错了的话)
glGetShaderiv(fragmentShader_1, GL_COMPILE_STATUS, &flag); // 获取编译状态
if( !flag )
{
glGetShaderInfoLog(fragmentShader_1, 512, NULL, infoLog); // 如果出错,用 glGetShaderInfoLog函数 来获取错误消息
cout<<"ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"<<infoLog<<endl;
}
编写着色器程序
glCreateProgram()
:创建着色器程序对象glAttachShader()
:附加着色器对象glLinkProgram()
:链接已附加着色器glGetProgramiv()
:检测链接着色器程序是否成功glDeleteShader()
:删除着色器对象glUseProgram()
:激活着色器程序
设置顶点数组对象(VAO)
glGenVertexArrays()
:创建顶点数组对象,存储了顶点数据的格式以及顶点数据所需的 VBO 对象的引用glBindVertexArray()
:绑定顶点数组对象,传入0
解绑
设置顶点缓冲对象(VBO)
glGenBuffers()
:创建顶点缓冲对象glBindBuffer()
:绑定顶点缓冲对象类型glBufferData()
:复制数据到缓冲内存, 即顶点数据传输到 GPU 的显存中,传入0
解绑
设值索引缓冲对象(EBO)
- glBindBuffer() 需要绑定到 GL_ELEMENT_ARRAY_BUFFER 目标上,并使用 glDrawElements() 进行绘制
链接顶点属性
glVertexAttribPointer()
:定义顶点属性, 设定了如何从顶点缓冲区中读取数据,以及这些数据的格式glEnableVertexAttribArray()
:启用顶点属性
绘制图形
glDrawArrays()
:使用当前已激活着色器绘制图元
GLSL
模板结构
- 版本声明
- 定义输入输出变量
- 定义uniform函数
- 定义main函数
向量结构
类型 | 含义 |
---|---|
vec+n | 包含n 个 float 分量的向量 |
bvec+n | 包含n 个 bool 分量的向量 |
ivec+n | 包含n 个 int 分量的向量 |
uvec+n | 包含n 个 unsigned int 分量的向量 |
dvec+n | 包含n 个 double 分量的向量 |
- 通过链操作符 +
.x
.y
.z
.w
来访问第1、2、3、4个分量
着色器的输入输出
- 顶点着色器的输入来自顶点数据,使用
layout (location = 0)
来链接 - 片段着色器的输入来自顶点着色器的输出,要确保片段着色器的输入变量和顶点着色器的输出变量相同,OpenGL就会把他们链接一起
uniform函数
功能
- 从CPU中的应用向GPU中的着色器发送数据,从而能够在运行阶段控制着色器
特点
- 全局性:uniform 变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问
- 持久性:无论把 uniform 值设置成什么,uniform 会一直保存它们的数据,直到它们被重置或更新。
着色器类
- 私有成员变量:顶点着色器、片段着色器
- 公共成员变量:着色器程序
- 构造函数:Shader(const GLchar *vertexPath, const GLchar *fragmentPath)
- 读取参数中传入的用GLSL编写的着色器源码,并转化为char数组
- 编译顶点和片段着色器
- 链接着色器程序
- 删除顶点和片段着色器
- 析构函数:~Shader
- 公共成员方法:激活着色器程序
Last updated on