Тип vbo
равен float*
, поэтому sizeof(vbo)
- это не размер массива, на который указывает vbo
, а размер указателя. См. sizeof
.
Обратите внимание, что третий параметр glBufferData
должен быть размером буфера в байтах.
Размер float* vbo = new float[78]
равен 78 * sizeof(float)
или 78 * sizeof(*vbo)
и размер int *element = new int[36]
равен 36 * sizeof(int)
или 36 * sizeof(*element)
Но sizeof(vbo)
- это размер указателя на массив или такой же, как sizeof(float*)
.
Это означает, что вы должны изменить код следующим образом:
glBufferData(GL_ARRAY_BUFFER, 78*sizeof(float), vbo, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36*sizeof(int), element, GL_STATIC_DRAW);
2-й параметр glDrawElements
должен быть числом индексов, а 3-й параметр должен быть GL_UNSIGNED_BYTE
, GL_UNSIGNED_SHORT
или GL_UNSIGNED_INT
, в зависимости от типа данных индексы:
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, NULL);
Обратите внимание, что вы предпочитаете использовать unsigned int *
вместо int*
для типа данных массива индекса (element
).
Ваше предположение неверно. Вы не можете смешивать 24 координаты вершины, 18 нормальных векторов и 36 цветов с разными массивами индексов непосредственно в одном объекте массива вершин .
Атрибуты вершины для каждой позиции вершины образуют набор данных. Это означает, что вы должны создать кортежи координат вершины, вектора нормали и цвета.
Подробнее Рендеринг сеток с несколькими индексами
Я рекомендую использовать std::vector
и сделать это как-то так:
#include <vector>
// 8 vertex coordiantes: 8 * 3 float
std::vector<float> v{
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f };
// 6 normal vectors: 6 * 3 float
std::vector<float> nv{
-1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f,
0.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f };
// 12 colors coordiantes: 12 * 3 float
std::vector<float> c{
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f,
0.597f, 0.770f, 0.761f,
0.559f, 0.436f, 0.730f,
0.359f, 0.583f, 0.152f,
0.483f, 0.596f, 0.789f,
0.559f, 0.861f, 0.639f,
0.195f, 0.548f, 0.859f };
// 12 faces 3*2 indices/face: 12 * 3 * 2 unsigned int
std::vector<unsigned int> indices{
2, 1, 3, 1, 1, 1,
4, 2, 7, 2, 3, 2,
8, 3, 5, 3, 7, 3,
6, 4, 1, 4, 5, 4,
7, 5, 1, 5, 3, 5,
4, 6, 6, 6, 8, 6,
2, 1, 4, 1, 3, 1,
4, 2, 8, 2, 7, 2,
8, 3, 6, 3, 5, 3,
6, 4, 2, 4, 1, 4,
7, 5, 5, 5, 1, 5,
4, 6, 2, 6, 6, 6 };
Создать данные массива вершин
// final vertex attributes 12 * 3 *(3 + 3 + 3) floats
// x0 y0 z0 nvx0 nvy0 nvz0 cr0 cg0 cb0
// x1 y1 z1 nvx1 nvy1 nvz1 cr1 cg1 cb1
std::vector<float> va;
const unsigned int no_of_faces = 12;
for (unsigned int f=0; f<no_of_faces; ++f )
{
for (unsigned int t=0; t<3; ++t )
{
unsigned int vi = indices[(f*3+t)*2]-1; // vertex index
unsigned int ni = indices[(f*3+t)*2+1]-1; // normal vector index
unsigned int ci = f; // color index
va.insert(va.end(), v.begin() + vi*3, v.begin() + vi*3+3); // insert vertex coordinate
va.insert(va.end(), nv.begin() + ni*3, nv.begin() + ni*3+3); // insert normal vector
va.insert(va.end(), c.begin() + ci*3, c.begin() + ci*3+3); // insert color
}
}
Создание объекта буфера вершин :
GLuint vbo;
glGenBuffers( 1, &vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, va.size()*sizeof(*va.data()), va.data(), GL_STATIC_DRAW );
Определите массивы общих данных атрибутов вершин:
glVertexPointer( 3, GL_FLOAT, 9*sizeof(*va.data()), 0 );
glEnableClientState( GL_VERTEX_ARRAY );
glNormalPointer( GL_FLOAT, 9*sizeof(*va.data()), (void*)(3*sizeof(*va.data())) );
glEnableClientState( GL_NORMAL_ARRAY );
glColorPointer( 3, GL_FLOAT, 9*sizeof(*va.data()), (void*)(6*sizeof(*va.data())) );
glEnableClientState( GL_COLOR_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
Нарисуйте массив:
glDrawArrays( GL_TRIANGLES, 0, 36 );
Предварительный просмотр: