2019年8月18日日曜日

opengl pyopengl jpg画像ファイルをテクスチャとして貼る




2019/09/07 変更
@@@ 画像が切り取られている。画像が90度回転している なんでか
@@@ glTexCoord2f の対応がまずかった。 displayTexPolygonを変更してok



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

#ファイル名 texture_tga_jpg.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
#OpenCVで画像を読み込んでOpenGLで表示
#http://blog.livedoor.jp/tmako123-programming/archives/16882784.html

"""
@@@ jpgファイルをテクスチャとして貼る
@@@ 画像ファイルをopencvで読む

@@@ 画像ファイルをopencvで読む
@@
@@@ GL_RGB GL_RGBAでもどちらでもいいみたい
@@@ 白黒画像だとどうなるかわからない
@@@ tgaファイルはよみこめない
"""
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
import cv2

spin=0.0


#画像ファイル管理用構造体もどき
#ダミーで数値を入れる
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)

#以下の関数はつかわない
#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)*
    glEnable(GL_TEXTURE_2D)
    glBegin(GL_QUADS)
    #glTexCoord2f(0.0, 1.0)
    glTexCoord2f(0.0, 0.0)
    glVertex3f(-5.0,-5.0, 0.0)
    #glTexCoord2f(0.125, 1.0)
    #glTexCoord2f(1.0, 1.0)
    glTexCoord2f(0.0, 1.0)
    glVertex3f(-5.0, 5.0, 0.0)
    #glTexCoord2f(0.125, 0.0)
    #glTexCoord2f(1.0, 0.0)
    glTexCoord2f(1.0, 1.0)
    glVertex3f( 5.0, 5.0, 0.0)
    #glTexCoord2f(0.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)
        Loadcv(textures, "test0.jpg")
        #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