Search code examples
c#openglperspectivelightingopentk

OpenTK C# Perspective Lighting looks glitchy


My goal is to make lighting in perspective view smooth. I'm using the same light settings for both perspective and orthographic. The images below show that the orthographic lighting looks great. The perspective lighting looks glitchy and flickers when I rotate it. What am I missing that would make the perspective view lighting look okay?

Processor: AMD FX 6100 6-core 3.31GHz

Graphics: AMD Radeon HD 6800

Note: I referenced from an OpenGL example. I was playing with the different light settings to find out how they work. The code I pasted at the end of this post is the code that created the images.

Perspective: https://i.sstatic.net/pSXul.png

Orthographic: https://i.sstatic.net/Q7Yr2.png

Here is the relevant code within my paint method.

private void glControl1_Paint(object sender, PaintEventArgs e)
{
    if (!glLoaded)
        return;

    GL.Enable(EnableCap.DepthTest);
    //GL.Enable(EnableCap.Blend);
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    //SET PERSPECTIVE OR ORTHOGRAPHIC VIEW
    if (chkPerspective.Checked)
    {
        double aspect = glControl1.Width / (double)glControl1.Height;

        Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)aspect, 0.0001f, 5000.0f);
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadIdentity();
        GL.LoadMatrix(ref perspective);

        Matrix4 lookat = Matrix4.LookAt(eyeOffset.X, eyeOffset.Y, eyeOffset.Z, 0, 0, 0, 0, 1, 0);

        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadMatrix(ref lookat);


        //GL.Translate(-boxOffset);
    }
    else
    {
        setupViewPort(); //Orthographic settings
        GL.MatrixMode(MatrixMode.Modelview); 
        GL.LoadIdentity();
    }

    GL.Rotate(angleY, 1.0f, 0, 0);
    GL.Rotate(angleX, 0, 1.0f, 0);

    //LIGHTING
    if (chkLighting.Checked)
    {
        float[] mat_specular = { 1.0f, 1.0f, 1.0f, 1.0f };
        float[] mat_shininess = { 50.0f };
        float[] light_position = { 1000.0f, 1000.0f, 1000.0f, 100.0f };
        float[] light_ambient = { 0.5f, 0.5f, 0.5f, 1.0f };

        GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        //GL.ShadeModel(ShadingModel.Smooth);

        //GL.Material(MaterialFace.Front, MaterialParameter.Specular, mat_specular);
        //GL.Material(MaterialFace.Front, MaterialParameter.Shininess, mat_shininess);
        GL.Light(LightName.Light0, LightParameter.Position, light_position);
        //GL.Light(LightName.Light0, LightParameter.Ambient, light_ambient);
        //GL.Light(LightName.Light0, LightParameter.Diffuse, mat_specular);

        GL.Enable(EnableCap.Lighting);
        GL.Enable(EnableCap.Light0);
        GL.Enable(EnableCap.ColorMaterial);
        //GL.Enable(EnableCap.CullFace);
    }
    else
    {
        GL.Disable(EnableCap.Lighting);
        GL.Disable(EnableCap.Light0);
    }

    foreach (Cube cube in cubes)
    {
        cube.drawCube(selectionCubeRadius);
    }

    glControl1.SwapBuffers();
}


Here is my orthographic viewport code in case it matters.

private void setupViewPort()
{
    if (chkPerspective.Checked)
        return;

    int w = glControl1.Width;
    int h = glControl1.Height;
    GL.MatrixMode(MatrixMode.Projection);
    GL.LoadIdentity();
    GL.Ortho(-w, w, -h, h, -5000, 5000); // Bottom-left corner pixel has coordinate (0, 0)
    GL.Viewport(0, 0, w, h); // Use all of the glControl paintingarea
}

Solution

  • I found a solution that will work for now. In perspective view, I reduced the size of the cubes from 200.0 to 5.0. Then I moved the camera closer so they appear the same size. Some also said that I should decrease the far Z-plane when I create my perspective field of view.

    Reducing the size of my models worked, but I also decreased the distance of the far z-plane for convention purposes. I'll also likely create an algorithm that determines what z-plane distance to use based on my current model size and angle.

    User 'dflemstr' asked about my GL.Normal3f calls. The answer is that I have none. What do they do, and are they necessary?