Search code examples
pythonlinuxgraphing

Showing a dynamic plane


I have written a Python program that continuously returns 4 changing Cartesian coordinates that align to form a square plane that can be at any given orientation; yaw, pitch, or roll. What is the best way to go about displaying the constantly updating plane in 3D space?

Note: This is being done on a Linux machine if that changes anything, however I cannot see how it would.


Solution

  • You can use PyOpenGL for that.

    http://pyopengl.sourceforge.net/

    It can be installed with pip.

    Easiest is to use the "legacy" API and draw a quad.

    To change yaw, pitch and roll, use a transformation matrix and glRotate.

    You can also use shaders with it and draw up the transformation matrix yourself.

    https://en.wikipedia.org/wiki/Rotation_matrix

    Example of drawing a textured plane with the OpenGL legacy API:

    import sys
    import math
    
    from OpenGL.GLUT import *
    from OpenGL.GL import *
    from OpenGL.GLU import *
    
    def init():
        global image, texName
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)
        glShadeModel(GL_FLAT)
        glEnable(GL_DEPTH_TEST)
    
        import Image, numpy
        img = Image.open('flagEn.bmp') # .jpg, .bmp, etc. also work
        img_data = numpy.array(list(img.getdata()), numpy.int8)
    
        global texture
        texture = glGenTextures(1)
        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
        glBindTexture(GL_TEXTURE_2D, texture)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
    
    def display():
        #global texName
        global texture
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glEnable(GL_TEXTURE_2D)
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
        glBindTexture(GL_TEXTURE_2D, texture)
        glBegin(GL_QUADS)
        glTexCoord2f(0, 0)
        glVertex3f(-2, -1, 0)
        glTexCoord2f(0, 10)
        glVertex3f(-2, 1, 0)
        glTexCoord2f(10, 10)
        glVertex3f(0, 1, 0)
        glTexCoord2f(10, 0)
        glVertex3f(0, -1, 0)
        glTexCoord2f(0, 0)
        glVertex3f(1, -1, 0)
        glTexCoord2f(0, 10)
        glVertex3f(1, 1, 0)
        glTexCoord2f(10, 10)
        glVertex3f(1+math.sqrt(2), 1, -math.sqrt(2))
        glTexCoord2f(10, 0)
        glVertex3f(1+math.sqrt(2), -1, -math.sqrt(2))
        glEnd()
        glFlush()
        glDisable(GL_TEXTURE_2D)
    
    def reshape(w, h):
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(60.0, w/h, 1.0, 30.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0.0, 0.0, -3.6);
    
    def keyboard(key, x, y):
        pass
    
    glutInit(sys.argv)
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE)
    glutInitWindowSize (500, 500)
    glutInitWindowPosition (100, 100)
    glutCreateWindow ('texture')
    init ()
    glutDisplayFunc(display)
    glutReshapeFunc(reshape)
    glutKeyboardFunc(keyboard)
    glutMainLoop()