OpenGL 绘制包裹纹理 (OpenTK)

OpenGL draws wrapped textures (OpenTK)

我有一个纹理:

但是 OpenGL 绘制了这个:

有人可以解释一下原因并帮助我解决这个问题吗?

此代码加载纹理(我正在使用 ImageSharp 加载图像)

            Handle = GL.GenTexture();
            GL.BindTexture(TextureTarget.Texture2D, Handle);

            Image<Rgba32> image = Image.Load(File.ReadAllBytes(path));

            image.Mutate(x => x.Flip(FlipMode.Vertical));

            List<byte> pixels = new List<byte>(4 * image.Width * image.Height);

            for (int y = 0; y < image.Height; y++)
            {
                var row = image.GetPixelRowSpan(y);
                
                for (int x = 0; x < image.Width; x++)
                {
                    pixels.Add(row[x].R);
                    pixels.Add(row[x].G);
                    pixels.Add(row[x].B);
                    pixels.Add(row[x].A);
                }
            }

            byte count = 1;
            foreach (byte pixel in pixels)
            {
                Console.Write(pixel + " ");
                if (count == 4)
                {
                    Console.WriteLine();
                    count = 0;
                }
                count++;
            }

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, PixelFormat.Rgba,
                PixelType.UnsignedByte, pixels.ToArray());

            GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);

并且绘制(ShaderTexture 类 正在工作,Texture 构造函数如上所示):

        private int VAO;
        private int VBO;
        private int EBO;

        private Shader shader;
        private Texture texture;

        float[] vertices =
        {
            //Position          Texture coordinates
             0.5f,  0.5f, 0.0f, 0.0f, 1.0f, // top right
             0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
            -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
            -0.5f,  0.5f, 0.0f, 0.0f, 1.0f  // top left
        };

        uint[] indices =
        {
            0, 1, 3,
            1, 2, 3,
        };

        VAO = GL.GenVertexArray();
        GL.BindVertexArray(VAO);

        shader.Use();
        texture.Use();

        EBO = GL.GenBuffer();
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, EBO);
        GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw);

        VBO = GL.GenBuffer();
        GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
        GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);

        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0);
        GL.EnableVertexAttribArray(0);

        GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0);
        GL.EnableVertexAttribArray(1);

        Matrix4 model = Matrix4.CreateRotationX(0);

        shader.SetMatrix4("projection", Transform.projection);
        shader.SetMatrix4("model", model);
        shader.SetMatrix4("view", Camera.viewMatrix);

        GL.DrawElements(PrimitiveType.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0);

片段着色器

#version 330

out vec4 outputColor;

in vec2 texCoord;

uniform sampler2D texture0;

void main()
{
    outputColor = texture(texture0, texCoord);
}

顶点着色器

#version 330 core

layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec2 aTexCoord;
out vec2 texCoord;

uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;

void main(void)
{
    gl_Position = vec4(aPosition, 1.0) * model * view * projection;
    texCoord = aTexCoord;
}

您的纹理包裹不正确,因为您将顶点坐标的 x 和 y 分量用作纹理坐标。
当命名缓冲区对象绑定到 ArrayBuffer 目标时,VertexAttribPointer 的最后一个参数被视为缓冲区对象数据存储中的字节偏移量。

您需要指定纹理坐标的偏移量。偏移量是3 * sizeof (float),因为属性缓冲区以顶点坐标的三个分量开始,后面是纹理坐标:

GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0);

GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 
    5 * sizeof(float), 3*sizeof(float));