マウスでオブジェクトを選択する(2)

OpenGLで描画した物体をマウスで選択していろいろとやってみたい。セレクションという機能を使って実現するのだが、その練習をやってみる。
前回(http://d.hatena.ne.jp/Megumi221/20110421)に続いて、セレクションを使ったサンプル(アニメーション版)Pythonで書き直したものを少し変えてみる。
マウスで選んだオブジェクトの色が変わるようにした。ソースは以下の通り。

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

SELECTIONS = 100
NOBJECTS = 5

color = [ [0.1, 0.1, 0.9],
          [0.1, 0.9, 0.1],
          [0.9, 0.1, 0.1],
          [0.1, 0.9, 0.9],
          [0.9, 0.1, 0.9],
          [0.9, 0.9, 0.1]
        ]
ARRANGEWIDTH = 4.0
ARRANGECENTER = ARRANGEWIDTH/2.0
ARRANGESTEP = ARRANGEWIDTH/(NOBJECTS-1)
ARRANGEDEPTH = 0.0
INITIALHEIGHT = 0.0

ESCAPE = 27
light0pos = [4.0, 8.0, 6.0, 1.0]
objects = None

def init():
    global objects

    glClearColor(1.0, 1.0, 1.0, 0.0)
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_CULL_FACE)
    glEnable(GL_LIGHT0)
    glEnable(GL_LIGHTING)
    objects = glGenLists(NOBJECTS)

def display():

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()
    gluLookAt(5.0, 4.0, 5.0, 0.4, 0.0, 0.0, 0.0, 1.0, 0.0)
    glLightfv(GL_LIGHT0, GL_POSITION, light0pos)

    for i in range(NOBJECTS):
        h = INITIALHEIGHT
        glMaterialfv(GL_FRONT, GL_DIFFUSE, color[i])
        glNewList(objects + i, GL_COMPILE_AND_EXECUTE)

        glPushMatrix()
        glTranslated(float(i)*ARRANGESTEP - ARRANGECENTER, h, ARRANGEDEPTH)
        glutSolidCube(0.8)
        glPopMatrix()

        glEndList()

    glutSwapBuffers()

def mouse(button, state, x, y):
    if state == GLUT_DOWN:
        if button == GLUT_LEFT_BUTTON:
            sel = glSelectBuffer(SELECTIONS)
            glRenderMode(GL_SELECT)
            glInitNames()
            glPushName(-1)
            glMatrixMode(GL_PROJECTION)

            glPushMatrix()
            glLoadIdentity()
            vp = glGetIntegerv(GL_VIEWPORT)
            gluPickMatrix(x, vp[3]-y-1, 1, 1, vp)
            gluPerspective(30.0, vp[2]/vp[3], 1.0, 100.0)
            glMatrixMode(GL_MODELVIEW)

            for i in range(NOBJECTS):
                glLoadName(i)
                glCallList(objects + i)

            glMatrixMode(GL_PROJECTION)
            glPopMatrix()
            glMatrixMode(GL_MODELVIEW)
            hits = glRenderMode(GL_RENDER)
            for n in hits:
                h = n.names[0]
                color[h] = [1.0, 1.0, 1.0]  #実質、ここを変えただけ。

def resize(w, h):
    glViewport(0, 0, w, h)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(30.0, w/h, 1.0, 100.0)
    glMatrixMode(GL_MODELVIEW)

def keyboard(key, x, y):
    if key == 'q':
        sys.exit()

def idle():
    glutPostRedisplay()

glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(320, 320)
glutCreateWindow("sample")
glutDisplayFunc(display)
glutReshapeFunc(resize)
glutKeyboardFunc(keyboard)
glutMouseFunc(mouse)
glutIdleFunc(idle)

init()

glutMainLoop()


初期画面。

物体の一つをマウスで選んでクリックすると、白色になる。

ほとんど白にした。