// shader_utils.cpp #include "shader_utils.hpp" #include 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(); std::cout << "顶点着色器代码:\n" << VertexShaderCode << std::endl; } 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(); std::cout << "片元着色器代码:\n" << FragmentShaderCode << std::endl; } 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 VertexShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); std::cerr << "顶点着色器编译错误:\n" << &VertexShaderErrorMessage[0] << std::endl; if (Result == GL_FALSE) { std::cerr << "顶点着色器编译失败" << std::endl; return 0; } } // 编译片元着色器 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 FragmentShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); std::cerr << "片元着色器编译错误:\n" << &FragmentShaderErrorMessage[0] << std::endl; if (Result == GL_FALSE) { std::cerr << "片元着色器编译失败" << std::endl; return 0; } } // 链接程序 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 ProgramErrorMessage(InfoLogLength+1); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); std::cerr << "着色器程序链接错误:\n" << &ProgramErrorMessage[0] << std::endl; if (Result == GL_FALSE) { std::cerr << "着色器程序链接失败" << std::endl; return 0; } } // 验证程序 glValidateProgram(ProgramID); glGetProgramiv(ProgramID, GL_VALIDATE_STATUS, &Result); glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); if (InfoLogLength > 0) { std::vector ProgramErrorMessage(InfoLogLength+1); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); std::cerr << "着色器程序验证错误:\n" << &ProgramErrorMessage[0] << std::endl; if (Result == GL_FALSE) { std::cerr << "着色器程序验证失败" << std::endl; return 0; } } // 打印所有uniform变量的位置 GLint numUniforms; glGetProgramiv(ProgramID, GL_ACTIVE_UNIFORMS, &numUniforms); std::cout << "活动uniform变量数量: " << numUniforms << std::endl; for (GLint i = 0; i < numUniforms; i++) { char uniformName[256]; GLint uniformSize; GLenum uniformType; glGetActiveUniform(ProgramID, i, sizeof(uniformName), NULL, &uniformSize, &uniformType, uniformName); GLint uniformLocation = glGetUniformLocation(ProgramID, uniformName); std::cout << "Uniform变量 " << i << ": " << uniformName << " (类型: " << uniformType << ", 大小: " << uniformSize << ", 位置: " << uniformLocation << ")" << std::endl; } glDetachShader(ProgramID, VertexShaderID); glDetachShader(ProgramID, FragmentShaderID); glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; }