[英]OpenTK/OpenGL blending semi-transparent texture issues
我正在為使用C#中的OpenTK的游戲開發2D菜單。 目前,菜單分為3個不同的紋理四邊形,即“圖層”,如下所示 。
第1層:按鈕的基本外觀。
第2層:鼠標懸停在“繼續”按鈕上時的外觀。
第3層:包含按鈕及其文本/名稱的“齒輪”。
這些層中的每一層都包含綁定到Quad的半透明(32位.png)紋理。 當只繪制層1和3,紋理似乎正常工作,但是當我想表明2層為好,第3層從我的屏幕上消失,因為看到這里 。 在此圖像中,僅繪制了我的基本按鈕(第1層)和突出顯示的“繼續”按鈕(第2層)。
我認為這是我的混合函數存在的問題,也是我繪制兩個以上精靈的事實。 我是OpenTK / OpenGL的新手,我希望這里的人可以幫助我解決此問題。 我將在下面添加一些代碼:
游戲開始時,我設置了一些GL屬性:
GL.Enable(EnableCap.DepthTest);
GL.Enable(EnableCap.CullFace);
GL.Enable(EnableCap.Texture2D);
GL.Enable(EnableCap.Blend); //I migh t be missing something here, like textEnv?
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
這部分代碼繪制了我的2D元素。 我從有關OpenTK的教程中學到了這一點。
public void DrawHUD()
{
// Clear only the depth buffer, so that everything
// we draw for the HUD will appear in front of the
// world objects.
GL.Clear(ClearBufferMask.DepthBufferBit);
// Reset the ModelView matrix so the following
// objects are not affected by the camera position
GL.LoadIdentity();
////draw 3d hud elements (weapon in the main game)
// Disable lighting for the HUD graphics
// GL.Disable(EnableCap.Lighting);
// Save the current perspective projection
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix();
// Switch to orthogonal view
GL.LoadIdentity();
GL.Ortho(0, Width, 0, Height, -1, 1); // Bottom-left corner pixel has coordinate (0, 0)
// Go back to working with the ModelView
GL.MatrixMode(MatrixMode.Modelview);
//// Draw the HUD elements
GameEngine.Draw2D();
// Switch back to perspective view
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix();
GL.MatrixMode(MatrixMode.Modelview);
// Turn lighting back on
// GL.Enable(EnableCap.Lighting);
}
我將菜單“圖層”添加到一個數組列表中,然后使用它通過Graphic進行繪制,該類保存了“圖層”的位置/紋理信息
public virtual void Draw2D()
{
Vector2 pos;
int Z = 0; //to fight z-fighting? this fixed an issue where drawing a 2nd sprite would also make the 1st one dissapear partially
foreach (Graphic G in _2DList)
{
if (G.visible())
{
pos = G.position();
Renderer.DrawHUDSprite(pos.X, pos.Y, Z, G.W(), G.H(), G.Texture());
Z++;
}
}
}
最后,我的hudsprite繪制函數如下所示:
public static void DrawHUDSprite(float x, float y, float z, float width, float height, int textID)
{
// Save the ModelView matrix
GL.PushMatrix();
// Move to the correct location on screen
GL.Translate(x, y, z);
GL.BindTexture(TextureTarget.Texture2D, textID);
// Setup for drawing the texture
GL.Color3(Color.White);
// Draw a flat rectangle
GL.Begin(PrimitiveType.Quads);
GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(width, 0, 0);
GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(width, height, 0);
GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0, height, 0);
GL.End();
// Restore the ModelView matrix
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.PopMatrix();
}
如果這與我加載紋理的方式有關,那么我還將添加代碼。
我設法自己解決了問題:問題出在我的draw2D()函數上,在該函數中,我使用Z坐標來防止剪切問題。 在2D模式下繪制時,Z坐標只能在[0..1]范圍內。
我較早的解決方案將Z增加1(Z ++),將導致超過2個紋理/圖形的問題(Z> 1,表示不顯示四邊形)。 固定版本如下所示:
public virtual void Draw2D()
{
if (_2DList.Count > 0) { //pervents dividing by 0, and skips memory allocation if we have no Graphics
Vector2 pos;
float Z = 0; //to fight z-fighting, the sprites ar drawn in the order they were added.
float step = 1.0f / _2DList.Count; //limiting the Z between [0..1]
foreach (Graphic G in _2DList)
{
if (G.visible())
{
pos = G.position();
Renderer.DrawHUDSprite(pos.X, pos.Y, Z, G.W(), G.H(), G.Texture());
Z += step; //with z starting at 0, it will never be 1.
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.