我寫精靈/紋理地圖功能的輔助類,使用C#與OpenTK色鍵。 到目前爲止,大多數功能工作正常(正交視圖上的簡單2D瓦片)。雪碧/紋理圖集:GDI + Bitmap.MakeTransparent與OpenTK
當調用GDI + Bitmap.MakeTransparent()方法設置用作顏色鍵的顏色(品紅色/ 0xFFFF00FF)時,我的問題與意外顯示結果有關。
這似乎是我使用不正確的像素格式參數的bitmap.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);
我已經使用上面的代碼在不同的Boxen有測試了一個小的演示,並觀察這些結果:
- 的Windows 7盒:品紅像素顯示爲透明(所需的結果)
- Windows XP框:洋紅色像素呈現爲黑色
- Ubuntu Linux框:呈現爲洋紅色的洋紅色像素a
這讓我很驚訝,因爲我預料到(GDI +和OpenGL以及OpenTK綁定)會在不同的框中發揮相同的作用。
要我吸收了GDI +和OpenGL/OpenTK API文檔的程度,我覺得我的困惑關於這兩點:
什麼是調用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 (其中指出,位圖將在Format32bppArgb調用MakeTranspar後ENT)。
對我來說,'Format32bppArgb'給出炒上的Win7 /英特爾的結果。 'Format32bppRgb'和'Format32bppPArgb'似乎工作。調查。 –
一些有趣的事情顯示出來:沒有'MakeTransparent'的'Format32bppArpb'具有'data.Stride = 128'; 'MakeTransparent','data.Stride = 512'。 'Format32bppPArgb'總是有'data.Stride = 128'。不知道這是爲什麼,但它可能指向一個解決方案。 –