-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtry3d.py
140 lines (114 loc) · 4.32 KB
/
try3d.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
# tutorial
# https://noobtuts.com/python/opengl-introduction
# the whole thing is very sensitive to variable type
# import stuff
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import numpy as np
# parameters
width, height = 500, 500 # window size
t = 0.0 # just a timestamp to change things
# define the parameter of cubes
nCube = 100
cube_angles = np.random.rand(nCube,1) * 360
cube_axes = np.random.rand(nCube,3)
cube_position = np.random.rand(nCube,3) - 0.5
cube_scales = np.random.rand(nCube,1) / 4 + 0.1
# constrain them to be on the shell of a spehre
cube_position = 5*(cube_position / np.repeat([np.sqrt(np.sum(cube_position**2, axis=1))] , 3, axis=0).T)
# main callback function
def draw():
# access time stamp variable t as a global variable
# otherwise any change you apply to t will not be propagated outside the
# function (you are operating on the local copy)
global t
# enable depth rendering
glEnable(GL_DEPTH_TEST)
# clear buffer (black screen now)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# load identity matrix
glLoadIdentity()
# define camera
refresh(width,height)
# update the timestamp to move things
t += 0.01
# draw cube
# make sure we are opearting on the modelview matrix
# this already has the camera matrix defined in refresh()
glMatrixMode(GL_MODELVIEW)
for i in range(nCube):
# save the current matrix
glPushMatrix()
# move and rotate the coordinate for each cube
# translation comes first so the thing rotates on the spot
glTranslated(cube_position[i,0], cube_position[i,1], cube_position[i,2]) # move
glRotatef(cube_angles[i] + t*200, cube_axes[i,0], cube_axes[i,1], cube_axes[i,2]) # rotate
glScaled(cube_scales[i], cube_scales[i], cube_scales[i])
draw_cube()
# bring back the original coordinate before the translation and rotation
glPopMatrix()
glutSwapBuffers() # this is like Flip in PTB?
# Draw a cube with different side colors and the edge length = 2
# centered at the origin
def draw_cube():
glBegin(GL_QUADS) # I am drawing a bunch of rectangles
glColor3f(1,0,1)
glVertex3f(1,-1,1)
glVertex3f(1,-1,-1)
glVertex3f(1,1,-1)
glVertex3f(1,1,1)
glColor3f(0,1,1)
glVertex3f(-1,1,1)
glVertex3f(1,1,1)
glVertex3f(1,1,-1)
glVertex3f(-1,1,-1)
glColor3f(1,1,0)
glVertex3f(1,-1,-1)
glVertex3f(-1,-1,-1)
glVertex3f(-1,1,-1)
glVertex3f(1,1,-1)
glColor3f(1,0,0)
glVertex3f(-1,-1,-1)
glVertex3f(-1,-1,1)
glVertex3f(-1,1,1)
glVertex3f(-1,1,-1)
glColor3f(0,1,0)
glVertex3f(-1,-1,-1)
glVertex3f(1,-1,-1)
glVertex3f(1,-1,1)
glVertex3f(-1,-1,1)
glColor3f(0,0,1)
glVertex3f(-1,-1,1)
glVertex3f(-1,1,1)
glVertex3f(1,1,1)
glVertex3f(1,-1,1)
glEnd()
# This function defines the camera and projection
def refresh(w, h):
# define the viewport transform
# this maps NDC cube ranging from [-1,1] to actual screen coordinate
# nothing interesting happens here
glViewport(0, 0, w, h)
# define the projection (use the perspective projection)
glMatrixMode(GL_PROJECTION)
glLoadIdentity() # intialize by loading identity
# Define a frustum for a perspective projection
# Position of four edges of the near plane + Z-position of near and far
# planes (camera is supposed to be at the origin)
# numbers are in the model coordinate (but after all rotations etc)
glFrustum(-1, 1, -1, 1, 2, 30.0)
# define the camera
glMatrixMode(GL_MODELVIEW)
glLoadIdentity() # intialize by loading identity
gluLookAt(20*np.cos(t), 0, 20*np.sin(t), # where your eye is
0,0,0, # where you are looking at
0.0, 1.0, 0.0) # which way is up
glutInit() # initialize opengl
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH) # define the display mode
glutInitWindowSize(width, height) # set the window size
glutInitWindowPosition(0, 0) # set the window position
win = glutCreateWindow(b"my window") # create a window with a title (only takes char = byte data hence b)
glutDisplayFunc(draw) # setting a callback (this happens everytime the user interacts with the window)
glutIdleFunc(draw) # draw all the time
glutMainLoop()