左ドラッグで回転して、右ドラッグでドリーするところまで
だいぶ思い出してきた。
昨日作ったフォント表示を使ってみたが
Windowサイズを変更すると行間隔が変わってしまっていまいちなことが判明。
単純にglRasterPosで指定するだけではだめか。
なんか位置を固定する方策が必要だ。
あとglutだとマウスホイールが使えない様子。
たぶんファイルダイアログ機能とかもなさげ。
適当なところでツールキットを変える必要がありますな。
Qt(PyQt)とか使ってみたいのだが新しいGUIはじめると
横道にそれて帰って来れなくなりそうだ。
#!/usr/bin/env python # -*- coding: utf-8 -*- from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * from Image import * # window idを記憶しておく window=0 # mouse情報 lmb=GLUT_UP mmb=GLUT_UP rmb=GLUT_UP last_x=0 last_y=0 # 視点情報 head=0.0 pitch=0.0 bank=0.0 distance=5.0 # フォント描画ディスプレイリストのオフセット fontOffset=0 # 初期化とWindow生成 def createWindow(width, height, title): global window # initialize glut glutInit("") glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) # create window glutInitWindowSize(width, height) glutInitWindowPosition(100, 100) window = glutCreateWindow(title) def initGL(): glShadeModel(GL_SMOOTH) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) # メタセコ風味 glClearColor(30.0/255.0, 65.0/255.0, 90.0/255.0, 1.0) # set callbacks glutDisplayFunc(display) glutReshapeFunc(reshape) glutKeyboardFunc(keyPressed) glutSpecialFunc(keyPressed) glutMouseFunc(mouse) glutMotionFunc(motion) def makeRasterFontFromBitmap(file, letter_width, letter_height): global fontOffset glPixelStorei(GL_UNPACK_ALIGNMENT, 1) # DisplayList fontOffset=glGenLists(128) # 画像からdisplayリストを作成 bitmap = open("font.bmp") for code in range(128): x=(code % 16)*letter_width y=(code / 16)*letter_height letter=bitmap.crop([x, y, x+letter_width, y+letter_height]).transpose(FLIP_TOP_BOTTOM) glNewList(fontOffset+code, GL_COMPILE) glBitmap(letter_width, letter_height, 0.0, 0.0, letter_width, 0.0, letter.tostring()) glEndList() def printString(text, x, y): global fontOffset glDisable(GL_LIGHTING) glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glMatrixMode(GL_MODELVIEW) glPushMatrix() glLoadIdentity() # defulatでは(-1, -1)-(1, 1)の空間 glColor(1.0, 0.0, 0.0) glRasterPos2f(x, y) glPushAttrib(GL_LIST_BIT) glListBase(fontOffset) glCallLists(text) glPopAttrib() glPopMatrix() glMatrixMode(GL_PROJECTION) glPopMatrix() glMatrixMode(GL_MODELVIEW) glEnable(GL_LIGHTING) def resetPosition(): global head, pitch, bank, display head=0 pitch=0 bank=0 display=5 # 描画 def display(): global head, pitch, bank, distance # バッファのクリア glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # クリア glLoadIdentity() # 視点 gluLookAt(0.0, 0.0, distance, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) glRotate(head, 0, 1, 0) glRotate(pitch, 1, 0, 0) glRotate(bank, 0, 0, 1) # 描画 glColor(1.0, 1.0, 1.0) glutSolidTeapot(1) # 文字 printString("head : %f" % (head), -1, -0.4) printString("pitch: %f" % (pitch), -1, -0.6) printString("bank : %f" % (bank), -1, -0.8) printString("dist : %f" % (distance), -1, -1) # 実行 glutSwapBuffers() # ウィンドウリサイズ def reshape(width, height): print 'reshape' if height==0: height=1 glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(30.0, float(width)/float(height), 1.0, 100.0); glMatrixMode(GL_MODELVIEW) def keyPressed(key, x, y): global window if key== '\033' or key== "q": glutDestroyWindow(window) sys.exit() if key==GLUT_KEY_HOME: resetPosition() glutPostRedisplay() else: print key # mouse button down & up def mouse(button, state, x, y): global lmb, mmb, rmb, last_x, last_y if button==GLUT_LEFT_BUTTON: lmb=state elif button==GLUT_MIDDLE_BUTTON: mmb=state elif button==GLUT_RIGHT_BUTTON: rmb=state last_x=x last_y=y glutPostRedisplay() # drag def motion(x, y): global lmb, mmb, rmb, last_x, last_y, head, pitch, bank, distance #glutGetModifiers if lmb==GLUT_DOWN: # left head & pitch head+=x-last_x head=head % 360 pitch+=y-last_y pitch=pitch % 360 elif mmb==GLUT_DOWN: # middle pan None elif rmb==GLUT_DOWN: # right dolly None distance+=x-last_x distance+=0.5*(y-last_y) if distance<3.0: distance=3.0 last_x=x last_y=y glutPostRedisplay() def main(): createWindow(150, 150, 'glut sample') initGL() makeRasterFontFromBitmap('font.bmp', 12, 12) glutMainLoop() if __name__ == '__main__': print "Hit ESC key to quit." main()