OpenTKでC#を使用して、スプライト/テクスチャアトラス機能のサポートクラスを作成しています。これまでのところ、ほとんどの機能は正常に機能しています(正投影ビューの単純な2Dタイル)。
私の問題は、GDI + Bitmap.MakeTransparent()メソッドを呼び出して、カラーキーとして使用する色(マゼンタ/ 0xFFFF00FF)を設定したときの予期しない表示結果に関連しています。
ビットマップ.LockBits()およびGL.TexImage2D()呼び出しに誤ったピクセル形式パラメーターを使用しているように見えます。私のコードは実際に機能する例に基づいていましたが、LockBits()に渡される長方形は画像全体のものであるという共通点がありました。
このプロセスに関連する呼び出しは次のとおりです。
<!-- language: C# -->
Bitmap bitmap = new Bitmap(filename);
bitmap.MakeTransparent(Color.Magenta);
GL.GenTextures(1, out texture_id);
GL.BindTexture(TextureTarget.Texture2D, texture_id);
// "rect" is initialized for one of:
// - the dimensions of the entire image
// (0, 0, bitmap.width, bitmap.height)
// - the dimensions for a sub-rectangle within the image (for one tile)
// (tile_x * tile_width, tile_y * tile_height, tile_width, tile_height)
// I observe different behaviors for a sub-rectangle,
// as compared to the entire image, when in combination with
// the .MakeTransparent() call.
//
// This code is in a load_tile() method, and the plan was to make
// multiple calls per image file, one per tile to extract as a GL texture.
// Without transparency, that worked fine.
Rectangle rect = new Rectangle(xx, yy, width, height);
BitmapData data = bitmap.LockBits(rect,
ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppRgb);
// In the absence of calling bitmap.MakeTransparent(),
// images loaded and displayed as expected with Format24bppRgb.
// With MakeTransparent() and Format32bppRgb, the results seem to be OS-dependent.
// (At first I thought the "correct" combination to be found,
// but then found that the results were "right" only under Windows 7.)
GL.TexImage2D(
OpenTK.Graphics.OpenGL.TextureTarget.Texture2D, // texture_target,
0, // level,
OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba, // internal_format
data.Width, data.Height, // width, height,
0, // border,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, // pixel_format
OpenTK.Graphics.OpenGL.PixelType.UnsignedByte, // pixel_type
data.Scan0 // pixels
);
// Certainly the internal_format and pixel_format arguments are pertinent,
// but other combinations I have tried produced various undesired display results.
// After reading various (OpenGL, OpenTK, and GDI+) docs, still I am not enlightened..
bitmap.UnlockBits(data);
上記のコードを使用して別のボクセンで小さなデモをテストし、次の結果を観察しました。
- Windows 7ボックス:マゼンタピクセルは透明として機能します(望ましい結果)
- Windows XPボックス:黒でレンダリングされたマゼンタピクセル
- Ubuntu Linuxボックス:マゼンタとしてレンダリングされたマゼンタピクセル
(GDI +とOpenGLおよびOpenTKバインディング)が異なるボックスで同じように動作すると予想したので、これは私を驚かせます。
GDI+とOpenGL/OpenTK APIのドキュメントを吸収した限り、私の戸惑いは次の2つの点に関係していると思います。
指定された色が透明としてレンダリングされるように、MakeTransparent()+ LockBits()+ GL.TexImage2D()を呼び出す正しい方法は何ですか?
LockBits()が画像全体ではなくサブ長方形に対して呼び出されたときに、特定のピクセル形式パラメーターの組み合わせに対して(「ストライド」が誤って計算されたかのように)奇妙な表示結果が表示されるのはなぜですか?
更新:コードをGithubの小さなプロジェクトにまとめました: https ://github.com/sglasby/OpenGL_Transparent_Sprite
また、機能するパラメーターの組み合わせ(LockBits()のarg 3はFormat32bppPArgb)に遭遇しましたが、ドキュメントが別のピクセル形式が必要であることを示唆しているため、なぜ機能するのかは明らかではありません: http ://msdn.microsoft.com/ en-us / library / 8517ckds.aspx (MakeTransparentを呼び出した後、ビットマップがFormat32bppArgbになることを示します)。