マウスでオブジェクトを選択する(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()