Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# OpenTK/OpenGL混合半透明纹理问题_C#_Opengl_Opentk_Blending - Fatal编程技术网

C# OpenTK/OpenGL混合半透明纹理问题

C# OpenTK/OpenGL混合半透明纹理问题,c#,opengl,opentk,blending,C#,Opengl,Opentk,Blending,我正在为一个使用C中OpenTK的游戏制作2D菜单。 目前,菜单分为3个不同的纹理四边形或“层”,看起来像 第1层:按钮的基本外观 第2层:鼠标悬停在“继续”按钮上时,“继续”按钮的外观 第三层:一个“装备”,它包含按钮及其文本/名称 每一层都由绑定到四边形的半透明32位.png纹理组成。 当只绘制第1层和第3层时,纹理似乎工作正常,但当我也想显示第2层时,第3层会从屏幕上消失,如图所示。在此图像中,仅绘制基本按钮层1和高亮显示的“继续”按钮层2 我相信这是我的混合函数的一个问题,事实上我画了两

我正在为一个使用C中OpenTK的游戏制作2D菜单。 目前,菜单分为3个不同的纹理四边形或“层”,看起来像

第1层:按钮的基本外观

第2层:鼠标悬停在“继续”按钮上时,“继续”按钮的外观

第三层:一个“装备”,它包含按钮及其文本/名称

每一层都由绑定到四边形的半透明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);
    }
我将菜单“layers”添加到arraylist,然后使用Graphic绘制,Graphic类保存我的“layer”的位置/纹理信息

 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++;
            }
        }
    }
最后,我的hudsprites绘制函数如下所示:

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();
    }
    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.
                }
            }
        }
    }

如果这与我加载纹理的方式有关,我也会为此添加代码。

我自己设法解决了这个问题:问题在于我的draw2D函数,我使用Z坐标来防止剪切问题。在2D中绘制时,Z坐标只能在[0..1]的范围内

我以前的解决方案将Z增加1 Z++会导致2个以上的纹理/图形Z>1的问题,这意味着不显示四边形。固定版本如下所示:

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();
    }
    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.
                }
            }
        }
    }

我设法解决了这个问题!