GLuint createTexture(const char* filename, int width=128, int height=128)
{
GLuint texture;
C99 可変長配列を使用して、幅*高さ*3 バイトのメモリをスタックに割り当てます。十分なスタックが残っていない場合、プログラムはスタック オーバーフローでクラッシュします。
char bitmap[width][height][3];
ファイルを開いてテクスチャを取得してみてください。ファイルは、チャンネルごとに 8 ビットの RGB データの、ヘッダーのない未加工のタイトな配列である必要があります。
FILE* fp=fopen(filename, "rb");
ファイルのオープンに失敗した場合、プログラムを終了します。技術的にこの目的で assert を使用することはプログラミング エラーです。なぜなら、a) assert はリリース ビルドでは何も行わず、b) これはエラーから簡単に回復できるからです。ファイルを開くことができなかった場合、関数は単に 0 を返す必要があります。
assert(fp);
width*height の 3 バイトのチャンクを読み取ります。sizeof(char)は、これの作成者が C について何も知らなかったことを示しています。C 標準では が定義sizeof(char) == 1されているため、その乗算を行う意味がありません。
予想される量のデータを読み取ることができなかった場合、デバッグ モードの場合はプログラムをクラッシュさせます。エラーが発生した場合、リリース ビルドは奇妙なことを行います。
assert(fread(bitmap, 3*sizeof(char), width*height, fp) == width*height);
ファイルを閉じます。
fclose(fp);
OpenGL テクスチャ オブジェクト ハンドルを割り当てます。
glGenTextures(1, &texture);
テクスチャ ハンドルをバインドして、テクスチャに影響を与える後続の OpenGL 操作が指定されたオブジェクトで動作するようにします。
glBindTexture(GL_TEXTURE_2D, texture);
テクスチャの拡大および縮小フィルターを設定します。mipmap レベルが不要になるように、linear を使用します。
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
データを OpenGL テクスチャにコピーします。これは新しく割り当てられたテクスチャ オブジェクト ハンドルを使用するため、テクスチャもこれによって初期化されます。
ここには多くの重要なステップがありません。つまり、配列からデータを読み取るために OpenGL を準備するには、glPixelStoreiを使用する必要があります。ラインアライメント、ストライドなど。
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,bitmap);
テクスチャ オブジェクトのバインドを解除します。
glBindTexture( GL_TEXTURE_2D,0);
テクスチャ オブジェクト ハンドルを返します。
return texture;
}
このコードの主な問題: デバッグ ビルドの場合、OpenGL エラー チェックが行われず、プログラムがクラッシュします。リリース ビルドでは、ファイル操作エラーは検出されず、処理されません。
このコードは使用しないでください。