I am trying to program some game with OpenGL and read a whole bunch of tutorials. Unfortunately I got a small problem who just interrupts my progress.
I created a "Mesh" class where I handover an array of GLfloats . These floats are included by an VAO and VBO. As long as I create the array inside the constructor (with the whole initialization-functions) it works fine. But if I want to handover the array as an argument OpenGL just won't draw. Did I forget something?
Here is my main code:
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();
}
I handover an array of GLfloats
No, you do not "handover" an array of anything. You passed a pointer . Pointers and arrays are different things in C++. Most importantly, arrays can "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)
is the size of a GLfloat*
. In all likelihood, that's either 4 or 8. It is most assuredly not the size of the array you had in the caller of the function.
The preferred method for handling this would be to pass the pointer and a size to that function. However, sizeof(vertices)
will be the number of bytes in the array, not the number of array elements.
One way to handle this would be to get a std::vector
rather than an array, through 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());
Alternately, you can calculate the size with some clever macros:
#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));
Or, if you want to use cleverer C++11 features:
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));
Or you can just skip the middle-man and employ the C++ Core Guidelines 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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.