Search code examples
c#openglvertexvertex-attributes

Why does the rendered object appear distorted?


I'm getting a distorted red triangle Outputwhen trying to display a red triangle with 3 vertices (at (-0.5,-0.5) (0.5,-0.5) (0,0.5)) I'm passing to the shader with this code

public void LoadData<T>(BufferConfig<T> config) where T : struct, IVertex
    {
        Bind();

        GL.BufferData(config.Target, config.VertexCount * config.Layout.SizeOfVertex, config.Vertices, config.Usage);

        int offset = 0;

        for (int i = 0; i < config.Layout.Attribs.Length; i++)
        {
            GL.EnableVertexAttribArray(i);
            GL.VertexAttribPointer(
                i, 
                config.Layout.Attribs[i].ElementCount, 
                config.Layout.Attribs[i].ElementType, 
                config.Layout.Attribs[i].IsNormalized, 
                config.Layout.Attribs[i].Stride,
                offset
                );

            offset += config.Layout.Attribs[i].Stride;
        }

        Unbind();
    }

The vertex consists of 2 Vector4's respectively representing position and colour, I have tried debugging it and the values seem fine as there are 2 attributes, position and color, the loop runs 2 times,

1st iteration: index = 0, count = 4, type = float, normalized = false, stride = 16, pointer = 0

2nd iteration: index = 1, count = 4, type = float, normalized = false, stride = 16, pointer = 16

Why exactly does this look like in the image ?

EDIT:

Vertex shader

#version 450 core

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;

out vec4 vs_color;

void main(void)
{
    gl_Position = position;
    vs_color = color;
}

Fragment shader

#version 450 core

in vec4 vs_color;
out vec4 fragColor;

void main(void)
{
    fragColor = vs_color;
}

Vertices

r1.AddVertices(new CVertex[] {
            new CVertex(new Vector4(-0.5f,-0.5f,0f,1f), new Vector4(1f,0f,0f,1f)),
            new CVertex(new Vector4(0.5f,-0.5f,0f,1f), new Vector4(0f,1f,0f,1f)),
            new CVertex(new Vector4(0f,0.5f,0f,1f), new Vector4(0f,0f,1f,0f))
        });

Solution

  • The stride is incorrect. The stride should be the number of bytes to skip for the next vertex attribute.

    In your case, to reach the next position you have to skip 4 floats for position and 4 floats for the color, to a total of 32 bytes (and similarly for the color).

    If you have multiple attributes in a single buffer, the stride should be the sum of the sizes of the attributes.

    Using a stride of 16 bytes instead of 32 results in the triangle: (-0.5, -0.5, 0)-(1, 0, 0)-(0.5, -0.5, 0). As pointed out by @Zebrafish in the comments, these are the position of the first vertex, the color of the first vertex, and the position of the second vertex.

    Instead of advancing from the position of the first vertex to the position of the second vertex (which are 32 bytes apart), it advances to the color of the first vertex, and then to the position of the second vertex.