Pygletで遊ぼう

cube

わずかな時間を見つけて Pyglet(http://www.pyglet.org/) で遊んだ。

立方体が回ります。

from __future__ import with_statement
from contextlib import contextmanager
import ctypes
from pyglet import gl
from pyglet import window


@contextmanager
def gl_excursion():
    gl.glPushMatrix()
    yield
    gl.glPopMatrix()

@contextmanager
def gl_mode(op):
    gl.glBegin(op)
    yield
    gl.glEnd()

def set_view(width, height):
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity()
    gl.gluPerspective(65, width / float(height), 0.01, 1000)
    gl.gluLookAt(2, 2, 2, 0, 0, 0, 0, 1, 0) 
    gl.glMatrixMode(gl.GL_MODELVIEW)

def on_resize(width, height):
    set_view(width, height)

class Box(object):
    def __init__(self, size=(1, 1, 1)):
        self._size = size

    def draw(self):
        lx,ly,lz = map(lambda x: 0.5 * x, self._size)
        gl.glColor4f(0.5, 0.5, 0.5, 0.5)
        with gl_excursion():
            # Front
            gl.glNormal3f(0, 0, 1)
            with gl_mode(gl.GL_TRIANGLE_STRIP):
                gl.glVertex3d(lx, ly, lz)
                gl.glVertex3d(-lx, ly, lz)
                gl.glVertex3d(lx, -ly, lz)
                gl.glVertex3d(-lx, -ly, lz)
            # Back
            gl.glNormal3f(0, 0, -1)
            with gl_mode(gl.GL_TRIANGLE_STRIP):
                gl.glVertex3d(lx, ly, -lz)
                gl.glVertex3d(lx, -ly, -lz)
                gl.glVertex3d(-lx, ly, -lz)
                gl.glVertex3d(-lx, -ly, -lz)
            # Left
            gl.glNormal3f(-1, 0, 0)
            with gl_mode(gl.GL_TRIANGLE_STRIP):
                gl.glVertex3d(-lx, ly, lz)
                gl.glVertex3d(-lx, ly, -lz)
                gl.glVertex3d(-lx, -ly, lz)
                gl.glVertex3d(-lx, -ly, -lz)
            # Right
            gl.glNormal3f(1, 0, 0)
            with gl_mode(gl.GL_TRIANGLE_STRIP):
                gl.glVertex3d(lx, ly, lz)
                gl.glVertex3d(lx, -ly, lz)
                gl.glVertex3d(lx, ly, -lz)
                gl.glVertex3d(lx, -ly, -lz)
            # Top
            gl.glNormal3f(0, 1, 0)
            with gl_mode(gl.GL_TRIANGLE_STRIP):
                gl.glVertex3d(lx, ly, lz)
                gl.glVertex3d(lx, ly, -lz)
                gl.glVertex3d(-lx, ly, lz)
                gl.glVertex3d(-lx, ly, -lz)
            # Bottom
            gl.glNormal3f(0, -1, 0)
            with gl_mode(gl.GL_TRIANGLE_STRIP):
                gl.glVertex3d(lx, -ly, lz)
                gl.glVertex3d(-lx, -ly, lz)
                gl.glVertex3d(lx, -ly, -lz)
                gl.glVertex3d(-lx, -ly, -lz)


def _main():
    config = gl.Config()
    config.double_buffer = True
    win = window.Window(
            config=config, 
            width=320, 
            height=240, 
            visible=False, 
            resizable=True)
    win.on_resize = on_resize

    box = Box()
    gl.glClearColor(0.5, 0.5, 1, 1)
    gl.glEnable(gl.GL_LIGHTING)
    gl.glEnable(gl.GL_LIGHT0)
    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glEnable(gl.GL_CULL_FACE)
    gl.glCullFace(gl.GL_BACK)
    Vector4f = ctypes.c_float * 4
    light_pos = Vector4f(3.0, 5.0, 5.0, 0.0)
    light_dif = Vector4f(1.0, 1.0, 1.0, 1.0)
    gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, light_pos)
    gl.glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE, light_dif)
    angle = 0
    win.set_visible()

    while not win.has_exit:
        win.dispatch_events()

        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
        gl.glClearColor(0.5, 0.5, 1, 1)
        gl.glLoadIdentity()
        gl.glRotatef(angle, 0, 1, 0)
        angle += 1.0
        box.draw()

        win.flip()

if __name__ == '__main__':
    _main()

with文って素敵ですね。