/
main.py
158 lines (122 loc) · 4.32 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#basic glut setup learned from here:
#http://www.java2s.com/Open-Source/Python/Game-2D-3D/PyOpenGL/PyOpenGL-Demo-3.0.1b1/PyOpenGL-Demo/NeHe/lesson2.py.htm
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
#helper modules
import glutil
from vector import Vec
#OpenCL code
import physics
#functions for initial values of particles
import initialize
#number of particles
maxnum = 600 #*10
#time step for integration
dt = 1e-2
class window(object):
def __init__(self, *args, **kwargs):
#mouse handling for transforming scene
self.mouse_down = False
self.mouse_old = Vec([0., 0.])
self.rotate = Vec([90., 90., 0.])
self.translate = Vec([0., 0., 0.])
self.initrans = Vec([0., 0., -20.])
self.width = 1024
self.height = 768
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(self.width, self.height)
glutInitWindowPosition(0, 0)
self.win = glutCreateWindow("The qMD Model")
#gets called by GLUT every frame
glutDisplayFunc(self.draw)
#handle user input
glutKeyboardFunc(self.on_key)
glutMouseFunc(self.on_click)
glutMotionFunc(self.on_mouse_motion)
#this will call draw every 30 ms
glutTimerFunc(30, self.timer, 30)
#setup OpenGL scene
self.glinit()
#set up initial conditions
(pos_vbo, col_vbo, vel) = initialize.fountain(maxnum)
num = len(vel)
#create our OpenCL instance
self.cle = physics.Particles(num, dt)
self.cle.loadData(pos_vbo, col_vbo, vel)
glutMainLoop()
def glinit(self):
glViewport(0, 0, self.width, self.height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60., self.width / float(self.height), .1, 1000.)
glMatrixMode(GL_MODELVIEW)
###GL CALLBACKS
def timer(self, t):
glutTimerFunc(t, self.timer, t)
glutPostRedisplay()
def on_key(self, *args):
ESCAPE = '\033'
if args[0] == ESCAPE or args[0] == 'q':
sys.exit()
elif args[0] == 'z':
self.translate.z += 5
elif args[0] == "Z":
self.translate.z -= 5
elif args[0] == 'x':
self.translate.x += 5
elif args[0] == 'X':
self.translate.x -= 5
elif args[0] == 'y':
self.translate.y += 5
elif args[0] == 'Y':
self.translate.y -= 5
elif args[0] == 's':
self.rotate.z += 20
elif args[0] == 't':
self.rotate.x += 20
elif args[0] == 'v':
self.rotate.y += 20
print("Angle (%f, %f, %f)"%(self.rotate.x, self.rotate.y, self.rotate.z))
def on_click(self, button, state, x, y):
if state == GLUT_DOWN:
self.mouse_down = True
self.button = button
else:
self.mouse_down = False
self.mouse_old.x = x
self.mouse_old.y = y
def on_mouse_motion(self, x, y):
dx = x - self.mouse_old.x
dy = y - self.mouse_old.y
if self.mouse_down and self.button == 0: #left button
self.rotate.x += dy * .2
self.rotate.y += dx * .2
elif self.mouse_down and self.button == 2: #right button
self.translate.z -= dy * .01
self.mouse_old.x = x
self.mouse_old.y = y
###END GL CALLBACKS
def draw(self):
"""Render the particles"""
#update or particle positions by calling the OpenCL kernel
self.cle.execute(20)
glFlush()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
#handle mouse transformations
glTranslatef(self.initrans.x, self.initrans.y, self.initrans.z)
glRotatef(self.rotate.x, 1, 0, 0)
glRotatef(self.rotate.z, 0, 0, 1)
glRotatef(self.rotate.y, 0, 1, 0) #we switched around the axis so make this rotate_z
glTranslatef(self.translate.x, self.translate.y, self.translate.z)
#render the particles
self.cle.render()
#draw the x, y and z axis as lines
glutil.draw_axes()
glutSwapBuffers()
if __name__ == "__main__":
p2 = window()