【问题标题】:Setting an Indices and Vertices array openGL ES设置索引和顶点数组 openGL ES
【发布时间】:2014-03-19 02:42:36
【问题描述】:

我正在为我的应用程序开发一个 .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);

我确实检查了两个数组是否都按照应有的方式初始化,并且确实如此。

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

// 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));

【问题讨论】:

    标签: ios iphone opengl-es indices


    【解决方案1】:

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

    - (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。不确定这是否是个问题,但似乎有可能。

    【讨论】:

    • 你在Faces 的大小上是对的,VerticesArr 的大小也是如此……现在我得到了图纸,但只有半个模型。有关于从哪里开始调试的提示吗?
    • 你是怎么解决这个问题的?您只是使用顶点数而不是 sizeof(VerticesArr) 吗?
    【解决方案2】:

    潜在问题:

    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 受益。

    【讨论】:

    • 非常感谢您的回答,tommy,您是否建议我应该为索引创建一个 GLuint 数组?意思是不使用Face3D 结构而只是一个接一个地添加它们? openGL 会知道如何分离 x、y、z 吗?我的意思是去 1,2,3 等等?
    • 顺便说一句,我刚刚检查过,确实是sizeof(struct Face3D) == sizeof(GLuint)*3,但现在我只画了一半的obj。这不容易处理!
    • 为了完全安全,您应该将结构化数据反序列化为原始数组以使 OpenGL 受益。只需为 glBufferData 编写自己的包装器,即 mallocs 是一个适当大小的数组,遍历结构以填充数组,然后通过 glBufferData 本身发布数组。
    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    相关资源
    最近更新 更多