The code below uses PyOpenGL , PIL (for textures), numpy , GLFW and the corresponding Python bundle cyglfw3 .
Here is a screenshot of the output:

The main code is added below. It uses some utilities from a file called glutils.py (for loading textures, compiling shaders, etc.), which you can find here:
https://github.com/electronut/pp/tree/master/simplegl
The following is a list of codes:
import OpenGL from OpenGL.GL import * from OpenGL.GLUT import * import numpy, math, sys, os import glutils import cyglfw3 as glfw strVS = """ #version 330 core layout(location = 0) in vec3 aVert; uniform mat4 uMVMatrix; uniform mat4 uPMatrix; uniform vec4 uColor; uniform float uTheta; out vec4 vCol; out vec2 vTexCoord; void main() { // rotational transform mat4 rot = mat4( vec4( cos(uTheta), sin(uTheta), 0.0, 0.0), vec4(-sin(uTheta), cos(uTheta), 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0) ); // transform vertex gl_Position = uPMatrix * uMVMatrix * rot * vec4(aVert, 1.0); // set color vCol = vec4(uColor.rgb, 1.0); // set texture coord vTexCoord = aVert.xy + vec2(0.5, 0.5); } """ strFS = """ #version 330 core in vec4 vCol; in vec2 vTexCoord; uniform sampler2D tex2D; uniform bool showCircle; out vec4 fragColor; void main() { if (showCircle) { // discard fragment outside circle if (distance(vTexCoord, vec2(0.5, 0.5)) > 0.5) { discard; } else { fragColor = texture(tex2D, vTexCoord); } } else { fragColor = texture(tex2D, vTexCoord); } } """ class Scene: """ OpenGL 3D scene class"""