Graphics · Three OpenGL programs
Graphics & Python Games
Three small PyOpenGL programs: a house in the rain, an arcade catcher drawn with a hand-written line algorithm, and a 3D survival shooter.
Stack
- Python
- PyOpenGL
- GLUT
- NumPy
RainFall
A 2D house under animated, wind-bent rain, with keyboard control over the weather.
- Python
- PyOpenGL
- NumPy
A house drawn from OpenGL polygons and line loops (walls, roof, door with a knob, two windows) on wet grass with elliptical puddles. A hundred raindrops fall continuously. The arrow keys tilt the rain to simulate wind, and W / S brighten or darken the sky.
def render_bent_rain(): global drop_positions, rain_direction glColor3f(0.0, 0.5, 1.0) glLineWidth(2) glBegin(GL_LINES) for i, pos in enumerate(drop_positions): bent_x = pos[0] + np.sin(rain_direction) * (1 - pos[1]) length = np.random.uniform(0.05, 0.08) glVertex2f(bent_x, pos[1]) glVertex2f(bent_x + np.sin(rain_direction) * 0.02, pos[1] - length) glEnd() # Fall speed drop_positions[:, 1] -= 0.025 # Reset drops when they go below the screen (vectorised with NumPy) reset_indices = drop_positions[:, 1] < -1 drop_positions[reset_indices, 1] = 1 drop_positions[reset_indices, 0] = np.random.uniform(-1, 1, np.sum(reset_indices))DiamondCatcher
Catch falling diamonds with a paddle. Every line on screen is drawn pixel by pixel.
- Python
- PyOpenGL
- GLUT
Diamonds of random colors fall from random positions. Arrow keys move the catcher, and on-screen restart, pause/play and exit buttons respond to the mouse. The fall speed increases every two catches, and a miss ends the round.
The interesting part is how it draws. It doesn't use OpenGL's line primitives: every shape (diamonds, catcher, buttons) is made of lines rasterised with a hand-written midpoint line algorithm, emitting single GL_POINTS. The midpoint algorithm only handles slopes between 0 and 1 (zone 0), so each line is first classified into one of eight zones, transformed into zone 0, drawn there, and each pixel is transformed back.
| zone | into zone 0 | pixel back |
|---|---|---|
| 0 | (x, y) | (x, y) |
| 1 | (y, x) | (y, x) |
| 2 | (y, −x) | (−y, x) |
| 3 | (−x, y) | (−x, y) |
| 4 | (−x, −y) | (−x, −y) |
| 5 | (−y, −x) | (−y, −x) |
| 6 | (−y, x) | (y, −x) |
| 7 | (x, −y) | (x, −y) |
def MPLDraw(x1, y1, x2, y2, zone): dx = x2 - x1 dy = y2 - y1 incE = 2 * dy incNE = 2 * (dy - dx) d = 2 * dy - dx x = x1 y = y1 while x < x2: drawasZero(x, y, zone) # map the zone-0 pixel back to its real zone if d < 0: d += incE x += 1 else: d += incNE x += 1 y += 1Survival-Barrage
A 3D survival shooter with an animated character, switchable cameras and an auto-aim cheat mode.
- Python
- PyOpenGL
- GLU
- GLUT
Enemies continuously pursue the player inside a bounded arena. The player character has moving limbs and a rotating gun, and bullets are tested for collision against enemies. You start with five lives, and the game also ends after ten missed shots, which rewards aiming over spraying.
- Perspective projection (
gluPerspective, 60° field of view) withgluLookAtcameras. - Right-click switches between third-person and first-person views, and the arrow keys adjust camera height and angle.
- Cheat mode (
C) enables auto-aim and auto-fire, plus an optional auto-following first-person camera (V).