无需硬编码构造 typedef

construct typedef without hardcoding

有这个 openGL 的 typedef

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

该示例对有效的位置和颜色进行了硬编码:

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

我不想对我的颜色和位置进行硬编码,这样我就可以为我的 OpenGL 绘图数据创建一个带有构造函数的 class。

我想知道为什么按以下方式构建我的数据不起作用以及正确的方法是什么。

Vertices                = malloc(sizeof(Vertex)*8); //make 8 vertice pointers
Vertices[0].Position[0] = 1;    Vertices[0].Position[1] = -1; Vertices[0].Position[2] = 0;
Vertices[0].Color[0]    = 1;    Vertices[0].Color[1]    = 0;    Vertices[0].Color[2]    = 0; Vertices[0].Color[3]= 1;

Vertices[1].Position[0] = 1;    Vertices[1].Position[1] = 1;    Vertices[1].Position[2] = 0;
Vertices[1].Color[0]    = 1;    Vertices[1].Color[1]    = 0;    Vertices[1].Color[2]    = 0; Vertices[1].Color[3]= 1;

Vertices[2].Position[0] = -1; Vertices[2].Position[1] = 1;  Vertices[2].Position[2] = 0;
Vertices[2].Color[0]    = 0;    Vertices[2].Color[1]    = 1;    Vertices[2].Color[2]    = 0; Vertices[2].Color[3]= 1;

Vertices[3].Position[0] = -1; Vertices[3].Position[1] = -1; Vertices[3].Position[2] = 0;
Vertices[3].Color[0]    = 0;    Vertices[3].Color[1]    = 1;    Vertices[3].Color[2]    = 0; Vertices[3].Color[3]= 1;

Vertices[4].Position[0] = 1;    Vertices[4].Position[1] = -1; Vertices[4].Position[2] = -1;
Vertices[4].Color[0]    = 1;    Vertices[4].Color[1]    = 0;    Vertices[4].Color[2]    = 0;  Vertices[4].Color[3]= 1;

Vertices[5].Position[0] = 1;    Vertices[5].Position[1] = 1;    Vertices[5].Position[2] = -1;
Vertices[5].Color[0]    = 1;    Vertices[5].Color[1]    = 0;    Vertices[5].Color[2]    = 0;  Vertices[5].Color[3]= 1;

Vertices[6].Position[0] = -1; Vertices[6].Position[1] = 1;  Vertices[6].Position[2] = -1;
Vertices[6].Color[0]    = 0;    Vertices[6].Color[1]    = 1;    Vertices[6].Color[2]    = 0;  Vertices[6].Color[3]= 1;

Vertices[7].Position[0] = -1; Vertices[7].Position[1] = -1; Vertices[7].Position[2] = -1;
Vertices[7].Color[0]    = 0;    Vertices[7].Color[1]    = 1;    Vertices[7].Color[2]    = 0;  Vertices[7].Color[3]= 1;

尽管打印出的两个数据结构看起来与

相同
    NSLog(@"print it");
for(unsigned int i = 0; i < 8; i ++)
{
    printf("i: %f\t%f\t%f\t%f\t%f\t%f\t%f\n", Vertices[i].Position[0], Vertices[i].Position[1], Vertices[i].Position[2], Vertices[i].Color[0], Vertices[i].Color[1], Vertices[i].Color[2], Vertices[i].Color[3]);
}

我打开的 GL 立方体没有绘制

首先,不要使用sizeof(int)来获取指针的大小。使用适当的类型,在本例中为 sizeof(Vertex*).

但主要问题出在内存分配上。你没有指针数组,你有一个数组。所以你应该根据那个分配内存。如果你想要八个顶点并假设你有 Vertex* Vertices,那么

Vertices = malloc(sizeof(Vertex) * 8);

这分配了足够的内存来将它们存储在一个块中。

由于问题的作者在对Sami Kuhmonen的问题的评论中对使用中的源代码发布了一个link,问题可以确定到这部分:

glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

您不能将 Vertex Vertices[8] 换成 Vertex* Vertices 并期望它仍然有效。数组和指针在 C/C++ 中 不同。数组上的 sizeof 将 return 整个数组的大小(以字节为单位)(在这种情况下,8*sizeof(Vertex),而指针上的 sizeof returns 大小指针的数量(因此在不正常的平台上通常为 4 或 8)。因此您当前仅将前 1 或 2 个浮点数加载到缓冲区中。

作为对 Sami 和 Derhas 的所有重要反馈的回应,当我执行以下操作时,代码对我有用 'not hard-coding' 从一开始的顶点或颜色(这样我以后可以把这在一个立方体 class 内,它将位置和颜色作为我的构造函数的输入)

Vertex Vertices[8];

.....

Vertices[0].Position[0] = 1;    Vertices[0].Position[1] = -1; Vertices[0].Position[2] = 0;
Vertices[0].Color[0]    = 1;    Vertices[0].Color[1]    = 0;    Vertices[0].Color[2]    = 0; Vertices[0].Color[3]= 1;


Vertices[1].Position[0] = 1;    Vertices[1].Position[1] = 1;    Vertices[1].Position[2] = 0;
Vertices[1].Color[0]    = 1;    Vertices[1].Color[1]    = 0;    Vertices[1].Color[2]    = 0; Vertices[1].Color[3]= 1;

Vertices[2].Position[0] = -1; Vertices[2].Position[1] = 1;  Vertices[2].Position[2] = 0;
Vertices[2].Color[0]    = 0;    Vertices[2].Color[1]    = 1;    Vertices[2].Color[2]    = 0; Vertices[2].Color[3]= 1;

Vertices[3].Position[0] = -1; Vertices[3].Position[1] = -1; Vertices[3].Position[2] = 0;
Vertices[3].Color[0]    = 0;    Vertices[3].Color[1]    = 1;    Vertices[3].Color[2]    = 0; Vertices[3].Color[3]= 1;

Vertices[4].Position[0] = 1;    Vertices[4].Position[1] = -1; Vertices[4].Position[2] = -1;
Vertices[4].Color[0]    = 1;    Vertices[4].Color[1]    = 0;    Vertices[4].Color[2]    = 0;  Vertices[4].Color[3]= 1;

Vertices[5].Position[0] = 1;    Vertices[5].Position[1] = 1;    Vertices[5].Position[2] = -1;
Vertices[5].Color[0]    = 1;    Vertices[5].Color[1]    = 0;    Vertices[5].Color[2]    = 0;  Vertices[5].Color[3]= 1;

Vertices[6].Position[0] = -1; Vertices[6].Position[1] = 1;  Vertices[6].Position[2] = -1;
Vertices[6].Color[0]    = 0;    Vertices[6].Color[1]    = 1;    Vertices[6].Color[2]    = 0;  Vertices[6].Color[3]= 1;

Vertices[7].Position[0] = -1; Vertices[7].Position[1] = -1;     Vertices[7].Position[2] = -1;
Vertices[7].Color[0]    = 0;    Vertices[7].Color[1]    = 1;    Vertices[7].Color[2]    = 0;  Vertices[7].Color[3]= 1;


....

- (void)setupVBOs
{
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

//works with Vertices[]
//glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices)*8, Vertices, GL_STATIC_DRAW);

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