Построить typedef без жесткого кодирования

Есть этот typedef для openGL

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.

Мне было интересно, почему построение моих данных, как показано ниже, не работает и каков будет правильный способ сделать это.

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 не рисует

3 ответа

Решение

Поскольку автор вопроса разместил ссылку на используемый исходный код в комментарии к вопросу Сами Кухмонена, проблема может быть идентифицирована в этой части:

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

Вы не можете обменять Vertex Vertices[8] от Vertex* Vertices и ожидать, что это все еще работает. Массивы и указатели - это не одно и то же в C/C++. sizeof в массиве вернет размер всего массива в байтах (в этом случае 8*sizeof(Vertex), в то время как sizeof on указатель возвращает размер указателя (так обычно 4 или 8 на необычной платформе). Таким образом, вы в настоящее время загружаете только первые 1 или 2 числа с плавающей точкой в ​​буфер.

Во-первых, не используйте sizeof(int) чтобы получить размер указателя. Используйте соответствующий тип, в этом случае sizeof(Vertex*),

Но главная проблема в распределении памяти. У вас нет массива указателей, у вас есть массив. Таким образом, вы должны распределить память на основе этого. Если вы хотите восемь вершин и предполагая, что у вас есть Vertex* Vertices, затем

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

Это выделяет достаточно памяти для хранения их в одном блоке.

Публикация в качестве ответа на все замечательные отзывы Сами и Дерхаса, код работает для меня, когда я делаю следующее "не жесткое кодирование" точек вершин или цветов с самого начала (так что позже я могу поместить это в куб класс, который принимает позицию и цвет в качестве входных данных для моего конструктора)

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);
}
Другие вопросы по тегам