#pragma once #include #include #include #include #include #include #include class Shader { public: // 程序ID unsigned int ID; // 构造器读取并构建着色器 Shader(const char* vertexPath, const char* fragmentPath) { std::string vertexCode; std::string fragmentCode; std::ifstream vShaderFile; std::ifstream fShaderFile; vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); std::stringstream vShaderStream, fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); vShaderFile.close(); fShaderFile.close(); vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (std::ifstream::failure e) { std::cout << "Error::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; std::cout << "=====Error Path=====" << std::endl << vertexPath << std::endl << fragmentPath << std::endl; } const char* vShaderCode = vertexCode.c_str(); const char* fShaderCode = fragmentCode.c_str(); // 编译着色器 unsigned int vertex, fragment; int success; char infoLog[512]; // 顶点着色器 vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vShaderCode, NULL); glCompileShader(vertex); glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertex, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // 片段着色器 fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fShaderCode, NULL); glCompileShader(fragment); glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragment, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } ID = glCreateProgram(); glAttachShader(ID, vertex); glAttachShader(ID, fragment); glLinkProgram(ID); glGetProgramiv(ID, GL_LINK_STATUS, &success); if (!success) { glGetShaderInfoLog(ID, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertex); glDeleteShader(fragment); } // 使用/激活程序 void use() { glUseProgram(ID); } // uniform工具函数 void setBool(const std::string& name, bool value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); } void setInt(const std::string& name, int value) const { glUniform1i(glGetUniformLocation(ID, name.c_str()), value); } void setFloat(const std::string& name, float value) const { glUniform1f(glGetUniformLocation(ID, name.c_str()), value); } void setMat4(const std::string& name, glm::mat4 m) { glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &m[0][0]); } void setVec3(const std::string& name, float x, float y, float z) { glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); } void setVec3(const std::string& name, const glm::vec3 v) { glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &v[0]); } };