0

试图在 raywenderlich.com 上修改这个OpenGL 和 GLKit 教程,我试图从波前 obj 文件渲染一个立方体,没有每个顶点的颜色信息和表面法线。但是被渲染的东西看起来一点也不像立方体。

为了解析一个 obj 文件,我有一个方法(createDrawable),它通过 obj 并将信息保存到一个结构(Drawable)中,该结构包含四件事:顶点缓冲区、索引缓冲区、对象中的面数和变换矩阵目的。(这里是文件、.m 文件.obj 文件。)

- (Drawable)createDrawable: (NSString *)objFileName {
    ......
    ......

    // Parsed obj and put info in vertexData and indices arrays.

    Drawable _drawable;

    _drawable.numFaces = numFaces;

    glGenBuffers(1, &_drawable.vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _drawable.vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData) * numFaces * 8, vertexData, GL_STATIC_DRAW);

    glGenBuffers(1, &_drawable.indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _drawable.indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices) * numFaces * 3, indices, GL_STATIC_DRAW);

    _drawable.matrix = GLKMatrix4Identity;
    _drawable.matrix = GLKMatrix4Translate(_drawable.matrix, 0.0f, 0.0f, 10.0f);

    return _drawable;
}

对于渲染,我使用另一种方法(renderDrawable)绑定对象的缓冲区,设置指向它们的指针,然后使用 glDrawElements(..) 进行渲染。

- (void) renderDrawable: (Drawable)object {
    glBindBuffer(GL_ARRAY_BUFFER, object.vertexBuffer);
    glEnableVertexAttribArray(GLKVertexAttribPosition);        
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) 0);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord1);
    glVertexAttribPointer(GLKVertexAttribTexCoord1, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) 3);
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) 5);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object.indexBuffer);
    glDrawElements(GL_LINES, sizeof(object.indexBuffer) * 3 * object.numFaces, GL_UNSIGNED_BYTE, (const GLvoid *) object.indexBuffer);
}

我认为我对缓冲区(此处显示的 createDrawable 的一部分和 .m 文件中的 renderDrawable 的一部分)做错了,但我就是不知道它是什么。

4

2 回答 2

1

我认为您的问题是您将 GL_LINES 传递给 glDrawElements() 而不是 GL_TRIANGLES。

于 2012-05-30T10:40:42.360 回答
1

我认为 glVertexArrayPointer 中的“步幅”参数应该设置为 8 * sizeof(float) 例如(单个顶点的大小)

glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (const GLvoid *) 5);

当步幅为 0 时 - 这意味着属性以连续的方式存储......但是您已经交错了属性,因此您必须向 OpenGL 提供更多信息。

另一个问题:什么是sizeof(vertexData) * numFaces * 8......我认为应该是:sizeof(vertexData) * numFaces * 3

对于索引缓冲区:sizeof(indices) * numFaces * 3-我认为应该是sizeof(int) * numFaces * 3

int - 索引类型,但你有 GL_BYTE (这意味着你只能有 256 个不同的索引!)

渲染时:glDrawArrays - 您已绑定索引缓冲区,因此将最后一个参数设置为 NULL

于 2012-05-30T10:45:37.170 回答