質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenGL ES

携帯電話のような組込み機器のためにデザインされたOpenGLのサブセットです。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3026閲覧

OpenGl ES2でインデックス画像を使用したい

fumiasi

総合スコア12

OpenGL ES

携帯電話のような組込み機器のためにデザインされたOpenGLのサブセットです。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/04/12 10:21

編集2017/05/13 12:59

以前に作成していたアプリをUnityに移植する事になりました。
元々はOpenGL ES1で作成していたのですが、UnityがES1のサポートが終了していたので、
ES2に移行させる必要が発生しました。

ES1の時は、8bitインデックを読み込む場合、
GL_PALETTE8_RGB8_OES
GL_PALETTE8_RGBA8_OES
GL_PALETTE8_R5_G6_B5_OES
GL_PALETTE8_RGBA4_OES
GL_PALETTE8_RGB5_A1_OES
GL_PALETTE8_RGB8_OES 等
を使用していたのですが、ES2ではこれらのサポートが終了しているようで
ES2での読み込み方法が解らなかった為、質問致しました。

###OpenGE ES1のソース

C++

1// test.cpp 2 3#include "test.h" 4 5TEXTURE::TEXTURE() : Width(0), Height(0), TexID(0), TexParam(0) 6{ 7} 8 9TEXTURE::~TEXTURE() 10{ 11 release(); 12} 13 14bool TEXTURE::loadBmpData(unsigned char *pLoadBuffer, int KeyIndex, unsigned char *pPalette) 15{ 16 int i; 17 18 BITMAPFILEHEADER *pBF = NULL; 19 BITMAPINFOHEADER *pBI = NULL; 20 21 unsigned int BmpPitch; 22 int PalCount; 23 unsigned char *pBmpPal; 24 unsigned char *pBmpBits; 25 26 unsigned int Pitch; 27 unsigned int Size; 28 unsigned char *pData; 29 unsigned short *pPal; 30 unsigned char *pBits; 31 32 int Point = 0; 33 int Point2 = 0; 34 unsigned int Format = 0; 35 36 if( pLoadBuffer == NULL ) return false; 37 if( 0 != memcpy( pLoadBuffer, "BM", 2 ) ) return false; 38 39 // ヘッダ部抽出。 40 pBF = (BITMAPFILEHEADER*)( pLoadBuffer ); 41 pBI = (BITMAPINFOHEADER*)( pLoadBuffer + sizeof(BITMAPFILEHEADER) ); 42 43 BmpPitch = ( ( ((pBI->biWidth * pBI->biBitCount) >> 2) + 7 ) & ~7 ) >> 1; 44 pBmpPal = &pLoadBuffer[ sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ]; 45 pBmpBits = &pLoadBuffer[ pBF->bfOffBits ]; 46 47 // パレット変更があるならポインタ差し替え 48 if( pPalette != NULL ) pBmpPal = pPalette; 49 50 // パレット数 51 PalCount = (1 << pBI->biBitCount); 52 53 // サイズを2の乗数になるように調整 54 Width = Height = 1; 55 while( Width < pBI->biWidth ) Width <<= 1; 56 while( Height < pBI->biHeight ) Height <<= 1; 57 58 Pitch = ((Width * pBI->biBitCount) >> 3); 59 Size = PalCount * sizeof(unsigned short) + Pitch * Height; 60 pData = (unsigned char*)malloc( Size ); 61 if( pData == NULL ) return false; 62 pPal = (unsigned short*)&pData[ 0 ]; 63 pBits = (unsigned char*)&pData[ PalCount * sizeof(unsigned short) ]; 64 65 // 8888を5551に変換 不透明部分に0xFF 透過部分に0x00を入れる 66 for( i = 0 ; i < PalCount ; i++ ) 67 { 68 if( KeyIndex == i ) pPal[ i ] = RGBA_TO_R5G5B5A1( pBmpPal[ i * 4 + 2 ], pBmpPal[ i * 4 + 1 ], pBmpPal[ i * 4 + 0 ], 0x00 ); 69 else pPal[ i ] = RGBA_TO_R5G5B5A1( pBmpPal[ i * 4 + 2 ], pBmpPal[ i * 4 + 1 ], pBmpPal[ i * 4 + 0 ], 0xFF ); 70 } 71 72 // データ部分を上下反転 73 for( i = pBI->biHeight - 1 ; i >= 0 ; i-- ) 74 { 75 Point = BmpPitch * i; 76 77 memcpy( &pBits[ Point2 ], &pBmpBits[ Point ], BmpPitch ); 78 79 Point2 += Pitch; 80 } 81 82 if( pBI->biBitCount == 4 ) Format = GL_PALETTE4_RGB5_A1_OES; 83 else Format = GL_PALETTE8_RGB5_A1_OES; 84 85 // OpenGLバッファ作成 86 glEnable( GL_TEXTURE_2D ); 87 glGenTextures( 1, &TexID ); 88 glBindTexture( GL_TEXTURE_2D, TexID ); 89 90 // テクスチャ作成 91 glCompressedTexImage2D( GL_TEXTURE_2D, 0, Format, Width, Height, 0, Size, pData ); 92 93 // パラメータ設定 94 glBindTexture( GL_TEXTURE_2D, TexID ); 95 96 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 97 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 98 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); 99 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); 100 101 if(pData) { free((void *)pData); pData = 0; } 102 103 return true; 104} 105 106void TEXTURE::release() 107{ 108 if( TexID == 0 ) return; 109 110 glBindTexture( GL_TEXTURE_2D, 0 ); 111 glDeleteTextures( 1, &TexID ); 112 113 Width = 0; 114 Height = 0; 115 TexID = 0; 116 TexParam = 0; 117} 118

C++

1// test.h 2 3#ifndef __TEXTURE_HEADER__ 4#define __TEXTURE_HEADER__ 5 6#ifdef __ANDROID__ 7#include <GLES/gl.h> 8#include <GLES/glxt.h> 9#else 10#include <OpenGLES/ES1/gl.h> 11#include <OpenGLES/ES1/glext.h> 12#endif 13 14#include <string.h> 15#include <stdlib.h> 16 17class TEXTURE 18{ 19public: 20 int Width; // 画像の幅 21 int Height; // 画像の高さ 22 GLuint TexID; // 識別番号 23 int TexParam; 24 25private: 26 27 void loadIndexObmData(unsigned char *pLoadBuffer, unsigned char *pPalette ); 28 29public: 30 TEXTURE(); 31 32 ~TEXTURE(); 33 34 bool loadBmpData(unsigned char *pLoadBuffer, int KeyIndex, unsigned char *pPalette); 35 36 void release(); 37}; 38 39struct BITMAPFILEHEADER 40{ 41 unsigned short bfType; 42 unsigned int bfSize; 43 unsigned short bfReserved1; 44 unsigned short bfReserved2; 45 unsigned int bfOffBits; 46}; 47 48 49struct BITMAPINFOHEADER 50{ 51 unsigned int biSize; 52 int biWidth; 53 int biHeight; 54 unsigned short biPlanes; 55 unsigned short biBitCount; 56 unsigned int biCompression; 57 unsigned int biSizeImage; 58 int biXPelsPerMeter; 59 int biYPelsPerMeter; 60 unsigned int biClrUsed; 61 unsigned int biClrImportant; 62}; 63 64#define RGBA_TO_R5G5B5A1( r, g, b, a ) ( (((r) >> 3) << 11) | (((g) >> 3) << 6) | (((b) >> 3) << 1) | ((a) >> 7) ) 65 66// Unityからの呼び出し用に追加 67extern "C" 68{ 69 namespace 70 { 71 TEXTURE* g_pTexture; // テクスチャー本体 72 int g_itextureCount = 0; 73 } 74 75 // TEXTUREを生成してポインターを返す 76 void* getTexture() 77 { 78 g_pTexture = new TEXTURE(); 79 return g_pTexture; 80 } 81 82 // TEXTUREを解放して削除する 83 void releaseTexture() 84 { 85 if(g_pTexture != nullptr) 86 delete g_pTexture; 87 } 88 89 // Bmpデータを読み込む 90 bool loadBmpData(void* ptr, unsigned char *pLoadBuffer, int KeyIndex, unsigned char *pPalette) 91 { 92 TEXTURE* pTexture = reinterpret_cast<TEXTURE*>(ptr); 93 return pTexture->loadBmpData( pLoadBuffer, KeyIndex, pPalette ); 94 } 95 96 // Unityで作成したテクスチャハンドルに描画するよう設定する 97 void setTextureID(void* ptr, void* texture_id) 98 { 99 TEXTURE* pTexture = reinterpret_cast<TEXTURE*>(ptr); 100 pTexture->TexID = (GLuint)(size_t)texture_id; 101 } 102} 103 104#endif // __TEXTURE_HEADER__ 105 106

上記をUnityのプラグインに移植して、Unity側から呼び出して使用しようと思っています。
具体的には
http://tips.hecomi.com/entry/2016/01/04/183121
のサイトで行われているような感じでテクスチャをプラグイン側で作成して
Unity側で読み込んでAndroid/iOSで表示させようと思っています。

画像を16bitにして、インデックスを使用しないパターンやpng化も考慮しましたが
アプリ容量の問題や画像数がかなり多いので、従来のデータ(8bitインデックス)を
読み込ませたいと考えています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

ES2では、パレット付きの画像はそのままでは読み込めない事が判明しました。
無理やり読み込ませるには、読み込む前にパレット情報を展開して下記の形式に変換する必要があります。

形式

  • GL_PALETTE4_RGB8_OES
    type:GL_UNSIGNED_BYTE format = GL_RGB bit:4 offset:3
  • GL_PALETTE4_RGBA8_OES
    type:GL_UNSIGNED_BYTE format = GL_RGBA bit:4 offset:4
  • GL_PALETTE4_R5_G6_B5_OES
    type:GL_UNSIGNED_SHORT_5_6_5 format = GL_RGB bit:4 offset:2
  • GL_PALETTE4_RGBA4_OES
    type:GL_UNSIGNED_SHORT_4_4_4_4 format = GL_RGBA bit:4 offset:2
  • GL_PALETTE4_RGB5_A1_OES
    type:GL_UNSIGNED_SHORT_5_5_5_1 format = GL_RGBA bit:4 offset:2
  • GL_PALETTE8_RGB8_OES
    type:GL_UNSIGNED_BYTE format = GL_RGB bit:8 offset:3
  • GL_PALETTE8_RGBA8_OES
    type:GL_UNSIGNED_BYTE format = GL_RGBA bit:8 offset:4
  • GL_PALETTE8_R5_G6_B5_OES
    type:GL_UNSIGNED_SHORT_5_6_5 format = GL_RGB bit:8 offset:2
  • GL_PALETTE8_RGBA4_OES
    type:GL_UNSIGNED_SHORT_4_4_4_4 format = GL_RGBA bit:8 offset:2
  • GL_PALETTE8_RGB5_A1_OES
    type:GL_UNSIGNED_SHORT_5_5_5_1 format = GL_RGBA bit:8 offset:2
// 引数はES1でglCompressedTexImage2Dに代入する値と同じ // 使用するタイミングはES1でglCompressedTexImage2Dを呼び出していた部分から呼び出す void glCompressedTexImage2D_pallet(GLenum target, GLint level, GLenum oldformat GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) { GLint b, o, x, y; // bはbit数、oはoffset、それぞれ上記の形式を参考に指定して下さい GLenum format, type; // format, typeの値は、上記の形式を参考に指定して下さい const GLubyte* palette, * p; GLubyte* image = (GLubyte*)malloc(o*width*height); // oldformatから様々な形式に変換を掛ける必要がある場合は // ここでswitch分岐する事をオススメします。単体の場合は上記の宣言時に直代入でも問題ない // (設定内容はi,o,format,typeで対応形式は上記を参照) palette = (GLubyte*)data; p = (GLubyte*)data+(1<<i)*o; // 4bit if (b == 4) { for(y = 0; y < height; y++) { for(x = 0; x < width; x+=2, p++) { for(GLint j = 0; j < o; j++) { image[(y*width+x)*o+j] = palette[((*p)>>4)*o+j]; if (x+1 < width) { image[(y*width+x+1)*o+j] = palette[((*p)&0xf)*o+j]; } } } } // 8bit } else { for(y = 0; y < height; y++) { for(x = 0; x < width; x++, p++) { for(GLint j = 0; j < o; j++) { image[(y*width+x)*o+j] = palette[(*p)*o+j]; } } } } glTexImage2D(target, level, format, width, height, 0, format, type, image); if (image) free(image); }

実際に処理する場合は様々な例外処理

ターゲットチェック
if (target != GL_TEXTURE_2D) return;

メモリー確保に失敗した場合
if (!(image = (GLubyte*)malloc(owidthheight))) return;

画像サイズのチェック
if (width <= 0 || height <= 0 ||
width > __GL_MAX_2D_TEX_SIZE || height > __GL_MAX_2D_TEX_SIZE ||
!__GL_IS_P2(height) || !__GL_IS_P2(width) || level < 0 || border != 0) return;

変換後のサイズチェック(switchを使用する場合はその後ろ)
if (((widthi)+7)/8height + (1<<i)*o != imageSize) return;

とかが必要になるかと思いますが、
必須ではないので上記では省略しています。

ES2でどうしてもパレットデータの読み込みさせたいと、
お悩みの同士の参考になれば幸いです。

投稿2017/05/09 14:34

編集2017/05/09 14:36
fumiasi

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問