【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

テクスチャの読み込み

id:n7shi:20091010でSystem.Drawing.BitmapからOpenGLにテクスチャを渡しましたが、同じことをVincent ESでもやってみました。

Compact Frameworkの制限でPixelFormat.Format32bppArgbがないためFormat32bppRgbを使います。OpenGL ESの制限でGL_BGRA_EXTがないためGL_RGBAを使います。そのためRとBの入れ替えが必要です。Format32bppRgbでの4バイト目(ARGBでα値が入る箇所)の値はPCでは常に255ですが、Windows Mobileでは0です。0のままOpenGL ESに渡すと透過してしまうため、255に直す必要があります。Format24bppRgbとGL_RGBを使えばα値を無視できそうですが、Vincent ESではサポートされていないらしくまともに描画できません。以下にコードを示します。

var id = new uint[1];
GL.glGenTextures(id.Length, id);
GL.glBindTexture(GL.GL_TEXTURE_2D, id[0]);
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
var presurf = new Bitmap(filename);
int w = presurf.Width, h = presurf.Height;
var bmpData = presurf.LockBits(new Rectangle(0, 0, w, h),
    ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
var buf = new byte[w * h * 4];
Marshal.Copy(bmpData.Scan0, buf, 0, buf.Length);
presurf.UnlockBits(bmpData);
presurf.Dispose();
for (int i = 0; i < buf.Length; i += 4)
{
    byte b = buf[i];
    buf[i] = buf[i + 2];
    buf[i + 2] = b;
    buf[i + 3] = 255; // alpha is always 0 in CE
}
GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, w, h, 0,
    GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buf);

このコードはフルバージョンの.NET FrameworkOpenGLの組み合わせでも動きます。