# 2D Sine Wave Example Using PyOpenGL

Here is an example of a moving 2D sine wave using Python 3, PyGame, and PyOpenGL.  See a https://blog.gahooa.com/2018/02/11/pygame-and-opengl-on-windows-10/  for how to install them.

This sample program is designed to have a 100×60 unit working area with a 10 unit buffer around the edges.  You can see the axis in the lower-left (0,0) where Y+ is up, and X+ is to the right.

The structure of the program was created to make it super easy to work on the “guts” of the graphics without getting it confused with the “bookkeeping” end of OpenGL or PyGame.

Note: the glOrtho() command is how 2D “parallel perspective” is setup.  It defines the left, right, bottom, top, near plane, and far plane.  Because it is parallel, there is not the notion of a “camera” per-se, but rather section of the plane that should be viewed.  Documented here:

https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glOrtho.xml

Here is the code!

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters

 #!/usr/bin/env python ############################################################################### # Action Happens Here 50 times per second def tick(i): #glRotatef(1, 0, 0, 1) #glTranslatef(0, 0, 1) # Draw Axis axis(i) # Draw sinewave for x in range(200): x = x/2.0 y = math.sin(math.radians(x+i) * 10) * 30 + 30 cquad((x,y,0), 1, (y/60.0,0,x/100.0)) #(center, diameter, color) ############################################################################### # The rest of this is the bones that make it work import time import pygame from pygame.locals import * from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.arrays import vbo import math FPS_TARGET = 50 def axis(i): glBegin(GL_LINES) #x = red #y = green #z = blue glColor3f(1, 0, 0) glVertex3fv((0, 0, 0)) glVertex3fv((1, 0, 0)) glColor3f(0, 1, 0) glVertex3fv((0, 0, 0)) glVertex3fv((0, 1, 0)) glColor3f(0, 0, 1) glVertex3fv((0, 0, 0)) glVertex3fv((0, 0, 1)) glEnd() def quad(points, color): glBegin(GL_QUADS) glColor3f(*color) for p in points: glVertex3fv(p) glEnd() def cquad(point, size, color): glBegin(GL_QUADS) glColor3f(*color) x,y,z = point s = size/2.0 glVertex3fv((x–s,y–s,z)) glVertex3fv((x+s,y–s,z)) glVertex3fv((x+s,y+s,z)) glVertex3fv((x–s,y+s,z)) glEnd() def main(): #initialize pygame and setup an opengl display pygame.init() pygame.display.set_mode((1200,800), OPENGL|DOUBLEBUF) glEnable(GL_DEPTH_TEST) #use our zbuffer glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); #setup the camera glMatrixMode(GL_PROJECTION) #gluPerspective(45.0,1000/1000,0.1,1000.0) #setup lens #glOrtho(-10,10,-10,10,1,20) glOrtho(–10,110,–10,70,–1,1) #glTranslatef(0, 0, -100) #move back #glRotatef(-20, 1, 0, 0) #orbit higher nt = int(time.time() * 1000) for i in range(2**63): nt += 1000//FPS_TARGET #check for quit'n events event = pygame.event.poll() if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): break glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) tick(i) pygame.display.flip() ct = int(time.time() * 1000) pygame.time.wait(max(1,nt – ct)) if i % FPS_TARGET == 0: print(nt–ct) if __name__ == '__main__': main()

view raw

sinewave.py

hosted with ❤ by GitHub

# PyGame and OpenGL on Windows 10

First I went to http://www.python.org and downloaded the latest version of Python for windows.  I made sure to select the option to add it to the system path.

Then I opened windows PowerShell (just a nicer term)

```py -m pip install pygame --user
py -m pip install numpy --user
py -m pip install pyopengl --user```

(I also installed NoteTab++, a nice text editor)

From there, I went to github and copied one of the examples from https://github.com/pygame/pygame/blob/master/examples/glcube.py and saved it on my desktop as myglcube.py.

In PowerShell, you just type:

```cd Desktop
py -m myglcube```

Here is my example:

(here is the code)

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters

 #!/usr/bin/env python """Draw a cube on the screen. every frame we orbit the camera around by a small amount and it appears the object is spinning. note i've setup some simple data structures here to represent a multicolored cube, we then go through a semi-unopimized loop to draw the cube points onto the screen. opengl does all the hard work for us. :] """ import time import pygame from pygame.locals import * try: from OpenGL.GL import * from OpenGL.GLU import * except ImportError: print ('The GLCUBE example requires PyOpenGL') raise SystemExit #some simple data for a colored cube #here we have the 3D point position and color #for each corner. then we have a list of indices #that describe each face, and a list of indieces #that describes each edge CUBE_POINTS = ( (0.5, –0.5, –0.5), (0.5, 0.5, –0.5), (–0.5, 0.5, –0.5), (–0.5, –0.5, –0.5), (0.5, –0.5, 0.5), (0.5, 0.5, 0.5), (–0.5, –0.5, 0.5), (–0.5, 0.5, 0.5) ) #colors are 0-1 floating values CUBE_COLORS = ( (1, 0, 0), (1, 1, 0), (0, 1, 0), (0, 0, 0), (1, 0, 1), (1, 1, 1), (0, 0, 1), (0, 1, 1) ) CUBE_QUAD_VERTS = ( (0, 1, 2, 3), (3, 2, 7, 6), (6, 7, 5, 4), (4, 5, 1, 0), (1, 5, 7, 2), (4, 0, 3, 6) ) CUBE_EDGES = ( (0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4), (6,7), (5,1), (5,4), (5,7), ) def drawcube(): "draw the cube" allpoints = list(zip(CUBE_POINTS, CUBE_COLORS)) glBegin(GL_QUADS) for face in CUBE_QUAD_VERTS: for vert in face: pos, color = allpoints[vert] glColor3fv(color) glVertex3fv(pos) glEnd() glColor3f(1.0, 1.0, 1.0) glBegin(GL_LINES) """ for line in CUBE_EDGES: for vert in line: pos, color = allpoints[vert] glVertex3fv(pos) """ for x in range(–50,50): glColor3f(x*.03%1.0, x*.04%1.0, x*.05%1.0) glVertex3fv((x, 0, –100)) glVertex3fv((x, 0, 100)) glVertex3fv((–100, 0, x)) glVertex3fv((100, 0, x)) glEnd() def main(): "run the demo" #initialize pygame and setup an opengl display pygame.init() pygame.display.set_mode((1024,768), OPENGL|DOUBLEBUF) glEnable(GL_DEPTH_TEST) #use our zbuffer #setup the camera glMatrixMode(GL_PROJECTION) gluPerspective(45.0,1024/768.0,0.1,100.0) #setup lens glTranslatef(0.0, 0.0, –20.0) #move back glRotatef(60, 1, 0, 0) #orbit higher nt = int(time.time() * 1000) for i in range(2**63): nt += 20 glTranslatef(0.0, 0.0, –.1) #check for quit'n events event = pygame.event.poll() if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): break #clear screen and move camera glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) #orbit camera around by 1 degree glRotatef(1, 0, 1, 0) drawcube() pygame.display.flip() ct = int(time.time() * 1000) pygame.time.wait(max(1,nt – ct)) if i % 50 == 0: print(nt–ct) if __name__ == '__main__': main()

view raw

myglcube.py

hosted with ❤ by GitHub