Skip to content
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

Error loading example #2

Closed
anderslindho opened this issue Nov 12, 2021 · 9 comments
Closed

Error loading example #2

anderslindho opened this issue Nov 12, 2021 · 9 comments

Comments

@anderslindho
Copy link

anderslindho commented Nov 12, 2021

I ran into this issue while trying out examples. Technically it seems to be a pyglet issue, but since I ran into it while trying out your library you may still want to be aware.

$ python3 examples/hello_triangle.py
2021-11-12 19:53:40.357 Python[11913:760548] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to /var/folders/96/t_1vtxwn7z5b5g22grwztfq80000gn/T/com.apple.python3.savedState
Traceback (most recent call last):
  File "examples/hello_triangle.py", line 5, in <module>
    window = Window(1280, 720)
  File "/Users/ades/repos/zengl/examples/window.py", line 17, in __init__
    super().__init__(width=width, height=height, config=config)
  File "/Users/ades/Library/Python/3.8/lib/python/site-packages/pyglet/window/__init__.py", line 658, in __init__
    self._create()
  File "/Users/ades/Library/Python/3.8/lib/python/site-packages/pyglet/window/cocoa/__init__.py", line 197, in _create
    self.context.attach(self.canvas)
  File "/Users/ades/Library/Python/3.8/lib/python/site-packages/pyglet/gl/cocoa.py", line 299, in attach
    self._nscontext.setView_(canvas.nsview)
AttributeError: 'NoneType' object has no attribute 'setView_'

I'm using:

  • macOS Big Sur 11.1:
  • Python 3.8.2
  • pyglet==1.5.21
  • numpy==1.21.4

I tested another app that uses pyglet and that loaded up just fine.

@szabolcsdombi
Copy link
Owner

szabolcsdombi commented Nov 13, 2021

Thank you for reporting this.
The window is configured in the examples/window.py and I had to make a blind fix for the macOS with the parameters there.
Probably I did not succeed with that.

Can you check if changing how we initialize the window,
or applying the fix from mmatl/pyrender#98 helps?

@anderslindho
Copy link
Author

anderslindho commented Nov 14, 2021

Changing the order of imports (including changing when we create the window and the context) appears to make no difference.

I tried modifying the configuration in examples/window.py but that also made no difference (and to be fair the settings look fine) until I removed specifying the version of opengl to use (in which case it'll crash when trying to load the shaders; when not specified my system will default to use 2.1).

I should mention here that I'm on ARM (M1) and that I haven't used OpenGL that much on this particular machine. I have, however, read that I should be able to use up to 4.1, but trying to specify that led to the same error message, both when using Rosetta and otherwise. I tested an older app I have that I wrote for 4.1 (but using Qt5 and PyOpenGL) and that loaded up fine in Rosetta but not without.

I might come back to play around a bit more with other ways of initialising the window - using Qt should demonstrably be an option. Do you have any preferences here?

@szabolcsdombi
Copy link
Owner

Thank you for the feedback.
I wonder if the pygame example (here) can also reach only OpenGL 2.1.
If you manage to get Qt to provide at least OpenGL 3.3 an example would be welcome with that.
I am happy to add any window library as an example.

Personally, I prefer to keep examples simple and explicit.

simple:
examples should only contain code/logic for what is intended to be demonstrated in the example.
For simplicity, I prefer the pygame example the most as it uses global variables and a simple loop, no functions, no classes.
However to port all examples, I would still wrap pygame related initialization into the window.py to get the example the cleanest. I can think of something like this would be best:

window = ....
ctx = zengl.context(...)
# images pipelines ...

while window.alive():
    # per frame logic here
    # final blit as last

I think examples like the above clarify that rendering with zengl is not tight to any type of window or render loop.
The user is allowed to define the render loop.

Most libraries, however, implement the render loop. The current examples use my second best option with an annotated function for the render. I like these a bit less compared to the first option, due to examples cannot modify the global variables from the render loop without a hack or an extra object.

My third option is to use classes and inheritance. those examples look bulkier and inheritance causes a lot of issues, so I consider it a bit error-prone.

explicit:
examples should contain all the code (all the zengl code) necessary to get the render result. code duplication is highly tolerated in this sense. simple and explicit examples are easy to understand by opening just one file.


Please note that all the above is my preference and not a proper guidance on how real-life projects should be structured.
Complex projects are barely maintainable this way.

I also prefer examples showing pros or cons for architectural decisions like the ones above. I even planned to add some for a pattern I got really convenient applying with moderngl on a large project in the past.


I chose the pyglet with the tweaked parameters due I understood that this was the only window that provided OpenGL 3.3 on OSX. I had no access to the computer that was used for testing.

A Vulkan 1.0 backend for the complete zengl api is in-progress, this improves headless rendering support and MoltenVK seems to work better on MacOS in general.

@anderslindho
Copy link
Author

I wonder if the pygame example (here) can also reach only OpenGL 2.1.

That example manages to open a window but doesn't render anything of note (black background). I get 3.3 when reading back GL_CONTEXT_[...]_VERSION, and if I print zengl.Context.info I get ('Apple', 'Apple M1', '4.1 Metal - 71.0.7'). I don't think I trust the context versions I am reading back from pygame. I also tried stepping through the app in pdb and it doesn't seem to get stuck on anything - it goes into the event loop and stays there. I tried running a random example from pygame (aliens) and that rendered OK, so I suspect it doesn't get past 2.1.

I tried running this and it will fail when loading the shaders regardless of if I try to set the context version or not (using pygame.display.gl_set_attribute)

@szabolcsdombi
Copy link
Owner

('Apple', 'Apple M1', '4.1 Metal - 71.0.7') looks promising,
if the shaders compile with the #version 330 it is very likely some finish / flush / swap / flip / double buffer issue is present and causing a black image.

To prove that we could try the headless rendering here
I assume the default headless context is not clever enough to get 4.1 like the pygame window
so the same content should be tested with a pygame window without headless=True.
The image read could prove the rendering works and the issue is the one mentioned above.

I prepare some examples soon for testing to be sure which one is the cause.

@szabolcsdombi
Copy link
Owner

I have created a branch with some examples to debug this issue: debug-on-m1

please run the pygame_* examples.
if none of those work, please compile this branch from source and run the examples starting with temp_*

PS: you can install this branch directly with:

pip install https://github.com/szabolcsdombi/zengl/archive/refs/heads/debug-on-m1.zip

@anderslindho
Copy link
Author

  • pygame_window.py: completely black screen; needed to install also pyopengl (plus the "expected" subjects)
  • pygame_window_no_double_buffer.py: success!

Do you still want me to test the other ones?

As an aside, I also tried used moderngl+moderngl-window with glfw as backend and that seemed to work fine, so that might be another option for a minimal window setup? (Albeit maybe that problem is irrelevant now with a working pygame configuration.)

@szabolcsdombi
Copy link
Owner

Thank you very much for your effort. I think I understand the problem. The single buffer example works because of the glFlush, but it is strange that the double buffer variant is still not working. I sort of expected it so I made the non double buffered example.

I have to add a few changes to support the double buffered windows too.

There is no need to test the temp_ examples, the problem was the missing flush.
Also, I think the first example was not working due to the default drawbuffer was not set properly.

Good to hear that glfw + OpenGL 3.3+ runs on M1 too.

@szabolcsdombi
Copy link
Owner

szabolcsdombi commented Nov 28, 2021

There were two problems:

AttributeError: 'NoneType' object has no attribute 'setView_'

this is resolved by

import pyglet
pyglet.options['shadow_window'] = False

and for some reason, if the window is has double buffering enabled and a non zero framebuffer is bound when the swap buffers is called then the screen will be white with a black rectangle on the bottom right corner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants