Search code examples
c#openglopentk

Incorrect drawing of box


I have a problem with drawing a box shape (it is very long)

Long box

Code to create the matrix (where width and height are the size of the window):

GL.Enable(EnableCap.DepthTest);
                GL.DepthMask(true);
                GL.DepthFunc(DepthFunction.Lequal);

                float aspect = (float)width / (float)height;

                matrix = Matrix4.CreateTranslation(0, 0, -100) * // 100 > 51 
                                 Matrix4.CreatePerspectiveOffCenter(-aspect, aspect, 1, -1, 1, 1000);

Code to draw Box:

public void Box(double w, double h, double d)
    {
        float x1 = (float)-w / 2f; float x2 = (float)w / 2f;
        float y1 = (float)-h / 2f; float y2 = (float)h / 2f;
        float z1 = (float)-d / 2f; float z2 = (float)d / 2f;

        var vertbuffer = new Vector3[]
        {
            // front
            new Vector3(x1, y1, z1),
            new Vector3(x2, y1, z1),
            new Vector3(x2, y2, z1),
            new Vector3(x1, y2, z1),

            // right
            new Vector3(x2, y1, z1),
            new Vector3(x2, y1, z2),
            new Vector3(x2, y2, z2),
            new Vector3(x2, y2, z1),

            // back
            new Vector3(x2, y1, z2),
            new Vector3(x1, y1, z2),
            new Vector3(x1, y2, z2),
            new Vector3(x2, y2, z2),

            // left
            new Vector3(x1, y1, z2),
            new Vector3(x1, y1, z1),
            new Vector3(x1, y2, z1),
            new Vector3(x1, y2, z2),

            // top
            new Vector3(x1, y1, z2),
            new Vector3(x2, y1, z2),
            new Vector3(x2, y1, z1),
            new Vector3(x1, y1, z1),

            // bottom
            new Vector3(x1, y2, z1),
            new Vector3(x2, y2, z1),
            new Vector3(x2, y2, z2),
            new Vector3(x1, y2, z2),
        };

        GL.EnableClientState(ArrayCap.VertexArray);
        GL.EnableClientState(ArrayCap.NormalArray);

        GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, vertbuffer);
        GL.NormalPointer(NormalPointerType.Float, Vector3.SizeInBytes, normalBuffer);

        GL.Color4(fillColor);
        GL.DrawArrays(PrimitiveType.Quads, 0, vertbuffer.Length);

        GL.Color4(strokeColor);
        GL.LineWidth((float)strokeWeight);

        for (int i = 0; i < vertbuffer.Length / 4; i++)
        {
            GL.DrawArrays(PrimitiveType.LineLoop, i * 4, 4);
        }
    }

it does look like the front quad isnt draw:

enter image description here

I have tried to reduce the depthFar parameter of the Matrix4.CreatePerspectiveOffCenter but this doesn't work.

Edit: I've updated the code.


Solution

  • All the geometry which is not in between the near and the far plane is clipped.

    The size of your cube is 100, 100, 100. The distance to the near plane is 1 and the distance to the far plane is 1000.
    Hence, the distance between the camera and the center of the cube must be at least 51 (d/2 + near = 100/2 +1), otherwise the front of the cube will be cut off by the close plane of the Viewing frustum.

    The OpenGL coordinate system is a right handed system. The x axis points to the right and the y axis points up. The z axis is computed by the cross product of x axis and y axis and points out of the view. Therefore the geometry must be shifted in the negative z direction.

    I recommend to use the following projection and translation for a cube with the size 100x100x100:

    float aspect = (float)width/(float)height;
    matrix = Matrix4.CreateTranslation(0, 0, -100) * // 100 > 51
        Matrix4.CreatePerspectiveOffCenter(-aspect, aspect, 1, -1, 1, 1000);