Giter Site home page Giter Site logo

pyglfw's People

Contributors

agx avatar almarklein avatar bendgk avatar brpollock avatar florianrhiem avatar fogleman avatar hoechenberger avatar jonathanhogg avatar lhl avatar odidev avatar papr avatar sinakhalili avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyglfw's Issues

Support to get native Window id's

Hey! we're building a Python wrapper around the wgpu lib, and would like to use glfw as a lightweight alternative to provide a window.

However, to make things work, I need to provide wgpu with a native window id so it can create a surface object. It looks like glfw in principal supports this via e.g. glfwGetWin32Window.

Any idea how feasible it is to expose this via the Python API?

Thanks!

CHANGELOG.md

Could you please consider to add it to pypi release tarball?

get the GLFWwindow* value?

Feels like I'm missing something obvious here, but how do I get the pointer value that I'd pass to some other library wanting a GLFWwindow*?

Fails to find GLFW on Mac M1

Fails to find GLFW on Mac M1:

Traceback (most recent call last):
  File "/Users/junglie85/Personal/pygraphics/main.py", line 1, in <module>
    import glfw
  File "/Users/junglie85/Personal/pygraphics/venv/lib/python3.9/site-packages/glfw/__init__.py", line 43, in <module>
    raise ImportError("Failed to load GLFW3 shared library.")
ImportError: Failed to load GLFW3 shared library.

Also cannot load manually installed GLFW PYGLFW_LIBRARY=/opt/homebrew/Cellar/glfw/3.3.4.

Default Error handling differs from GLFW

According to GLFW developer @elmindreda (see glfw/glfw#1121 (comment)) errors in GLFW are not critical (as in halting the execution of the program). In pyGLFW the default behaviour is the opposite (halting execution on all errors). This makes for a bad developer experience and breaks wayland support (see mentioned issue request)

Therefore I propose to change:

ERROR_REPORTING = True

To

ERROR_REPORTING = "warn"

Support Wayland with Linux wheels

Currently, the Linux wheels are built on the manylinux2010 image with a few more X11-related libraries (libXinerama, libXrandr, libXcursor and libXi). This works well for X11 users, but on Wayland users still need to install the GLFW shared library themselves. Ideally, the Linux wheels would allow users of both X11 and Wayland to run GLFW without installing additional packages.

As far as I know, the wheel platform tags are all for X11 based systems so far. I'm not aware of any Wayland support for CentOS 6, which manylinux2010 is based on. manylinux2014 is based on CentOS 7, which seems to have some Wayland support, though it's not the default.

  • Find out how stable the Wayland libraries are and whether a GLFW library built on manylinux2014 with Wayland packages would work on a more modern Wayland system, e.g. Ubuntu 19.04 or Archlinux
  • Change the library search to allow for two GLFW libraries to be included in a wheel
  • Change the library search to ensure the correct GLFW library will be loaded, depending on the current X11 or Wayland session, for users who have installed both libraries' dependencies
  • Update the GitLab CI config to build both Wayland and X11 based libraries and package them in a single wheel

Potential issues with package binaries on Linux

I meant to test out the latest version on Linux (Ubuntu 19.10), because I suspected there might be an issue on Wayland, but ran into an issue. pip install glfw will take the tar.gz instead of the wheel. Pointing pip directly at the wheel gives me glfw-1.10.1-py2.py3-none-manylinux2010_x86_64.whl is not a supported wheel on this platform. So it looks like there's a flag somewhere there that prevents it from being used. I tried with pip 18.x and 20.0.1. Have you looked at auditwheel to verify/repair these wheels?

edit: the below turns out not to be an issue
I could therefore not test the potential issue I was looking into, so I'll just describe it. I can have a look later if needed. If the binary glfw lib that comes packaged is preferred over the system library, it will probably fail on Wayland (because it needs a differently compiled lib). The user can of course use PYGLFW_LIBRARY but that's annoying.

The README says that you can use the system library by installing it, but library.py seems to prefer the packaged lib instead, but I may be wrong here.

None of these are pressing issues, BTW :)

Bug: Changing CWD

Using your API changes the current working directory. So i had problems including my shaders with relative path.

Resizable and Visible hints not working?

I can't seem to get window hints to work. The following produces a window that can be resized and is visible. Any idea on how I can get this to work? Primary goal is to get the OpenGL stuff working on the core profile but can't seem to get it to work.

Mac 10.13 High Sierra

import glfw

def main():
    if not glfw.init():
        exit()

    window = glfw.create_window(640, 480, "HELLO WORLD", None, None)
    if not window:
        glfw.terminate()
        exit()

    glfw.window_hint(glfw.RESIZABLE, False)
    glfw.window_hint(glfw.VISIBLE, False)
    #glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
    #glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3)
    #glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    #glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, True)

    glfw.make_context_current(window)

    while not glfw.window_should_close(window):

        glfw.swap_interval(1)
        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.terminate()

main()

Support for Windows

glfw.py, line 140: add this:

if _glfw is None:
    _glfw = ctypes.CDLL("glfw3.dll")

I can't make much sense of the detection code that's there. It looks like it should pick up a .dll, but it didn't.

Invalid window hint when setting CENTER_CURSOR

I was trying to disable the feature which moves the cursor to the center of a newly created fullscreen window by setting the GLFW_CENTER_CURSOR window hint (glfw.CENTER_CURSOR for this package). This returns the following error when glfw.create_window is called:

Traceback (most recent call last): File "d:/Alejandro/HSCDMV2/Test-Codes/glfwbug.py", line 5, in <module> glfw.window_hint(glfw.CENTER_CURSOR, glfw.FALSE) File "C:\Users\shilab\AppData\Local\Programs\Python\Python37\lib\site-packages\glfw\__init__.py", line 1110, in window_hint _glfw.glfwWindowHint(hint, value) File "C:\Users\shilab\AppData\Local\Programs\Python\Python37\lib\site-packages\glfw\__init__.py", line 609, in errcheck _reraise(exc[1], exc[2]) File "C:\Users\shilab\AppData\Local\Programs\Python\Python37\lib\site-packages\glfw\__init__.py", line 45, in _reraise raise exception.with_traceback(traceback) File "C:\Users\shilab\AppData\Local\Programs\Python\Python37\lib\site-packages\glfw\__init__.py", line 588, in callback_wrapper return func(*args, **kwargs) File "C:\Users\shilab\AppData\Local\Programs\Python\Python37\lib\site-packages\glfw\__init__.py", line 800, in _raise_glfw_errors_as_exceptions raise GLFWError(message) glfw.GLFWError: (65539) b'Invalid window hint 131081'

Below is a code which reproduces the issue on my machine:

https://github.com/alejandroengineer/HSCDMV2/blob/4d82de9d00bf6b296b4face7dcb5b71743b21fb6/Test-Codes/glfwbug.py#L1-L7

Loading issues with the default bundled glfw3.dll on windows

While using the package in an anaconda environment (pip installed the glfw package into anacona env), I ran into an issue where ctypes.CDLL wouldn't load the bundled dll.

Downloading the glfw3 official precompiled binaries and replacing the bundled binary with the 64 bit lib-vc2015 build (my system specifics) eventually solved the problem, but I'm raising the issue so that if others run into this kind of problem, they may have a shortcut.

Or maybe there's a convenient solution to this, I'm not sure :)

Thanks anyways!

set_monitor_user_pointer doesn't work

Error:

  File "C:\Users\huml-dkn\Desktop\F95Checker\venv\lib\site-packages\glfw\__init__.py", line 1090, in set_monitor_user_pointer
    _monitor_user_data_repository[monitor] = data
TypeError: unhashable type

Needs something similar like set_window_user_pointer
monitor_addr = ctypes.cast(ctypes.pointer(monitor), ctypes.POINTER(ctypes.c_long)).contents.value

same for get_monitor_user_pointer

windows glfw3.x64 dll appears to be incorrect

I downloaded glfw-1.8.5-py2.py3-none-win32.zip and glfw-1.8.5-py2.py3-none-win_amd64.zip from pypi and unzipped them:

md5 glfw-win*/glfw3.dll
MD5 (glfw-win32/glfw3.dll) = cc96a6eed5b83cc4521a16499ddf7187
MD5 (glfw-win_amd64/glfw3.dll) = cc96a6eed5b83cc4521a16499ddf7187

It looks like the packaging is messed up and that these are both the 32 bit dll, any ideas?

MD5 (glfw-3.3.bin.WIN32/lib-vc2010/glfw3.dll) = cc96a6eed5b83cc4521a16499ddf7187

Maximal hidden windows size?

Hi,
I used to render to frame buffer object images with width< 1061 using this code:
glfw.init()
glfw.window_hint(glfw.VISIBLE, False)
self.window = glfw.create_window(self.width, self.height, "My OpenGL window", None, None)
glfw.make_context_current(self.window)

And that work fine. For example, if I used: glGetDoublev(GL_VIEWPORT) I will get:
array([ 0., 0., 1300., 1000.])
But when I try to use the same code for an image with a width larger then 1061 I get:
array([ 0., 0., 1300., 1061.])

I am using windows PyOpenGL and PyGlfw.
Thanks,
Avi

'VideoMode' object is not iterable

I'm trying to set my main loop rate to my monitor refresh rate for more control:

...

mon = GLFW.get_primary_monitor()
mode = mon.video_mode

size, bits, refresh_rate = mode

...

while not win.should_close:
    GLFW.poll_events()

    _display(W,H)

    win.swap_buffers()
    time.sleep(1./refresh_rate)

swap interval is not guaranteed at 75Hz

Full screen print screen on Windows 10 only captures first frame

When using Windows' print screen functionality (Print Screen, Win + Print Screen, Alt + Print Screen), only the very first rendered frame is captured. This only seems to happen in full screen mode and not in windowed mode.

I've been asking around and might be related to double/triple buffering on the driver side of things. Not sure if anything can be done about this?

Missing Linux AArch64 wheel on PyPI

Installing glfw on Linux AArch64 machine using command python -m pip install glfw, downloads the source distribution and build/install it. This installation results in missing X11 and Wayland libraries.

@FlorianRhiem and team, can you please let me know your thoughts on release Linux AArch64 wheels on PyPI?

Process.Communicate failure, expects string not bytes

In Python 3.4 glfw.py[130]: out = process.communicate(_to_char_p(filename))[0] fails with TypeError: must be str, not bytes

As far as I can tell, when universal_newlines=True is set in the previous line it tells subprocess to use
type _io.TextIOWrapper for stdin. TextIOWrapper expects string input, not bytes:

All streams are careful about the type of data you give to them. For example giving a str object to the write() method of a binary stream will raise a TypeError. So will giving a bytes object to the write() method of a text stream.

I can get around the problem by scrapping the use of the _to_char_p lambda and just passing the string filename.

What exactly is PYGLFW_PREVIEW

Does setting this env var mean that pyglfw automatically clones the latest code from glfw and builds it?

Or is the glfw version compiled by you (@FlorianRhiem I'd assume) at some point?

Can't create window on Wayland 3.36

Hi Florian,
Using pyGLFW 1.11 on Wayland I get the following message when creating a window:
...

  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'

I've tried the "fix" I've found on one of the solved issues:

if sys.platform.startswith("linux"):
            if "wayland" in os.getenv("XDG_SESSION_TYPE", "").lower():
                glfw.window_hint(glfw.FOCUSED, False)

However, I get the following:

File "/home/aanjos/Documents/git_sandbox/g3D/g3D/Drawable.py", line 36, in vbo_vertex_data
    gl.glVertexAttribPointer(layout_pos, 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(Error: Attempt to retrieve context when no valid context

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

Changing OpenGL version doesn't work

Whatever version I set, the command glfw.get_version_string() always returns version:b'3.3.5 Win32 WGL EGL OSMesa VisualC DLL'. Is it a bug?

The demo below shows that it always prints OpenGL version: b'3.3.5 Win32 WGL EGL OSMesa VisualC DLL'

import glfw
from OpenGL.GL import *

# initializing glfw library
if not glfw.init():
    raise Exception("glfw can not be initialized!")

# Configure the OpenGL context.
# If we are planning to use anything above 2.1 we must at least
# request a 3.3 core context to make this work across platforms.
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 0)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
# 4 MSAA is a good default with wide support
glfw.window_hint(glfw.SAMPLES, 4)

# creating the window
window = glfw.create_window(1280, 720, "My OpenGL window", None, None)

# check if window was created
if not window:
    glfw.terminate()
    raise Exception("glfw window can not be created!")

# Query the actual framebuffer size so we can set the right viewport later
# -> glViewport(0, 0, framebuffer_size[0], framebuffer_size[1])
framebuffer_size = glfw.get_framebuffer_size(window)

# set window's position
glfw.set_window_pos(window, 400, 200)

# make the context current
glfw.make_context_current(window)


version = glfw.get_version_string()
print(f"OpenGL version:{version}")

# the main application loop
while not glfw.window_should_close(window):
    glfw.poll_events()
    glfw.swap_buffers(window)

# terminate glfw, free up allocated resources
glfw.terminate()

Support lloading glfw3.so from LD_LIBRARY_PATH

This is with pyglfw 1.3.3 on Linux. The _load_library call in glfw.py uses a fixed set of paths that it searches for the GLFW shared lib. Unfortunately, I don't have GLFW3 installed system-wide as the available Debian package on jessie is a bit old. So I compiled and installed the latest GLFW3 in a custom location (/software/glfw/3.2.1 in this case), but I can't direct pyglfw to get the shared lib from there without hacking glfw.py.

Here's an updated excerpt of glfw.py, starting around line 150, to make it search the paths in LD_LIBRARY_PATH as well:

if sys.platform == 'win32':
# only try glfw3.dll on windows
try:
_glfw = ctypes.CDLL('glfw3.dll')
except OSError:
_glfw = None
else:
search_paths = [
'',
'/usr/lib64', '/usr/local/lib64',
'/usr/lib', '/usr/local/lib',
'/run/current-system/sw/lib',
'/usr/lib/x86_64-linux-gnu/'
]

if 'LD_LIBRARY_PATH' in os.environ:
    search_paths.extend(os.environ['LD_LIBRARY_PATH'].split(':'))
    
_glfw = _load_library(['glfw', 'glfw3'], ['.so', '.dylib'],
                      search_paths, _glfw_get_version)

"import glfw" fails in "subprocess.py" when using Python 3 (but not Python 2)

When I try to import pyGLFW, the import fails in "subprocess.py" because it tries to use encode on a bytes-type object. This does not happen in Python 2.7.5 on the same machine.

Python 3.3.2 (default, Jun 30 2014, 17:20:03)
[GCC 4.8.3 20140624 (Red Hat 4.8.3-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.

import glfw
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.3/site-packages/glfw.py", line 138, in
['', '/usr/lib', '/usr/local/lib'], _glfw_get_version)
File "/usr/lib/python3.3/site-packages/glfw.py", line 74, in _load_library
version = version_check_callback(filename)
File "/usr/lib/python3.3/site-packages/glfw.py", line 130, in _glfw_get_version
out = process.communicate(_to_char_p(filename))[0]
File "/usr/lib64/python3.3/subprocess.py", line 922, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "/usr/lib64/python3.3/subprocess.py", line 1546, in _communicate
orig_timeout)
File "/usr/lib64/python3.3/subprocess.py", line 1619, in _communicate_with_poll
self._save_input(input)
File "/usr/lib64/python3.3/subprocess.py", line 1580, in _save_input
self._input = self._input.encode(self.stdin.encoding)
AttributeError: 'bytes' object has no attribute 'encode'

GLFW 3.3 support

GLFW 3.3 was released last week. I won't have time to work on this until mid may, but after that I will start adding the missing functions and constants.

ctypes.ArgumentError in glfwGetMonitorContentScale

Hi, I'm getting the following error when calling glfwGetMonitorContentScale:

... (traceback in my code) ...

  File "/home/pfa/.pyenv/versions/3.6.9/lib/python3.6/site-packages/glfw/__init__.py", line 937, in get_monitor_content_scale
    _glfw.glfwGetMonitorContentScale(monitor, xscale, yscale)
ctypes.ArgumentError: argument 2: <class 'TypeError'>: expected LP_c_float instance instead of LP_c_int

It seems that pyGLFW is trying to call the ctypes function with ints, but glfwGetMonitorContentScale requires floats: https://www.glfw.org/docs/latest/group__monitor.html#gad3152e84465fa620b601265ebfcdb21b

Im using GLFW 3.3 and pyGLFW 1.8.6 on Ubuntu 18.04.

No sdist on PyPI

Hello, could you please publish the source distribution of v1.9.0 on PyPI as well? Thank you very much!

glfw.set_window_opacity :: TypeError: this function takes at least 2 arguments (1 given)

Getting error when trying to call glfw.set_window_opacity. Here is the traceback significant part ->

File "/home/roni/.pyenv/versions/3.8.3/lib/python3.8/site-packages/glfw/init.py", line 1337, in set_window_opacity
_glfw.glfwSetWindowOpacity(window)
TypeError: this function takes at least 2 arguments (1 given)

Maybe the second param was missed somehow.
I fixed it with passing the second param manually and it works.

Lacking support for glViewport()

I don't see the wrapper for this in any of the branches and when I tried glfw.gl_viewport(0, 0, 640, 480) my program crashes to an AttributeError: module 'glfw' has no attribute 'gl_viewport'

Attempt to retrieve context when no valid context

Im following a very simple code example to draw something on screen using glfw and opengl but I get met with

Traceback (most recent call last):
  File "/home/nanyo/Documents/ProgrammingEnvs/PythonEnvs/pyVisuals/src/__unused/test.py", line 75, in <module>
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, ctypes.c_void_p(0))
  File "/home/nanyo/Documents/ProgrammingEnvs/PythonEnvs/pyVisuals/lib/python3.10/site-packages/OpenGL/latebind.py", line 63, in __call__
    return self.wrapperFunction( self.baseFunction, *args, **named )
  File "/home/nanyo/Documents/ProgrammingEnvs/PythonEnvs/pyVisuals/lib/python3.10/site-packages/OpenGL/GL/VERSION/GL_2_0.py", line 469, in glVertexAttribPointer
    contextdata.setValue( key, array )
  File "/home/nanyo/Documents/ProgrammingEnvs/PythonEnvs/pyVisuals/lib/python3.10/site-packages/OpenGL/contextdata.py", line 58, in setValue
    context = getContext( context )
  File "/home/nanyo/Documents/ProgrammingEnvs/PythonEnvs/pyVisuals/lib/python3.10/site-packages/OpenGL/contextdata.py", line 40, in getContext
    raise error.Error(
OpenGL.error.Error: Attempt to retrieve context when no valid context

I have reduced my code as much as possible so I can post it here, I am doing glfw.make_context_current(window) to make the context current so I am not sure what is going wrong:

import glfw
from OpenGL.GL import *
import numpy as np

glfw.init()

glfw.window_hint(glfw.FOCUSED, glfw.FALSE)

window = glfw.create_window(640, 400, "Window", None, None)
glfw.make_context_current(window)

vertices = [
    0.5,  0.5, 0.0,
    0.5, -0.5, 0.0,
    -0.5, -0.5, 0.0,
    -0.5,  0.5, 0.0
]

indices = [
    0, 1, 3,
    1, 2, 3
]

vertices = np.array(vertices, dtype=np.float32)
indices = np.array(indices, dtype=np.int32)

vertex_shader_source = """
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
"""

frag_shader_source = """
#version 330 core
out vec4 FragColor;
void main()
{
    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
"""

vertex_shader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertex_shader, [vertex_shader_source])
glCompileShader(vertex_shader)
print(glGetShaderiv(vertex_shader, GL_COMPILE_STATUS))

frag_shader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(frag_shader, [frag_shader_source])
glCompileShader(frag_shader)
print(glGetShaderiv(frag_shader, GL_COMPILE_STATUS))

shader_program = glCreateProgram()
glAttachShader(shader_program, vertex_shader)
glAttachShader(shader_program, frag_shader)
glLinkProgram(shader_program)
print(glGetProgramiv(shader_program, GL_LINK_STATUS))

glDeleteShader(vertex_shader)
glDeleteShader(frag_shader)

VAO = glGenVertexArrays(1)
VBO = glGenBuffers(1)
EBO = glGenBuffers(1)

glBindVertexArray(VAO)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW)

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)

glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)

glClearColor(1, 0, 0, 1)

while not glfw.window_should_close(window):
    glClear(GL_COLOR_BUFFER_BIT)
    glUseProgram(shader_program)
    glBindVertexArray(VAO)
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
    glfw.swap_buffers(window)
    glfw.poll_events()

glfw.terminate()

Putting:

print(glfw.get_current_context())

just before:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, ctypes.c_void_p(0))

prints <glfw.LP__GLFWwindow object at 0x7f822c987340> meaning that some context was created for that window, as far as I understand the glfw docs.

EDIT: might be worth mentioning that I compiled glfw from source and replaced the wheel package with this newly compiled version as glfw 3.3.x does not work with ubuntu 21 and its wayland version

EDIT2: I am currently investigating if this has potentially something to do with my nvidia drivers and my gpu not showing up on some places as it should. Although I have an igpu capable of OpenGL 4.6 support

Add camelCase (and GLFW_ prefixes)

Hi Florian,

I just did a fork of pyGLFW where I switched all variable names from lowercase_with_underscores to camelCase (or 'mixedCase') and added the 'GLFW_' prefixes to the macros.
Even though this is not the recommended PEP8 way, in this case the camelCase approach is very helpful when you want to port C++ code to Python.

That got me thinking...

So. long story short: I would like to ask you to add support for camelCase (and the GLFW_ prefixes) alongside lowercase_with_underscores. It would only have benefits - existing code still works, porting C++ code can be done a lot quicker and pyGLFW would fit the naming scheme of the library it's most likely accompanied by -- PyOpenGL (which also uses camelCase).

Naturally, the user would have to make a from import instead.
from glfw import *

Please let me know what you think about the idea.

Thanks for your consideration and best regards,
--Zuzu_Typ--

Catching exceptions raised from callbacks attached to GLFW - improvement idea

Currently there is no way to catch errors from callbacks attached to glfw using glfw.set_*_callback.

Consider following example:

import glfw


def error_callback(err, description):
    raise RuntimeError("GLFW error (%s): %s" % (err, description))


def main():
    # this will fail because glfw was not initialized yet
    glfw.set_error_callback(error_callback)
    try:
        window = glfw.create_window(640, 480, "Hello World", None, None)
    except Exception as err:
        print("Exception raised: %s" % err)
        exit(1)

    if not window:
        print("Exception not raised but window creation failed")
        glfw.terminate()
        return

if __name__ == "__main__":
    main()

When executed it gives following output:

$ python glfwerrs.py 
Traceback (most recent call last):
  File "_ctypes/callbacks.c", line 314, in 'calling callback function'
  File "glfwerrs.py", line 6, in error_callback
    raise RuntimeError("GLFW error (%s): %s" % (err, description))
RuntimeError: GLFW error (65537): The GLFW library is not initialized
Exception not raised but window creation failed

This means that exception is raised but the only effect is that traceback is printed on standard output. Program simply continues its flow. This can be problematic in some situations. For instance if we have keyboard handler that fails at some point and it is also responsible for catching input that should close application (ESC key) then user will find difficult to exit such program. Unexpected exceptions should be propagated in stack so would terminate application if not handled properly. For this case it is not such big issue because glfw.create_window informs about error with output value but (as stated by GLFW docs) not all functions does that and the only way to reliably handle errors is through error callbacks.

Proper propagation of exceptions could be achieved if we provide default error callback that stores latest error state (e.g. in some global/module-level variable) and utilise ctypes' errcheckprotocol by attaching custom errcheck function to every function in glfw._glfw library instance.

Here is simple proof of concept of how it could work:

import glfw
_errors = [None]


def _errcheck(result, func, args):
    if _errors[0] is not None:
        _errors[0], error = None, _errors[0]
        raise error
    return result

for function in glfw._glfw.__dict__.values():
    if hasattr(function, 'errcheck'):
        function.errcheck = _errcheck


def error_callback(err, description):
    _errors[0] = RuntimeError("GLFW error (%s): %s" % (err, description))


def main():
    glfw.set_error_callback(error_callback)
    window = glfw.create_window(640, 480, "Hello World", None, None)

    if not window:
        print("Exception not raised but window creation failed")
        glfw.terminate()
        return

if __name__ == "__main__":
    main()

This approach also gives possibility to wrap all the errors with some custom base exception class e.g. GlfwException or even differentiate different kind of errors with different error classe by inspecting error codes.

Above example is of course not complete because:

  • Adding some custom error callback will break backwards compatibility and it is highly possible that this package users made their own workarounds or are simply happy with this particular behaviour.
  • This is completely not thread safe. If thread safety is a concern (I suppose it is) then errors should be stored in per-thread (maybe using dict, proper locking and thread.get_ident() as state key)

I can happily provide pull request for that change but I would like first to know what do you think about that and how would you prefer to solve some issues:

  1. should be the behaviour opt-in or opt-out? If opt-in then how it should be triggered? I see few options:
    1. additional function in glfw API like enable_exception_propagation() that will initialize error state structure, set default handler and attach errcheck to each glfw._glfw (DLL) function
    2. add custom errcheck to every library function but internally verify if error propagation was enabled (again new API function).
  2. Is thread safety a concern and if so do you have any special requirements about how it should be achieved?
  3. All additional API elements that would be created are something additional that is not found in GLFW. It would be great to somehow inform the package user that they are not a part of GLFW function mapping but something specific only for this single python wrapper. Is information in README enough or maybe we should use specific naming convention or even some submodule?

I think also that it could be very useful to expose some more internals of above behaviour so user could easily add their own error callbacks that will still properly propagate exceptions. Maybe some decorator?

As a side note about defining opt-in mechanism: I would not recommend using environment variables for defining expected behaviour because the end-user could accidentally completely corrupt application flow if it would heavily rely on exception handling.

EDIT: I have realised that I had mixed up two different things. One thing is propagating GLFW errors as exceptions and the other thing is propagating exceptions from python input handlers (keyboard, mouse, joystick etc.). Still I think that we can solve two issues using similar approach and propagating GLFW function errors as exceptions is a good start.

NameError: name '_raise_glfw_errors_as_exceptions' is not defined

In __init__.py, line 840, in set_error_callback
    if previous_callback is not None and previous_callback[0] != _raise_glfw_errors_as_exceptions:
NameError: name '_raise_glfw_errors_as_exceptions' is not defined

For my use case, downgrading to version 1.9 solved it. Leaving it open here to address, so that projects that have pyglfw as a requirement (e.g. mujoco_py) are not affected downstream.

Cannot create Window on Wayland

Tried this on Ubuntu 18.04, with Wayland (before logging in, select Wayland via the little menu next to the unlock button), and installing the glfw lib via sudo apt install libglfw-wayland.

This simple example fails:

import glfw
glfw.init()
# glfw.ERROR_REPORTING = False
w = glfw.create_window(640, 480, "glfw window", None, None)

Traceback:

Traceback (most recent call last):
  File "<tmp 1>", line 4, in <module>
    w = glfw.create_window(640, 480, "glfw window", None, None)
  File "/home/almar/.local/lib/python3.6/site-packages/glfw/__init__.py", line 1141, in create_window
    monitor, share)
  File "/home/almar/.local/lib/python3.6/site-packages/glfw/__init__.py", line 609, in errcheck
    _reraise(exc[1], exc[2])
  File "/home/almar/.local/lib/python3.6/site-packages/glfw/__init__.py", line 45, in _reraise
    raise exception.with_traceback(traceback)
  File "/home/almar/.local/lib/python3.6/site-packages/glfw/__init__.py", line 588, in callback_wrapper
    return func(*args, **kwargs)
  File "/home/almar/.local/lib/python3.6/site-packages/glfw/__init__.py", line 800, in _raise_glfw_errors_as_exceptions
    raise GLFWError(message)
glfw.GLFWError: (65544) b'Wayland: Focusing a window requires user interaction'

If I uncomment the line to ignore errors, it works, except the window is undecorated.

Some context: glfw/glfw#1121 seems to suggest that the error is more of a warning? See also these.

It looks like PyGLFW checks if there are errors and raises them as Python exceptions. Perhaps there should be a filter to ignore specific exceptions like this one?

Vulkan surface creation error

using glfw.create_window_surface I get an error:

ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type

argument 1 is the vulkan instance and mine was created as it should : <cdata 'struct VkInstance_T *' 0x0000022EF5F83520>

visual studio redistributable

Currently, the windows version of glfw needs to have the VC redistributable installed or else it fails with an error when you attempt to use it. Would you be willing to redistribute the DLL inside the windows wheel?

For the x64 version this looks like copying msvcr110.dll from c:\windows\system32 to the package directory, then modifying this code: https://github.com/FlorianRhiem/pyGLFW/blob/master/glfw/library.py#L161 to look something like this:

elif sys.platform == 'win32':
    # try glfw3.dll using windows search paths
    try:
        glfw = ctypes.CDLL('glfw3.dll')
    except OSError:
        # try glfw3.dll in package directory
        try:
            glfw = ctypes.CDLL(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'glfw3.dll'))
        except OSError:
            # try glfw3.dll with included VC redistributable
            os.environ["PATH"] = os.environ["PATH"] + ";" + os.path.abspath(os.path.dirname(__file__))
            try:
                glfw = ctypes.CDLL('glfw3.dll')
            except OSError:
                glfw = None

It looks like you are explicitly allowed to redistribute the redistributable DLLs: https://docs.microsoft.com/en-us/cpp/windows/determining-which-dlls-to-redistribute?view=vs-2019

Better support for Vulkan types

The GLFW API uses the Vulkan types VkInstance, VkPhysicalDevice, VkAllocationCallbacks, VkSurfaceKHR and VkResult. pyGLFW wraps these types using ctypes.c_void_p (except for VkResult, which is wrapped as a ctypes.c_int). To make these Vulkan types more easily usable, the corresponding types from Python Vulkan wrappers should be supported.

Improved error traceback for Python 2

The current traceback isn't so helpful when using Python 2. The traceback message typically looks something like this

Traceback (most recent call last):
  File "..\main.py", line 237, in process_user_input
    glfw.poll_events() # Get events from GLFW
  File "C:\Python27\lib\site-packages\glfw\__init__.py", line 1340, in poll_events
    _glfw.glfwPollEvents()
  File "C:\Python27\lib\site-packages\glfw\__init__.py", line 518, in errcheck
    _reraise(exc[1], exc[2])
  File "C:\Python27\lib\site-packages\glfw\__init__.py", line 51, in _reraise
    raise (exception, None, traceback)
TypeError: object.__init__() takes no parameters`

This issue arises since glfw re-raises the exception. Python 3 solves this by using raise exception.with_traceback(traceback). Solutions for this issue are discussed here https://stackoverflow.com/questions/18188563/how-to-re-raise-an-exception-in-nested-try-except-blocks

I tried Laurent LAPORTE's solution using the six-module and it seems to be working properly. However, I'm sure you want to avoid depending on this module.

# glfw/__init__.py
...
# Python 3 compatibility:
try:
    _getcwd = os.getcwdu
except AttributeError:
    _getcwd = os.getcwd
if sys.version_info.major > 2:
    _to_char_p = lambda s: s.encode('utf-8')
    def _reraise(exception, traceback):
        raise exception.with_traceback(traceback)
else:
    import six
    _to_char_p = lambda s: s
    def _reraise(exception, traceback):
        six.reraise(exception, None, traceback) 
        #raise (exception, None, traceback) # <- Old code
...

Perhaps there is some other way of solving this without using a 3rd part module?

glfw mac binaries

Hi! Thanks for making these bindings! It looks like glfw now releases mac binaries on the official site: https://www.glfw.org/download.html

Would you have any interest in including these in a mac-specific wheel so that users can get started easily?

M1 MacBook Conda install issue

Installed via pip (pip install glfw) but when I run

python
>>>import glfw

I get this error:

_default_error_callback = _GLFWerrorfun(_handle_glfw_errors)
MemoryError

Not sure what's going on.

Just also tested deactivating my conda env and installing/running in a simple vanilla python virtualenv and the import worked but I need it through Conda.

Is there a conda incompatibility?

missing new hint "GLFW_MOUSE_PASSTHROUGH" in current version

Hello, thank you for creating this awesome library.

it was added/released in glfw hours before the last release of pyGLFW!

I tried glfw.window_hint(0x0002000D, glfw.TRUE) instead of glfw.window_hint(glfw.MOUSE_PASSTHROUGH, glfw.TRUE) but found out the compiled library needs updating.

Traceback (most recent call last):
  File "./test-clickthrough.py", line 37, in <module>
    glfw.window_hint(0x0002000D, 1)
  File "glfw/__init__.py", line 1138, in window_hint
    _glfw.glfwWindowHint(hint, value)
  File "glfw/__init__.py", line 628, in errcheck
    _reraise(exc[1], exc[2])
  File "glfw/__init__.py", line 52, in _reraise
    raise exception.with_traceback(traceback)
  File "glfw/__init__.py", line 607, in callback_wrapper
    return func(*args, **kwargs)
  File "glfw/__init__.py", line 820, in _handle_glfw_errors
    raise GLFWError(message)
glfw.GLFWError: (65539) b'Invalid window hint 0x0002000D'

can you please release an update?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.