pyglet 1.1 introduces new features for rendering high performance graphics and text, is more convenient to use, and integrates better with the operating system. Some of the existing interfaces have also been redesigned slightly to conform with standard Python practice or to fix design flaws.
pyglet 1.1 is backward compatible with pyglet 1.0. Any application that uses only public and documented methods of pyglet 1.0 will continue to work unchanged in pyglet 1.1. If you encounter an issue where this is not the case, please consider it a bug in pyglet and file an issue report.
Some methods have been marked deprecated in pyglet 1.1. These methods continue to work, but have been superceded by newer methods that are either more efficient or have a better design. The API reference has a complete list of deprecated methods; the main changes are described in the next section.
Deprecated methods will continue to be supported in all minor revisions of pyglet 1.x. A pyglet 2.0 release will no longer support these methods.
The following minor changes have been made for design or efficiency reasons. Applications which no longer need to support pyglet 1.0 should make the appropriate changes to ensure the deprecated methods are not called.
dispatch_events method on Player and the equivalent function on the
pyglet.media module should no longer be called. In pyglet 1.1, media
objects schedule an update function on pyglet.clock at an appropriate
interval. New applications using media are required to call
The AbstractImage properties
image_data, and so on have
been replaced with equivalent methods
The ImageData properties data, format and pitch, which together were
used to extract pixel data from an image, have been replaced with a single
get_data. The format and pitch properties should now be used
only to determine the current format and pitch of the image.
The get_current_context function has been replaced with a global variable, current_context, for efficiency.
pyglet 1.1 introduces new features that make it easier to program with, so the standard practice as followed in many of the pyglet example programs has changed.
In pyglet 1.0, it was necessary to explicitly import each submodule required by the application; for example:
from pyglet import font from pyglet import image from pyglet import window
pyglet now lazily loads submodules on demand, so an application can get away
with importing just pyglet. This is especially handy for modules that are
typically only used once in an application, and frees up the names
window and so on for the application developer. For example:
window = pyglet.window.Window()
Every application using pyglet 1.0 provides its own event loop, such as:
while not window.has_exit: dt = clock.tick() update(dt) window.dispatch_events() window.clear() draw() window.flip()
Besides being somewhat repetitious to type, this type of event loop is difficult to extend with more windows, and exausts all available system resources, even if the application is not doing anything.
The new pyglet.app module provides an application event loop that is less demanding of the CPU yet more responsive to user events. A complete application that opens an empty window can be written with:
window = pyglet.window.Window() @window.event def on_draw(): window.clear() pyglet.app.run()
Note the new on_draw event, which makes it easy to specify different drawing functions for each window. The pyglet.app event loop takes care of dispatching events, ticking the clock, calling the draw function and flipping the window buffer.
Update functions can be scheduled on the clock. To have an update function be called as often as possible, use clock.schedule (this effectively degenerates into the older dispatch_events practice of thrashing the CPU):
def update(dt): pass clock.schedule(update)
Usually applications can update at a less frequent interval. For example, a game that is designed to run at 60Hz can use clock.schedule_interval:
def update(dt): pass clock.schedule_interval(update, 1/60.0)
This also removes the need for clock.set_fps_limit.
Besides the advantages already listed, windows managed by the event loop will not block while being resized or moved; and the menu bar on OS X can be interacted with without blocking the application.
It is highly recommended that all applications use the event loop. The loop can be extended if you need to add additional hooks or integrate with another package. Applications continuing to use Window.dispatch_events gain no advantage, but suffer from poorer response, increased CPU usage and artifacts during window resizing and moving.
See The application event loop for more details.
Locating resources such as images, sound and video files, data files and fonts is difficult to do correctly across all platforms, considering the effects of a changing working directory and various distribution packages such as setuptools, py2exe and py2app.
The new pyglet.resource module implements the correct logic for all these cases, making it simple to load resources that belong to a specific module or the application as a whole. A resource path can be set that is indexed once, and can include filesystem directories, Python module paths and ZIP files.
For example, suppose your application ships with a
logo.png that needs to
be loaded on startup. In pyglet 1.0 you might have written:
import os.path from pyglet import image script_dir = os.path.dirname(__file__) logo_filename = os.path.join(script_dir, 'logo.png') logo = image.load(logo_filename)
In pyglet 1.1, you can write:
logo = pyglet.resource.image('logo.png')
And will actually work in more scenarios (such as within a setuptools egg file, py2exe and py2app).
The resource module efficiently packs multiple small images into larger textures, so there is less need for artists to create sprite sheets themselves for efficient rendering. Images and textures are also cached automatically.
See Application resources for more details.
The pyglet.graphics module is a low-level abstraction of OpenGL vertex arrays and buffer objects. It is intended for use by developers who are already very familiar with OpenGL and are after the best performance possible. pyglet uses this module internally to implement its new sprite module and the new text rendering module. The Graphics chapter describes this module in detail.
The pyglet.sprite module provide a fast, easy way to display 2D graphics on screen. Sprites can be moved, rotated, scaled and made translucent. Using the batch features of the new graphics API, multiple sprites can be drawn in one go very quickly. See Sprites for details.
The pyglet.image.load_animation function can load animated GIF images. These are returned as an Animation, which exposes the individual image frames and timings. Animations can also be played directly on a sprite in place of an image. The Animations chapter describes how to use them.
The pyglet.image.atlas module packs multiple images into larger textures for efficient rendering. The pyglet.resource module uses this module for small images automatically, but you can use it directly even if you’re not making use of pyglet.resource. See Texture bins and atlases for details.
Images now have
anchor_y attributes, which specify a
point from which the image should be drawn. The sprite module also uses the
anchor point as the center of rotation.
Textures have a get_transform method for retrieving a TextureRegion that refers to the same texture data in video memory, but with optional horizontal or vertical flipping, or 90-degree rotation.
The pyglet.text module can render formatted text efficiently. A new class Label supercedes the old pyglet.font.Text class (which is now actually implemented in terms of Label). The “Hello, World” application can now be written:
window = pyglet.window.Window() label = pyglet.text.Label('Hello, world', font_name='Times New Roman', font_size=36, x=window.width//2, y=window.height//2, halign='center', valign='center') @window.event def on_draw(): window.clear() label.draw() pyglet.app.run()
You can also display multiple fonts and styles within one label, with HTMLLabel:
label = pyglet.text.HTMLLabel('<b>Hello</b>, <font color=red>world!</font>')
More advanced uses of the new text module permit applications to efficiently display large, scrolling, formatted documents (for example, HTML files with embedded images), and to allow the user to interactively edit text as in a WYSIWYG text editor.
EventDispatcher now has a remove_handlers method which provides finer control over the event stack than pop_handlers.
@event decorator has been fixed so that it no longer overrides
existing event handlers on the object, which fixes the common problem of
handling the on_resize event. For example, the following now works without
any surprises (in pyglet 1.0 this would override the default handler, which
sets up a default, necessary viewport and projection):
@window.event def on_resize(width, height): pass
A variant of clock.schedule_interval, clock.schedule_interval_soft has been added. This is for functions that need to be called periodically at a given interval, but do not need to schedule the period immediately. Soft interval scheduling is used by the pyglet.media module to distribute the work of decoding video and audio data over time, rather than stalling the CPU periodically. Games could use soft interval scheduling to spread the regular computational requirements of multiple agents out over time.
In pyglet 1.0, font.load attempted to match the font resolution (DPI) with the operating system’s typical behaviour. For example, on Linux and Mac OS X the default DPI was typically set at 72, and on Windows at 96. While this would be useful for writing a word processor, it adds a burden on the application developer to ensure their fonts work at arbitrary resolutions. In pyglet 1.1 the default DPI is set at 96 across all platforms. It can still be overridden explicitly by the application if desired.
Video sources in pyglet.media can now be stepped through frame-by-frame: individual image frames can be extracted without needing to play back the video in realtime.
For a complete list of new features and bug fixes, see the
distributed with the source distribution.