对于着色器创建使用,可以按照下面步骤:
1. 创建着色器对象
创建一个着色器对象
将着色器源代码编译为对象
验证着色器的编译是否成功。
2. 创建着色器程序
创建一个着色器程序
将着色器对象关联到着色器程序
链接着色器程序
判断着色器的链接是否成功
使用着色器来处理顶点和片元
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path)
{
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); //创建着色器对象
GLuint framentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Glint tesscontrolShader = glCreateShader(GL_TESS_CONTROL_SHADER); 细分着色器
// GLint geometry = glCreateShader(GL_GEOMETRY_SHADER); 几何着色器
/// 读取vectex shader code
std::ifstream vertexShaderStream(vertex_file_path, std::ios::in);
std::string vertexShaderCode;
if (vertexShaderStream.is_open())
{
std::string line;
while (getline(vertexShaderStream, line))
vertexShaderCode += "\n" + line;
vertexShaderStream.close();
}
else
{ printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
getchar();
return 0;
}
/// 读取fragment shader code
std::ifstream fragmentShaderStream(fragment_file_path, std::ios::in);
std::string fragmentShaderCode;
if (fragmentShaderStream.is_open())
{
std::string line;
while (getline(fragmentShaderStream, line))
fragmentShaderCode += "\n" + line;
fragmentShaderStream.close();
}
else
{ printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", fragment_file_path);
getchar();
return 0;
}
/// specify vertex shorce and compile
const GLchar *vertexCodePointer = vertexShaderCode.c_str();
glShaderSource(vertexShaderID, 1, &vertexCodePointer, NULL); //关联着色器对象
glCompileShader(vertexShaderID); //编译着色器对象
GLint success;
int infoLogLength;
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success); //返回编译状态
glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); //返回编译信息
if (infoLogLength > 0)
{
std::vector<char> vertexShaderErrorMessage(infoLogLength + 1);
glGetShaderInfoLog(vertexShaderID, infoLogLength, NULL, &vertexShaderErrorMessage[0]); //返回编译结果,验证是否成功
printf("%s\n", &vertexShaderErrorMessage[0]);
}
/// compile fragment shader
const GLchar *fragmentCodePointer = fragmentShaderCode.c_str();
glShaderSource(framentShaderID, 1, &fragmentCodePointer, NULL);
glCompileShader(framentShaderID);
glGetShaderiv(framentShaderID, GL_COMPILE_STATUS, &success);
glGetShaderiv(framentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0)
{
std::vector<char> fragmentShaderErrorMessage(infoLogLength + 1);
glGetShaderInfoLog(framentShaderID, infoLogLength, NULL, &fragmentShaderErrorMessage[0]);
printf("%s\n", &fragmentShaderErrorMessage[0]);
}
/// link the program
GLuint programID = glCreateProgram(); //创建着色器程序
glAttachShader(programID, vertexShaderID); //将着色器对象关联到程序
glAttachShader(programID, framentShaderID);
glLinkProgram(programID); //链接程序
glGetProgramiv(programID, GL_LINK_STATUS, &success); //查询链接结果和信息
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0){
std::vector<char> ProgramErrorMessage(infoLogLength + 1);
glGetProgramInfoLog(programID, infoLogLength, NULL, &ProgramErrorMessage[0]); //返回链接日志,判断是否成功
printf("%s\n", &ProgramErrorMessage[0]);
}
glDetachShader(programID, vertexShaderID); //取消关联
glDetachShader(programID, framentShaderID);
glDeleteShader(vertexShaderID); //删除关联
glDeleteShader(framentShaderID);
return programID;
}
另外还有 glValidateProgram(programID): 在生成可执行程序后,使用它确保不会出现错误
glUseProgram(programID): 调用着色器
具体见:http://blog.csdn.net/Dionysos_lai/article/details/50939229
OpenGL着色语言GLSL
1、OpenGL的可编程管线
①顶点着色阶段:接收顶点数据,独立处理每个顶点。
②细分着色阶段:可选阶段。在OpenGL管线内部生成新的几何体。
③几何着色阶段:可选阶段。在OpenGL管线内部对所有几何图元进行修改。
④片元着色阶段:处理OpenGL光栅化之后生成的独立片元。
⑤计算着色阶段:在程序中相对独立的一个阶段。
2、OpenGL/GLSL接口
3、GLSL基础
①基本数据类型
float、int、uint、bool
②二维向量
vec2、ivec2、uvec2、bvec2
③三维向量
vec3、ivec3、uvec3、bvec3
④四维向量
vec4、ivec4、uvec4、bvec4
⑤矩阵类型
mat2、mat3、mat4
mat2x2、mat2x3、mat2x4
mat3x2、mat3x3、mat3x4
mat4x2、mat4x3、mat4x4
⑥GLSL类型限定符
invariant限制符、precise限制符。
uniform块、buffer块、in/out块