Search code examples
openglvbovertexvertex-buffervao

When configuring VAOs and VBOs, should the vertex data array be in the same method? (OpenGL)


I was implementing human skeletal animation with OpenGL using VBOs and VAOs. However, I found something interesting. First of all, this is my basic 'bone' class

class Bone {
private:
    //Joint information compared to the parent Joint!
    int BoneID;
    glm::mat4 R;
    glm::mat4 T;
    //orientation of the bone
    glm::mat4 Orientation;
    Bone * childBone[MAX];
    int nChildren = 0;
    void recalculateOrientation() {
        Orientation = Orientation * R;
    }
public:
    unsigned int VAO, VBO;
    Bone(int BoneID, glm::mat4 R = glm::mat4(), glm::mat4 T = glm::mat4(), glm::mat4 Orientation = glm::mat4()) {
        //setup the matrices and orientation
        this->BoneID = BoneID;
        this->R = R;
        this->T = T;
        this->Orientation = Orientation;
    }
    void setVAO(float * vertexData) {
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glBindVertexArray(VAO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    }
    void setChild(Bone * child) {
        childBone[nChildren] = child;
        nChildren++;
    }
    ......
};

The method to focus on is Bone::setVAO(float * vertexData). Then I used the following method to set the vertex position data to the Bone arrays.

void setVertexData(Bone * Bones) {
    //Bones
    float pelvisVertices[] = {
        // Back face
        -0.5f, -0.2f, -0.2f, // Bottom-left
        0.5f,  0.2f, -0.2f, // top-right
        0.5f, -0.2f, -0.2f, // bottom-right         
        0.5f,  0.2f, -0.2f, // top-right
        -0.5f, -0.2f, -0.2f, // bottom-left
        -0.5f,  0.2f, -0.2f, // top-left
        ......
    }
    Bones[0].setVAO(pelvisVertices);
}

After I called setVertexData() from main(), I tried the following code in the render loop.

//For debugging
        glm::mat4 model;
        glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        glm::mat4 view = camera.GetViewMatrix();
        shader.setMat4("model", model);
        shader.setMat4("projection", projection);
        shader.setMat4("view", view);
        glBindVertexArray(Bones[0].returnVAO());
        glDrawArrays(GL_TRIANGLES, 0, 36);

However, nothing was drawn on the window. So I changed the code a little bit and this time, I just decided to configure the VAO and VBOs inside setVertexData(Bone * bones) like this.

void setVertexData(Bone * Bones) {
    //Bones
    float pelvisVertices[] = {
        // Back face
        -0.5f, -0.2f, -0.2f, // Bottom-left
        0.5f,  0.2f, -0.2f, // top-right
        0.5f, -0.2f, -0.2f, // bottom-right         
        0.5f,  0.2f, -0.2f, // top-right
        -0.5f, -0.2f, -0.2f, // bottom-left
        -0.5f,  0.2f, -0.2f, // top-left
        ......      
    };
    // Bones[0].setVAO(pelvisVertices);
    glGenVertexArrays(1, &Bones[0].VAO);
    glGenBuffers(1, &Bones[0].VBO);
    glBindVertexArray(Bones[0].VAO);
    glBindBuffer(GL_ARRAY_BUFFER, Bones[0].VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(pelvisVertices), pelvisVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
}

As you can see, I simply just put the vertex data array and VAO, VBO configuration on the same method. However, this time it was drawn on the screen! I never heard that vertex data arrays should be in the same method with VAO, VBO configurations. What is the reason this is happening?


Solution

  • That is because sizeof a pointer wont return the number of elements, but the size of a pointer (4 or 8 bytes). Thus, you are telling OpenGL your vertex array has 4 or 8 bytes