2019年9月5日木曜日

opengl pyopengl 立方体にテクスチャを貼る





coding:utf-8

#ファイル名 rippoutai_texture.py
# @@@立方体にテクスチャを貼る
# @@@立方体を描く 塗りつぶし マウスクリックで回転
#q', 'Q', または ESC キーでプログラムが終了
# 見る方向によるのか 正方形にしか見えない 透視投影を使って立方体にみえるようにする
# http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#8
# 元コードでは 図形が変な風に見えるので gluLookAtを入れる 

#参考サイト
#2005年06月10日 [OpenGL][テクスチャ] 第16回 テクスチャの部分的な置き換え
#http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20050610

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

vertex=[
        [0.0, 0.0, 0.0],
        [1.0, 0.0, 0.0],
        [1.0, 1.0, 0.0],
        [0.0, 1.0, 0.0],
        [0.0, 0.0, 1.0],
        [1.0, 0.0, 1.0],
        [1.0, 1.0, 1.0],
        [0.0, 1.0, 1.0] ]
face = [
        [3, 2, 1, 0],
        [2, 6, 5, 1],
        [6, 7, 4, 5],
        [7, 3, 0, 4],
        [0, 1, 5, 4],
        [7, 6, 2, 3]]
#頂点のテクスチャ座標
texcoord = [
  [[ 0.0,   1.0 ], [ 0.125, 1.0 ], [ 0.125, 0.0 ], [ 0.0,   0.0 ]],
  [[ 0.125, 1.0 ], [ 0.25,  1.0 ], [ 0.25,  0.0 ], [ 0.125, 0.0 ]],
  [[ 0.25,  1.0 ], [ 0.375, 1.0 ], [ 0.375, 0.0 ], [ 0.25,  0.0 ]],
  [[ 0.375, 1.0 ], [ 0.5,   1.0 ], [ 0.5,   0.0 ], [ 0.375, 0.0 ]],
  [[ 0.5,   1.0 ], [ 0.625, 1.0 ], [ 0.625, 0.0 ], [ 0.5,   0.0 ]],
  [[ 0.625, 1.0 ], [ 0.75,  1.0 ], [ 0.75,  0.0 ], [ 0.625, 0.0 ]],
];


#面の色の設定
color = [
        [1.0, 0.0, 0.0],
        [0.0, 1.0, 0.0],
        [0.0, 0.0, 1.0],
        [1.0, 1.0, 0.0],
        [1.0, 0.0, 1.0],
        [0.0, 1.0, 1.0]]
#上から 赤 緑 青 黄 マゼンタ シアン
edge=[
        [0, 1],
        [1, 2],
        [2, 3],
        [3, 0],
        [4, 5],
        [5, 6],
        [6, 7],
        [7, 4],
        [0, 4],
        [1, 5],
        [2, 6],
        [3, 7] ]
r = 0

import sys
import cv2



#画像ファイル管理用構造体もどき
#ダミーで数値を入れる
class textures:
    imageData = [] #イメージデータ(32ビットまで)                                   
    bpp    = 0              # ビット/ピクセル
    width  = 0           # 横幅                                                       
    height = 0          # 高さ                                                     
    texID  = 0          #ID(複数使用時) 

def Loadcv(texture, filename):
    TGAheader  = [0,0,2,0,0,0,0,0,0,0,0,0]#無圧縮のTGAヘッダ                   
    TGAcompare = []                       #ヘッダの比較用                                 
    header     = [] #ヘッダの最初の便利な6バイト用

    bytesPerPixel = 0#(バイト/ピクセル)
    imageSize     = 0 #画像サイズ用
    temp          = 0    #一時データ用
    type          = GL_RGBA #デフォルトは「RGBA」(32bpp)                                   
    try:
        im = cv2.imread(filename)
        #opencvのy座標はopenglのy座標と逆になっている
        #画像をx軸を中心に上下反転させる
        im = cv2.flip(im, 0)
    except:
        print "画像ファイル読み込めませんでした。"
    texture.width = im.shape[1]
    texture.height = im.shape[0]


    #テクスチャ作成 IDで分ける
    glGenTextures(1, texture.texID)

    #バインドなど
    glBindTexture(GL_TEXTURE_2D, texture.texID)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    #glTexImage2D(GL_TEXTURE_2D, 0, type,
    #       texture.width, texture.height,
    #            0, GL_BGR, GL_UNSIGNED_BYTE, im)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
            texture.width, texture.height,
                 0, GL_BGR, GL_UNSIGNED_BYTE, im)




def idle():
    glutPostRedisplay()
    #プログラム中でウィンドウの再描画イベントを発生させる
    #これをプログラムが「暇なとき」に繰り返し呼び出すことで, アニメーションが実現できます. >
   
def display():
    print 'display'
    global r
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()#描画の一番最初にglLoadIdentity()を使い,ワールド座標系(単位行列)を読み>
    gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

    glRotated(r, 0.0, 1.0, 0.0)
    print r

    #図形の描画
    # glVertex3dv() は,引数に3つの要素を持つ GLdouble 型(double と
    # 等価)の配列のポインタを与えて, 頂点を指定します.
    glColor3d(0.0, 1.0, 0.0)
    glEnable(GL_TEXTURE_2D)
    glBegin(GL_QUADS)
    for j in range(0,6):
        glColor3dv(color[j])
        for i in range(0,4):
            glTexCoord2dv(texcoord[j][i])
            glVertex3dv(vertex[face[j][i]])
    glEnd()
    glDisable(GL_TEXTURE_2D)

    #glFlush()
    glutSwapBuffers()

    #一周回ったら回転角を0に戻す
    if r>=360:
        r = 0
    else:
        r = r + 1

def resize(w,h):
    print 'resize'
    glViewport(0,0,w,h)
    #透視変換行列の設定
    glMatrixMode(GL_PROJECTION) #glMatrixModeは引き数で 変換したい座標変換を指定
    glLoadIdentity
    gluPerspective(30.0, w/h, 1.0, 100.0)

    #モデルビュー変換行列の設定
    glMatrixMode(GL_MODELVIEW)

def mouse(button, state, x, y):
    if button == GLUT_LEFT_BUTTON:
        if state == GLUT_DOWN:
            #アニメーション開始
            glutIdleFunc(idle)
        else:
            #アニメーション停止
            glutIdleFunc(0)

    elif button == GLUT_RIGHT_BUTTON:
        if state == GLUT_DOWN:
            #コマ送り
            glutPostRedisplay()

def keyboard(key, x, y):
    if key == 'q' or key == 'Q' or key == '\033':
        exit(0)

def init():
    glClearColor(1.0, 1.0, 1.0, 1.0)
    #色の指定
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_CULL_FACE)
    glCullFace(GL_BACK)

    Loadcv(textures, "dice.jpg")

def main():
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE)
    glutCreateWindow("aka")
    glutDisplayFunc(display)
    glutReshapeFunc(resize)
    glutMouseFunc(mouse)
    glutKeyboardFunc(keyboard)
    init()
    #glClearColor() は, プログラムの実行中に背景色を変更する
    #ことがなければ, 最初に一度だけ設定すれば十分です. そこ
    #でこのような初期化処理を行う関数は, glMainLoop() の前に
    #実行する関数 init() にまとめて置くことにします
    glutMainLoop()

if __name__ == "__main__":
    main()


0 件のコメント:

コメントを投稿

About

参加ユーザー

連絡フォーム

名前

メール *

メッセージ *

ページ

Featured Posts