diff --git a/Userland/Libraries/LibGL/Shaders/Program.cpp b/Userland/Libraries/LibGL/Shaders/Program.cpp index f55598d75e..8a76a258fd 100644 --- a/Userland/Libraries/LibGL/Shaders/Program.cpp +++ b/Userland/Libraries/LibGL/Shaders/Program.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace GL { @@ -49,7 +50,42 @@ ErrorOr Program::attach_shader(Shader& shader) ErrorOr Program::link() { - // FIXME: Implement actual program linker + m_info_log = TRY(String::from_utf8(""sv)); + + GLSL::Linker linker; + + // Link vertex shader objects + + Vector vertex_shader_object_files; + for (auto vertex_shader : m_vertex_shaders) + vertex_shader_object_files.append(vertex_shader->object_file()); + + auto linked_vertex_shader_or_error = linker.link(vertex_shader_object_files); + + if (linked_vertex_shader_or_error.is_error()) { + m_link_status = false; + m_info_log = linker.messages(); + return linked_vertex_shader_or_error.error(); + } + + m_linked_vertex_shader = linked_vertex_shader_or_error.release_value(); + + // Link fragment shader objects + + Vector fragment_shader_object_files; + for (auto fragment_shader : m_fragment_shaders) + fragment_shader_object_files.append(fragment_shader->object_file()); + + auto linked_fragment_shader_or_error = linker.link(fragment_shader_object_files); + + if (linked_fragment_shader_or_error.is_error()) { + m_link_status = false; + m_info_log = linker.messages(); + return linked_fragment_shader_or_error.error(); + } + + m_linked_fragment_shader = linked_fragment_shader_or_error.release_value(); + m_link_status = true; return {}; } diff --git a/Userland/Libraries/LibGL/Shaders/Program.h b/Userland/Libraries/LibGL/Shaders/Program.h index 7c9320cc6a..9c3b217add 100644 --- a/Userland/Libraries/LibGL/Shaders/Program.h +++ b/Userland/Libraries/LibGL/Shaders/Program.h @@ -9,10 +9,12 @@ #include #include #include +#include #include #include #include #include +#include namespace GL { @@ -31,6 +33,8 @@ private: Vector> m_vertex_shaders; Vector> m_fragment_shaders; Optional m_info_log; + OwnPtr m_linked_vertex_shader; + OwnPtr m_linked_fragment_shader; }; } diff --git a/Userland/Libraries/LibGL/Shaders/Shader.cpp b/Userland/Libraries/LibGL/Shaders/Shader.cpp index 8de48e6e07..501140aa0f 100644 --- a/Userland/Libraries/LibGL/Shaders/Shader.cpp +++ b/Userland/Libraries/LibGL/Shaders/Shader.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace GL { @@ -23,8 +24,22 @@ ErrorOr Shader::add_source(StringView source_code) ErrorOr Shader::compile() { - // FIXME: Implement actual shader compilation + m_info_log = TRY(String::from_utf8(""sv)); + + GLSL::Compiler compiler; + + auto object_file_or_error = compiler.compile(m_sources); + + if (object_file_or_error.is_error()) { + m_compile_status = false; + m_info_log = compiler.messages(); + return object_file_or_error.error(); + } + + m_object_file = object_file_or_error.release_value(); + m_compile_status = true; + return {}; } diff --git a/Userland/Libraries/LibGL/Shaders/Shader.h b/Userland/Libraries/LibGL/Shaders/Shader.h index 108298c33a..c4662ecbd6 100644 --- a/Userland/Libraries/LibGL/Shaders/Shader.h +++ b/Userland/Libraries/LibGL/Shaders/Shader.h @@ -9,12 +9,14 @@ #include #include #include +#include #include #include #include #include #include -#include +#include +#include namespace GL { @@ -27,6 +29,7 @@ public: ErrorOr compile(); GLenum type() const { return m_type; } bool compile_status() const { return m_compile_status; } + GLSL::ObjectFile const* object_file() const { return m_object_file.ptr(); } size_t info_log_length() const; size_t combined_source_length() const; @@ -41,6 +44,7 @@ private: GLenum m_type; bool m_compile_status { false }; Optional m_info_log; + OwnPtr m_object_file; }; }