Skip to content

Added opengl support for --format png output #1982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Sep 28, 2021

Conversation

k4pran
Copy link
Collaborator

@k4pran k4pran commented Aug 30, 2021

Overview: What does this pull request change?

Added opengl support for outputing pngs using the --format png flag.

Motivation and Explanation: Why and how do your changes improve the library?

#1970

Currently png output is only available for cairo. This PR extends it to opengl.

Links to added or changed documentation pages

Further Information and Comments

This PR makes some changes to the behaviour of dry_run, from what I can tell the getter and setter were using old configs self.save_pngs and self.save_as_gif meaning that it was enabling dry run when --format png or --format gif were used. I couldn't see any negative affects but I guess as part of reviewing it is worth looking out for any consequences of this change.

Another point about this PR is related to interactive mode, there are cases were calling interactive_mode() does not have any affect, such as when write_to_movie is set or animations are disabled. I extended this to include --format png and in cases where the window has not been initialized as it errors in the latter case.

I added a check for context before using a cached program, this is because if multiple tests run it will render multiple scenes and create multiple contexts. It will fail with an error if you try to use a cached program that belongs to another context.

Reviewer Checklist

  • The PR title is descriptive enough for the changelog, and the PR is labeled correctly
  • If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
  • If applicable: newly added functions and classes are tested

@k4pran k4pran added opengl Concerning the OpenGL renderer. enhancement Additions and improvements in general labels Aug 31, 2021
@k4pran k4pran force-pushed the add_png_opengl_support branch from 950019a to 039bd0d Compare August 31, 2021 12:23
@k4pran k4pran changed the title Add opengl support for --format png output Added opengl support for --format png output Sep 1, 2021
@k4pran k4pran marked this pull request as ready for review September 1, 2021 12:25
Copy link
Member

@hydrobeam hydrobeam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR really cleans up a lot of the flags for opengl, great work!

I'm of the opinion that calling a scene with no flags should effectively call self.interactive_embed() so that the -p flag does one job, but that can be handled in another PR 🤔

Comment on lines 270 to 273
def should_create_window(self):
return (
config["preview"] and not config["format"] and not config["write_to_movie"]
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it makes so that --write_to_movie makes it so that the window no longer pops up, which I think is a good idea. However, being able to adjust the scene manually while it's recording is a neat (albeit niche) feature for debugging. Maybe a flag like --force_window (or anything) to let the window exist while --write_to_movie is recording?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea sounds good, I will look at adding a flag for this!

Copy link
Collaborator Author

@k4pran k4pran Sep 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hydrobeam was this ever possible to do? It seems to cause other issues, for example, caching means that frames will be not written to the opengl window, and when you try to write a movie at the same time as render to the window it also causes ValueError: write to closed file. It works with pngs but performance is really slow

EDIT: Fixed the ValueError by checking if the pipe is closed, not sure about caching though, unless you think it is ok to force disable caching when force_window is enabled?

EDIT again: I added some tests for force_window flag, but discovered another issue testing opengl, it seems running multiple opengl tests result in it trying to reuse the context which then fails so had to mark the last test xfail. They work when running individually

@@ -99,7 +99,7 @@ markers = "platform_python_implementation == 'CPython'"

[tool.pytest.ini_options]
markers = "slow: Mark the test as slow. Can be skipped with --skip_slow"
addopts = "--no-cov-on-fail --cov=manim --cov-report xml --cov-report term -n auto"
addopts = "--no-cov-on-fail --cov=manim --cov-report xml --cov-report term -n auto --dist=loadfile"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naveen521kk I added this argument as it seems like it would allow parallelization but, for tests in the same file they would share a worker to avoid issues with multiple opengl windows running at the same time. Does this make sense to you? got the information here - https://stackoverflow.com/questions/4637036/is-there-a-way-to-control-how-pytest-xdist-runs-tests-in-parallel

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@k4pran k4pran requested a review from hydrobeam September 21, 2021 20:32
Copy link
Member

@hydrobeam hydrobeam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was doing some testing and --force_window works as expected! Although, I also noticed that when calling a scene with animations via with -ps (and/or) --write_to_movie, the window pops up and animations are played (although the file is saved as a png at the end of the anims).

I'm not sure if this is in the scope of this PR, but here's the code i used to test:

manim -ps mkt.py --renderer=opengl MTV --disable_caching --write_to_movie
class MTV(Scene):
    def construct(self):
        def f(x):
            return x ** 2

        table_x = np.array([0, 1, 2, 3, 4])
        table_data = np.array([table_x, list(map(f, table_x))])
        print(f"{table_data=}")

        table = DecimalTable(table_data, row_labels=[MathTex("x"), MathTex("f(x)")])
        self.add(table)
        s = OpenGLVMobject(
            fill_opacity=0.3,
            fill_color=GREEN,
            stroke_width=0,
        )
        s.points= table.get_cell((1,2)).points 

        length = len(table.get_entries_without_labels())

        for ent in range(length):
            pos =(min(ent//5 + 1, 2), min(ent%5 + 2,6))
            curr_cell = table.get_cell(pos)

            self.play(s.animate.set_points(curr_cell.points))

@k4pran
Copy link
Collaborator Author

k4pran commented Sep 22, 2021

I was doing some testing and --force_window works as expected! Although, I also noticed that when calling a scene with animations via with -ps (and/or) --write_to_movie, the window pops up and animations are played (although the file is saved as a png at the end of the anims).

I'm not sure if this is in the scope of this PR, but here's the code i used to test:

manim -ps mkt.py --renderer=opengl MTV --disable_caching --write_to_movie
class MTV(Scene):
    def construct(self):
        def f(x):
            return x ** 2

        table_x = np.array([0, 1, 2, 3, 4])
        table_data = np.array([table_x, list(map(f, table_x))])
        print(f"{table_data=}")

        table = DecimalTable(table_data, row_labels=[MathTex("x"), MathTex("f(x)")])
        self.add(table)
        s = OpenGLVMobject(
            fill_opacity=0.3,
            fill_color=GREEN,
            stroke_width=0,
        )
        s.points= table.get_cell((1,2)).points 

        length = len(table.get_entries_without_labels())

        for ent in range(length):
            pos =(min(ent//5 + 1, 2), min(ent%5 + 2,6))
            curr_cell = table.get_cell(pos)

            self.play(s.animate.set_points(curr_cell.points))

Yea I think it is in scope, I fixed it if you want to try again. One other thing I am wondering, the logic as it stands means that if we omit the -p flag and any ouputs like png or write_to_movie, and use interactive_embed, the window will not be created. Seems like interactive_embed shouldn't rely on -p what do you think? So many permutations of this lol. I opened a discussion btw here - #2010. Not related as much to these scenarios, but it is the same idea. Config is creating a lot of permutations, maybe we should start agreeing on what makes most sense and creating various modes or something to avoid needing to have a string of if statements each time. Created an issue #2069 to improve handling of these scenarios

Copy link
Member

@hydrobeam hydrobeam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tested it out and it works more in line with what one would expect 👍. Although the behaviour isn't perfect atm in my opinion, this PR is a huge step up and shouldn't be stalled further. I've outlined how I think we should handle the flags as a whole in #2069 . LGTM!

@k4pran k4pran merged commit 4831e1d into ManimCommunity:main Sep 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Additions and improvements in general opengl Concerning the OpenGL renderer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants