简体   繁体   中英

OpenGL array handover do not work

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM