配置VAO和VBO时,顶点数据数组是不是应该使用相同的方法? (OpenGL)[重复]

Posted

技术标签:

【中文标题】配置VAO和VBO时,顶点数据数组是不是应该使用相同的方法? (OpenGL)[重复]【英文标题】:When configuring VAOs and VBOs, should the vertex data array be in the same method? (OpenGL) [duplicate]配置VAO和VBO时,顶点数据数组是否应该使用相同的方法? (OpenGL)[重复] 【发布时间】:2018-09-26 07:45:03 【问题描述】:

我正在使用 VBO 和 VAO 使用 OpenGL 实现人体骨骼动画。不过,我发现了一些有趣的事情。首先,这是我的基本“骨骼”类

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++;
    
    ......
;

关注的方法是Bone::setVAO(float * vertexData)。然后我用下面的方法将顶点位置数据设置到Bone数组中。

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);

在我从main() 调用setVertexData() 之后,我在渲染循环中尝试了以下代码。

//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);

但是,没有在窗口上绘制任何内容。所以我稍微改了一下代码,这次我决定像这样配置setVertexData(Bone * bones)里面的VAO和VBO。

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);

如您所见,我只是简单地将顶点数据数组和VAO、VBO配置放在同一个方法上。但是,这一次是在屏幕上绘制的!我从未听说过顶点数据数组应该与 VAO、VBO 配置采用相同的方法。发生这种情况的原因是什么?

【问题讨论】:

【参考方案1】:

这是因为 sizeof 指针不会返回元素的数量,而是指针的大小(4 或 8 字节)。因此,您告诉 OpenGL 您的顶点数组有 4 或 8 个字节

【讨论】:

以上是关于配置VAO和VBO时,顶点数据数组是不是应该使用相同的方法? (OpenGL)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

初识OpenGL (-)VAO&VBO

初识OpenGL (-)VAO&VBO

初识OpenGL (-)VAO&VBO

我的OpenGL学习进阶之旅介绍 顶点数组对象VAO并实战一下

绑定到“顶点数组对象”后,我应该删除“顶点缓冲区对象”吗?

VAO 与 VBO 和 IBO 的手动绑定