In this tutorial, we're going to learn how to use PyOpenGL library in Python. 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, followed by writing a simple example demonstrating the usage of the library.
The easiest way to install OpenGL using Python is through the pip package manager. If you have pip installed in your system, run the following command to download and install OpenGL:
$ pip install PyOpenGL PyOpenGL_accelerate
I'd recommend copying the above command to help avoid typos.
Once this command finishes execution, if the installation is successful, you should get the following output at the end:
Successfully installed PyOpenGL-3.1.0 PyOpenGL-accelerate-3.1.0
If this doesn't work, you can also download it manually. For that, this link, scroll down to the 'downloading and installation' heading, and download all the files over there. After that, navigate to the folder where you downloaded those files, and run the following command in the terminal or command prompt:
$ python setup.py
It is pertinent to mention that you require Visual C++ 14.0 build tools installed on your system in order to work with OpenGL libraries in Python.
Now that we have successfully installed OpenGL on our system, let's get our hands dirty with it.
The first thing we need to do to use OpenGL in our code is to import it. To do that, run the following command:
Before we proceed, there are a few other libraries that you need to import whenever you intend to use this library in your program. Below is the code for those imports:
import OpenGL.GL import OpenGL.GLUT import OpenGL.GLU print("Imports successful!") # If you see this printed to the console then installation was successful
Now that we are done with the necessary imports, let's first create a window in which our graphics will be shown. The code for that is given below, along with its explanation in the comments:
def showScreen(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Remove everything from screen (i.e. displays all white) glutInit() # Initialize a glut instance which will allow us to customize our window glutInitDisplayMode(GLUT_RGBA) # Set the display mode to be colored glutInitWindowSize(500, 500) # Set the width and height of your window glutInitWindowPosition(0, 0) # Set the position at which this windows should appear wind = glutCreateWindow("OpenGL Coding Practice") # Give your window a title glutDisplayFunc(showScreen) # Tell OpenGL to call the showScreen method continuously glutIdleFunc(showScreen) # Draw any graphics or shapes in the showScreen function at all times glutMainLoop() # Keeps the window created above displaying/running in a loop
Copy the imports above, as well as this code in a single python (.py) file, and execute it. You should see a white square dimension screen pop up. Now, if we wish to draw any shapes or make any other kind of graphics, we need to do that in our "showScreen" function.
Let's now try to make a square using OpenGL, but before we do we need to understand the coordinate system that OpenGL follows.
The (0,0) point is the bottom left of your window, if you go up from there, you're moving along the y-axis, and if you go right from there, you're moving along the x-axis. So, the top left point of your window would be (0, 500), top right would be (500, 500), bottom right would be (500, 0).
Note: We're talking about the window we created above, which had a dimension of 500 x 500 in our example, and not your computer's full screen.
Now that we've got that out of the way, lets code a square. The explanation to the code can be found in the comments.
from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * w, h = 500,500 # ---Section 1--- def square(): # We have to declare the points in this sequence: bottom left, bottom right, top right, top left glBegin(GL_QUADS) # Begin the sketch glVertex2f(100, 100) # Coordinates for the bottom left point glVertex2f(200, 100) # Coordinates for the bottom right point glVertex2f(200, 200) # Coordinates for the top right point glVertex2f(100, 200) # Coordinates for the top left point glEnd() # Mark the end of drawing # This alone isn't enough to draw our square # ---Section 2--- def showScreen(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Remove everything from screen (i.e. displays all white) glLoadIdentity() # Reset all graphic/shape's position square() # Draw a square using our function glutSwapBuffers() #---Section 3--- glutInit() glutInitDisplayMode(GLUT_RGBA) # Set the display mode to be colored glutInitWindowSize(500, 500) # Set the w and h of your window glutInitWindowPosition(0, 0) # Set the position at which this windows should appear wind = glutCreateWindow("OpenGL Coding Practice") # Set a window title glutDisplayFunc(showScreen) glutIdleFunc(showScreen) # Keeps the window open glutMainLoop() # Keeps the above created window displaying/running in a loop
Running the code above would draw a square, but that square would not be visible since it's color would be the same as the color of our window, so we need to assign it a different color as well, for that we will make some changes in "Section 2" of the code above i.e. the
showScreen function. Add the following line below the
glLoadIdentity statement and above the
glColor3f(1.0, 0.0, 3.0) # Set the color to pink
However, our code is still not complete. What it currently does is draw the square once, and then clear the screen again. We don't want that. Actually, we won't even be able to spot the moment when it actually draws the square because it would appear and disappear in a split second. Lets write another function to avoid this.
# Add this function before Section 2 of the code above i.e. the showScreen function def iterate(): glViewport(0, 0, 500,500) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0.0, 500, 0.0, 500, 0.0, 1.0) glMatrixMode (GL_MODELVIEW) glLoadIdentity()
Call this iterate function in "Section 2" of the code above. Add it below
glLoadIdentity and above the
glColor3d statement in the
Let's now compile all this into a single code file so that there are no ambiguities:
from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * w,h= 500,500 def square(): glBegin(GL_QUADS) glVertex2f(100, 100) glVertex2f(200, 100) glVertex2f(200, 200) glVertex2f(100, 200) glEnd() def iterate(): glViewport(0, 0, 500, 500) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0.0, 500, 0.0, 500, 0.0, 1.0) glMatrixMode (GL_MODELVIEW) glLoadIdentity() def showScreen(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() iterate() glColor3f(1.0, 0.0, 3.0) square() glutSwapBuffers() glutInit() glutInitDisplayMode(GLUT_RGBA) glutInitWindowSize(500, 500) glutInitWindowPosition(0, 0) wind = glutCreateWindow("OpenGL Coding Practice") glutDisplayFunc(showScreen) glutIdleFunc(showScreen) glutMainLoop()
When you run this, a window should appear with a pink colored square box in it.
In this tutorial, we learned about OpenGL, how to download and install it, followed by using it an a short example program. In this example we also practiced making a basic shape using OpenGL, which gave us an insight into some complex function calls that need to be made whenever we need to draw something using this library. To conclude, OpenGL is very resourceful and gets more and more complex as we dive deeper into it.