Shader
Shader(着色器):一种运行在GPU端的类C语言GLSL,用于处理顶点数据以及决定像素片元最终着色。
Shader对三角形数据的处理,分为顶点处理和片元处理,分别称为顶点着色器(Vertex Shader)和片元着色器(Fragment Shader)
GLSL
GLSL(Graphic Library Shader Language):着色器使用GLSL编写,GLSL包含一些针对向量和矩阵操作的有用特性。
- GLSL程序本质上是一种将输入转化为输出的程序
- GLSL程序是战役中非常独立的程序,彼此之间无法通信,只能通过输入输出相互承接。
Vertex Shader
顶点着色器的主要任务是将输入的顶点坐标转换为NDC坐标。
tips:OpenGL是一个3D图形库,所以在OpenGL中我们指定的所有坐标都是3D坐标(x、y和z)。OpenGL不是简单地把所有的3D坐标变换为屏幕上的2D像素;OpenGL仅当3D坐标在3个轴(x、y和z)上-1.0到1.0的范围内时才处理它。
#version 460 core:表示使用opengl4.6核心模式
Fragment Shader
片元着色器所做的是计算像素最后的颜色输出
编译和链接
//1 完成vs与fs的源代码,并且装入字符串
const char* vertexShaderSource =
"#version 460 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
//2 创建Shader程序(vs、fs)
GLuint vertex, fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
fragment = glCreateShader(GL_FRAGMENT_SHADER);
//3 为shader程序输入shader代码
glShaderSource(vertex, 1, &vertexShaderSource, NULL);
glShaderSource(fragment, 1, &fragmentShaderSource, NULL);
int success = 0;
char infoLog[1024];
//4 执行shader代码编译
glCompileShader(vertex);
//检查vertex编译结果
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex, 1024, NULL, infoLog);
std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;
}
glCompileShader(fragment);
//检查fragment编译结果
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment, 1024, NULL, infoLog);
std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;
}
//5 创建一个Program壳子
GLuint program = 0;
program = glCreateProgram();
//6 将vs与fs编译好的结果放到program这个壳子里
glAttachShader(program, vertex);
glAttachShader(program, fragment);
//7 执行program的链接操作,形成最终可执行shader程序
glLinkProgram(program);
//检查链接错误
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(program, 1024, NULL, infoLog);
std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;
}
//清理
glDeleteShader(vertex);
glDeleteShader(fragment);
glShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
string表示一个字符串数组,count表示数组大小,length是一个长度数组,表示字符串数组中每个字符串的长度
string 是一个指向常量指针的常量指针,既不能改变其指向也不能改变值。