Search code examples
pythonopenglcoordinate-transformationpyopenglopengl-compat

How to rotate a 2D line in PyOpenGL?


I've written a code to draw a line. Here is the function:

def drawLines():
    r,g,b = 255,30,20
    #drawing visible axis
    glClear(GL_COLOR_BUFFER_BIT)
    glColor3ub(r,g,b)
    glBegin(GL_LINES)
    #glRotate(10,500,-500,0)
    glVertex2f(0,500)
    glVertex2f(0,-500)

    glEnd()
    glFlush()

Now I'm trying to rotate the line. I'm trying to follow this documentation but can't understand. According to the documentation the rotating function is defined as follows:

def glRotate( angle , x , y , z ):

I've no z-axis. So I'm keeping z=0. What i'm I missing here?


Solution

  • Note, that drawing by glBegin/glEnd sequences nad the fixed function pipeline matrix stack, is deprecated since decades. Read about Fixed Function Pipeline and see Vertex Specification and Shader for a state of the art way of rendering:


    The x, y and z parameter which are passed to glRotate are the axis of rotation. Since geometry is drawn in the xy-plane, the axis of rotation has to be the z-axis (0,0,1):

    glRotatef(10, 0, 0, 1)
    

    To rotate around a pivot you have to define a model matrix, which displaces by the inverted pivot, then rotates and final transforms back by to the pivot (glTranslate):

    glTranslatef(pivot_x, pivot_y, 0)
    glRotatef(10, 0, 0, 1)
    glTranslatef(-pivot_x, -pivot_y, 0)
    

    Further note that operations like glRotate are not allowed within a glBegin/glEnd sequence. In glBegin/glEnd sequence only operations are allowed which set the vertex attributes like glVertex or glColor. You have to set the matrix before glBegin:

    e.g.

    def drawLines():
        pivot_x, pivot_y = 0, 250
        r,g,b = 255,30,20
    
        glTranslatef(pivot_x, pivot_y, 0)
        glRotatef(2, 0, 0, 1)
        glTranslatef(-pivot_x, -pivot_y, 0)
    
        glClear(GL_COLOR_BUFFER_BIT)
        glColor3ub(r,g,b)
    
        #drawing visible axis
        glBegin(GL_LINES)
        glVertex2f(0,500)
        glVertex2f(0,-500)
        glEnd()
    
        glFlush()
    

    If you want to rotate the line only, without affecting other objects, then you have save and restore the matirx stack by glPushMatrix/glPopMatrix:

    angle = 0
    
    def drawLines():
        global angle 
        pivot_x, pivot_y = 0, 250
        r,g,b = 255,30,20
    
        glClear(GL_COLOR_BUFFER_BIT)
    
        glPushMatrix()
    
        glTranslatef(pivot_x, pivot_y, 0)
        glRotatef(angle, 0, 0, 1)
        angle += 2
        glTranslatef(-pivot_x, -pivot_y, 0)
    
        glColor3ub(r,g,b)
    
        #drawing visible axis
        glBegin(GL_LINES)
        glVertex2f(0,500)
        glVertex2f(0,-500)
        glEnd()
    
        glPopMatrix()
    
        glFlush()