设置索引和顶点数组openGL ES

时间:2014-02-19 01:28:16

标签: ios iphone opengl-es indices

我正在为我的应用程序开发.obj加载器,为此,我设置了一个索引数组和一个顶点数组,并在运行时初始化它们。

这是结构的定义方式:

typedef struct {
    float Position[3];
    float Color[4];
    float TexCoord[2];
} Vertex;

typedef struct {
    GLuint  v1;
    GLuint  v2;
    GLuint  v3;
} Face3D;

这就是数组在.h文件中的方式:

Vertex* VerticesArr;
Face3D* Faces;

但是当我启动它们时,我在屏幕上看不到任何内容,而不是使用这种方式:

const Vertex Vertices[] = {
    {{1, -1, 0}, {1, 0, 0, 1},{0,0}},
    {{1, 1, 0}, {0, 1, 0, 1},{0,0}},
    {{-1, 1, 0}, {0, 0, 1, 1},{0,0}},
    {{-1, -1, 0}, {0, 0, 0, 1},{0,0}}
};

const GLubyte Indices[] = {
    0, 1, 2,
    2, 3, 0
};

通过使用这些const数组,我得到了屏幕上的绘图。

我的问题是,使用索引和顶点数组是否可行? 我相信它似乎是错误的。

这就是我在前面介绍的两种方式下设置VBO的方法:

- (void)setupVBOs {

    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(VerticesArr), VerticesArr, GL_STATIC_DRAW);

    GLuint indexBuffer;
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Faces), Faces, GL_STATIC_DRAW);

}

以及我使用绘图元素的方式:

glDrawElements(GL_POINTS, sizeof(Faces)/sizeof(Faces[0]), GL_UNSIGNED_INT, 0);

我确实检查了两个数组是否应该是init,而且确实如此。

这就是我为他们分配空间的方式:

// Allocate space for the Vertices array
NSLog(@"Size of vertice is: %lu",sizeof(Vertex));
VerticesArr = (Vertex*)(malloc(sizeof(Vertex) * vertexCombinations.count));
// Allocate space for the Faces
NSLog(@"Size of face is: %lu",sizeof(Face3D));
Faces = (Face3D*)(malloc(sizeof(Face3D)*faceCount));

2 个答案:

答案 0 :(得分:2)

我看到的第一个问题是代码的这一部分:

- (void)setupVBOs {

    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(VerticesArr), VerticesArr, GL_STATIC_DRAW);

    GLuint indexBuffer;
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Faces), Faces, GL_STATIC_DRAW);

}

创建常量数组时sizeof(Faces)将返回数组的大小,但是当您动态分配它们时,sizeof(Faces)将是指针的大小(通常为4个字节)。我看到的第二个问题是,在静态分配期间,您的隐私为GLUByte,但在Face3D中,它们为GLUInt。不确定这是否是一个问题,但似乎可能是。

答案 1 :(得分:1)

潜在问题:

1)C不保证结构的紧密包装。所以例如编译器可能会查看你的Face3D,发现它长12个字节,并决定将其填充到16个字节 - 每个结构在最后都有四个未使用的字节,因为这样做可能会使单个结构更快地读取。同样,它保留在结构中的各个项之间填充的权限。您使用的是原生大小的单位,因此填充不一定是可能的,但您的编译器保留添加它的权利,并依赖于紧密包装意味着依赖于未定义的行为。

2)sizeof(Faces)/sizeof(Faces[0]) - sizeof(struct Face3D)sizeof(GLuint)的数量非常不同,所以即使您的结构紧密包装,这也是两段代码之间的差异。

您可以在运行时检查sizeof(struct Face3D) == sizeof(GLuint)*3和等效测试。如果是这样,那么您可以将结构直接传递给glBufferData。如果没有那么你可能只是通过glVertexAttribPointer传递适当的步幅,具体取决于确切的填充,但更有可能你需要明确地序列化到非结构化数组以获得OpenGL的好处。