如何在OpenTK中使对象透明

时间:2014-04-15 08:57:39

标签: c# opentk

我使用OpenTK和C#,我在3D空间中定义了一个平面,如下所示:

GL.Begin(BeginMode.Quads);
GL.Color3(Color.Magenta);
GL.Vertex3(-100.0f, -25.0f, -150.0f);
GL.Vertex3(-100.0f, -25.0f,  150.0f);
GL.Vertex3( 200.0f, -25.0f,  100.0f);
GL.Vertex3( 200.0f, -25.0f, -100.0f);
GL.End();

有人可以帮助我让飞机透明吗?

4 个答案:

答案 0 :(得分:5)

所以你想要这样的东西?

Picture

有很多事情需要照顾到那里。

这一切都始于一个包含alpha值<255的Color对象。例如,下面的球体为Color.FromArgb(85, Color.Turquoise)

主渲染类,设置摄影机视图并渲染所有灯光,然后渲染场景中的所有对象:

    public void RenderOnView(GLControl control)
    {
        control.MakeCurrent();
        var camera=views[control];
        GL.Clear(ClearBufferMask.ColorBufferBit|ClearBufferMask.DepthBufferBit);
        GL.Disable(EnableCap.CullFace);
        GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
        camera.LookThrough();
        if (EnableLights)
        {
            GL.LightModel(LightModelParameter.LightModelAmbient, new[] { 0.2f, 0.2f, 0.2f, 1f });
            GL.LightModel(LightModelParameter.LightModelLocalViewer, 1);
            GL.Enable(EnableCap.Lighting);
            foreach (var light in lights)
            {
                light.Render();
            }
        }
        else
        {
            GL.Disable(EnableCap.Lighting);
            GL.ShadeModel(ShadingModel.Flat);
        }
        GL.Enable(EnableCap.LineSmooth); // This is Optional 
        GL.Enable(EnableCap.Normalize);  // These is critical to have
        GL.Enable(EnableCap.RescaleNormal);
        for (int i=0; i<objects.Count; i++)
        {
            GL.PushMatrix();
            objects[i].Render();
            GL.PopMatrix();
        }
        control.SwapBuffers();
    }

然后每个对象都有一个基本呈现代码Render(),它会调用更专业的代码Draw()

    public void Render()
    {
        if (Shading==ShadingModel.Smooth)
        {
            GL.Enable(EnableCap.ColorMaterial);
            GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse);
            GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, SpecularColor);
            GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, EmissionColor);
            GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, Shinyness);
            GL.Enable(EnableCap.Lighting);
        }
        else
        {
            GL.Disable(EnableCap.ColorMaterial);
            GL.Disable(EnableCap.Lighting);
        }
        GL.ShadeModel(Shading);
        GL.Translate(Position);
        GL.Scale(Scale, Scale, Scale);

        Draw(); // Draws triangles and quads to make up a shape
    }

例如,绘制一个四边形表面

    protected void DrawQuad(Color color, params Vector3[] nodes)
    {
        GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
        GL.Enable(EnableCap.PolygonOffsetFill);
        // special code when translucent
        if (color.A<255)
        {
            GL.Enable(EnableCap.Blend);
            GL.DepthMask(false);
        }
        GL.Begin(PrimitiveType.Quads);
        GL.Color4(color);    //this is where the color with alpha is used
        for (int i=0; i<nodes.Length; i++)
        {
            GL.Vertex3(nodes[i]);
        }
        GL.End();
        // special code when translucent
        if (color.A<255)
        {
            GL.Disable(EnableCap.Blend);
            GL.DepthMask(true);
        }
    }

也是用于绘制在DrawQaud()

之后调用的四边形轮廓的代码
    protected void DrawLineLoop(Color color, params Vector3[] nodes)
    {
        GL.Disable(EnableCap.PolygonOffsetFill);
        GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
        if (color.A<255)
        {
            GL.Enable(EnableCap.Blend);
            GL.DepthMask(false);
        }
        GL.Begin(PrimitiveType.LineLoop);
        GL.Color4(color);
        for (int i=0; i<nodes.Length; i++)
        {
            GL.Vertex3(nodes[i]);
        }
        GL.End();
        if (color.A<255)
        {
            GL.Disable(EnableCap.Blend);
            GL.DepthMask(true);
        }
    }

答案 1 :(得分:4)

最后我找到了问题的解决方案:

GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);
GL.Enable(EnableCap.Blend);

//Definition of Plane
GL.Begin(BeginMode.Quads);
GL.Color4(0, 0.2, 1, 0.5);
GL.Vertex3(-100.0f, -25.0f, -150.0f);
GL.Vertex3(-100.0f, -25.0f,  150.0f);
GL.Vertex3( 200.0f, -25.0f,  100.0f);
GL.Vertex3( 200.0f, -25.0f, -100.0f);
GL.End();

GL.Disable(EnableCap.Blend);

答案 2 :(得分:0)

只需使用GL.Color4而不是GL.Color3。第四个值将是alpha

答案 3 :(得分:0)

在计算中,使用color blending来消除透明效果。对于特殊情况,我们谈论ÀlphaBandnding`

对于透明度,混合因子通常存储在颜色的第4个分量(RGBA中的A)中,代表alpha。所以你必须用它设置所有的颜色。

半透明蓝色(如玻璃)的例子:

GL.Color4(0,0,1,0.5f);

在OpenGL中,必须使用以下命令激活混合,这将在渲染管道上启用补充阶段。

GL.Enable( EnableCap.Blend );

然后,因为混合可以用于混合颜色而不是透明度,所以你必须指定要使用的blending function。以下是透明度的常用功能:

GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

http://www.opentk.com/doc/chapter/2/opengl/fragment-ops/blending