Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
260 lines (184 sloc) 9.25 KB
'''
Created on May 9, 2013
@author: ivano.ras@gmail.com
MIT license
'''
import OpenGL
OpenGL.ERROR_CHECKING = True
from OpenGL.GL import *
from OpenGL.GLU import *
from PyQt4 import QtCore, QtGui, QtOpenGL
from PyQt4.QtOpenGL import *
from PyQt4.QtCore import *
class OGLViewer (QGLWidget):
def __init__ (self, parent = None):
frmt = QGLFormat ()
frmt.setSampleBuffers (True)
super (OGLViewer, self).__init__ (frmt, parent)
#self.setMouseTracking (True)
self.setCursor (QtCore.Qt.OpenHandCursor)
self.__Ctrl_or_Meta_key_pressed = False
self.__Alt_key_pressed = False
self.__current_angles = QtCore.QPoint (0,0)
self.__last_pos = QtCore.QPoint (0,0)
self.__delta = QtCore.QPoint (0,0)
self.__mouse = QtGui.QCursor ()
self.__orig = QtGui.QVector3D (0.0, 0.0, 0.0)
self.__camera_dist = 0.0
self.__mtx = (GLdouble * 16)()
self.__z_near = 0.1
self.__z_far = 2000.0
self.__fovy = 45.0
self.__frame_counter = 0
self.__w = 800
self.__h = 600
self.__aspect_ratio = float(self.__w)/float(self.__h)
self.setMinimumSize (self.__w, self.__h)
# matrix changed signal. The signal's payload is the matrix itself.
self.__GLMatrixChanged = QtCore.SIGNAL ("MatrixChanged (PyQt_PyObject)")
def initializeGL (self):
glClearColor (0.05, 0.05, 0.05, 1.0)
glClearDepth (1.0)
glMatrixMode (GL_PROJECTION)
glLoadIdentity();
gluPerspective (self.__fovy, float(self.__w)/float(self.__h), self.__z_near, self.__z_far)
self.__mtx = glGetDoublev (GL_MODELVIEW_MATRIX)
def run (self):
self.paintGL() # render actual frame
self.swapBuffers()
def paintGL (self):
zero = GLdouble (0.0)
self.__delta = QtCore.QPoint (0,0)
q = self.__mouse.pos()
if self.__Ctrl_or_Meta_key_pressed ^ self.__Alt_key_pressed: # xor (strictly one or the other)
if self.__Alt_key_pressed: # rotation
self.__delta = q - self.__last_pos
else: # translation
# get the mouse deltas and transform them with the camera's local axes so that
# it'll look like as if the camera will translate based on the local axes x and y.
# What happens in reality is that the origin will shift.
# Somehow similar to the Maya Camera Track Tool.
d_x = q.x() - self.__last_pos.x()
d_y = q.y() - self.__last_pos.y()
vec_x = - self.__mtx[0][0]*d_x + self.__mtx[0][1]*d_y + self.__mtx[0][2]*zero
vec_y = - self.__mtx[1][0]*d_x + self.__mtx[1][1]*d_y + self.__mtx[1][2]*zero
vec_z = - self.__mtx[2][0]*d_x + self.__mtx[2][1]*d_y + self.__mtx[2][2]*zero
self.__orig.setX (self.__orig.x() + 0.03*vec_x)
self.__orig.setY (self.__orig.y() + 0.03*vec_y)
self.__orig.setZ (self.__orig.z() + 0.03*vec_z)
# fire signal after done changing the model matrix.
self.emit (self.__GLMatrixChanged, self.__mtx)
self.__last_pos = q
self.__current_angles += self.__delta
if glCheckFramebufferStatus (GL_FRAMEBUFFER) == 36053: # GL_FRAMEBUFFER_COMPLETE = 36053
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
# Set the camera orientation :
glMatrixMode (GL_MODELVIEW)
glLoadIdentity ()
gluLookAt (self.__orig.x(),self.__orig.y(),self.__orig.z()-40, # CameraPos
self.__orig.x(),self.__orig.y(),self.__orig.z(), # CameraLookAt
0, 1, 0) # CameraUp
# Rotate and move camera forward or backward-
glTranslatef (0, 0, -self.__camera_dist)
glTranslatef (self.__orig.x(), self.__orig.y(), self.__orig.z()) # rotation around current origin. Part 1/3
glRotatef (-30 - self.__current_angles.y() * 0.15, 1, 0, 0) # rotate around axis x. Part 2/3
glRotatef (-30 + self.__current_angles.x() * 0.1, 0, 1, 0) # rotate around axis y. Part 2/3
glTranslatef (-self.__orig.x(), -self.__orig.y(), -self.__orig.z()) # rotation around current origin. Part 3/3
# get the camera matrix (or anyway the main matrix) and put it into self.__mtx.
self.__mtx = glGetDoublev (GL_MODELVIEW_MATRIX)
self.drawGrid ()
self.drawFixedOriginAxes ()
self.drawCurrentOriginAxes ()
def resizeGL (self, w, h):
self.__w = w
self.__h = h
self.__aspect_ratio = float (self.__w)/float(self.__h)
glMatrixMode (GL_MODELVIEW)
glLoadIdentity ()
gluPerspective (self.__fovy, self.__aspect_ratio, self.__z_near, self.__z_far)
glViewport (0, 0, self.__w, self.__h)
gluLookAt (0, 0,-1, # CameraPos
0, 0 ,0, # CameraLookAt
0, 1 ,0) # CameraUp
def updateCameraDistanceFromCenter (self, dist):
self.__camera_dist += dist * 0.01
# getters / setters
def setAltAsKeyPressed (self, boo): self.__Alt_key_pressed = boo
def setCtrlOrMetaAsKeyPressed (self, boo): self.__Ctrl_or_Meta_key_pressed = boo
def getCtrlOrMetaAsKeyPressed (self): return self.__Ctrl_or_Meta_key_pressed
def setCameraDist (self, dist): self.__camera_dist = dist
def getCameraDist (self): return self.__camera_dist
# graphics axes
def drawGrid (self):
for i in range (-10, 11):
glBegin (GL_LINES)
glColor3ub (75, 75, 75)
glVertex3f (-10, 0, i)
glVertex3f (10, 0, i)
glVertex3f (i, 0,-10)
glVertex3f (i, 0, 10)
glEnd ()
def drawFixedOriginAxes (self):
glBegin (GL_LINES)
glColor3ub (250, 0, 0); glVertex3f (0, 0, 0); glVertex3f (0, 0, 5);
glColor3ub (125, 0, 0); glVertex3f (0, 0, 5); glVertex3f (0, 0, 10);
glEnd ()
glBegin (GL_LINES)
glColor3ub (0, 250, 0); glVertex3f (0, 0, 0); glVertex3f (0, 5, 0);
glColor3ub (0, 125, 0); glVertex3f (0, 5, 0); glVertex3f (0, 10, 0);
glEnd ()
glBegin (GL_LINES)
glColor3ub (0, 0, 250); glVertex3f (0, 0, 0); glVertex3f (5, 0, 0);
glColor3ub (0, 0, 125); glVertex3f (5, 0, 0); glVertex3f (10, 0, 0);
glEnd ()
def drawCurrentOriginAxes (self):
glPointSize (6.0)
glBegin (GL_POINTS)
glColor3f (0.0,1.0,1.0)
glVertex3f (self.__orig.x(), self.__orig.y(), self.__orig.z())
glEnd ()
glBegin (GL_LINES)
glColor3ub (250, 0, 0)
glVertex3f (self.__orig.x(), self.__orig.y(), self.__orig.z())
glVertex3f (self.__orig.x(), self.__orig.y(), self.__orig.z()+5)
glEnd ()
glBegin (GL_LINES)
glColor3ub (0, 250, 0)
glVertex3f (self.__orig.x(), self.__orig.y(), self.__orig.z())
glVertex3f (self.__orig.x(), self.__orig.y()+5, self.__orig.z())
glEnd ()
glBegin (GL_LINES)
glColor3ub (0, 0, 250)
glVertex3f (self.__orig.x(), self.__orig.y(), self.__orig.z())
glVertex3f (self.__orig.x()+5, self.__orig.y(), self.__orig.z())
glEnd ()
class Container (QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.widget = OGLViewer (self)
self.setCentralWidget (self.widget)
# call the function run regularly (60 FPS if interval = 20)
timer = QtCore.QTimer (self)
timer.setInterval (20)
QtCore.QObject.connect(timer, QtCore.SIGNAL ('timeout()'), self.widget.run)
timer.start ()
m = ''
QtCore.QObject.connect (self.widget, QtCore.SIGNAL ("MatrixChanged (PyQt_PyObject)"), self.displayGLMatrix)
def keyPressEvent (self, e):
if e.key() == QtCore.Qt.Key_Control or e.key() == QtCore.Qt.Key_Meta: self.widget.setCtrlOrMetaAsKeyPressed (True)
if e.key() == QtCore.Qt.Key_Alt: self.widget.setAltAsKeyPressed (True)
def keyReleaseEvent (self, e):
if e.key() == QtCore.Qt.Key_Control or e.key() == QtCore.Qt.Key_Meta: self.widget.setCtrlOrMetaAsKeyPressed (False)
if e.key() == QtCore.Qt.Key_Alt: self.widget.setAltAsKeyPressed (False)
def wheelEvent (self, e):
if self.widget.getCtrlOrMetaAsKeyPressed () == True:
self.widget.updateCameraDistanceFromCenter (e.delta())
def displayGLMatrix (self, e):
pass
#print e
if __name__ == '__main__':
app = QtGui.QApplication (['OpenGL Viewer'])
window = Container ()
window.show ()
app.exec_ ()