Closed a-anjos closed 4 years ago
Hello António, can you please run this (almost) minimal example to see whether a context can be created?
import glfw
from OpenGL import GL
glfw.ERROR_REPORTING = 'warn'
if not glfw.init():
print("init failed")
exit(1)
window = glfw.create_window(100, 100, "Hello World", None, None)
if not window:
print("create_window failed")
exit(2)
glfw.make_context_current(window)
print(GL.glGetString(GL.GL_VERSION))
Hi Florian,
Here goes:
/home/aanjos/.local/lib/python3.8/site-packages/glfw/__init__.py:810: GLFWError: (65544) b'Wayland: Focusing a window requires user interaction'
warnings.warn(message, GLFWError)
b'3.0 Mesa 19.3.3'
Thanks, António
Thank you, this looks like a window was created successfully and an OpenGL context is bound to it. So it's unlikely to be an issue with GLFW or this wrapper.
Could it be that you forgot to call glfw.make_context_current(window)
in your actual code?
Dear Florian,
No, I didn't:
self.world = world
self.width = width
self.height = height
log.debug('Initialize context')
glfw.init()
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 6)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.RESIZABLE, False)
#if sys.platform.startswith("linux"):
# if "wayland" in os.getenv("XDG_SESSION_TYPE", "").lower():
# glfw.window_hint(glfw.FOCUSED, False)
self.win = glfw.create_window(width, height, '3D world', None, None)
glfw.make_context_current(self.win) # set current context
glfw.set_key_callback(self.win, self.on_key) # event handling
print('OpenGL:', gl.glGetString(gl.GL_VERSION))
#print('GLSL:', gl.glGetString(gl.GL_SHADING_LANGUAGE_VERSION))
print('Renderer:', gl.glGetString(gl.GL_RENDERER).decode())
gl.glClearColor(*bg)
gl.glEnable(gl.GL_DEPTH_TEST)
self.fill_modes = cycle([gl.GL_LINE, gl.GL_POINT, gl.GL_FILL])
self.cull = True
gl.glEnable(gl.GL_CULL_FACE)
Like I said, it was working perfectly on Ubuntu 20.04 (I didn't make note of the versions of glfw, etc., I was using there). Maybe a problem with Wayland?
Thanks, António
The PyOpenGL error you reported earlier states that it was caused by the lack of a current, valid OpenGL context. If you can create an OpenGL context and make it current, I would guess that it either wasn't current at the time, somehow became invalid or was lost completely. I suggest that you create a minimal working example of this and debug it from there.
In any case, I don't see any relation between the issue and this wrapper around GLFW, so I'll close this.
I'm having the same issue, with no valid context being found during glVertexAttribPointer()
even though I do create it. I am also on Wayland. This is the error I get:
Traceback (most recent call last):
File "first.py", line 121, in <module>
gl.glVertexAttribPointer(LOCATION, 2, gl.GL_FLOAT, False, STRIDE, OFFSET)
File "/usr/lib/python3.8/site-packages/OpenGL/latebind.py", line 63, in __call__
return self.wrapperFunction( self.baseFunction, *args, **named )
File "/usr/lib/python3.8/site-packages/OpenGL/GL/VERSION/GL_2_0.py", line 469, in glVertexAttribPointer
contextdata.setValue( key, array )
File "/usr/lib/python3.8/site-packages/OpenGL/contextdata.py", line 58, in setValue
context = getContext( context )
File "/usr/lib/python3.8/site-packages/OpenGL/contextdata.py", line 40, in getContext
raise error.Error(
OpenGL.error.Error: Attempt to retrieve context when no valid context
@FlorianRhiem, of course, it does not out-right seem like an issue with pyGLFW, but it would be nice if we could resolve it here.
Do you have a minimal working example for this?
Dear Florian,
I cannot test this (my glfw/opengl is not working - maybe you could, please?), however, I suppose it's working. I took it from here: https://metamost.com/opengl-with-python/:
import contextlib, sys
from OpenGL import GL as gl
import glfw
@contextlib.contextmanager
def create_main_window():
if not glfw.init():
sys.exit(1)
try:
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
title = 'Tutorial 2: First Triangle'
window = glfw.create_window(500, 400, title, None, None)
if not window:
sys.exit(2)
glfw.make_context_current(window)
glfw.set_input_mode(window, glfw.STICKY_KEYS, True)
gl.glClearColor(0, 0, 0.4, 0)
yield window
finally:
glfw.terminate()
if __name__ == '__main__':
with create_main_window() as window:
while (
glfw.get_key(window, glfw.KEY_ESCAPE) != glfw.PRESS and
not glfw.window_should_close(window)
):
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
glfw.swap_buffers(window)
glfw.poll_events()
The result is the same:
Traceback (most recent call last):
File "test.py", line 32, in <module>
with create_main_window() as window:
File "/usr/lib/python3.8/contextlib.py", line 113, in __enter__
return next(self.gen)
File "test.py", line 18, in create_main_window
window = glfw.create_window(500, 400, title, None, None)
File "/home/aanjos/.local/lib/python3.8/site-packages/glfw/__init__.py", line 1156, in create_window
return _glfw.glfwCreateWindow(width, height, _to_char_p(title),
File "/home/aanjos/.local/lib/python3.8/site-packages/glfw/__init__.py", line 616, in errcheck
_reraise(exc[1], exc[2])
File "/home/aanjos/.local/lib/python3.8/site-packages/glfw/__init__.py", line 52, in _reraise
raise exception.with_traceback(traceback)
File "/home/aanjos/.local/lib/python3.8/site-packages/glfw/__init__.py", line 595, in callback_wrapper
return func(*args, **kwargs)
File "/home/aanjos/.local/lib/python3.8/site-packages/glfw/__init__.py", line 808, in _handle_glfw_errors
raise GLFWError(message)
glfw.GLFWError: (65544) b'Wayland: Focusing a window requires user interaction'
Thanks, António
@a-anjos I do not have a Wayland system at the moment. Your code is missing the glfw.ERROR_REPORTING = 'warn'
to prevent the Wayland GLFWError from causing an exception and glVertexAttribPointer
isn't even used in it.
Dear Florian,
Right. Here goes another example I've found here: http://morpheo.inrialpes.fr/~franco/3dgraphics/_downloads/eade9051662493ff8d990dddc139677f/
The result is:
/home/aanjos/.local/lib/python3.8/site-packages/glfw/__init__.py:810: GLFWError: (65544) b'Wayland: Focusing a window requires user interaction'
warnings.warn(message, GLFWError)
OpenGL 4.6 (Core Profile) Mesa 19.3.3, GLSL 4.60, Renderer Mesa DRI Intel(R) UHD Graphics 620 (Kabylake GT2)
Traceback (most recent call last):
File "viewer.py", line 173, in <module>
main() # main function keeps variables locally scoped
File "viewer.py", line 164, in main
viewer.add(SimpleTriangle(color_shader))
File "viewer.py", line 76, in __init__
GL.glVertexAttribPointer(0, 3, GL.GL_FLOAT, False, 0, None)
File "/home/aanjos/.local/lib/python3.8/site-packages/OpenGL/latebind.py", line 63, in __call__
return self.wrapperFunction( self.baseFunction, *args, **named )
File "/home/aanjos/.local/lib/python3.8/site-packages/OpenGL/GL/VERSION/GL_2_0.py", line 469, in glVertexAttribPointer
contextdata.setValue( key, array )
File "/home/aanjos/.local/lib/python3.8/site-packages/OpenGL/contextdata.py", line 58, in setValue
context = getContext( context )
File "/home/aanjos/.local/lib/python3.8/site-packages/OpenGL/contextdata.py", line 40, in getContext
raise error.Error(
OpenGL.error.Error: Attempt to retrieve context when no valid context
Cheers, António
If this lets you reproduce the error, then please reduce it to a minimal working example.
@FlorianRhiem This is quite minimal, it just draws a triangle.
I doubt that it needs to draw a triangle to reproduce the issue, neither will it need classes, etc.
Like I said, I do not have a Wayland system available and I do not think that the issue is related to my work. I can try to guide you towards finding the cause of this issue, but I cannot do the work for you.
I'd gladly simplify the code (or produce a minimal version), however, since I have no system where I could run it, it would be hard to not introduce lots of bugs. Thanks though.
Okay, here is the smallest, complete program that produces this. It is modified from a tutorial example. I'm not sure if there is anything extraneous. The error occurs at line 51, with the function: glVertexAttribPointer()
from ctypes import c_void_p
import glfw
import OpenGL.GL as gl
from numpy import zeros, float32
glfw.init()
glfw.ERROR_REPORTING = 'warn'
glfw.window_hint(glfw.FOCUSED, False) # prevent Wayland focusing warning
WINDOW = glfw.create_window(512, 512, "Hello World", None, None)
glfw.make_context_current(WINDOW)
PROGRAM = gl.glCreateProgram()
VERTEX = gl.glCreateShader(gl.GL_VERTEX_SHADER)
FRAGMENT = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
VERTEX_CODE = """
#version 460
in vec2 position;
void main(){ gl_Position = vec4(position, 0.0, 1.0); } """
FRAGMENT_CODE = """
#version 460
out vec4 FragColor;
void main() { FragColor = vec4(1.0, 0.0, 0.0, 1.0); } """
gl.glShaderSource(VERTEX, VERTEX_CODE)
gl.glShaderSource(FRAGMENT, FRAGMENT_CODE)
gl.glCompileShader(VERTEX)
gl.glCompileShader(FRAGMENT)
gl.glAttachShader(PROGRAM, VERTEX)
gl.glAttachShader(PROGRAM, FRAGMENT)
gl.glLinkProgram(PROGRAM)
gl.glDetachShader(PROGRAM, VERTEX)
gl.glDetachShader(PROGRAM, FRAGMENT)
gl.glUseProgram(PROGRAM)
DATA = zeros(4, [("position", float32, 2)])
GPU_BUFFER = gl.glGenBuffers(1)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, GPU_BUFFER)
STRIDE = DATA.strides[0]
OFFSET = c_void_p(0)
LOCATION = gl.glGetAttribLocation(PROGRAM, "position")
gl.glEnableVertexAttribArray(LOCATION)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, GPU_BUFFER)
gl.glVertexAttribPointer(LOCATION, 2, gl.GL_FLOAT, False, STRIDE, OFFSET)
glfw.terminate()
Thank you, @physkets. If you leave out the shader program and the vertex array object, does it still produce the error?
Basically this:
from ctypes import c_void_p
import glfw
import OpenGL.GL as gl
glfw.init()
glfw.ERROR_REPORTING = 'warn'
glfw.window_hint(glfw.FOCUSED, False) # prevent Wayland focusing warning
WINDOW = glfw.create_window(512, 512, "Hello World", None, None)
glfw.make_context_current(WINDOW)
LOCATION = 0
gl.glVertexAttribPointer(LOCATION, 2, gl.GL_FLOAT, False, 0, c_void_p(0))
If this doesn't cause the error, does an OpenGL error (namely GL_INVALID_VALUE
) occur when you pass an invalid value for LOCATION
, e.g. LOCATION = gl.GL_MAX_VERTEX_ATTRIBS
or does it cause the issue then?
Also, please check whether the context is still there after it has been reported as missing, e.g. by wrapping the glVertexAttribPointer
call with a try-except-pass and then adding print(gl.glGetString(gl.GL_VERSION))
.
Also, what happens if you add the following to the beginning of a script that causes the issue:
import OpenGL
OpenGL.CHECK_CONTEXT = False
This disables the context checking done by PyOpenGL, which is likely to be the source of the error message.
The same error (no valid context) occurs even when using that snippet (without the shader program).
Catching the exception like this:
try:
gl.glVertexAttribPointer(LOCATION, 2, gl.GL_FLOAT, False, 0, c_void_p(0))
except:
print(gl.glGetString(gl.GL_VERSION))
prints out: b'4.6 (Compatibility Profile) Mesa 20.0.4'
.
Setting the context check to False
still leaves me with the same error:
OpenGL.error.Error: Attempt to retrieve context when no valid context
.
Alright, then the issue is definitely with the function loading and context checking of PyOpenGL.
What does the following return before (and possibly after) the call to glVertexAttribPointer
?
from OpenGL import platform
print(platform.PLATFORM)
print(platform.GetCurrentContext())
Firstly, my syntax checker tells me:
no-member: Module 'OpenGL.platform' has no 'PLATFORM' member
no-member: Module 'OpenGL.platform' has no 'GetCurrentContext' member
And if I go ahead anyway, I see the following output, both before and after the call to glVertexAttribPointer()
:
<OpenGL.platform.glx.GLXPlatform object at 0x7f6623fd0be0>
0
Shouldn't I be using EGL on Wayland, instead of GLX?
PyOpenGL does some trickery to load the actual platform and fill in the namespace of OpenGL.platform
, that's likely the reason your checker complains. And the fact that GetCurrentContext
is the reason glVertexAttribPointer
doesn't work, though as you say, I also would've expected a OpenGL.platform.egl.EGLPlatform
object for Wayland. Can you please set the environment variable PYOPENGL_PLATFORM
to egl
, either by setting it on the command line or by adding the following to the beginning of your script?
import os
os.environ['PYOPENGL_PLATFORM'] = 'egl'
When I set that environment variable, the outputs are:
<OpenGL.platform.egl.EGLPlatform object at 0x7ff271373c10>
275506848
And there is no error in the minimal example. In my actual code, I still get some errors at the same glVertexAttribPointer()
, but that seems like something else.
So that's that. It was just a matter of the wrong platform being chose. Thanks a lot Florian.
Isn't there some way this can be checked for, and a more relevant error is reported, in pyGLFW? (So someone else doesn't have to go through all this to figure it out) Or would it be more appropriate in pyOpenGL?
Yes, it could be fixed in pyGLFW with something like this:
if "wayland" in os.getenv("XDG_SESSION_TYPE", "").lower() and not os.environ.get("PYOPENGL_PLATFORM", ""):
os.environ["PYOPENGL_PLATFORM"] = "egl"
However I would strongly prefer if this is actually fixed in PyOpenGL as opposed to here, as it has nothing to do with pyGLFW specifically and very, very little with GLFW in general. As far as I am aware, EGL is the OpenGL context creation API for Wayland, so using it as default for Wayland sessions seems generally reasonable when GLX is the only real alternative.
I was already discussing this on the pyOpenGL mailinglist:
https://sourceforge.net/p/pyopengl/mailman/pyopengl-users/thread/M5HjopY--3-2%40tutanota.com/
I think I might file a bug report with them, with that solution you just wrote.
Hi Florian, Using pyGLFW 1.11 on Wayland I get the following message when creating a window: ...
I've tried the "fix" I've found on one of the solved issues:
However, I get the following:
Everything was working on Ubuntu 20.04. I've installed Debian testing today because it has the Linux kernel 5.5 and I got this problem.
I have libgfw3-wayland 3.3.2-1.
Thanks, António