見出し画像

BitmapをOpenGL向けの画像データに変換する

上の記事に System.Drawing.Image.Bitmap を使って画像ファイルをプログラム内に取り込む方法を書いた。 

この記事では取り込んだ画像データを、OpenGL ライブラリを使って画面に表示するために、Bitmap の画像データを OpenGL 向けの画像データに変換するコードをメモしておく。

変換した画像データはテクスチャマッピングする。


Bitmapの画像データは、画像の左上隅のピクセルから順番に色データが並んでいる。色の並び順はB、G、R。

一方で OpenGL では、画像データは画像の左下隅のピクセルから順番に色データが並んでいると見なされる。Bitmapとは上下が逆で、左右は同じ。左から右、下から上に向かってデータが並ぶ。色の並び順はR、G、B。これも Bitmap とは逆。


これを踏まえ、Bitmap を OpenGL 向けの画像データに変換するプログラムは以下のようになる。

今回もコードは C++/CLI で書いている。


Bitmap を入力すると OpenGL 向けの画像データ配列 forGL を返す関数。

forGL は関数内で動的にアンマネージメモリ確保しているため、呼び出した側が使い終えたら delete[] する必要がある。

void BitmapToGL( Bitmap^ src, byte** forGL )
{
  auto rect = System::Drawing::Rectangle( 0, 0, src->Width, src->Height );
  Imaging::BitmapData^ bmpData = src->LockBits( rect, 
                                  Imaging:ImageLockMode::ReadOnly, 
                                  Imaging::PixelFormat::Format24bppRgb );

  int w = bmpData->Width;
  int h = bmpData->Height;
  const byte* scan0 = (const byte*)bmpData->Scan0.ToPointer();
  *forGL = new byte[3 * w * h]; // need to be delete[]
  int iterator = 0;
  for ( int j = 0 ; j < h ; ++j ) {
    for ( int i = 0 ; i < w ; ++i ) {
      int sIndex = i + w * j ;
      int dIndex = i + w * ( h - j - 1 );
      ( *forGL )[3 * dIndex + 2] = scan0[iterator++]; // bmp B to OpenGL R
      ( *forGL )[3 * dIndex + 1] = scan0[iterator++]; // bmp G to OpenGL G
      ( *forGL )[3 * dIndex    ] = scan0[iterator++]; // bmp R to OpenGL B 
    }
    iterator = ( j + 1 ) * bmpData->Stride;
  }

  src->UnlockBits( bmpData );
}



いいなと思ったら応援しよう!