Introduction
In this article we will understand the OpenGL interface, we will see how we can use the OpenGL interface, how we can resize windows, how error checking is done in OpenGL, and many more. The interface is used by all high-level pyglet APIs so that every rendering is done smoothly with the graphics card rather than the operating system. You can access this interface directly; it is similar to using OpenGL from C.
The OpenGL interface
Pyglet provides the interface to OpenGL and GLU. The interface is used by all high-level pyglet APIs so that every rendering is done smoothly with the graphics card, rather than the operating system. You can access this interface directly; using it is similar to using OpenGL from C. The interface is a "small wrapper" around libGL.so for Linux, opengl32.dll for Windows, and OpenGL.framework for OS X. Pyglet administrators are updating the link from the latest specifications, so then it is always up to date with the latest version, and almost all extensions.
The interface is provided by the pyglet.gl package. To use it you will need good knowledge of OpenGL, C, and ctypes. You may choose to use OpenGL without using ctypes, where you should check PyOpenGL. PyOpenGL provides the same functionality as the "Pythonic" interface and will work with the pyglet without modification.
Using OpenGL
Import package provides access to OpenGL, GLU, and all registered OpenGL extensions. This is sufficient for all but the most advanced use of OpenGL:
from pyglet.gl import *
All function names and constants are the same as counterparts C. For example, the following program draws a triangle on the screen:
from pyglet.gl import *
# Direct OpenGL commands to this window.
window = pyglet.window.Window()
@window.event
def on_draw():
glClear(GL_COLOR_BUFFER_BIT)
glLoadIdentity()
glBegin(GL_TRIANGLES)
glVertex2f(0, 0)
glVertex2f(window.width, 0)
glVertex2f(window.width, window.height)
glEnd()
pyglet.app.run()
Some OpenGL functions require a data connection. These same members should be formed as the same ctypes of the appropriate type. The following example draws the same triangle as above but uses a vertex array instead of nearby mode functions. Note the structure of the vertex array using the same type of GLfloat ctypes:
from pyglet.gl import *
window = pyglet.window.Window()
vertices = [0, 0,
window.width, 0,
window.width, window.height]
vertices_gl_array = (GLfloat * len(vertices))(*vertices)
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(2, GL_FLOAT, 0, vertices_gl_array)
@window.event
def on_draw():
glClear(GL_COLOR_BUFFER_BIT)
glLoadIdentity()
glDrawArrays(GL_TRIANGLES, 0, len(vertices) // 2)
pyglet.app.run()
Resizing the window
The pyglet sets the viewing area and orthographic projection in each window automatically. It does this automatically on_resize() the defined window:
@window.event
def on_resize(width, height):
glViewport(0, 0, width, height)
glMatrixMode(gl.GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, -1, 1)
glMatrixMode(gl.GL_MODELVIEW)
If you need to explain your prediction (for example, to use a 3-dimensional view), you should bring this event to your attention; For example:
@window.event
def on_resize(width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(65, width / float(height), .1, 1000)
glMatrixMode(GL_MODELVIEW)
return pyglet.event.EVENT_HANDLED
Note that when on_resize() handler is called for a window the first time it is displayed after that it can be resized.
Error checking
By default, pyglet calls glGetError after each GL function (except where such testing does not work). When an error is reported, pyglet raises GLException with the effect of gluErrorString as a message. This is very helpful during development, as it captures common coding errors early. However, it has a huge impact on performance and is disabled when python is run with the O-option.
You can also disable this bug check by setting the following option before importing pyglet.gl or pyglet.window:
You can also disable this bug check by setting the following option before importing pyglet.gl or pyglet.window:
# Disable error checking for increased performance
pyglet.options['debug_gl'] = False
from pyglet.gl import *
Setting the option after importing pyglet.gl will have no effect. If disabled, there is no error checking for each GL call.
Using extension functions
Before using the extension function, you should check that the extension is in use by the current driver.
if pyglet.gl.gl_info.have_extension('GL_ARB_shadow'):
# ... do shadow-related code.
else:
# ... raise an exception, or use a fallback method
if pyglet.gl.gl_info.have_version(1,5):
# We can assume all OpenGL 1.5 functions are implemented.
Remember to only call gl_info functions after creating a window.
There is a glu_info compatible module for testing the GLU version and extensions.
Nvidia usually releases hardware with extensions before they are officially registered. When you import * from pyglet.gl you are only importing registered extensions. You can download the latest Nvidia extensions with:
from pyglet.gl.glext_nv import *
Using Multiple Windows
Pyglet lets you create and display any number of windows simultaneously. Each one will be built with its own OpenGL context. However, all context will share the same texture, display lists, shader programs, etc. Each contexts has its own shape and framebuffers.
There is always a working context (unless there are no windows). When using pyglet.app.run () in the app loop of events, pyglet ensures that the correct window is active before sending on_draw () or on_resize () events.
In some cases, you can clearly set the active context with pyglet.window.Window.switch_to.
AGL, GLX, and WGL
OpenGL theme itself is managed by the operating system library: AGL for OS X, GLX under X11, and WGL for Windows. Pyglet handles this information when a window is created, but you may need to use functions directly.
The modules are named pyglet.gl.agl, pyglet.gl.glx and pyglet.gl.wgl. You must only enter the correct operating system module:
if sys.platform.startswith('linux'):
from pyglet.gl.glx import *
glxCreatePbuffer(...)
elif sys.platform == 'darwin':
from pyglet.gl.agl import *
aglCreatePbuffer(...)
Alternatively you can use pyglet.compat_platform to support platforms that are not supported by pyglet. For example FreeBSD programs will appear as linux-compat at pyglet.compat_platform.
There are useful modules to query the version and extensions of WGL and GLX named pyglet.gl.wgl_info and pyglet.gl.glx_info, whereas AGL does not have such a module.
If you are using GLX extensions, you can import pyglet.gl.glxext_arb for registered extensions or pyglet.gl.glxext_nv for the latest Nvidia extensions.