最終更新:
mikk_ni3_92 2008年07月29日(火) 14:21:35履歴
現在地 >> メニュー >> 基本編06 >> tga形式の画像 >> TGA画像読み込み
「TGA形式の画像」は、「先頭の18ビット分(0〜17)」が「ヘッダ情報」である。
[参考]:TGA(targa形式)
http://www.shiojiri.ne.jp/~openspc/format/TGA/
※↑このページのカラーマップエントリー(2バイト)の後、「カラーマップの長さ(2バイト)」が抜けているようです。
(画像の横幅まで本当は12バイトある)
以下nehe production lesson 24 より
以下のようなデータ構造を用意する
[画像用の構造体]
無圧縮のtga画像の読み込みは、ヘッダ情報の読み込みの方が複雑。
― 手順 ―
以上でデータ読み込みができる。
テクスチャへのコンバートで注意する点は、読み込んだtga画像が「RGB」か「RGBA」かを判断する点。
以上をまとめて、以下のように書ける
「TGA形式の画像」は、「先頭の18ビット分(0〜17)」が「ヘッダ情報」である。
[参考]:TGA(targa形式)
http://www.shiojiri.ne.jp/~openspc/format/TGA/
※↑このページのカラーマップエントリー(2バイト)の後、「カラーマップの長さ(2バイト)」が抜けているようです。
(画像の横幅まで本当は12バイトある)
以下nehe production lesson 24 より
以下のようなデータ構造を用意する
[画像用の構造体]
typedef struct { GLubyte *imageData; //イメージデータ(32ビットまで) GLuint bpp; // ビット/ピクセル GLuint width; // 横幅 GLuint height; // 高さ GLuint texID; //ID(複数使用時) } TextureImage;
無圧縮のtga画像の読み込みは、ヘッダ情報の読み込みの方が複雑。
― 手順 ―
- 先頭の12バイトを読み込んで、無圧縮のtgaヘッダと比較
- 次の6バイト内から縦・横のサイズ等の情報を取得
- 画像データを読み込む
FILE *file = fopen("TGAimg.tga", "rb"); ... ... GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};//無圧縮のTGAヘッダ GLubyte TGAcompare[12]; //ヘッダ情報格納用(12バイト分) fread(TGAcompare,1,sizeof(TGAcompare),file); //12バイトを読み込む if ( memcmp(TGAheader , TGAcompare, sizeof(TGAheader) ) != 0 ) //12バイト分の比較 { return false; } ... ...
TextureImage *texture; ... ... GLuint bytesPerPixel;//(バイト/ピクセル) GLubyte header[6]; fread(header, 1, sizeof(header), file) //次の6バイトを読み込む texture->width = header[1] * 256 + header[0];//TGA画像の幅を決定(上位バイト*256+下位バイト) texture->height = header[3] * 256 + header[2];//TGA画像の高さの決定 (上位バイト*256+下位バイト) //幅、高さが0じゃないかどうか?24ビットか、32ビットか? if(texture->width <= 0 || texture->height <= 0 || (header[4]!=24 && header[4]!=32) ) { fclose(file); //エラー ならファイルを閉じる return false; } texture->bpp = header[4];//TGA画像のbppを取得(24か32か) bytesPerPixel = texture->bpp/8; //何色あるかを計算(24/ 8 = 3色、 32/8 = 4色)
GLuint imageSize; //画像サイズ用 GLuint temp; //一時データ用 //必要なメモリ数を計算 imageSize = texture->width * texture->height * bytesPerPixel; //(縦)×(横)×(3 or 4) //メモリー確保 texture->imageData=(GLubyte *)malloc(imageSize); if(texture->imageData==NULL) { return false; } //画像データの読み込み if( fread(texture->imageData, 1, imageSize, file) != imageSize) { //正しく読み込めなかったら各種エラー処理 if(texture->imageData!=NULL){ free(texture->imageData); } fclose(file); return false; } //BRG -> RGBの変換 for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel) { temp=texture->imageData[i]; texture->imageData[i] = texture->imageData[i + 2]; texture->imageData[i + 2] = temp; } fclose (file);
以上でデータ読み込みができる。
テクスチャへのコンバートで注意する点は、読み込んだtga画像が「RGB」か「RGBA」かを判断する点。
TextureImage *texture; TextureImage textures[1]; GLuint type=GL_RGBA; //デフォルトは「RGBA」 ... ... glGenTextures(1, &texture[0].texID); glBindTexture(GL_TEXTURE_2D, texture[0].texID); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //もしも、24(ビット/ピクセル)の画像の時 if (texture[0].bpp==24) { type=GL_RGB; //タイプ変更 } glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
以上をまとめて、以下のように書ける
TextureImage textures[1]; int LoadTGA(TextureImage *texture, char *filename) { GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};//無圧縮のTGAヘッダ GLubyte TGAcompare[12]; //ヘッダの比較用 GLubyte header[6];//ヘッダの最初の便利な6バイト用 GLuint bytesPerPixel;//(バイト/ピクセル) GLuint imageSize; //画像サイズ用 GLuint temp; //一時データ用 GLuint type=GL_RGBA; //デフォルトは「RGBA」(32bpp) //ファイルオープン FILE *file = fopen(filename, "rb"); if(file==NULL || fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || //12バイトかどうかチェック memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || //ヘッダファイルがただしいか? fread(header,1,sizeof(header),file)!=sizeof(header)) //よければ、次の6バイトを読む { if (file == NULL) return false; else //何らかのエラー { fclose(file); return false; } } //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)) { //ミスったら、エラー fclose(file); return false; } //TGA画像のbppを取得(24か32か) texture->bpp = header[4]; bytesPerPixel = texture->bpp/8; //色数を取得 //イメージサイズの計算 imageSize = texture->width*texture->height*bytesPerPixel; //メモリー確保 texture->imageData=(GLubyte *)malloc(imageSize); //メモリがとれたかをチェック if(texture->imageData==NULL || fread(texture->imageData, 1, imageSize, file)!=imageSize) { //メモリー開放 if(texture->imageData!=NULL){ free(texture->imageData); } fclose(file); return false; } for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel) { //BRG -> RGBの変換 temp=texture->imageData[i]; texture->imageData[i] = texture->imageData[i + 2]; texture->imageData[i + 2] = temp; } fclose (file); //テクスチャ作成 IDで分ける glGenTextures(1, &texture[0].texID); //バインドなど glBindTexture(GL_TEXTURE_2D, texture[0].texID); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //もしも、24(ビット/ピクセル)の画像の時 if (texture[0].bpp==24) { type=GL_RGB; //タイプ変更 } glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData); return true; }