OpenGL specifies an API for 2D and 3D computer graphics. The API consists of functions and constants. We will be concentrating on the Python implementation called PyOpenGL.
Install PyOpenGL with the following command:
pip install PyOpenGL PyOpenGL_accelerate
You might need to have root access to execute this command. The corresponding easy_install
command is as follows:
easy_install PyOpenGL PyOpenGL_accelerate
For the purpose of demonstration we will draw a Sierpinski gasket with OpenGL. This is a fractal pattern in the shape of a triangle created by the mathematician Waclaw Sierpinski. The triangle is obtained via a recursive and in principle infinite procedure.
def display_openGL(w, h): pygame.display.set_mode((w,h), pygame.OPENGL|pygame.DOUBLEBUF) glClearColor(0.0, 0.0, 0.0, 1.0) glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) gluOrtho2D(0, w, 0, h)
glColor3f(1.0, 0, 0) vertices = numpy.array([[0, 0], [DIM/2, DIM], [DIM, 0]]) NPOINTS = 9000 indices = numpy.random.random_integers(0, 2, NPOINTS) point = [175.0, 150.0] for index in indices: glBegin(GL_POINTS) point = (point + vertices[index])/2.0 glVertex2fv(point) glEnd() glFlush()
The Sierpinski triangle looks like this:
The full Sierpinski gasket demo code with all the imports is shown as follows:
import pygame from pygame.locals import * import numpy from OpenGL.GL import * from OpenGL.GLU import * def display_openGL(w, h): pygame.display.set_mode((w,h), pygame.OPENGL|pygame.DOUBLEBUF) glClearColor(0.0, 0.0, 0.0, 1.0) glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) gluOrtho2D(0, w, 0, h) def main(): pygame.init() pygame.display.set_caption('OpenGL Demo') DIM = 400 display_openGL(DIM, DIM) glColor3f(1.0, 0, 0) vertices = numpy.array([[0, 0], [DIM/2, DIM], [DIM, 0]]) NPOINTS = 9000 indices = numpy.random.random_integers(0, 2, NPOINTS) point = [175.0, 150.0] for index in indices: glBegin(GL_POINTS) point = (point + vertices[index])/2.0 glVertex2fv(point) glEnd() glFlush() pygame.display.flip() while True: for event in pygame.event.get(): if event.type == QUIT: return if __name__ == '__main__': main()
As promised here is a line-by-line explanation of the most important parts of the example:
Function |
Description |
---|---|
|
This sets the display mode to the required width, height, and OpenGL display. |
|
This clears the buffers using a mask. Here we clear the color buffer and depth buffer bits. |
|
This defines a 2D orthographic projection matrix with the coordinates of the left, right, top, and bottom clipping planes. |
|
This defines the current drawing color using three float values for RGB (0-1 instead of 0-255 that is usual for Pygame). In this case we will be painting in red. |
|
This delimits the vertices of primitives or a group of primitives. Here the primitives are points. |
|
This renders a point given a vertex. |
|
This closes a section of code started with |
|
This forces execution of GL commands. |