glfw库的python绑定
pyglfw的Python项目详细描述
GLFW库的python绑定。
主页:https://bitbucket.org/pyglfw/pyglfw
镜像:https://github.com/pyglfw/pyglfw
简介
在开发的时候已经有了 glfw库到python的绑定有很多变体。 除了由nih综合征驱动外,这些结合还发展了 考虑到以下假设:
- Compatibility with GLFW version 3 and higher API.
- Support for both Python2 (2.7) and Python3 (3.3+).
- Provide low-level and pythonic API separately.
- No external dependencies. Thus using ctypes.
平台
在开发过程中,这些绑定被证明是有效的 在所有主要操作系统环境中,包括 Windows、OSX和Linux。
cpython实现是根据版本测试的 没有发现严重问题的Python2.7和Python3.3。
顺便说一下,测试是用pypy进行的。因此 在pypy中发现了与cTypes实现有关的问题。发行 已修复,应作为Pypy 2.2.2的一部分提供。
许可
这些绑定是根据 zlib许可证的条件(文件除外) 在没有限制的examples文件夹中 使用。带版权声明的许可证全文为 在许可证文件中提供。
安装
确保已安装glfw共享库二进制文件 根据项目相关页面上的说明 安装操作系统。
项目版本可以从pypi获得,并且可以 使用p i p或easy_install安装,即:
# pip install pyglfw
此外,可在windows平台上安装exe 可以在项目的主页上找到download page
此外,ubuntu用户可以安装pyglfw 使用项目的PPA。存档还提供包 对于glfw3库本身和后端口python opengl。
可以从克隆源安装最新版本 提供setup.py脚本。以下命令 取决于使用的系统:
在Linux和OSX上
$ python ./setup.py sdist
然后
# easy_install dist/pyglfw-<ver>.tar.gz
或
# pip install dist/pyglfw-<ver>.tar.gz
在Windows上
> python.exe setup.py bdist_wininst
然后从dist文件夹运行exe安装程序。
libapi
低层libapi包用作薄包装 在GLFW图书馆上方。它的api基本上类似于 C库,但需要通过引用传递的函数除外 参数。根据经验,所有功能 返回void并通过pass by ref填充多个值 参数映射到返回元组的函数 价值观。以及返回指向数组的指针的函数 通过pass by ref参数设置的项目数为 映射到返回项列表的函数。即:
int major, minor, rev; glfwGetVersion(&major, &minor, &rev)
变成
major, minor, rev = glfwGetVersion()
以及
int n_items; GLFWmonitor **monitors = glfwGetMonitors(&n_items)
变成
monitors = glfwGetMonitors()
关于窗口指针,应特别注意 功能。glfwsetwindowpointer允许设置 python对象作为窗口私有数据并检索 它用glfwgetwindowpointer返回。但是它仍然 需要在python中保留对该对象的引用 代码。同样,此功能也不能与pypy一起使用 由于缺少py_对象支持而实现。
保存引用的要求也扩展到 设置变量回调的函数。拜托 有关用法入门,请参阅示例中的raw_api。
PYGLFW
pythonicpyglfw包处理以下时刻:
- Encapsulation of struct pointers and functions API into objects with properties and methods.
- Transparent usage of strings (either from python 2 or from python 3).
- Raising exceptions in case of errors.
- Eliminates need to use of ctypes structures and ctypes-based callback prototypes.
- Holds references for set to callback functions, so there is no need to hold them outside.
- Provide pythonic types for callback functions.
并且以下功能受到限制:
- No get/set window pointers. Due to its ambiquity.
- No set error callback. Error callback is used to raise exeptions.
- Set callback methods doesn’t return previously used callback. It’s unable to certainly map them to python object in every case.
- No check for extensions and proc address query. This should be handled with dedicated frameworks like PyOpenGL.
并排
这里是相同操作的并排比较 通过低级(libapi)和pythonic(pyglfw)执行 绑定。
基础知识
libapi:
from pyglfw.libapi import * glfwInit() glfwGetVersion() glfwTerminate() glfwPollEvents()
PYGLFW:
import pyglfw.pyglfw as glfw glfw.init() glfw.api_version() glfw.terminate() glfw.poll_events()
监视器
libapi:
monitorp = glfwGetPrimaryMonitor() curmode = glfwGetVideoMode(monitorp) allmodes = glfwGetVideoModes(monitorp) @GLFWmonitorfun def on_monitor_event(monitor, event): if event == GLFW_CONNECTED: print(glfwGetMonitorName(monitor)) glfwSetMonitorCallback(on_monitor_event)
PYGLFW:
monitor = glfw.get_primary_monitor() curmore = monitor.video_mode allmodes = monitor.video_modes def on_monitor_event(monitor, event): if event == glfw.Monitor.CONNECTED: print(monitor.name) glfw.Monitor.set_callback(on_monitor_event)
提示
libapi:
glfwDefaultWindowHints() glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API) w, h = curmode.width, curmode.height windowp = glfwCreateWindow(w, h, b'libapi', None, None) glfwDestroyWindow(windowp)
PYGLFW:
glfw.Window.hint() glfw.Window.hint(client_api=glfw.Window.OPENGL_API) w, h = curmode.width, curmode.height window = glfw.Window(w, h, 'pyglfw') window.close()
交换
libapi:
context = glfwGetCurrentContext() glfwMakeContextCurrent(windowp) glfwSwapInterval(0) glfwMakeContextCurrent(context) glfwMakeContextCurrent(windowp) glfwSwapBuffers(windowp)
PYGLFW:
# makes context current # and restores previous window.swap_interval(0) window.make_current() window.swap_buffers()
窗口
libapi:
if not glfwWindowShouldClose(): glfwSetWindowTitle(b'libapi') size = glfwGetWindowSize() glfwShowWindow() is_visible = glfwGetWindowAttrib(GLFW_VISIBLE) client_api = glfwGetWindowAttrib(GLFW_CLIENT_API) glfwSetWindowAttrib(GLFW_FOCUSED, 1) @GLFWwindowsizefun def on_window_size(windowp, w, h): glfwSetWindowSize(windowp, size[0], size[1]) glfwSetWindowSizeCallback(windowp, on_window_size)
PYGLFW:
if not window.should_close: window.set_title('pyglfw') size = window.size window.show() is_visible = window.visible client_api = window.client_api window.has_focus = True def on_window_size(window, w, h): window.size = size window.set_window_size_callback(on_window_size)
输入
libapi:
mode = glfwGetInputMode(windowp, GLFW_STICKY_KEYS) glfwSetInputMode(windowp, GLFW_STICKY_MOUSE_BUTTONS, mode) is_escape = glfwGetKey(windowp, GLFW_ESCAPE) is_middle = glfwGetMouseButton(windowp, GLFW_MOUSE_BUTTON_MIDDLE) cursor_at = glfwGetCursorPos(windowp) @GLFWkeyfun def on_key(windowp, key, scancode, action, mods): if key == GLFW_ESCAPE: glfwSetWindowShouldClose(1) glfwSetKeyCallback(windowp, on_key) if glfwJoystickPresent(0): joy_name = glfwGetJoystickName(0) joy_axes = glfwGetJoystickAxes(0)
PYGLFW:
mode = window.sticky_keys window.sticky_mice = mode is_escape = window.keys.escape is_middle = window.mice.middle cursor_at = window.cursor_pos def on_key(window, key, scancode, action, mods): if key == glfw.Keys.ESCAPE: window.should_close = True window.set_key_callback(on_key) js = glfw.Joystick(0) if js: joy_name = js.name joy_axes = js.axes