ManimCommunity / manim

A community-maintained Python framework for creating mathematical animations.
https://www.manim.community
MIT License
24.58k stars 1.72k forks source link

Line can be seen through vertex dots when using `~.get_line_graph()` in OpenGL #2006

Open alembcke opened 3 years ago

alembcke commented 3 years ago

Description of bug / unexpected behavior

When drawing a line graph with vertex dots using the OpenGL renderer, the line is visible through the vertex dots:

LineGraphExample_ManimCE_v0 10 0_OpenGL

Now compare this to the Cairo-rendered version:

LineGraphExample_ManimCE_v0 10 0_Cairo

The lines are behind the vertex dots, as they should be.

Expected behavior

The vertex dots should fully cover the lines.

How to reproduce the issue

Code for reproducing the problem ```py from manim import * class LineGraphExample(Scene): def construct(self): plane = NumberPlane( x_range = (0, 7), y_range = (0, 5), x_length = 7, axis_config={"include_numbers": True}, ) plane.center() line_graph = plane.get_line_graph( x_values = [0, 1.5, 2, 2.8, 4, 6.25], y_values = [1, 3, 2.25, 4, 2.5, 1.75], line_color=RED, vertex_dot_style=dict(stroke_width=3, fill_color=BLUE), stroke_width = 4, ) self.play(Create(VGroup(plane, line_graph))) self.wait(1) ```

System specifications

System Details - OS (with version, e.g Windows 10 v2004 or macOS 10.15 (Catalina)): Ubuntu 21.04 - RAM: 32GB - Python version (`python/py/python3 --version`): 3.9.5 - Installed modules (provide output from `pip list`): ``` Package Version ----------------------- --------------------- manim 0.10.0 moderngl 5.6.4 moderngl-window 2.4.0 ```

Additional comments

behackl commented 3 years ago

This is because the order for cairo is managed by setting a z_index, this is not implemented for OpenGL. I am not sure whether there currently is a way to control the order of overlapping mobjects, except for moving them IN a bit.

k4pran commented 2 years ago

I was able to fix this kind of, the problem is that when using groups like VDict and VGroup all the mobjects contained will be rendered together and their data is combined. Then the order of rendering follows this list.

        wrapper_lists = [
            back_stroke_shader_wrappers,
            fill_shader_wrappers,
            stroke_shader_wrappers,
        ]

So the fills of the dots will always be rendered first then the strokes from the lines. If we add lines to the back_stroke_wrapper it will fix the lines issue but because we have the plane also in a group the lines will always be rendered before the plane:

Screenshot 2021-10-24 at 09 16 29

To get it working correctly we would need to also remove the plane from the group

        self.play(Create(plane), Create(line_graph))
Screenshot 2021-10-24 at 09 17 00

So this looks correct, but I don't think we can expect users to know that using groups will affect the rendering order of the objects inside, so I think for 2D scenes where we have no z-index we need to make sure that for groups render in the order they were added