3

I'm using OpenTK and C#, I have defined a plane in 3D space as follows:

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

Can anyone please help me to make the plane transparent?

John Alexiou
  • 28,472
  • 11
  • 77
  • 133
harishli2020
  • 305
  • 6
  • 19

4 Answers4

8

So you want something like this?

Picture

There are a lot of things to take care of to get there.

It all starts with a Color object that contains an alpha value<255. For example Color.FromArgb(85, Color.Turquoise) for the sphere below.

The main render class, sets up the camera view and renders all the lights, and then renders all the objects in the scene:

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

Then each object has a base rendering code Render(), which calls more specialized code 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
    }

and for example to draw a quad surface you have

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

also the code to draw the outline of a quad to be called after 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);
        }
    }
John Alexiou
  • 28,472
  • 11
  • 77
  • 133
5

Finally I found solution of my question:

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);
harishli2020
  • 305
  • 6
  • 19
2

In computing, Transparency effects are fained using color blending.For The special case of transprency, we talk about Àlpha Blending`

For transparency the blending factor is usualy stored in the 4th component of the colour (the A in RGBA) which stands for alpha. So you have to set all your colors with it.

example for half transparent blue (like glass):

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

In OpenGL, blending have to be activated with the following command, which enable a supplementary stage on the rendering pipeline.

GL.Enable( EnableCap.Blend );

Then, because blending could be used to mix colors for other purpose than transparency, you have to specify the blending function to use. Here is the common function for transparency:

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

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

j-p
  • 1,622
  • 10
  • 18
  • 1
    Don't forget to disable depth check `GL.DepthMask(false);` before drawing with `GL.BlendFunc()` as specified. And _always_ draw your translucent objects last. – John Alexiou Apr 16 '14 at 12:47
  • @ja72: default depth testing is ok (I guess), I've tried to keep it as simple as possible. – j-p Apr 16 '14 at 17:30
  • 1
    If you are drawing one thing then depth test does not matter. In general though, it needs to be off on the 2nd pass for drawing correctly translucency. – John Alexiou Apr 16 '14 at 17:54
0

Simply use GL.Color4 instead of GL.Color3. The 4th value will be the alpha

Vengarioth
  • 684
  • 5
  • 13
  • 1
    I have used GL.Color4(0.6, 0.6, 0.6, 0.5); and then later GL.Color4(0.6, 0.6, 0.6, 1.0); but still my plane doesn't become transparent. – harishli2020 Apr 15 '14 at 22:59