2019年8月17日土曜日

opengl pyopengl tga画像ファイルをテクスチャで貼り付ける






#!/usr/bin/env python
#coding:utf-8

#ファイル名 texture_tga.py

#参考サイト
#OpenGl勉強会用資料のページ テクスチャマッピング
#http://www.oit.ac.jp/is/L231/~whashim^U/Article/OpenGL/Chapter7/index.html
#OpenGL de プログラミング
#https://seesaawiki.jp/w/mikk_ni3_92/d/TGA%B2%E8%C1%FC%C6%C9%A4%DF%B9%FE%A4%DF

"""
@@@ tgaファイルをテクスチャとして貼る
"""
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys

spin=0.0

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

#tga画像ファイルを読み込む
def LoadTGA(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)                                   
    flg_ferror    = 0

    #ファイルオープン
    try:
        f = open(filename, "rb")
    except:
        flg_ferror = 1
        print "ファイルを読み込めませんでした。"
    #12バイトかどうかチェック
    #なんでチェックしないとだめか?
    #読み込みに成功したオブジェクトの数。 エラーまたはファイル終端
    #に達した場合は count より少なくなることがあります。
    for size in range(len(TGAheader)):
        #readメソッドは読み込んだデータを文字列として扱うので、整数値と
        #して扱う場合は関数ordを使用します。
        #ord アスキーコードに変換
        byt = f.read(1)
        #ファイルのeofにきた。または読み込めなかった場合
        if byt == '':
            flg_ferror = 1
            break
        acode = ord(byt)
        TGAcompare.append(acode)

    #ヘッダファイルがただしいか?
    if TGAheader != TGAcompare:
        flg_ferror = 1

    #よければ、次の6バイトを読む                 
    for size in range(6):
        byt = f.read(1)
        #ファイルのeofにきた。または読み込めなかった場合
        if byt == '':
            flg_ferror = 1
            break
        acode = ord(byt)
        header.append(acode)

    #思ったように上操作できなかったら
    if flg_ferror == 1:
        print "flg_ferror=1"
        f.close()

    #TGA画像の幅を決定(上位バイト*256+下位バイト)     
    texture.width   = header[1] * 256 + header[0]
    #TGA画像の高さの決定 (上位バイト*256+下位バイト)
    texture.height = header[3] * 256 + header[2]
    #幅、高さが0じゃないかどうか?24ビットか、32ビットか?
    #if(texture.width   <=0 ||  texture.height <=0
    #       || (header[4]!=24 && header[4]!=32))
    if texture.width <= 0 or texture.height <=0\
            or (header[4]!=24 and header[4]!=32):
        #ミスったら、エラー
        f.close()


    #TGA画像のbppを取得(24か32か)
    texture.bpp = header[4]
    #色数とは? 上bpp参照 RGBかRGBAを判断している
    bytesPerPixel    = texture.bpp/8 #色数を取得
    #イメージサイズの計算                     
    imageSize = texture.width*texture.height*bytesPerPixel

    for size in range(imageSize):
        byt = f.read(1)
        #ファイルのeofにきた。または読み込めなかった場合
        if byt == '':
            flg_ferror = 1
            break
        acode = ord(byt)
        texture.imageData.append(acode)

    #思ったように上操作できなかったら
    if flg_ferror == 1:
        f.close()

    for i in range(0, imageSize, bytesPerPixel):
         temp=texture.imageData[i]
         texture.imageData[i] = texture.imageData[i + 2]
         texture.imageData[i + 2] = temp
    f.close()


    #テクスチャ作成 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)

    #もしも、24(ビット/ピクセル)の画像の時
    #bpp=32ならRGBAとなる
    if texture.bpp==24:
         type=GL_RGB     #タイプ変更

    glTexImage2D(GL_TEXTURE_2D, 0, type,
            texture.width, texture.height,
                 0, type, GL_UNSIGNED_BYTE, texture.imageData)



#以下コードを有効にして上LoadTGAを無功にするとチェッカー模様になる
TEX_HEIGHT = 16
TEX_WIDTH   = 16
#TEX_HEIGHT  = 32
#TEX_WIDTH  = 32
#テクスチャサイズの16×16とその一つ一つの画素にRGBAの4バイトを割り当て
#ている
image = [[[0 for i in range(4)] for j in range(TEX_WIDTH)]
            for k in range(TEX_HEIGHT)]

#テクスチャの準備
#テクスチャのサイズは縦横とも2の累乗になっていなければならない
def initTexture():
    for i in range(TEX_HEIGHT):
        for j in range(TEX_WIDTH):
            #2で割り切れる場合1そうでない場合0
            #以下ビット演算だからi=1,2,3,4,....
            #i&0x01 は 1,0,1,0.....  ^排他的論理和 1^1=0 0^0=1
            #故に i=1 ならc=0,1,0,1....
            #故に i=0 ならc=1,0,1,0....
            c = ( ((i&0x01)==0)^((j&0x01)==0) )
            #RGBには0か255の値、Aには255を入れる
            image[i][j][0]= image[i][j][1]= image[i][j][2]=c*255
            image[i][j][3]=255


def displayTexPolygon():
    glEnable(GL_TEXTURE_2D)
    glBegin(GL_QUADS)
    glTexCoord2f(0.0, 0.0)
    glVertex3f(-5.0,-5.0, 0.0)
    glTexCoord2f(0.0, 1.0)
    glVertex3f(-5.0, 5.0, 0.0)
    glTexCoord2f(1.0, 1.0)
    glVertex3f( 5.0, 5.0, 0.0)
    glTexCoord2f(1.0, 0.0)
    glVertex3f( 5.0,-5.0, 0.0)
    glEnd()
    glDisable(GL_TEXTURE_2D)

def display():
    global spin
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glPushMatrix()

    glTranslatef(0.0, 0.0,-20.0)
    glRotatef(spin, 0.0, 1.0, 0.0)
    glColor3f(1.0, 1.0, 1.0)
    displayTexPolygon()

    spin+=1.0
    glPopMatrix()
    glFlush()
    glutSwapBuffers()


def init() :
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glDepthFunc(GL_LEQUAL)
    glEnable(GL_DEPTH_TEST)
    LoadTGA(textures, "test0.tga")
    #initTexture()
    #glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
    #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    #glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    #glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT,
    #    0, GL_RGBA, GL_UNSIGNED_BYTE, image)


def reshape(w, h):
    glViewport(0, 0,  w,  h)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glFrustum(-5.0, 5.0,-5.0, 5.0, 5.0, 500.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

def main():
    glutInit(sys.argv)
    glutInitDisplayMode (GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA)
    glutInitWindowSize (250, 250)
    glutInitWindowPosition (100, 100)
    glutCreateWindow ("tgaファイルテクスチャ")
    init()
    glutIdleFunc(display)
    glutDisplayFunc(display)
    glutReshapeFunc(reshape)
    glutMainLoop()


if __name__ == "__main__":
    main()

0 件のコメント:

コメントを投稿

About

参加ユーザー

連絡フォーム

名前

メール *

メッセージ *

ブログ アーカイブ

ページ

Featured Posts