PyOpenGL 6

テクスチャ

プロシージャルテクスチャ(チェッカー模様)をつけてみます。

#!env python

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


vertex = [
    [ -1.0, 0.0, 1.0 ],
    [ 1.0, 0.0, 1.0 ],
    [ 1.0, 0.0, -1.0 ],
    [ -1.0, 0.0, -1.0 ]]

face = [
    [ 0, 1, 2, 3 ]]

uvcoord = [
    [0.0, 0.0],
    [1.0, 0.0],
    [1.0, 1.0],
    [0.0, 1.0]]

angleX = 0.0
angleY = 0.0

def maketex():
    w = 32
    h = 32
    n = 2
    data = ''
    for x in range(w):
        for y in range(h):
            xx = x % (w/n) < w/(n*2)
            yy = y % (h/n) < h/(n*2)
            if xx ^ yy:
                data += struct.pack('BBB', 255, 0, 0)
            else:
                data += struct.pack('BBB', 0, 255, 0)
    tex = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, tex)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data)


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 draw():
    global angleX, angleY

    glClearColor(0.0, 0.0, 1.0, 0.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    glLoadIdentity()
    gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
    glRotated(angleX, 1.0, 0.0, 0.0);
    glRotated(angleY, 0.0, 1.0, 0.0);

    glEnable(GL_TEXTURE_2D)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    glBegin(GL_QUADS)
    for j in range(len(face)):
        for i in range(4):
            n = face[j][i]
            glTexCoord2f(uvcoord[n][0], uvcoord[n][1])
            glVertex(vertex[n])
    glEnd()

    glFlush()
    glutSwapBuffers()


def keyboard(key, x, y):
    global angleX, angleY
    if key=='q':
        sys.exit()
    elif key=='h':
        angleY += 1.0
        glutPostRedisplay()
    elif key=='j':
        angleX += 1.0
        glutPostRedisplay()

glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(320, 320)
glutCreateWindow("PyOpenGL 15")
glutDisplayFunc(draw)
glutReshapeFunc(resize)
glutKeyboardFunc(keyboard)

glClearColor(0.0, 0.0, 1.0, 0.0)
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)

maketex()

glutMainLoop()

スクリプト解説

import struct
pack() メソッドを使用するために、struct モジュールをインポートします。
w = 32
テクスチャの横方向の解像度です。
h = 32
テクスチャの縦方向の解像度です。
n = 2
テクスチャの繰り返し回数です。
xx = x % (w/n) < w/(n*2)
yy = y % (h/n) < h/(n*2)
テクスチャにどちらの色をつけるかを決めるための計算です。
if xx ^ yy:
上で計算した xx, yy の排他的論理和によって、どちらの色にするかを決めます。
xx yy xx ^ yy
0 0 0
1 0 1
0 1 1
1 1 0
data += struct.pack('BBB', 255, 0, 0)
255, 0, 0 を3バイトのバイナリデータにして、data に追加します。
以下の様な式を使用すると、if 文の部分を省略できます。
data += struct.pack('BBB', 255*(xx^yy), 255*(not (xx^yy)), 0)
tex = glGenTextures(1)
テクスチャの番号を得る関数です。
引数
テクスチャの個数
返り値は、番号の入ったリストになります。
glBindTexture(GL_TEXTURE_2D, tex)
テクスチャを選択します。
ここでは、tex によって指定されるテクスチャです。
1番目の引数
GL_TEXTURE_1D
1次元テクスチャ
GL_TEXTURE_2D
2次元テクスチャ
2番目の引数
テクスチャの番号
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data)
2次元テクスチャを作成します。
1番目の引数
GL_TEXTURE_2D
2次元テクスチャ
GL_PROXY_TEXTURE_2D
ミップマップ
2番目の引数
テクスチャの場合は 0、ミップマップの場合は 1 以上。
3番目の引数
GL_RGB
色データが R, G, B の場合。
GL_RGBA
色データがアルファを含んでいる場合。
4番目の引数
テクスチャの幅。(2の累乗)
5番目の引数
テクスチャの高さ。(2の累乗)
6番目の引数
0
テクスチャに枠をつけない
1
テクスチャに枠をつける
7番目の引数
関数に渡すデータの形式。
GL_RGB
色データが R, G, B の場合。
GL_RGBA
色データがアルファを含んでいる場合。
8番目の引数
関数に渡すデータの型。
ここでは、色ごとに符号無し1バイトなので、GL_UNSIGNED_BYTEを指定しています。
9番目の引数
テクスチャの色データ。
glEnable(GL_TEXTURE_2D)
2次元テクスチャを使用可能にします。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
テクスチャの張り方の設定です。
1番目の引数
GL_TEXTURE_1D
1次元テクスチャ
GL_TEXTURE_2D
2次元テクスチャ
2番目の引数
パラメータの指定です。
GL_TEXTURE_MIN_FILTER
テクスチャが縮小されて張られるときの設定。
GL_TEXTURE_MAG_FILTER
テクスチャが拡大されて張られるときの設定。
GL_TEXTURE_WRAP_S
横方向に対して、テクスチャが繰り返されるかどうか。
GL_TEXTURE_WRAP_T
縦方向に対して、テクスチャが繰り返されるかどうか。
GL_TEXTURE_PRIORITY
テクスチャの優先度
3番目の引数
2番目の引数が、 GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTERの場合は、以下のいずれかです。
GL_NEAREST
近いピクセルの色を使用。
GL_LINEAR
まわりの色を補間して使用。
2番目の引数が、 GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_Tの場合は、以下のいずれかです。
GL_CLAMP
繰り返さない。
GL_REPEAT
繰り返す。
2番目の引数が、 GL_TEXTURE_PRIORITYの場合は0.0から1.0の数値を指定します。
glTexCoord2f(uvcoord[n][0], uvcoord[n][1])
テクスチャ上での座標を指定します。
glTexParameteri() でGL_REPEATが指定されている場合は、0.0 〜 1.0 以外の数値も指定できます。

練習問題

  1. 前回の練習問題を参考にして、Maya の Obj ファイルを読み込んでテクスチャ表示ができるようにしてみましょう。
    また、4キーでワイヤーフレーム表示、5キーで陰影表示、6でテクスチャ表示を切り換えることができるようにしてください。
    読み込むファイル名は、コマンドラインで指定します。
    # python objdisplay4.py sphere.obj
    4 キーを押したとき

    5 キーを押したとき

    6 キーを押したとき

    上図のObjデータ

参考


Prev | Next
index | home
abetmhr@gmail.com