1.
O,penGL in Python
1.1. Introduction of OpenGL
OpenGL (Open Graphics Library) is a cross-platform, hardware-accelerated, language-
independent, industrial standard API for producing 3D (including 2D) graphics. Modern
computers have dedicated GPU (Graphics Processing Unit) with its own memory to speed up
graphics rendering. OpenGL is the software interface to graphics hardware. In other words,
OpenGL graphic rendering commands issued by your applications could be directed to the
graphic hardware and accelerated.
We use 3 sets of libraries in our OpenGL programs:
1) OpenGL Utilities Toolkit (GLUT): OpenGL is designed to be independent of the
windowing system or operating system. GLUT is needed to interact with the Operating
System (such as creating a window, handling key and mouse inputs); it also provides more
building models (such as sphere and torus). GLUT commands start with a prefix of "glut"
(e.g., glutCreatewindow, glutMouseFunc). GLUT is platform independent, which is built
on top of platform-specific OpenGL extension such as GLX for X Window System, WGL
for Microsoft Window, and AGL, CGL or Cocoa for Mac OS. Quoting from
the opengl.org: "GLUT is designed for constructing small to medium sized OpenGL
programs. While GLUT is well-suited to learning OpenGL and developing simple
OpenGL applications, GLUT is not a full-featured toolkit so large applications requiring
sophisticated user interfaces are better off using native window system toolkits. GLUT is
simple, easy, and small." Alternative of GLUT includes SDL, ....
2) Core OpenGL (GL): consists of hundreds of commands, which begin with a prefix
"gl" (e.g., glColor, glVertex, glTranslate, glRotate). The Core OpenGL models an object
via a set of geometric primitives such as point, line and polygon.
3) OpenGL Utility Library (GLU): built on-top of the core OpenGL to provide
important utilities (such as setting camera view and projection) and more building models
(such as qradric surfaces and polygon tessellation). GLU commands start with a prefix
"glu" (e.g., gluLookAt, gluPerspective).
1|Page
1.2. OpenGL installation in Python
OpenGL is an application programming interface also we call it API which is merely software
library for accessing features in graphic hardware and also OpenGL is designed as streamlined,
hardware independent interface that can be implemented on many different types of graphic
hardware systems. OpenGL is a graphics library which is supported by multiple platforms
including Windows, Linux, and MacOS, and is available for use in multiple other languages as
well; however, the scope of this post will be limited to its usage in the Python programming
language.
OpenGL, as compared to other similar graphics libraries, is fairly simple. We'll start with setting
it up on our system, by following below procedure to add it library in our system.
A. Install python setup or interpreter
B. Install a software used for writing/editing programming language such as PyCharm,
Visual Studio
C. If you are running 64-bit windows, use the following procedure to install PyOpenGL. In
your Environment.
To properly install, follow these steps:
1) Don’t install PyOpenGL using(pip install PyOpenGL PyOpenGL_accelerate) or if
you installed previously from online website of the library of a python, Uninstall
existing PyOpenGL, to Uninstall use (pip uninstall PyOpenGL
PyOpenGL_accelerate)
2) Download the 64-bit builds of PyOpenGL and PyOpenGL accelerate from
here: https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl
3) How to choose which one to download? Well, first you need to check your python
version. Run python --version to determine.
Then according to your version download the .whl files for PyOpenGL and
PyOpenGL accelerate.
For example, if you have Python 3.11, download these 2 files:
PyOpenGL-3.1.6-cp311-cp311-win_amd64.whl
PyOpenGL_accelerate-3.1.6-cp311-cp311-win_amd64.whl
2|Page
Similarly, if you run Python 3.9, download these instead:
PyOpenGL-3.1.5-cp39-cp39-win_amd64.whl
PyOpenGL_accelerate-3.1.5-cp39-cp39-win_amd64.whl
Note: Must download amd64 ones, after all, you're running 64-bit windows and also
if you're running 32-bit windows follow the same procedure except you have to
download win32 of PyOpenGL and PyOpenGL_accelerate from the same link. And
then follow the same steps.
4) Now go to the folder where you downloaded the files and run power shell/command
prompt(cmd) with administrator there.
5) Use pip to force install those files. For example:
pip install PyOpenGL-3.1.6-cp311-cp311-win_amd64.whl --force-reinstall
pip install PyOpenGL_accelerate-3.1.6-cp311-cp311-win_amd64.whl --force-
reinstall
Note: Install PyOpenGL first and then PyOpenGL_accelerate
6. If the installation succeeds, you may be able now to run.
It is necessary to restart your desktop if you reinstall any one of them (Python,
OpenGL)
3|Page
1.3. Setting up OpenGL Utility Toolkit (GLUT)
GLUT provides high-level utilities to simplify OpenGL programming, especially in interacting
with the Operating System (such as creating a window, handling key and mouse inputs). The
following GLUT functions were used in the above program:
glutInit: initializes GLUT, must be called before other GL/GLUT functions.
glutInit()
glutCreateWindow: creates a window with the given title.
glutCreateWindow(title)
glutInitWindowSize: specifies the initial window width and height, in pixels.
glutInitWindowSize(width, height)
glutInitWindowPosition: positions the top-left corner of the initial window at (x, y). The
coordinates (x, y), in term of pixels, is measured in window coordinates, i.e., origin (0, 0) is
at the top-left corner of the screen; x-axis pointing right and y-axis pointing down. It Set
the position at which this window should appear
glutInitWindowPosition(x, y)
glutDisplayFunc: registers the callback function (or event handler) for handling window-
paint event. The OpenGL graphic system calls back this handler when it receives a window
re-paint request. In the example, we register the function display () as the handler.
glutDisplayFunc(function)
glutMainLoop: enters the infinite event-processing loop, i.e, put the OpenGL graphics system
to wait for events (such as re-paint), and trigger respective event handlers (such
as display()).
glutMainLoop()
glutInitDisplayMode: sets the initial display mode.
glutInitDisplayMode(mode)
4|Page
Usage: glutInitDisplayMode(mode)
Mode: Display mode, normally the bitwise OR-ing of GLUT display mode bit masks.
See values below:
GLUT_RGBA: Bit mask to select an RGBA mode window. This is the default if
neither GLUT_RGBA nor GLUT_INDEX are specified.
GLUT_RGB: An alias for GLUT_RGBA.
GLUT_INDEX: Bit mask to select a color index mode window. This overrides
GLUT_RGBA if it is also specified.
GLUT_SINGLE: Bit mask to select a single buffered window. This is the default
if neither GLUT_DOUBLE or GLUT_SINGLE are specified.
GLUT_DOUBLE: Bit mask to select a double buffered window. This overrides
GLUT_SINGLE if it is also specified.
GLUT_ACCUM: Bit mask to select a window with an accumulation buffer.
GLUT_ALPHA: Bit mask to select a window with an alpha component to the
color buffer(s).
GLUT_DEPTH: Bit mask to select a window with a depth buffer.
GLUT_STENCIL: Bit mask to select a window with a stencil buffer.
GLUT_MULTISAMPLE: Bit mask to select a window with multisampling
support. If multisampling is not available, a non-multisampling window will
automatically be chosen. Note: both the OpenGL client-side and server-side
implementations must support the GLX_SAMPLE_SGIS extension for
multisampling to be available.
GLUT_STEREO: Bit mask to select a stereo window.
GLUT_LUMINANCE: Bit mask to select a window with a ``luminance'' color
model. This model provides the functionality of OpenGL's RGBA color model,
but the green and blue components are not maintained in the frame buffer. Instead
each pixel's red component is converted to an index between zero and
glutGet(GLUT_WINDOW_COLORMAP_SIZE)-1 and looked up in a per-
window color map to determine the color of pixels within the window. The initial
5|Page
colormap of GLUT_LUMINANCE windows is initialized to be a linear gray
ramp, but can be modified with GLUT's colormap routines.
Example:
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *
def display ():
print("Hello This is the first OpenGL")
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
glutInitWindowPosition(0, 0)
wind = glutCreateWindow("OpenGL Third Class")
glutDisplayFunc(display)
glutMainLoop()
6|Page
1.4. Drawing Primitives
In OpenGL, an object is made up of geometric primitives such as triangle, quad, line segment
and point. A primitive is made up of one or more vertices. OpenGL supports the following
primitives:
A primitive "object" can be anything from a 3D point to a line to a
triangle to an n-sided polygon. Each primitive has at least one vertex.
With points, vertex is just that - the point. A line has only 2 vertices -
its starting point and its ending point. With polygons, there should be
7|Page
more than 2 vertices since polygons are surfaces defined by more or
equal to 3 vertices residing on the same plane. A triangle is, for
instance, a polygon with 3 vertices. This all should be obvious to you at
this point, if you're serious about 3D graphics. Note that a 3D cube
cannot be considered a primitive. Generally, primitives restrict
themselves to triangles. A four-sided polygon can generate a quad but
that quad will still be made out of 2 polygons. Points and lines can also
be considered primitives.
Table of OpenGL Primitives
As you read the following descriptions, assume that n vertices (v0, v1, v2, ... , v n–1) are
described between a glBegin() and glEnd() pair.
GL_POINTS Draws a point at each of the n vertices.
GL_LINES Draws a series of unconnected line segments. Segments are
drawn between v0 and v1, between v2 and v3, and so on. If
n is odd, the last segment is drawn between vn–3 and vn–2,
and v n–1 is ignored.
GL_LINE_STRIP Draws a line segment from v0 to v1, then from v1 to v2,
and so on, finally drawing the segment from v n–2 to vn–1.
Thus, a total of n – 1 line segments are drawn. Nothing is
drawn unless n is larger than 1. There are no restrictions on
8|Page
the vertices describing a line strip (or a line loop); the lines
can intersect arbitrarily.
GL_LINE_LOOP Same as GL_LINE_STRIP, except that a final line
segment is drawn from vn–1 to v0, completing a loop.
GL_TRIANGLES Draws a series of triangles (three-sided polygons) using
vertices v0, v1, v2, then v3, v4, v5, and so on. If n isn’t a
multiple of 3, the final one or two vertices are ignored.
GL_TRIANGLE_STRIP Draws a series of triangles (three-sided
polygons) using vertices v0, v1, v2, then v2, v1, v3 (note
the order), then v2, v3, v4, and so on. The ordering is to
ensure that the triangles are all drawn with the same
orientation so that the strip can correctly form part of a
surface.
GL_TRIANGLE_FAN Same as GL_TRIANGLE_STRIP, except that the
vertices are v0, v1, v2, then v0, v2, v3, then v0, v3, v4, and
so on
GL_QUADS Draws a series of quadrilaterals (four-sided polygons)
using vertices v0, v1, v2, v3, then v4, v5, v6, v7, and so
on. If n isn’t a multiple of 4, the final one, two, or three
vertices are ignored.
GL_QUAD_STRIP Draws a series of quadrilaterals (four-sided
polygons) beginning with v0, v1, v3, v2, then v2, v3, v5,
v4, then v4, v5, v7, v6, and so on (see Figure 2-7). n must
be at least 4 before anything is drawn. If n is odd, the final
vertex is ignored.
GL_POLYGON Draws a polygon using the points v0, ... , vn–1 as vertices.
n must be at least 3, or nothing is drawn. In addition, the
polygon specified must not intersect itself and must be
convex. If the vertices don’t satisfy these conditions, the
results are unpredictable.
9|Page
glVertex
The main function (and probably the most used OpenGL function) is function named glVertex.
This function defines a point (or a vertex) in your 3D world and it can vary from receiving 2 up
to 4 coordinates.
glVertex2f(100.0, 150.0) - defines a point at x = 100, y = 150, z = 0; this function takes
only 2 parameters, z is always 0. glVertex2f can be used in special cases and won't be
used a lot unless you're working with pseudo-2D sprites or triangles and points that
always have to be constrained by the depth coordinate.
glVertex3f(100.0, 150.0, -25.0) - defines a point at x = 100, y = 150, z = -25.0; this
function takes 3 parameters, defining a fully 3D point in your world.
glVertex4f(100.0, 150.0, -25.0, 1.0) - this is the same as glVertex3f, the only difference
is in the last coordinate that specifies a scaling factor. The scaling factor is set to 1.0 by
default. It can be used to make your 3D points look thicker than one pixel.
glBegin and glEnd
glVertex alone won't draw anything on the screen, it merely defines a vertex, usually of a more
complex object. To really start displaying something on the screen you will have to use two
additional functions. These functions are
glBegin(mode) and glEnd( )
glBegin and glEnd delimit the vertices of a primitive or a group of like primitives. What
this means is that everytime you want to draw a primitive on the screen you will first
have to call glBegin, specifying what kind of primitive it is that you want to draw in the
mode parameter of glBegin, and then list all vertices one by one (by sequentially calling
glVertex) and finally call glEnd to let OpenGL know that you're done drawing a
primitive.
The parameter mode of the function glBegin can be one of the following:
GL_POINTS
GL_LINES
10 | P a g e
GL_LINE_STRIP
GL_LINE_LOOP
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRIANGLE_FAN
GL_QUADS
GL_QUAD_STRIP
GL_POLYGON
These flags are self-explanatory. As an example the code given below to
shows how to draw some primitives.
# this code will draw a point located at [100, 100, -25]
glBegin(GL_POINTS)
glVertex3f(100.0, 100.0, -25.0)
glEnd( )
# next code will draw a line at starting and ending coordinates specified by glVertex3f
glBegin(GL_LINES)
glVertex3f(100.0, 100.0, 0.0) #origin of the line
glVertex3f(200.0, 140.0, 5.0) #ending point of the line
glEnd( )
#the following code draws a triangle
glBegin(GL_TRIANGLES
glVertex3f(100.0, 100.0, 0.0)
glVertex3f(150.0, 100.0, 0.0)
glVertex3f(125.0, 50.0, 0.0)
glEnd( )
Example:
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *
def display():
11 | P a g e
glClear(GL_COLOR_BUFFER_BIT) # clear all pixels
glBegin(GL_QUADS)
glColor3f(0.0, 1.0, 0.0) # draw green color quads(rectangle)
glVertex2f(-0.7, -0.6)
glVertex2f(-0.1, -0.6)
glVertex2f(-0.1, 0.0)
glVertex2f(-0.7, 0.0)
glEnd()
glFlush() #start processing buffered OpenGL routines or Render(create picture)
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
glutInitWindowPosition(0, 0)
wind = glutCreateWindow("OpenGL Rectangle Picture")
glutDisplayFunc(display)
glutMainLoop()
Output:
12 | P a g e
glMatrixMode (mode) - The glMatrixMode function specifies which matrix is the current
matrix.
glOrtho(left, right, bottom, top, zNear, zFar) - The glOrtho function multiplies the current
matrix by an orthographic matrix.
glPointSize (size) - glPointSize sets the width in pixels for rendered points; size must be
greater than 0.0 and by default is 1.0.
glLineWidth(width) - glLineWidth sets the width in pixels for rendered lines; width must
be greater than 0.0 and by default is 1.0.
glutPostRedisplay() - glutPostRedisplay marks the current window as needing to be
redisplayed.
glPushMatrix (), glPopMatrix (void) - The glPushMatrix and glPopMatrix functions
push and pop the current matrix stack.
glRenderMode (mode) - The glRenderMode function sets the rasterization mode.
glRotatef (angle, x, y, z) - The glRotatef functions multiply the current matrix by a rotation
matrix.
glScalef (x, y, z) - The glScalef functions multiply the current matrix by a general scaling
matrix.
glTranslatef (x, y, z) - The glTranslatef functions multiply the current matrix by a
translation matrix.
glViewport (x, y, width, height) - The glViewport function sets the viewport.
glEnable, glDisable() - The glEnable and glDisable functions enable or disable OpenGL
capabilities.
glutBitmapCharacter() - The glutBitmapCharacter function used for font style.
glColor3f() - to set a color, use the command glColor3f(). It takes three parameters, all of
which are floating-point numbers between 0.0 and 1.0. The parameters are, in order, the red,
green, and blue components of the color. You can think of these three values as specifying a
13 | P a g e
"mix" of colors: 0.0 means don't use any of that component, and 1.0 means use all you can of
that component.
Thus, the code glColor3f(1.0, 0.0, 0.0), makes the brightest red the system can draw, with no
green or blue components. All zeros makes black; in contrast, all ones makes white. Setting
all three components to 0.5 yields gray (halfway between black and white).
Here are eight commands and the colors they would set.
glColor3f(0.0, 0.0, 0.0) # black
glColor3f(1.0, 0.0, 0.0) # red
glColor3f(0.0, 1.0, 0.0) # green
glColor3f(1.0, 1.0, 0.0) # yellow
glColor3f(0.0, 0.0, 1.0) # blue
glColor3f(1.0, 0.0, 1.0) # magenta
glColor3f(0.0, 1.0, 1.0) # cyan
glColor3f(1.0, 1.0, 1.0) # white
glClearColor(), takes four parameters, the first three of which match the parameters
for glColor3f(). The fourth parameter is the alpha value; For now, set the fourth parameter
of glClearColor() to 0.0, which is its default value.
glClearColor(red, green, blue, alpha)
14 | P a g e