#include #include #include #include #include namespace Light { glShader::glShader(BasicFileHandle vertexFile, BasicFileHandle pixelFile): m_ShaderID(0u) { // create m_ShaderID = glCreateProgram(); std::string vertexSource(vertexFile.GetData(), vertexFile.GetData() + vertexFile.GetSize()); std::string pixelSource(pixelFile.GetData(), pixelFile.GetData() + pixelFile.GetSize()); unsigned int vertexShader = CompileShader(vertexSource, Shader::Stage::VERTEX); unsigned int pixelShader = CompileShader(pixelSource, Shader::Stage::PIXEL); // attach shaders glAttachShader(m_ShaderID, vertexShader); glAttachShader(m_ShaderID, pixelShader); // link shader program glLinkProgram(m_ShaderID); // delete shaders (free memory) glDeleteShader(vertexShader); glDeleteShader(pixelShader); } glShader::~glShader() { glDeleteProgram(m_ShaderID); } void glShader::Bind() { glUseProgram(m_ShaderID); } void glShader::UnBind() { glUseProgram(NULL); } // shaderc::SpvCompilationResult glShader::CompileGLSL(BasicFileHandle file, Shader::Stage stage) // { // // compile options // shaderc::CompileOptions options; // options.SetTargetEnvironment(shaderc_target_env_opengl, shaderc_env_version_opengl_4_5); // options.SetOptimizationLevel(shaderc_optimization_level_performance); // // // compile // shaderc::Compiler compiler; // shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(reinterpret_cast(file.GetData()), stage == Shader::Stage::VERTEX ? // shaderc_shader_kind::shaderc_vertex_shader : shaderc_shader_kind::shaderc_fragment_shader, // file.GetName().c_str(), options); // // // log error // if (result.GetCompilationStatus() != shaderc_compilation_status_success) // { // LOG(err, "Failed to compile {} shader at {}...", stage == Shader::Stage::VERTEX ? "vertex" : // "pixel", file.GetPath()); LOG(err, " {}", result.GetErrorMessage()); // } // // return result; // } unsigned int glShader::CompileShader(std::string source, Shader::Stage stage) { // &(address of) needs an lvalue const char *lvalue_source = source.c_str(); unsigned int shader = glCreateShader( stage == Shader::Stage::VERTEX ? GL_VERTEX_SHADER : stage == Shader::Stage::PIXEL ? GL_FRAGMENT_SHADER : stage == Shader::Stage::GEOMETRY ? GL_GEOMETRY_SHADER : NULL ); // compile glShaderSource(shader, 1, &lvalue_source, NULL); glCompileShader(shader); // check int isCompiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); if (isCompiled == GL_FALSE) { int logLength = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); char *errorLog = (char *)alloca(logLength); glGetShaderInfoLog(shader, logLength, &logLength, &errorLog[0]); LOG(err, "glShader::glShader: failed to compile {} shader:\n {}", stage == Shader::Stage::VERTEX ? "Vertex" : "Pixel", errorLog); return NULL; } #define LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG #ifdef LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG // info log { int logLength = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); if (logLength) { char *infoLog = (char *)alloca(logLength); glGetShaderInfoLog(shader, logLength, &logLength, &infoLog[0]); LOG(warn, infoLog); } } #endif return shader; } } // namespace Light