DEV Community

Cover image for Graphic designing using OpenGL and Python [Beginners]
Suvin Nimnaka
Suvin Nimnaka

Posted on

Opengl Python Graphic designing using OpenGL and Python [Beginners]

What is OpenGL, GLUT and PyOpenGL?

OpenGL (Open Graphics Library) is a cross-language, cross-platform application programming interface (API) for rendering 2D and 3D vector graphics. And GLUT is the OpenGL Utility Toolkit, a window system independent toolkit for writing OpenGL programs. It implements a simple windowing API for OpenGL. GLUT makes it considerably easier to learn about and explore OpenGL Programming. And finally, PyOpenGL is the most common cross platform Python binding to OpenGL and related APIs.
(Definitions from OpenGL docs)

Installation

  1. Create a new directory and open it.
    mkdir opengl-learn && cd opengl-learn

  2. Create a virtual environment. (Just to be safe!)
    python3 -m venv opengl-tut

  3. Activate the virtual environment.
    source opengl-tut/bin/activate

  4. Install the libraries.
    pip install PyOpenGL PyOpenGL_accelerate

What we are gonna do?

  1. First we are gonna create a window with following properties.

    • Height: 500px , Width: 500px
    • Background Color: RGB(1,1,0)
    • Window Position: (100, 100)
    • Objects Color: RGB (0.2, 0.5, 0.4)
    • Title: 'My OpenGL Code'
  2. Create two points in following coordinates.

    • P1 (100,100)
    • P2 (300, 200)
    • Point Size: 10px
  3. Draw a Rectangle.

    • Height: 100px
    • Width: 200px
    • Starting point; (100, 100)
  4. Draw a triangle 10px above the given rectangle.

Lets Code

Step 1
First open an empty file and name it as drawing.py (use any name you want). Then you have to import the libraries.

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
Enter fullscreen mode Exit fullscreen mode

Step 2
First we need to initiate GLUT.

glutInit()
Enter fullscreen mode Exit fullscreen mode

Then you can see in our windows properties, the colors are given in RGB format. So we need to initiate the display mode with RGB.

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
Enter fullscreen mode Exit fullscreen mode

Here, GLUT_SINGLE refers to the buffer context. SINGLE means there is only one frame buffer that is used to draw and display the content. Simply, that you draw more or less directly to the screen .

Step 3
Next we need to set the window size and window position. This is pretty much a straight forward. The command itself explains what is it.

glutInitWindowSize(500, 500)  #(height, width)
glutInitWindowPosition(100, 100) #(x pos, y pos)
Enter fullscreen mode Exit fullscreen mode

Step 4
Now with the given basic configuration, we can create the window with any name we want.

glutCreateWindow("My OpenGL Code") #Use any name you want
Enter fullscreen mode Exit fullscreen mode

Step 5
Next we need to add some extra settings for the window we just created. First we need to create a new function. I'm calling it myInit(). Inside this function, Im setting up the background color and foreground color. Define this function before glutInit().

def myInit():
   glClearColor(1.0, 1.0, 0.0, 1.0); #RGBA
   glColor3f(0.2, 0.5, 0.4); #RGB

Enter fullscreen mode Exit fullscreen mode

glClearColor sets the background color in RGBA (Red, Green, Blue, Alpha) format and glColor3f sets the color for our objects in RGB format.

And then we can go ahead and call this function and initiate.

So that's it for the basic setup. Now we can see our code like this.

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

def myInit():
    glClearColor(1.0, 1.0, 0.0, 1.0)
    glColor3f(0.2, 0.5, 0.4)


glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)  

glutInitWindowSize(500, 500)
glutInitWindowPosition(100, 100) 

glutCreateWindow("My OpenGL Code") 

myInit()

Enter fullscreen mode Exit fullscreen mode

Now we will create the two points. OpenGL draws objects using coordinates. Just like you drew shapes in Cartesian plane (කාටිසීය තලය, ඛණ්ඩාංක තලය in Sinhala) when you were a kid.
Before doing anything, we need to define a projection matrix.
Here, we are using an Orthographic projection matrix. Orthographic projection means representing three-dimensional objects in two dimensions. For more info on Orthographic projections, refer John White's Video on YouTube.

Goto your myInit function and define your matrix like this.

gluOrtho2D(0, 500, 0, 500) // left, right, bottom, top
Enter fullscreen mode Exit fullscreen mode

This will create a projection matrix, which maps 0 to the left border of the frame, 500 to the right, 0 to the bottom and 500 to the top.

Then it says the point size is 10px. Let's define that as well. Again inside your myInit function, define the point size as 10px. Make sure you pass a float value!

glPointSize(10.0)
Enter fullscreen mode Exit fullscreen mode

Now that the setup is done, we can draw out points on the matrix. To do that, I'm going to create a new function called display. This display function will hold the code that is used to draw anything inside our frame.

def display():

Enter fullscreen mode Exit fullscreen mode

We will start by clearing the current color buffer.

glClear(GL_COLOR_BUFFER_BIT)
Enter fullscreen mode Exit fullscreen mode

Then we define the start point of what we are going to draw by

glBegin(GL_POINTS)
Enter fullscreen mode Exit fullscreen mode

GL_POINTS means that we are going to draw points in this section.
Now we can draw out first coordinate (vertex). In the above properties list, it says that the first coordinate is P1(100,100). We'll draw that one first.

glVertex2f(100, 100)
Enter fullscreen mode Exit fullscreen mode

The second coordinate P2 (300, 200) goes in the same way.

glVertex2f(300, 300)
Enter fullscreen mode Exit fullscreen mode

Then at last, mark the end by

glEnd()
glFlush()
Enter fullscreen mode Exit fullscreen mode

glFlush() will clean the buffer. Now we need to call this display() function in order to draw the points on our frame. To do this, we have a function named glutDisplayFunc() in GLUT library.

glutDisplayFunc(display) 
Enter fullscreen mode Exit fullscreen mode

And right after that, we need to set the loop for the program to run. This function loops within itself, processing events and triggering your callback functions when necessary.

glutMainLoop()
Enter fullscreen mode Exit fullscreen mode

So the complete code as of now will look like this.

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

def myInit():
    glClearColor(1.0, 1.0, 0.0, 1.0) 
    glColor3f(0.2, 0.5, 0.4)
    glPointSize(10.0)
    gluOrtho2D(0, 500, 0, 500)

def display():
    glClear(GL_COLOR_BUFFER_BIT)

    glBegin(GL_POINTS)
    glVertex2f(100, 100)
    glVertex2f(300, 200)
    glEnd()

    glFlush()


glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)   
glutInitWindowSize(500, 500)  
glutInitWindowPosition(100, 100)  
glutCreateWindow("My OpenGL Code")
myInit()
glutDisplayFunc(display) 
glutMainLoop()

Enter fullscreen mode Exit fullscreen mode

You can run the file by executing python drawing.py on your command line.

Now let's move onto the second object. The rectangle.
Goto the display() function and after glEnd() function, we have to write the code for the rectangle.

Before writing any code, I drew my rectangle with the given starting coordinate and the measurements for the width and height on a paper. So starting point is (100,100) and height is 100px and width is 200px. It will give you something like this.

So now let's set this coordinates in the code.

glBegin( GL_QUADS ) 
glVertex2f( 100.0, 100.0 ) 
glVertex2f( 300.0, 100.0 ) 
glVertex2f( 300.0, 200.0 ) 
glVertex2f( 100.0, 200.0 ) 
glEnd()
Enter fullscreen mode Exit fullscreen mode

Here you have to define GL_QUADS as a parameter to glBegin(). GL_QUADS will treat each group of four vertices(coordinates) as an independent quadrilateral.

Then we'll move onto the Triangle part. In the properties section, it says that the triangle will have to position 10px above the rectangle. So like the previous time, I drew this on a paper.

Now the code. Here you have to pass GL_TRIANGLE_STRIP into glBegin() so that it will group 3 vertices as a triangle.

glBegin(GL_TRIANGLE_STRIP) 
glVertex2f(100.0, 210.0) 
glVertex2f(300.0, 210.0) 
glVertex2f(300.0, 310.0) 
glEnd()
Enter fullscreen mode Exit fullscreen mode

That's it! Now you can run the code and see the following output.

Complete Code:
https://gist.github.com/Suvink/fe5837701c62761d2e9661dfaaae7b84

If you have any questions, feel free to ask in the comments section.
Thanks!

Top comments (1)

Collapse
 
suvink profile image
Suvin Nimnaka

You can find the implementation of the above task in C here.
gist.github.com/Suvink/5fd314b7599...