如何构建这个OpenGL项目

时间:2014-01-24 06:28:37

标签: ios arrays xcode opengl-es

我正在开发一个OpenGL应用程序,它做了很多不同的事情,我已经在非图形方面完成了大部分代码,但是我无法弄清楚如何将它与OpenGL集成在XCode中。

我的申请有几个部分

首先,使用算法生成的顶点创建一个对象

我创建了一个自定义对象,它有一个自定义表面对象数组,每个对象都有自定义三角形对象(三角形应该让我很容易告诉OpenGL如何绘制该死的东西)。

其次,对OpenGL方法不能做的那个对象做一些事情

我说的是4D旋转和类似的东西,所以我有很多变化,我无法进入常规的GL变换矩阵。

第三,以某种方式将三角形赋予OpenGL

在此之前一切正常(我之前已经开始使用Java和2D顶点,所以这并不奇怪);下一步是我真的很困惑。我正在关注XCode OpenGL模板,他们定义了这样的顶点:

GLfloat gCubeVertexData[216] = 
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
    0.5f, -0.5f, -0.5f,        1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, -0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, -0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, -0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, -0.5f,          1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, 0.5f,         1.0f, 0.0f, 0.0f,

如果我可以避免法线,那很好,但是我更关心的是我不知道如何初始化这样的GLfloat数组然后改变它的值。也许我没有把这个问题弄清楚,我为此道歉,但我已经在这方面工作了好几个星期,我仍然没有想出一个很好的方法来解决这个问题。

1 个答案:

答案 0 :(得分:0)

首先讲述“初始化GLfloat数组”:一般来说,创建大量数据应该通过在内存中分配来完成。你可以简单地使用

GLfloat *array = malloc(sizeof(GLfloat)*numberOfFloats)

或目标C ++

new GLfloat[numberOfFloats]

在这两种情况下,您都需要通过调用free(array)delete [] array(C ++)来自行释放此内存。通过执行此操作,您可以重用相同的数据数组,您可以将其传递给其他对象,但我建议将其存储在某个objectiveC类中(array将在其标头中定义)。然后,您应该在对象初始化时分配内存,并在dealloc方法中释放它。这样做可以保留所有ARC功能。

要更进一步,您可以创建自己的Vertex结构,其中包含定义单个点所需的所有数据。例如:

struct Vertex {
    float x, y, z;
    Vector3f normal;
    Vector4f someOtherData;
};

然后在分配数组时使用sizeof(Vertex)new Vertex[]。您可以通过简单地调用array[index]来访问任何数组元素,并且您应该直接在阵列上执行所有CPU工作(除非它的大小需要更改,在这种情况下您应该将数据复制到新数组)。您可以随时更改Vertex的结构而不会破坏代码。这应该涵盖整个CPU问题。

对于openGL部分,建议您要绘制的每个数组都有自己的VBO(顶点缓冲区对象)。生成缓冲区后,您需要调用glBufferData来分配GPU上的内存;使用sizeof(Vertex)*numberOfVertices作为尺寸参数,如果您不想传输数据,可以使用NULL的数据参数;如果您的数据已经存在,请使用array阵列。要随时更新数据,您可以使用glBufferSubData直接覆盖部分缓冲区或glMapBufferRange,直接访问GPU数据。

至于绘图它几乎是相同的,除了你需要绑定缓冲区并设置正确的指针和步幅:

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));
glVertexAttribPointer(ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal));

请注意,因为您的顶点结构将拥有更多数据,然后openGL实际上需要您在GPU上消耗一些额外的内存。要删除它,您需要将顶点数组转换为仅包含与openGL相关的值的其他数据,但这些数据的内存消耗非常小。如果你的结构中有10个额外的GLfloat值,并且一次使用10000个顶点,它将使用大约400kB的额外内存。