Search code examples
c#openglopentk

How to make objects transparent in OpenTK


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?


Solution

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