我正在尝试用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();
}
切换一个glfloat数组
不,你不能"移交"任何数组。您传递了一个指针。指针和数组在c++中是不同的东西。最重要的是,数组可以"衰减"为指针(这使得您可以将它们传递给接受指针的函数),但是当它们这样做时,所有的大小信息都会丢失。
sizeof(vertices)
为GLfloat*
的大小。十有八九是4或8。最确定的是不是函数调用方中数组的大小。
sizeof(vertices)
将是数组中字节数,而不是数组元素数。
处理这个问题的一种方法是通过c++ 11获得std::vector
而不是数组:
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);