Как сделать объекты прозрачными в OpenTK

Я использую OpenTK и C#, я определил плоскость в трехмерном пространстве следующим образом:

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 ответа

Решение

Так ты хочешь что-то подобное?

Картина

Есть много вещей, чтобы позаботиться о том, чтобы туда добраться.

Все начинается с Color объект, который содержит альфа-значение<255. Например 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);
        }
    }

Наконец я нашел решение своего вопроса:

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);

В вычислениях эффекты прозрачности ослабляются с помощью смешивания цветов. Для особого случая прозрачности мы говорим об альфа-смешивании.

Для прозрачности фактор смешивания обычно сохраняется в 4-м компоненте цвета (A в RGBA), что означает alpha, Таким образом, вы должны установить все свои цвета с ним.

пример для полупрозрачного синего (как стекло):

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

В OpenGL смешивание необходимо активировать с помощью следующей команды, которая включает дополнительный этап в конвейере рендеринга.

GL.Enable( EnableCap.Blend );

Затем, поскольку смешивание можно использовать для смешивания цветов для целей, отличных от прозрачности, необходимо указать функцию смешивания, которую следует использовать. Вот общая функция для прозрачности:

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

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

Просто используйте GL.Color4 вместо GL.Color3. 4-е значение будет альфа

Другие вопросы по тегам