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);
并且绘制(Shader
和 Texture
类 正在工作,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));
我有一个纹理:
但是 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);
并且绘制(Shader
和 Texture
类 正在工作,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));