/usr/share/pyshared/glitch/camera.py is in python-glitch 0.6-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | "The abstract camera node."
from __future__ import with_statement
import ctypes
import OpenGL.GL as gl
import OpenGL.GLU as glu
import glitch
from glitch.context import Context
# XXX: buggy with extreme vertical aspect ratios
class Camera(glitch.Node):
def __init__(self, eye=(0, 0, 5), ref=(0, 0, 0), up=(0, 1, 0), fovx=60,
fovy=60, zNear=0.1, zFar=50, clear=(0, 0, 0, 0), **kwargs):
glitch.Node.__init__(self, **kwargs)
self.eye = list(eye)
self.ref = list(ref)
self.up = list(up)
self.fovy = fovx
self.fovx = fovy
self.zNear = zNear
self.zFar = zFar
self.clear = clear
self.context = Context()
def draw(self, ctx):
if ctx['w'] == 0:
return
gl.glClearColor(*self.clear)
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glColor(1, 1, 1)
gl.glMaterialfv(
gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT_AND_DIFFUSE, (1, 1, 1, 1))
if ctx.get('debug', False):
gl.glLightModelfv(gl.GL_LIGHT_MODEL_AMBIENT, [.3, .3, .3, 1])
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)
gl.glColor(0, 1, 0, 1)
else:
gl.glLightModelfv(gl.GL_LIGHT_MODEL_AMBIENT, [0, 0, 0, 1])
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
gl.glViewport(0, 0, ctx['w'], ctx['h'])
self.aspect = ctx['w'] / float(ctx['h'])
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glLoadIdentity()
glu.gluLookAt(*(self.eye + self.ref + self.up))
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
selection = ctx.get('selection')
if selection is not None:
(x, y, w, h) = selection
glu.gluPickMatrix(x, y, w, h, (0, 0, ctx['w'], ctx['h']))
fovy = max(self.fovy, self.fovx/self.aspect)
glu.gluPerspective(fovy, self.aspect, self.zNear, self.zFar)
gl.glEnable(gl.GL_DEPTH_TEST)
gl.glMatrixMode(gl.GL_MODELVIEW)
def select(self, parent_ctx, x, y, width=3, height=3):
with self.context.push('selection', (x, y, width, height)):
gl.glSelectBuffer(1000)
gl.glRenderMode(gl.GL_SELECT)
self.render(None)
hits = gl.glRenderMode(gl.GL_RENDER)
return [
# The GL selection buffer contains the addresses of the Python node
# objects on the stack when the hit occurred. Here we turn the
# addresses back in to Python objects. This presumably won't work
# outside CPython.
ctypes.cast(int(id), ctypes.py_object).value
for (_misc1, _misc2, path) in hits for id in path]
def _save(self):
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glPushMatrix()
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glPushMatrix()
# XXX: Should we just save/restore everything?
gl.glPushAttrib(gl.GL_VIEWPORT_BIT | gl.GL_TRANSFORM_BIT |
gl.GL_ENABLE_BIT | gl.GL_LIGHTING_BIT | gl.GL_CURRENT_BIT)
def _restore(self):
gl.glPopAttrib()
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glPopMatrix()
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glPopMatrix()
def _all_lights_off(self, ctx):
# Disable all lights in the parent scene, to prevent them affecting
# the child scene.
for light in ctx.get('lights', {}).values():
gl.glDisable(gl.GL_LIGHT0 + light)
def render(self, parent_ctx):
# If this camera is part of an existing scene, we save and restore the
# parent state.
if parent_ctx is not None:
self._save()
parent_ctx.push('lights', {})
parent_ctx.push('w', self.context['w'])
parent_ctx.push('h', self.context['h'])
glitch.Node.render(self, parent_ctx)
parent_ctx.pop()
parent_ctx.pop()
parent_ctx.pop()
self._restore()
else:
glitch.Node.render(self, self.context)
def refresh(self):
"Ask the camera to render whatever it renders to."
raise NotImplementedError
def run(self):
"""Display this camera, whatever that means.
This might involve, for example, creating a window or starting a
mainloop."""
raise NotImplementedError
|