Передача массива OpenGL не работает

Я пытаюсь запрограммировать какую-нибудь игру с помощью OpenGL и читаю целую кучу учебников. К сожалению, у меня возникла небольшая проблема, которая просто мешает моему прогрессу.

Я создал класс «Mesh», где я передаю массив GLfloats. Эти поплавки включены VAO и VBO.
Пока я создаю массив внутри конструктора (со всеми функциями инициализации), он работает нормально. Но если я захочу передать массив в качестве аргумента, OpenGL просто не будет рисовать. Я что-то забыл?

Вот мой основной код:

Mesh.cpp

Mesh::Mesh(GLfloat* vertices)
{
glGenVertexArrays(1, &m_vertexArray);
glBindVertexArray(m_vertexArray);

glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

glBindVertexArray(0);
}

Mesh::~Mesh()
{
glDeleteVertexArrays(1, &m_vertexArray);
}

void Mesh::draw()
{
glBindVertexArray(m_vertexArray);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}

main.cpp

[...]

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f,  0.5f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
-0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices);

while (!mainWindow->isClosed())
{
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

shaders->bind();

// here main functions:

mesh.draw();

mainWindow->update();
}

0

Решение

Я передаю массив GLfloats

Нет, вы не «передаете» массив чего-либо. Вы прошли указатель. Указатели и массивы — это разные вещи в C ++. Самое главное, массивы могут «распадаться» на указатели (это то, что позволяет передавать их функциям, которые принимают указатели), но при этом вся информация о размерах теряется.

sizeof(vertices) это размер GLfloat*, По всей вероятности, это либо 4, либо 8. Это наверняка не размер массива, который вы имели в вызывающей функции.

Предпочтительным методом для обработки этого было бы передать указатель и размер этой функции. Тем не мение, sizeof(vertices) будет количество байтов в массиве, а не количество элементов массива.

Одним из способов справиться с этим было бы получить std::vector а не массив, через C ++ 11:

std::vector<GLfloat> vertices = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f,  0.5f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
-0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices.data(), vertices.size());

Кроме того, вы можете рассчитать размер с некоторыми умными макросами:

#define ARRAY_COUNT(arr) ( sizeof(arr) / sizeof(arr[0]))

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f,  0.5f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
-0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices, ARRAY_COUNT(vertices));

Или, если вы хотите использовать более умные возможности C ++ 11:

template<typename T, size_t N>
constexpr size_t array_count(T (&arr)[N]) {return N;}

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f,  0.5f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
-0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices, array_count(vertices));

Или вы можете просто пропустить посредника и применить основные принципы C ++ поддержка библиотеки класса span:

Mesh::Mesh(gsl::span<GLfloat> vertices)
{
glGenVertexArrays(1, &m_vertexArray);
glBindVertexArray(m_vertexArray);

glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size_bytes(), vertices.data(), GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

glBindVertexArray(0);
}

GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f,  0.5f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
-0.5f,  0.0f, 0.0f
};

Mesh mesh(vertices);
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]