diff --git a/App/Source/Shader.cpp b/App/Source/Shader.cpp index fb04437..c0524ca 100644 --- a/App/Source/Shader.cpp +++ b/App/Source/Shader.cpp @@ -5,19 +5,24 @@ #include -uint32_t CreateComputeShader(const std::filesystem::path& path) +static std::string ReadTextFile(const std::filesystem::path& path) { std::ifstream file(path); if (!file.is_open()) { std::cerr << "Failed to open file: " << path.string() << std::endl; - return -1; + return {}; } std::ostringstream contentStream; contentStream << file.rdbuf(); - std::string shaderSource = contentStream.str(); + return contentStream.str(); +} + +uint32_t CreateComputeShader(const std::filesystem::path& path) +{ + std::string shaderSource = ReadTextFile(path); GLuint shaderHandle = glCreateShader(GL_COMPUTE_SHADER); @@ -79,3 +84,101 @@ uint32_t ReloadComputeShader(uint32_t shaderHandle, const std::filesystem::path& glDeleteProgram(shaderHandle); return newShaderHandle; } + +uint32_t CreateGraphicsShader(const std::filesystem::path& vertexPath, const std::filesystem::path& fragmentPath) +{ + std::string vertexShaderSource = ReadTextFile(vertexPath); + std::string fragmentShaderSource = ReadTextFile(fragmentPath); + + // Vertex shader + + GLuint vertexShaderHandle = glCreateShader(GL_VERTEX_SHADER); + + const GLchar* source = (const GLchar*)vertexShaderSource.c_str(); + glShaderSource(vertexShaderHandle, 1, &source, 0); + + glCompileShader(vertexShaderHandle); + + GLint isCompiled = 0; + glGetShaderiv(vertexShaderHandle, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) + { + GLint maxLength = 0; + glGetShaderiv(vertexShaderHandle, GL_INFO_LOG_LENGTH, &maxLength); + + std::vector infoLog(maxLength); + glGetShaderInfoLog(vertexShaderHandle, maxLength, &maxLength, &infoLog[0]); + + std::cerr << infoLog.data() << std::endl; + + glDeleteShader(vertexShaderHandle); + return -1; + } + + // Fragment shader + + GLuint fragmentShaderHandle = glCreateShader(GL_FRAGMENT_SHADER); + + source = (const GLchar*)fragmentShaderSource.c_str(); + glShaderSource(fragmentShaderHandle, 1, &source, 0); + + glCompileShader(fragmentShaderHandle); + + isCompiled = 0; + glGetShaderiv(fragmentShaderHandle, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) + { + GLint maxLength = 0; + glGetShaderiv(fragmentShaderHandle, GL_INFO_LOG_LENGTH, &maxLength); + + std::vector infoLog(maxLength); + glGetShaderInfoLog(fragmentShaderHandle, maxLength, &maxLength, &infoLog[0]); + + std::cerr << infoLog.data() << std::endl; + + glDeleteShader(fragmentShaderHandle); + return -1; + } + + // Program linking + + GLuint program = glCreateProgram(); + glAttachShader(program, vertexShaderHandle); + glAttachShader(program, fragmentShaderHandle); + glLinkProgram(program); + + GLint isLinked = 0; + glGetProgramiv(program, GL_LINK_STATUS, (int*)&isLinked); + if (isLinked == GL_FALSE) + { + GLint maxLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + + std::vector infoLog(maxLength); + glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); + + std::cerr << infoLog.data() << std::endl; + + glDeleteProgram(program); + glDeleteShader(vertexShaderHandle); + glDeleteShader(fragmentShaderHandle); + + return -1; + } + + glDetachShader(program, vertexShaderHandle); + glDetachShader(program, fragmentShaderHandle); + return program; +} + +uint32_t ReloadGraphicsShader(uint32_t shaderHandle, const std::filesystem::path& vertexPath, const std::filesystem::path& fragmentPath) +{ + uint32_t newShaderHandle = CreateGraphicsShader(vertexPath, fragmentPath); + + // Return old shader if compilation failed + if (newShaderHandle == -1) + return shaderHandle; + + glDeleteProgram(shaderHandle); + return newShaderHandle; +} diff --git a/App/Source/Shader.h b/App/Source/Shader.h index d628203..491d226 100644 --- a/App/Source/Shader.h +++ b/App/Source/Shader.h @@ -3,4 +3,7 @@ #include uint32_t CreateComputeShader(const std::filesystem::path& path); -uint32_t ReloadComputeShader(uint32_t shaderHandle, const std::filesystem::path& path); \ No newline at end of file +uint32_t ReloadComputeShader(uint32_t shaderHandle, const std::filesystem::path& path); + +uint32_t CreateGraphicsShader(const std::filesystem::path& vertexPath, const std::filesystem::path& fragmentPath); +uint32_t ReloadGraphicsShader(uint32_t shaderHandle, const std::filesystem::path& vertexPath, const std::filesystem::path& fragmentPath); \ No newline at end of file