c# - OpenGL渲染:所有顶点移动到单位球体的边界
问题描述
我正在使用 C# 中的 OpenTK 为我的玩具游戏引擎编写渲染器。因为它仅供我使用,所以我使用的是 OpenGL 4.5。在我实现了基础之后,我尝试渲染犹他茶壶。这就是我得到的:
当我渲染一个简单的立方体时,它渲染得很好。一旦我添加了更多的顶点,一切都开始像一个球体。我使用 .obj 文件格式。我的加载器没有导致问题,我将所有顶点位置记录到控制台并手动创建了另一个带有这些位置的 .obj 文件,将它们导入到 Blender 并且它们显示得很好。我的顶点着色器只是传递所有数据,片段着色器只是分配白色。我浏览了整个互联网,但没有人遇到这个问题。我只是加载 .obj 文件,创建顶点和索引数组,创建 VAO,带顶点的 VBO,带索引的 EBO。GL.GetError()
没有给我任何东西。我认为问题在于将模型数据加载到 VBO 中,但我就是找不到问题所在。这是我加载网格数据的代码:
private bool _initialized = false;
public readonly int _id, _vertexCount, _indexCount;
private readonly int _vboID, _iboID;
public Mesh(Vertex[] vertices, int[] indices)
{
_vertexCount = vertices.Length;
_indexCount = indices.Length;
GL.CreateVertexArrays(1, out _id);
GL.CreateBuffers(1, out _vboID);
GL.NamedBufferStorage(
_vboID,
Vertex.Size * _vertexCount, // Vertex is a struct with Vector3 position, Vector2 texCoord, Vector3 normal
vertices,
BufferStorageFlags.MapReadBit);
GL.EnableVertexArrayAttrib(_id, 0); // _id is the VAO id provided by GL.CreateVertexArrays()
GL.VertexArrayAttribFormat(
_id,
0,
3, // Vector3 - position
VertexAttribType.Float,
false,
0); // first item, offset 0
GL.VertexArrayAttribBinding(_id, 0, 0);
GL.EnableVertexArrayAttrib(_id, 1);
GL.VertexArrayAttribFormat(
_id,
1,
2, // Vector2 - texCoord
VertexAttribType.Float,
false,
12); // sizeof(float) * (3) = (Size of Vector3)
GL.VertexArrayAttribBinding(_id, 1, 0);
GL.EnableVertexArrayAttrib(_id, 2);
GL.VertexArrayAttribFormat(
_id,
0,
3, // Vector3 - normal
VertexAttribType.Float,
false,
20); // sizeof(float) * (3 + 2) = (Size of Vector3 + Vector2)
GL.VertexArrayAttribBinding(_id, 2, 0);
GL.VertexArrayVertexBuffer(_id, 0, _vboID, IntPtr.Zero, Vertex.Size);
GL.CreateBuffers(1, out _iboID);
GL.NamedBufferStorage(
_iboID,
sizeof(int) * _indexCount,
indices,
BufferStorageFlags.MapReadBit);
GL.VertexArrayElementBuffer(_id, _iboID);
_initialized = true;
}
解决方案
问题在于设置法线向量属性数组时。的第二个参数GL.VertexArrayAttribFormat
是属性索引,在您的情况下必须是 2 而不是 0:
GL.EnableVertexArrayAttrib(_id, 2);
GL.VertexArrayAttribFormat(
_id,
2, // <----------------------- 2 instead of 0
3,
VertexAttribType.Float,
false,
20);
GL.VertexArrayAttribBinding(_id, 2, 0);
属性索引 0 导致顶点坐标规范被法线向量覆盖。法线向量是单位向量(长度 == 1),如果将它们视为顶点坐标,它们会形成球形。
推荐阅读
- git - 如何在 Jenkins 构建历史中按 Git 分支过滤
- javascript - MutationObserver 没有检测到使用 .appendChild() 创建的新节点
- node.js - 导出后是否可以修改导出的变量
- regex - 句子语法的正则表达式
- r - 如何在 system() 函数中包含变量文件名以调用 Windows 命令
- python - 数据框的箱线图未正确绘制
- c# - ServiceStack 会话时间增加
- go - 如何使用对象而不是字节发送新请求?
- javascript - Javascript:HTML5 Canvas 和带有 getElementById 的 id 循环
- twitter-bootstrap-3 - 带有 Bootsrap 问题的 Cakephp 3 分页器模板与 sort()