Procházet zdrojové kódy

LibGL: Implement glAttachShader

Stephan Unverwerth před 2 roky
rodič
revize
7f062e35a4

+ 10 - 2
Userland/Libraries/LibGL/Shader.cpp

@@ -95,8 +95,16 @@ void GLContext::gl_delete_program(GLuint program)
 
 void GLContext::gl_attach_shader(GLuint program, GLuint shader)
 {
-    dbgln("gl_attach_shader({}, {}) unimplemented ", program, shader);
-    TODO();
+    auto program_it = m_allocated_programs.find(program);
+    auto shader_it = m_allocated_shaders.find(shader);
+    // FIXME: implement check "GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL."
+    RETURN_WITH_ERROR_IF(program_it == m_allocated_programs.end(), GL_INVALID_OPERATION);
+    RETURN_WITH_ERROR_IF(shader_it == m_allocated_shaders.end(), GL_INVALID_OPERATION);
+
+    // NOTE: attach_result is Error if the shader is already attached to this program
+    auto attach_result = program_it->value->attach_shader(*shader_it->value);
+    RETURN_WITH_ERROR_IF(attach_result.is_error() && attach_result.error().is_errno() && attach_result.error().code() == ENOMEM, GL_OUT_OF_MEMORY);
+    RETURN_WITH_ERROR_IF(attach_result.is_error(), GL_INVALID_OPERATION);
 }
 
 void GLContext::gl_link_program(GLuint program)

+ 30 - 2
Userland/Libraries/LibGL/Shaders/Program.cpp

@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <LibGL/GL/gl.h>
 #include <LibGL/Shaders/Program.h>
 
 namespace GL {
@@ -13,9 +14,36 @@ NonnullRefPtr<Program> Program::create()
     return adopt_ref(*new Program());
 }
 
-ErrorOr<void> Program::attach_shader(Shader&)
+bool Program::is_shader_attached(Shader const& shader) const
 {
-    TODO();
+    switch (shader.type()) {
+    case GL_VERTEX_SHADER:
+        return m_vertex_shaders.contains_slow(shader);
+    case GL_FRAGMENT_SHADER:
+        return m_fragment_shaders.contains_slow(shader);
+    default:
+        VERIFY_NOT_REACHED();
+    }
+}
+
+ErrorOr<void> Program::attach_shader(Shader& shader)
+{
+    if (is_shader_attached(shader))
+        return Error::from_string_literal("Trying to attach a shader that is already attached");
+
+    switch (shader.type()) {
+    case GL_VERTEX_SHADER:
+        TRY(m_vertex_shaders.try_append(shader));
+        break;
+
+    case GL_FRAGMENT_SHADER:
+        TRY(m_fragment_shaders.try_append(shader));
+        break;
+
+    default:
+        VERIFY_NOT_REACHED();
+    }
+
     return {};
 }
 

+ 2 - 0
Userland/Libraries/LibGL/Shaders/Program.h

@@ -6,6 +6,7 @@
 
 #pragma once
 
+#include <AK/Error.h>
 #include <AK/NonnullRefPtr.h>
 #include <AK/RefCounted.h>
 #include <AK/Vector.h>
@@ -17,6 +18,7 @@ class Program final : public RefCounted<Program> {
 public:
     static NonnullRefPtr<Program> create();
 
+    bool is_shader_attached(Shader const&) const;
     ErrorOr<void> attach_shader(Shader&);
     ErrorOr<void> link();
 

+ 1 - 0
Userland/Libraries/LibGL/Shaders/Shader.h

@@ -7,6 +7,7 @@
 #pragma once
 
 #include <AK/Error.h>
+#include <AK/NonnullRefPtr.h>
 #include <AK/RefCounted.h>
 #include <AK/RefPtr.h>
 #include <AK/String.h>