#include "Shader/Shader.hpp"
Shader::Shader(const std::string& vertexShaderPath, const std::string& fragmentShaderPath,std::string name) { this->name = name;
std::ifstream vertexShaderStream, fragmentShaderStream; std::stringstream vertexShaderCode, fragmentShaderCode;
vertexShaderStream.exceptions(std::ifstream::failbit | std::ifstream::badbit); fragmentShaderStream.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { vertexShaderStream.open(vertexShaderPath,std::ios::in); fragmentShaderStream.open(fragmentShaderPath,std::ios::in);
if(!vertexShaderStream.is_open() ||!fragmentShaderStream.is_open()) { throw std::runtime_error("Failed to open shader files."); }
vertexShaderCode << vertexShaderStream.rdbuf(); vertexShaderStream.close(); fragmentShaderCode << fragmentShaderStream.rdbuf(); fragmentShaderStream.close();
std::string vCode,fCode; vCode = vertexShaderCode.str(); fCode = fragmentShaderCode.str();
const char *vertexSource = vCode.c_str(); const char *fragmentSource = fCode.c_str();
unsigned int vertexShaderID = glCreateShader(GL_VERTEX_SHADER); unsigned int fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(vertexShaderID, 1, &vertexSource, NULL); glShaderSource(fragmentShaderID, 1, &fragmentSource, NULL); glCompileShader(vertexShaderID); glCompileShader(fragmentShaderID); int success; char infoLog[512]; glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShaderID, 512, NULL, infoLog); std::cerr << "顶点着色器编译失败!\n" << infoLog << std::endl; } glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShaderID, 512, NULL, infoLog); std::cerr << "片元着色器编译失败!\n" << infoLog << std::endl; } shaderProgramID = glCreateProgram(); glAttachShader(shaderProgramID, vertexShaderID); glAttachShader(shaderProgramID, fragmentShaderID); glLinkProgram(shaderProgramID); glGetProgramiv(shaderProgramID, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgramID, 512, NULL, infoLog); std::cerr << "着色器链接失败!\n" << infoLog << std::endl; } glDeleteShader(vertexShaderID); glDeleteShader(fragmentShaderID); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return; } }
Shader::Shader(const std::string &vertexShaderPath, const std::string &geometryShaderPath, const std::string &fragmentShaderPath,std::string name) { this->name = name;
std::ifstream vertexShaderStream,geometryShaderStream ,fragmentShaderStream; std::stringstream vertexShaderCode,geometryShaderCode , fragmentShaderCode;
vertexShaderStream.exceptions(std::ifstream::failbit | std::ifstream::badbit); geometryShaderStream.exceptions(std::ifstream::failbit | std::ifstream::badbit); fragmentShaderStream.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { vertexShaderStream.open(vertexShaderPath,std::ios::in); geometryShaderStream.open(geometryShaderPath,std::ios::in); fragmentShaderStream.open(fragmentShaderPath,std::ios::in);
if(!vertexShaderStream.is_open() ||!fragmentShaderStream.is_open()||!geometryShaderStream.is_open()) { throw std::runtime_error("Failed to open shader files."); }
vertexShaderCode << vertexShaderStream.rdbuf(); vertexShaderStream.close();
geometryShaderCode << geometryShaderStream.rdbuf(); geometryShaderStream.close(); fragmentShaderCode << fragmentShaderStream.rdbuf(); fragmentShaderStream.close();
std::string vCode,gCode,fCode; vCode = vertexShaderCode.str(); gCode = geometryShaderCode.str(); fCode = fragmentShaderCode.str();
const char *vertexSource = vCode.c_str(); const char *geometrySource = gCode.c_str(); const char *fragmentSource = fCode.c_str();
unsigned int vertexShaderID = glCreateShader(GL_VERTEX_SHADER); unsigned int geometryShaderID = glCreateShader(GL_GEOMETRY_SHADER); unsigned int fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(vertexShaderID, 1, &vertexSource, NULL); glShaderSource(geometryShaderID, 1, &geometrySource, NULL); glShaderSource(fragmentShaderID, 1, &fragmentSource, NULL); glCompileShader(vertexShaderID); glCompileShader(geometryShaderID); glCompileShader(fragmentShaderID); CheckCompileErrors(vertexShaderID, "VERTEX"); CheckCompileErrors(geometryShaderID, "GEOMETRY"); CheckCompileErrors(fragmentShaderID, "FRAGMENT");
shaderProgramID = glCreateProgram(); glAttachShader(shaderProgramID, vertexShaderID); glAttachShader(shaderProgramID, geometryShaderID); glAttachShader(shaderProgramID, fragmentShaderID); glLinkProgram(shaderProgramID); CheckCompileErrors(shaderProgramID, "PROGRAM");
glDeleteShader(vertexShaderID); glDeleteShader(geometryShaderID); glDeleteShader(fragmentShaderID); } catch (const std::exception& e) { std::cerr<<name<<"-着色器初始化失败!\n"<<e.what()<<std::endl; std::cerr << e.what() << std::endl; return; } }
void Shader::Use() { glUseProgram(shaderProgramID); }
void Shader::CheckCompileErrors(GLuint shader, std::string type) { int success; char infoLog[512];
if (type != "PROGRAM") { glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader, 512, NULL, infoLog); std::cerr << "Shader compilation error of type: " << type << "\n" << infoLog << std::endl; } } else { glGetProgramiv(shader, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shader, 512, NULL, infoLog); std::cerr << "Program linking error of type: " << type << "\n" << infoLog << std::endl; } } }
|