Search code examples
pythonopenglmatrixpyqtpyopengl

modelview matrix not updated using pyopengl and pyqt


I am using PyQt and PyOpenGl and I have some problems with updating of modelview matrix when I try to translate/pan. The drawing/painting is done in method paintGL

def paintGL(self):
        """
        display geometry
        """
        # Clear the screen
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        #    setup camera
        glMatrixMode(GL_MODELVIEW)

        #    drawing here....

the translation/pan is called in method mouseMoveEvent

def mouseMoveEvent(self, event):
        dx = dxy.x() 
        dy = dxy.y() 
        if event.buttons() & Qt.MidButton:
            #    translate
            if event.modifiers() & Qt.ControlModifier:
                self.camera.translate(dx, dy, 0)

and the Camera object with method translate is:

class Camera(object):
    '''
    Connection between mouse motion and transformation matrix
    '''
    def __init__(self):
        self.currentMatrix = []
        self.reset()

    def reset(self):
        glPushMatrix()
        glLoadIdentity()
        self.currentMatrix = glGetDoublev(GL_MODELVIEW_MATRIX)
        glPopMatrix()

    def translate(self, x, y, z):
        glPushMatrix()
        glLoadIdentity()
        glTranslatef(tx, ty, tz)
        glMultMatrixf( self.currentMatrix )
        self.currentMatrix = glGetFloatv( GL_MODELVIEW_MATRIX )
        glPopMatrix()

The problem I have is that the modelview matrix is transformed (when translating - moving a mouse) but before drawing the modelview matrix is again equal to glLoadIdentity(). How can the code be modified to solve the problem?


Solution

  • If anyone else will have similar problems I am posting here the solution that halped me solving the problem. In the class OpenGLWidget I had the following code (among the rest):

    class OpenGLWidget(QtOpenGL.QGLWidget):
        def __init__(self, parent=None):
            self.parent = parent
            self.camera = camera_view.View()
    

    As the class View was called before initializing OpenGL and it always returned the GL_MODELVIEW_MATRIX as zero matrix. The solution for me the following; the code:

    self.camera = camera_view.View()

    is moved to the method that initializes OpenGL that is:

    def initializeGL(self):
        #    background color
        glClearColor(0,0.0,0,1)
    
        glEnable(GL_DEPTH_TEST)
        glShadeModel(GL_SMOOTH) 
        glEnable(GL_NORMALIZE)
        glEnable(GL_CULL_FACE)
    
        #    lights settings
        glEnable( GL_LIGHTING )
        glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 0 )
        glEnable( GL_LIGHT0 )
        light_pos_0 = np.array([0.0, 10.0, 10.0])
        glLightfv( GL_LIGHT0, GL_POSITION, light_pos_0 )
        glLightfv( GL_LIGHT0, GL_AMBIENT, [0.8, 0.8, 0.8, 1] )
        glLightfv( GL_LIGHT0, GL_DIFFUSE, [1, 1, 1, 0] )
        glLightfv( GL_LIGHT0, GL_SPECULAR, [1, 1, 1, 0] )
    
        #    camera
        self.camera = camera_view.View()
        #    viewing
        self.geometry()
    

    Hope that will help anyone.