OpenGL阵列切换不起作用
问题描述:
我想用OpenGL编程一些游戏并阅读大量教程。不幸的是,我遇到了一个小问题,只是打断了我的进步。OpenGL阵列切换不起作用
我创建了一个“网格”类,我移交了一个数组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();
}
答
我移交GLfloats
号的数组,你不 ”切换“一系列任何事情。你通过了指针。指针和数组在C++中是不同的。最重要的是,阵列可以"decay" into pointers (that's what allows you to pass them to functions that take pointers), but when they do, all sizing information is lost。
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++核心指南support library class 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);
您是否尝试过动态分配数组?编译器最终可能会将数组置于范围之外,从而在获得绘制机会之前离开堆栈。只是一个猜测。 – Cedric