I have a texture:
But OpenGL draws this:
Can someone explain me why and help me solve this problem?
This code loads texture (i'm using ImageSharp to load image)
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);
And this draws (Shader
and Texture
classes are working, Texture
constructor is shown above):
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);
Fragment shader
#version 330
out vec4 outputColor;
in vec2 texCoord;
uniform sampler2D texture0;
void main()
{
outputColor = texture(texture0, texCoord);
}
Vertex shader
#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;
}
Your texture is wrapped incorrectly because you are using the x and y components of the vertex coordinates for the texture coordinates.
When a named buffer object is bound, to the ArrayBuffer
,target, the last argument of VertexAttribPointer
is treated as a byte offset into the buffer object's data store.
You need to specify the offset for the texture coordinates. The offset is 3 * sizeof (float)
, since the attribute buffer begins with the three components of the vertex coordinates, followed by the texture coordinates:
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false,
5 * sizeof(float), 3*sizeof(float));