为啥在 GLFW 窗口中使用此代码在我的屏幕上没有绘制立方体?

Posted

技术标签:

【中文标题】为啥在 GLFW 窗口中使用此代码在我的屏幕上没有绘制立方体?【英文标题】:How come no cube is drawn on my screen with this code in a GLFW window?为什么在 GLFW 窗口中使用此代码在我的屏幕上没有绘制立方体? 【发布时间】:2019-11-06 03:19:13 【问题描述】:

我有一堆代码(从各种教程中复制)应该绘制一个随机的变色立方体,相机每秒左右移动一次(带有一个变量,尚未使用计时器)。在我将我的代码移动到独特的类中并将其全部推入我的主函数之前,它过去是有效的,但现在我在主窗口上除了空白背景之外什么都看不到。我无法在此处查明任何特定问题,因为我没有收到任何错误或异常,并且我自己定义的代码已检出;当我调试时,每个变量都有一个我期望的值,并且在我重新组织我的代码之前,我使用的着色器(以字符串形式)在过去工作。我也可以在与glDrawArrays() 函数相同的范围内打印出立方体的顶点,并且它们也具有正确的值。基本上,我不知道我的代码有什么问题导致无法绘制。

我最好的猜测是,我在 Model 类的三种方法之一中调用了(或忘记调用)某些 opengl 函数,其中的数据错误。在我的程序中,我创建了一个Model 对象(在初始化glfw 和glad,然后调用Model 构造函数),通过update() 函数不时更新它(时间无关紧要),然后每次我的主循环通过draw() 函数运行时将其绘制到我的屏幕上。

代码错误的可能位置:

    Model::Model(std::vector<GLfloat> vertexBufferData, std::vector<GLfloat> colorBufferData) 

        mVertexBufferData = vertexBufferData;
        mColorBufferData = colorBufferData;

        // Generate 1 buffer, put the resulting identifier in vertexbuffer
        glGenBuffers(1, &VBO);
        // The following commands will talk about our 'vertexbuffer' buffer
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        // Give our vertices to OpenGL.
        glBufferData(GL_ARRAY_BUFFER, sizeof(mVertexBufferData), &mVertexBufferData.front(), GL_STATIC_DRAW);

        glGenBuffers(1, &CBO);
        glBindBuffer(GL_ARRAY_BUFFER, CBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(mColorBufferData), &mColorBufferData.front(), GL_STATIC_DRAW);

        // Create and compile our GLSL program from the shaders
        programID = loadShaders(zachos::DATA_DEF);
        glUseProgram(programID);
    

    void Model::update() 
        for (int v = 0; v < 12 * 3; v++) 
            mColorBufferData[3 * v + 0] = (float)std::rand() / RAND_MAX;
            mColorBufferData[3 * v + 1] = (float)std::rand() / RAND_MAX;
            mColorBufferData[3 * v + 2] = (float)std::rand() / RAND_MAX;
        
        glBufferData(GL_ARRAY_BUFFER, sizeof(mColorBufferData), &mColorBufferData.front(), GL_STATIC_DRAW);
    

    void Model::draw() 

        // Setup some 3D stuff
        glm::mat4 mvp = Mainframe::projection * Mainframe::view * model;

        GLuint MatrixID = glGetUniformLocation(programID, "MVP");
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);

        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glVertexAttribPointer(
            0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  // size
            GL_FLOAT,           // type
            GL_FALSE,           // normalized?
            0,                  // stride
            (void*)0            // array buffer offset
        );
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, CBO);
        glVertexAttribPointer(
            1,                                // attribute. No particular reason for 1, but must match the layout in the shader.
            3,                                // size
            GL_FLOAT,                         // type
            GL_FALSE,                         // normalized?
            0,                                // stride
            (void*)0                          // array buffer offset
        );

        // Draw the array
        glDrawArrays(GL_TRIANGLES, 0, mVertexBufferData.size() / 3);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
    ;

我的问题很简单,为什么我的程序不会在我的屏幕上绘制一个立方体?问题出在这三个功能之内还是其他地方?如果需要,我可以提供有关绘图过程的更多一般信息,但我相信我提供的代码就足够了,因为我实际上只是调用model.draw()

【问题讨论】:

【参考方案1】:

sizeof(std::vector) 通常只有 24 字节(因为结构通常包含 3 个指针)。所以基本上你的两个缓冲区都加载了 6 个浮点数,这对于单个三角形来说是不够的,更不用说立方体了!

在将数据加载到顶点缓冲区时,您应该在向量上调用 size()。

glBufferData(GL_ARRAY_BUFFER,
   mVertexBufferData.size() * sizeof(float), ///< this!
   mVertexBufferData.data(), ///< prefer calling data() here!
   GL_STATIC_DRAW);

【讨论】:

完美运行。事实证明,我也从未定义过 Modelmodel 矩阵,所以它以一种奇怪的方式显示。

以上是关于为啥在 GLFW 窗口中使用此代码在我的屏幕上没有绘制立方体?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在我的视图被推送到导航堆栈之前我的 UIAlertView 没有在屏幕上消失?

GLFW 窗口仅显示 Clear Color 而没有其他内容

在 Pyqt 窗口中使用 glfw 窗口

为啥片段着色器没有附加?

我的渲染技术进阶之旅glfw库简单介绍

我的渲染技术进阶之旅glfw库简单介绍