FilipeMarch / manim_in_kivy

Rendering MANIM animations directly on a Kivy application

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

manim_in_kivy

Rendering MANIM animations directly on a Kivy application with OpenGL

kivy_complex_animation-2022-06-29_03.11.39.mp4

If you want to render MANIM animations on a mobile app, the first step is being able to render MANIM inside Kivy.

  1. First, install MANIM and Kivy

Hacking MANIM

  1. modify the file manim.renderer.opengl_renderer.OpenGLRenderer. Inside OpenGLRenderer, modify the function get_raw_frame_buffer_object_data: we are going to intercept the frames that would be sent to ffmpeg and send them to Kivy
    def get_raw_frame_buffer_object_data(self, dtype="f1"):
        # Copy blocks from the fbo_msaa to the drawn fbo using Blit
        # pw, ph = self.get_pixel_shape()
        # gl.glBindFramebuffer(gl.GL_READ_FRAMEBUFFER, self.fbo_msaa.glo)
        # gl.glBindFramebuffer(gl.GL_DRAW_FRAMEBUFFER, self.fbo.glo)
        # gl.glBlitFramebuffer(
        #     0, 0, pw, ph, 0, 0, pw, ph, gl.GL_COLOR_BUFFER_BIT, gl.GL_LINEAR
        # )
        num_channels = 4
        ret = self.frame_buffer_object.read(
            viewport=self.frame_buffer_object.viewport,
            components=num_channels,
            dtype=dtype,
        )
        from kivy.app import App
        app = App.get_running_app()
        app.update_frame_to_render(ret)
        return ret
  1. Run main.py

  2. Enjoy rendering MANIM animations inside a cross-platform Kivy app.

Optional:

I you want to make sure ffmpeg is not used, go to manim.scene.scene_file_writer.SceneFileWriter and change the function write_opengl_frame:

    def write_opengl_frame(self, renderer):
        if write_to_movie():
            renderer.get_raw_frame_buffer_object_data(),

            # self.writing_process.stdin.write(
            #     renderer.get_raw_frame_buffer_object_data(),
            # )
        elif is_png_format() and not config["dry_run"]:
            target_dir = self.image_file_path.parent / self.image_file_path.stem
            extension = self.image_file_path.suffix
            self.output_image(
                renderer.get_image(),
                target_dir,
                extension,
                config["zero_pad"],
            )

Obviously the whole approach is not optimal and a lot of improvements can be done, this is just a minimal runnable example and feel free to improve it, I will probably improve it in the future.

About

Rendering MANIM animations directly on a Kivy application

License:GNU General Public License v3.0


Languages

Language:Python 100.0%