Skip to content

Instantly share code, notes, and snippets.

@devilholk
Created May 27, 2017 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devilholk/bd9cffca7e250e27a4e440bd3830b2a0 to your computer and use it in GitHub Desktop.
Save devilholk/bd9cffca7e250e27a4e440bd3830b2a0 to your computer and use it in GitHub Desktop.
Simple free fly camera (libglfw, libGL, python3)
from lowlevel_gl import *
# Test
#Kom ihåg error check för push/pop matrix
import threading
assert glfwInit() == 1
w = glfwCreateWindow(640, 480, b"Hello World!", None, None)
assert w, 'Failed to create window'
sx = 100
sy = 100
sr = 45
s = 100
fov = 90
class identity_matrix(matrix_f):
def __init__(self):
matrix_f.__init__(self)
self[0][0] = 1.0
self[1][1] = 1.0
self[2][2] = 1.0
self[3][3] = 1.0
#camera_pos = vec3(0,100,-500)
class camera:
def __init__(self, initial_position):
self.position = initial_position
self.id = identity_matrix()
self.up = vec_3f(0,1,0)
self.tilt = 0.0
self.pan = 0.0
self.motion = vec_3f()
self.local = identity_matrix()
def think(self):
i = self.local.invert()
#self.position += vec_3f(*(self.local.z * self.motion.z * -5.0)[:3])
self.position += vec_3f(*(i.z * self.motion.z * 5.0)[:3])
self.position += vec_3f(*(i.x * self.motion.x * 5.0)[:3])
def mouse_xy(self, dx, dy):
self.pan = -.1 * dx
self.tilt = .1 * dy
def apply_transform(self):
self.local = matrix_f.rodriguez_transform(self.up, self.pan) * matrix_f.rodriguez_transform(self.id.x, self.tilt)
glMultMatrixf(self.local)
glTranslatef(*self.position)
cam = camera(vec_3f(0, 100, -500))
def render_test_loop(window):
global cam
glfwMakeContextCurrent(window)
width = ctypes.c_int(0)
height = ctypes.c_int(0)
#glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA);
glEnable(GL_BLEND)
while not glfwWindowShouldClose(window):
rx = math.sin(time.time())*30+30
ry = math.cos(time.time())*30+30
cam.think()
glfwGetFramebufferSize(window, int_pointer(width), int_pointer(height))
glViewport(0,0, width.value-1, height.value-1)
#glMatrixMode(GL_PROJECTION)
#glLoadIdentity()
#glOrtho(0, width.value-1, height.value-1, 0,0,1)
gl_perspective(fov, width.value/height.value, 1, 20000)
cam.apply_transform()
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glClear(GL_COLOR_BUFFER_BIT)
q = 50
glPushMatrix()
glTranslatef(-q*s/2,0,-q*s/2)
glColor4f(0.7,1.0,0.3,0.4)
glBegin(GL_LINES)
for c in range(q+1):
glVertex3f(c*s, 0, 0)
glVertex3f(c*s, 0, q*s)
glVertex3f(0, 0, c*s)
glVertex3f(q*s, 0, c*s)
glEnd()
glPopMatrix()
glfwSwapBuffers(window)
glfwPollEvents()
glfwDestroyWindow(window)
glfwTerminate()
t = threading.Thread(target=render_test_loop, args=(w,))
t.start()
camera_control = None
last_pos = None
def handle_key(window, key, scancode, action, mods):
global camera_control, last_pos, cam
if key == 32:
if action == GLFW_PRESS.value:
if camera_control:
camera_control = None
else:
camera_control = cam
if camera_control:
last_pos = None
glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
else:
glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL)
return
if key == 256:
glfwSetWindowShouldClose(w, GLFW_TRUE)
return
if camera_control:
if key == ord('W'):
if action == GLFW_PRESS.value:
camera_control.motion.z = 1.0
elif action == GLFW_RELEASE.value:
camera_control.motion.z = 0.0
return
if key == ord('S'):
if action == GLFW_PRESS.value:
camera_control.motion.z = -1.0
elif action == GLFW_RELEASE.value:
camera_control.motion.z = 0.0
return
if key == ord('A'):
if action == GLFW_PRESS.value:
camera_control.motion.x = 1.0
elif action == GLFW_RELEASE.value:
camera_control.motion.x = 0.0
return
if key == ord('D'):
if action == GLFW_PRESS.value:
camera_control.motion.x = -1.0
elif action == GLFW_RELEASE.value:
camera_control.motion.x = 0.0
return
print("unhandled key", window, key, scancode, action, mods)
def handle_cursor(window, x, y):
global last_pos, camera_matrix, old_camera_matrix
if camera_control:
if last_pos != None:
ox, oy = last_pos
camera_control.mouse_xy(x - ox, y - oy)
else:
last_pos = x, y
cb1 = cursor_callback_signature(handle_cursor)
cb2 = key_callback_signature(handle_key)
glfwSetCursorPosCallback(w, cb1)
glfwSetKeyCallback(w, cb2)
print(cb1, cb2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment