【问题标题】:OpenGL rendering: All vertices move to bounds of unit sphereOpenGL渲染:所有顶点移动到单位球体的边界
【发布时间】:2019-05-28 03:52:30
【问题描述】:

我正在使用 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;
}

【问题讨论】:

    标签: c# opengl opentk opengl-4


    【解决方案1】:

    问题在于设置法线向量属性数组时。 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 导致顶点坐标规范被法线向量覆盖。法线向量为Unit vectors(长度== 1),如果将它们视为顶点坐标,则它们形成球形。

    【讨论】:

    • 非常感谢!我的两天研究结束了:D 现在我认为这个问题不值得出现在这个网站上。
    • @MarekMracna 不客气。也许这个问题是一个边界案例,跑题了。无论如何,球形效果令人困惑和有趣。
    • 球形真的很有趣。我正在使用着色器并将颜色设置为 vec4(正常,1.0)。它以某种方式显示颜色。我不知道为什么,如果法线在属性索引 0 中。
    猜你喜欢
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    相关资源
    最近更新 更多