首页 > 解决方案 > GLFW 努力渲染 1000 个对象

问题描述

我正在开发一个使用 OpenGL、GLFW 和 GLSL 的项目。这是我的主要 while 循环的样子

    while (!glfwWindowShouldClose(window))
    {


        double fps = showFPS(window);
        std::cout << fps << std::endl;

        double xpos, ypos;
        glfwGetCursorPos(window, &xpos, &ypos);

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);


        glActiveTexture(GL_TEXTURE0);

        processInput(window);

        for (int x = -chunkSize.x/2; x < chunkSize.x/2; x++) {
            for (int y = -chunkSize.y / 2; y < chunkSize.y/2; y++) {
                Block b = blockBuffer[x+(int)chunkSize.x/2][y+(int)chunkSize.y/2];
                if (b.state != 0) {
                    if (b.state == containerTexture) {
                        container.use();
                    }
                    else if (b.state == wallTexture) {
                        wall.use();
                    }

                    glm::mat4 transform = glm::mat4(1.0f);
                    transform = glm::translate(transform,
                        glm::vec3(
                            x * blockSize.x - cameraPosition.x,
                            y * blockSize.y - cameraPosition.y,
                            0)
                    );

                    unsigned int transformLoc;

                    if (b.state == containerTexture) {
                        container.use();
                        transformLoc = glGetUniformLocation(container.getShader().ID, "transform");
                    }

                    else if (b.state == wallTexture) {
                        wall.use();
                        transformLoc = glGetUniformLocation(wall.getShader().ID, "transform");
                    }


                    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));


                    glBindVertexArray(block.VAO);
                    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
                }
                
            }
        }



        glm::mat4 transform = glm::mat4(1.0f);
        transform = glm::translate(transform,
            glm::vec3(
                0,
                0,
                0)
        );

        transform = glm::scale(transform, glm::vec3(1.0f, 2.0f, 1.0f));

        unsigned int transformLoc = glGetUniformLocation(playerTexture.getShader().ID, "transform");

        playerTexture.use();


        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));


        glBindVertexArray(block.VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);


        glfwSwapBuffers(window);
        glfwPollEvents();
    }

我知道我做错了什么,因为要渲染大约 1000 个对象,我得到了大约 3 FPS(我的 GPU 应该能够处理更多)。有谁知道为什么会发生这种情况?

如果您想了解有关我的代码的更多信息,请在评论中询问我,我可以分享您需要的部分,我只是不想让最初的帖子太长。

标签: c++openglglslglfw

解决方案


您发布的代码效率非常低,这里有一些关于您的循环的提示:

  • 永远不要查询统一的位置,查询着色器程序的创建并存储它们
  • 将纹理和缓冲区切换减少到绝对最低限度,对资源进行分类。另请注意,缓冲区保持绑定,无需在每次绘制调用之前重新绑定四边形缓冲区。
  • 很少分配内存,在循环之外分配,你不需要一个 4x4 矩阵来移动二维空间中的东西
  • 不要单独绘制每个四边形

推荐阅读