Repository: ManimCommunity/manim
File: manim/renderer/shader.py (Python)

Code before:
        return copy

    def set_uniforms(self, renderer: OpenGLRenderer) -> None:
        self.shader.set_uniform(
            "u_model_matrix",
            opengl.matrix_to_shader_input(self.model_matrix),
        )
        self.shader.set_uniform("u_view_matrix", renderer.camera.formatted_view_matrix)
        self.shader.set_uniform(
            "u_projection_matrix",
            renderer.camera.projection_matrix,
        )

    def render(self) -> None:
        if self.skip_render:
            return

        if self.use_depth_test:
            self.shader.context.enable(moderngl.DEPTH_TEST)
        else:
            self.shader.context.disable(moderngl.DEPTH_TEST)

        shader_attributes: list[Attribute] = []
        for k, v in self.shader.shader_program._members.items():
            if isinstance(v, Attribute):
                shader_attributes.append(k)
        shader_attributes_converted = filter_attributes(
            self.attributes, shader_attributes
        )

        vertex_buffer_object = self.shader.context.buffer(
            shader_attributes_converted.tobytes()
        )
        if self.indices is None:
            index_buffer_object = None
        else:
            vert_index_data = self.indices.astype("i4").tobytes()
            if vert_index_data:
                index_buffer_object = self.shader.context.buffer(vert_index_data)
            else:
                index_buffer_object = None
        vertex_array_object = self.shader.context.simple_vertex_array(
            self.shader.shader_program,
            vertex_buffer_object,
            *shader_attributes_converted.dtype.names,
            index_buffer=index_buffer_object,
        )
        vertex_array_object.render(self.primitive)
        vertex_buffer_object.release()
        vertex_array_object.release()
        if index_buffer_object is not None:

Review comment (suggestion):
The list should actually contain names (strings). The name `shader_attributes` is a bit misleading and used in a strange way later, so I'd suggest renaming the variable to `shader_attribute_names`. Similarly, `k` and `v` ("key" and "value") could be `member_name` and `member` instead for more clarity.
```suggestion
        shader_attribute_names: list[str] = []
        for member_name, member in self.shader.shader_program._members.items():
            if isinstance(member, moderngl.Attribute):
                shader_attribute_names.append(member_name)
```

Code after:
        copy = Mesh(
            attributes=self.attributes.copy(),
            shader=self.shader,
            indices=self.indices.copy() if self.indices is not None else None,
            use_depth_test=self.use_depth_test,
            primitive=self.primitive,
        )
        copy.skip_render = self.skip_render
        copy.model_matrix = self.model_matrix.copy()
        copy.normal_matrix = self.normal_matrix.copy()
        # TODO: Copy updaters?
        return copy

    def set_uniforms(self, renderer: OpenGLRenderer) -> None:
        self.shader.set_uniform(
            "u_model_matrix",
            opengl.matrix_to_shader_input(self.model_matrix),
        )
        self.shader.set_uniform("u_view_matrix", renderer.camera.formatted_view_matrix)
        self.shader.set_uniform(
            "u_projection_matrix",
            renderer.camera.projection_matrix,
        )

    def render(self) -> None:
        if self.skip_render:
            return

        if self.use_depth_test:
            self.shader.context.enable(moderngl.DEPTH_TEST)
        else:
            self.shader.context.disable(moderngl.DEPTH_TEST)

        shader_attribute_names: list[str] = []
        for member_name, member in self.shader.shader_program._members.items():
            if isinstance(member, moderngl.Attribute):
                shader_attribute_names.append(member_name)
        filtered_shader_attributes = filter_attributes(
            self.attributes, shader_attribute_names
        )

        vertex_buffer_object = self.shader.context.buffer(
            filtered_shader_attributes.tobytes()
        )
        if self.indices is None:
            index_buffer_object = None
        else:
            vert_index_data = self.indices.astype("i4").tobytes()
            if vert_index_data:
                index_buffer_object = self.shader.context.buffer(vert_index_data)
            else: