読者です 読者をやめる 読者になる 読者になる

TadaoYamaokaの日記

山岡忠夫 Home で公開しているプログラムの開発ネタを中心に書いていきます。

WindowsのPythonでOpenGLを使う

Python OpenGL Windows GLUT

写真の線画化を、iBUG 300-Wの300枚の画像に試してみたけど、あまりきれいな線画が生成できなかった。
学習データの生成には他のアプローチを試したい。
Live2Dのような方法で、線画のキャラクタの向きや表情のバリエーションを増やせないかと考えている。
Live2Dは2Dの画像を変形させるために、ポリゴンを使用しているようなので、OpenGLを使って同じようなことを試そうと思う。

OpenGLC++の情報が多いが、最近Pythonの使いやすさに慣れてしまったので、OpenGLPythonから使えたらそちらを使いたい。
PythonOpenGLを使うには、PyOpenGLというライブラリがあるようだ。
ということで、PyOpenGLを試してみた。

下記の例では、ウィンドウの表示部分にGLUTを使用した。
PyQt4を使うこともできるようなので、後で試したい。

実行環境

PyOpenGLのインストール

公式の説明通り、pipでPyOpenGLをインストールする。

pip install PyOpenGL PyOpenGL_accelerate

FreeGLUTのインストール

PyOpenGLとは別に、GLUTをインストールする必要がある。
GLUTは、OpenGLをプラットフォーム非依存で扱うためのライブラリのようだ。

本家のGLUTは、Windowsの64bitのバイナリがダウンロードできない。
代わりに、64bitのバイナリが提供されているFreeGLUTを導入する。

FreeGLUTのページから
Martin Payne's Windows binaries (MSVC and MinGW)
のリンクをたどり、
Download freeglut 3.0.0 for MSVC
からfreeglut-MSVC-3.0.0-2.mp.zipをダウンロードする。

zipファイル内のfreeglut\bin\x64\にあるfreeglut.dllをC:\Windows\System32にコピーする。

これで、GLUTが使用できるようになる。

サンプル実行

こちらのページを参考に、ティーポットを表示してみる。
pyOpenGL を Windows8 (64bit) にインストールする | n3956.net

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

def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH)
    glutInitWindowSize(300, 300)     # window size
    glutInitWindowPosition(100, 100) # window position
    glutCreateWindow(b"teapot")      # show window
    glutDisplayFunc(display)         # draw callback function
    glutReshapeFunc(reshape)         # resize callback function
    init(300, 300)
    glutMainLoop()

def init(width, height):
    """ initialize """
    glClearColor(0.0, 0.0, 0.0, 1.0)
    glEnable(GL_DEPTH_TEST) # enable shading

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    ##set perspective
    gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)

def display():
    """ display """
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    ##set camera
    gluLookAt(0.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
    ##draw a teapot
    glColor3f(1.0, 0.0, 0.0)
    glutWireTeapot(1.0)   # wireframe
#    glutSolidTeapot(1.0)  # solid
    glFlush()  # enforce OpenGL command

def reshape(width, height):
    """callback function resize window"""
    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)

if __name__ == "__main__":
    main()
注意点

glutCreateWindowの引数にPythonの文字列をそのまま渡すと、TypeErrorになる。
Python2ではそのまま渡すことができるが、Python3で文字列がデフォルトでunicode文字列になったため、文字列リテラルの前にbを付けて、バイト列として渡す必要がある。

実行結果

f:id:TadaoYamaoka:20170228064226p:plain