#define GLFW_INCLUDE_NONE #include "OpenGLShader.h" #include #include #include #include #include namespace XCEngine { namespace RHI { OpenGLShader::OpenGLShader() : m_program(0) { } OpenGLShader::~OpenGLShader() { Shutdown(); } bool OpenGLShader::CompileFromFile(const char* vertexPath, const char* fragmentPath) { std::string vertexCode, fragmentCode; std::ifstream vShaderFile(vertexPath), fShaderFile(fragmentPath); if (!vShaderFile.is_open() || !fShaderFile.is_open()) { return false; } std::stringstream vShaderStream, fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); vShaderFile.close(); fShaderFile.close(); vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); return Compile(vertexCode.c_str(), fragmentCode.c_str()); } bool OpenGLShader::Compile(const char* vertexSource, const char* fragmentSource) { unsigned int vertex, fragment; vertex = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex, 1, &vertexSource, NULL); glCompileShader(vertex); if (!CheckCompileErrors(vertex, "VERTEX")) { return false; } fragment = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment, 1, &fragmentSource, NULL); glCompileShader(fragment); if (!CheckCompileErrors(fragment, "FRAGMENT")) { return false; } m_program = glCreateProgram(); glAttachShader(m_program, vertex); glAttachShader(m_program, fragment); glLinkProgram(m_program); if (!CheckLinkErrors(m_program)) { return false; } glDeleteShader(vertex); glDeleteShader(fragment); return true; } void OpenGLShader::Shutdown() { if (m_program) { glDeleteProgram(m_program); m_program = 0; } } void OpenGLShader::Use() const { glUseProgram(m_program); } void OpenGLShader::SetInt(const std::string& name, int value) const { glUniform1i(glGetUniformLocation(m_program, name.c_str()), value); } void OpenGLShader::SetFloat(const std::string& name, float value) const { glUniform1f(glGetUniformLocation(m_program, name.c_str()), value); } void OpenGLShader::SetVec3(const std::string& name, float x, float y, float z) const { glUniform3f(glGetUniformLocation(m_program, name.c_str()), x, y, z); } void OpenGLShader::SetVec3(const std::string& name, const float* values) const { glUniform3fv(glGetUniformLocation(m_program, name.c_str()), 1, values); } void OpenGLShader::SetMat4(const std::string& name, const float* value) const { glUniformMatrix4fv(glGetUniformLocation(m_program, name.c_str()), 1, GL_FALSE, value); } bool OpenGLShader::CheckCompileErrors(unsigned int shader, const char* type) { int success; char infoLog[1024]; glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader, 1024, NULL, infoLog); std::cout << "ERROR::SHADER_COMPILATION_ERROR: " << type << "\n" << infoLog << std::endl; return false; } return true; } bool OpenGLShader::CheckLinkErrors(unsigned int program) { int success; char infoLog[1024]; glGetProgramiv(program, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(program, 1024, NULL, infoLog); std::cout << "ERROR::PROGRAM_LINKING_ERROR\n" << infoLog << std::endl; return false; } return true; } } // namespace RHI } // namespace XCEngine