opengl-homework/shader_utils.cpp
2025-05-21 12:14:57 +08:00

96 lines
3.6 KiB
C++

// shader_utils.cpp
#include "shader_utils.hpp"
#include <vector>
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){
// 创建着色器
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// 从文件读取顶点着色器代码
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open()){
std::stringstream sstr;
sstr << VertexShaderStream.rdbuf();
VertexShaderCode = sstr.str();
VertexShaderStream.close();
} else {
std::cerr << "无法打开 " << vertex_file_path << ". 你是否在正确的目录下运行程序?" << std::endl;
getchar();
return 0;
}
// 从文件读取片元着色器代码
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::stringstream sstr;
sstr << FragmentShaderStream.rdbuf();
FragmentShaderCode = sstr.str();
FragmentShaderStream.close();
} else {
std::cerr << "无法打开 " << fragment_file_path << ". 你是否在正确的目录下运行程序?" << std::endl;
getchar();
return 0;
}
GLint Result = GL_FALSE;
int InfoLogLength;
// 编译顶点着色器
std::cout << "编译着色器: " << vertex_file_path << std::endl;
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// 检查顶点着色器
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
std::cerr << &VertexShaderErrorMessage[0] << std::endl;
}
// 编译片元着色器
std::cout << "编译着色器: " << fragment_file_path << std::endl;
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// 检查片元着色器
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
std::cerr << &FragmentShaderErrorMessage[0] << std::endl;
}
// 链接程序
std::cout << "链接程序" << std::endl;
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// 检查程序
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
std::cerr << &ProgramErrorMessage[0] << std::endl;
}
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}