Search code examples
c++openglvertex-array-object

My OpenGL Vertex Array no longer works when abstracted out into a class


I am using OpenGL to render some cubes and I have managed to get around 10 cubes rendering however I now want to abstract the code out into classes. I have started with the vertex array object.

I have looked through the code and followed it through to the shader making sure vertex data gets where it needs to.

#include "cube_vertex_array.h"

cube_vertex_array::cube_vertex_array(float* vertex_buffer, const std::string& texture_file)
{
    GLCall(glGenVertexArrays(1, &va_ID));
    GLCall(glBindVertexArray(va_ID));

GLCall(glGenBuffers(1, &vb_ID));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, vb_ID));
GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer), vertex_buffer, GL_STATIC_DRAW));
GLCall(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(0 * sizeof(float))));
GLCall(glEnableVertexAttribArray(0));
GLCall(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))));
GLCall(glEnableVertexAttribArray(1));

GLCall(glGenTextures(1, &texture));
GLCall(glBindTexture(GL_TEXTURE_2D, texture));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
int width, height, nrChanells;
stbi_set_flip_vertically_on_load(true);
unsigned char* data = stbi_load(texture_file.c_str(), &width, &height, &nrChanells, 0);
if (data)
{
    GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
    GLCall(glGenerateMipmap(GL_TEXTURE_2D));
}
else { std::cout << "failed to load texture" << std::endl; }
stbi_image_free(data);

GLCall(glBindVertexArray(0));
}

void cube_vertex_array::bind()
{
    GLCall(glBindVertexArray(va_ID));
}

Also, here is the part of main() that uses this class:

main()
{
cube_vertex_array cube_1(vertices, "resources/test.png");
cube_1.bind();
while (!glfwWindowShouldClose(window))
    {
    cube_1.bind();
    GLCall(glDrawArrays(GL_TRIANGLES, 0, 36));
    }
    GLCall(glDeleteVertexArrays(1, &cube_1.va_ID));                                                                             
GLCall(glDeleteBuffers(1, &cube_1.vb_ID));
}   

I expect to see multiple cubes rendering however this doesn't happen. If I implement the vertex array directly into the main file, the code renders cubes however it does not render anything when abstracted into a class. What could be the problem here?


Solution

  • The problem is that you "call" sizeof(vertex_buffer) on this line:

    GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer), vertex_buffer, GL_STATIC_DRAW));
    

    vertex_buffer is a pointer to the array so if you "call" sizeof on it you will get the size of a float* and not the number of elements in the array times sizeof(float).

    One way to solve this is passing the size of the array as a parameter. Another thing you could do is send in the amount of elements in the array and multiply it by sizeof(float).