OpenGL并没有渲染我的立方体

OpenGL is not rendering my cube

本文关键字:我的 立方体 并没有 OpenGL      更新时间:2023-10-16

我最近开始使用http://www.opengl-tutorial.org上的教程学习OpenGl。最初的几个教程很好,我在屏幕上放了三角形。现在,我搬到了Cube教程,但是我遇到了以下问题。我只对三角计划进行了2个重大更改,以渲染我的立方体:

  • 我通过添加更多顶点将三角形更改为立方体
  • 我将所有初始化代码从我的主要功能移动到其他功能。

问题是,当我运行程序时,它会填充并显示深蓝色屏幕(我设置了清除屏幕的颜色(,但它不会渲染我的立方体。

我的完整代码在这里:

#include "common/shader/loadShader.h"
#include "common/logpp/log++.h"
#include <GLglew.h>
#include <GLglfw3.h>
#include <vector>
logpp::FileLog mainLog;
//Contains all functions for initializing OpenGL, GLEW and GLFW
namespace GLInit
{

    void SetGLFWWindowHints()
    {
        glfwWindowHint(GLFW_SAMPLES, 4);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); /*OpenGL 3.3*/
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
#ifdef __APPLE__
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    }
    void InitGLFW()
    {
        if (!glfwInit())
        {
            logpp::Console::error("Failed to initialize GLFW!");
            return;
        }

        SetGLFWWindowHints();
    }
    void InitGLEW()
    {
        glewExperimental = true; //Needed in core profile
        if (glewInit() != GLEW_OK)
        {
            logpp::Console::error("Failed to initialize GLEW!");
            return;
        }
    }
    GLuint CreateVAO()
    {
        GLuint VertexArrayID;
        glGenVertexArrays(1, &VertexArrayID);
        glBindVertexArray(VertexArrayID);
        return VertexArrayID;
    }
    GLFWwindow* CreateWin(int width, int height, char const* caption)
    {
        auto window = glfwCreateWindow(width, height, caption, nullptr, nullptr);
        if (window == nullptr)
        {
            std::string msg = "Failed to create window!";
            logpp::Console::error(msg);
            mainLog.write("[ERROR]: " + msg);
            glfwTerminate();
            return nullptr;
        }
        glfwMakeContextCurrent(window);
        return window;
    }
    GLFWwindow* Init(int width, int height, char const* caption)
    {
        InitGLFW();
        auto window = CreateWin(width, height, caption);
        InitGLEW();
        return window;
    }
}
using namespace GLInit;

int main()
{
    static const int VERTICES_IN_TRIANGLE = 3;

    PathConverter::setBase(R"(C:Usersmichi_000DesktopC++OpenGLA Colored Cubex64Debug)");
    try
    {
        mainLog.open(PathConverter::convert("logs\main.log"), false);
    }
    catch (logpp::FileLog::Exception e)
    {
        logpp::Console::error(e.what());
    }
    auto window = Init(800, 600, "A Colored Cube");
    auto VertexArrayID = CreateVAO();
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    static const std::vector<GLfloat> cube //Vertices for the cube
    {
        -1.0f,-1.0f,-1.0f, // triangle 1 : begin
        -1.0f,-1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f, // triangle 1 : end
        1.0f, 1.0f,-1.0f, // triangle 2 : begin
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f,-1.0f, // triangle 2 : end
        1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f,-1.0f,
        1.0f,-1.0f,-1.0f,
        1.0f, 1.0f,-1.0f,
        1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f,-1.0f,
        1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f, 1.0f,
        -1.0f,-1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f,-1.0f, 1.0f,
        1.0f,-1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f,-1.0f,-1.0f,
        1.0f, 1.0f,-1.0f,
        1.0f,-1.0f,-1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f,-1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 1.0f,-1.0f,
        -1.0f, 1.0f,-1.0f,
        1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f,-1.0f,
        -1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
        1.0f,-1.0f, 1.0f
    }; 
    static const std::vector<GLfloat> cube_colors
    {
        0.583f,  0.771f,  0.014f,
        0.609f,  0.115f,  0.436f,
        0.327f,  0.483f,  0.844f,
        0.822f,  0.569f,  0.201f,
        0.435f,  0.602f,  0.223f,
        0.310f,  0.747f,  0.185f,
        0.597f,  0.770f,  0.761f,
        0.559f,  0.436f,  0.730f,
        0.359f,  0.583f,  0.152f,
        0.483f,  0.596f,  0.789f,
        0.559f,  0.861f,  0.639f,
        0.195f,  0.548f,  0.859f,
        0.014f,  0.184f,  0.576f,
        0.771f,  0.328f,  0.970f,
        0.406f,  0.615f,  0.116f,
        0.676f,  0.977f,  0.133f,
        0.971f,  0.572f,  0.833f,
        0.140f,  0.616f,  0.489f,
        0.997f,  0.513f,  0.064f,
        0.945f,  0.719f,  0.592f,
        0.543f,  0.021f,  0.978f,
        0.279f,  0.317f,  0.505f,
        0.167f,  0.620f,  0.077f,
        0.347f,  0.857f,  0.137f,
        0.055f,  0.953f,  0.042f,
        0.714f,  0.505f,  0.345f,
        0.783f,  0.290f,  0.734f,
        0.722f,  0.645f,  0.174f,
        0.302f,  0.455f,  0.848f,
        0.225f,  0.587f,  0.040f,
        0.517f,  0.713f,  0.338f,
        0.053f,  0.959f,  0.120f,
        0.393f,  0.621f,  0.362f,
        0.673f,  0.211f,  0.457f,
        0.820f,  0.883f,  0.371f,
        0.982f,  0.099f,  0.879f
    };
/*  static const std::vector<GLfloat> cube
    {
        1.0, -1.0, 0.0,
        -1.0, -1.0, 0.0,
        0.0, 1.0, 0.0
    };*/
    static const std::vector<GLfloat>::size_type triangleCount = cube.size() / VERTICES_IN_TRIANGLE;
    GLuint programID = LoadShaders(PathConverter::convert("shaders\vertex.glsl").c_str(),
        PathConverter::convert("shaders\fragment.glsl").c_str());
    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, cube.size(), &cube, GL_STATIC_DRAW);
    GLuint colorbuffer;
    glGenBuffers(1, &colorbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
    glBufferData(GL_ARRAY_BUFFER, cube_colors.size(), &cube_colors, GL_STATIC_DRAW);
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
    do 
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUseProgram(programID);
        glEnableVertexAttribArray(0); //enable vertices
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glVertexAttribPointer(0, triangleCount, GL_FLOAT, GL_FALSE, 0, nullptr);
        glDisableVertexAttribArray(0);
        // 2nd attribute buffer : colors
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
        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
            nullptr                          // array buffer offset
        );
        glDisableVertexAttribArray(1);
        logpp::Console::debug("Drawing triangles");
        glDrawArrays(GL_TRIANGLES, 0, triangleCount);
//      glDisableVertexAttribArray(0);
        glfwSwapBuffers(window);
        glfwPollEvents();
    } while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS
            && !glfwWindowShouldClose(window));
    glfwTerminate();
    return 0;
}

最后一个说明,如果我删除颜色属性,然后将整个立方体设置为红色,它仍然给出相同的深蓝色屏幕。

代码中有几个问题:

绘制之前,您正在禁用所有顶点属性。glDisableVertexAttribArray的调用必须在glDrawArrays之后进行,否则在绘制时不会附加任何数据。

更好的解决方案是将VAO设置移到主环之前,而绝不会调用glDisableVertexAttribArray。指针永远不会改变,并且存储顶点属性设置正是VAO的目的。似乎该教程在解释/使用它们时非常优越。

另一个问题是该行:

glVertexAttribPointer(0, triangleCount, GL_FLOAT, GL_FALSE, 0, nullptr);

应生成GL_INVALID_VALUE错误,因为仅允许大小(第二个参数(为1、2、3或4。在您的情况下,trianglecount等于12.大小描述了多少元素每个 of of的每个元素顶点应消耗。因此,如果属性是Vec3类型的,则应为3。

您应始终检查glGetError是否在询问之前返回任何错误。这节省了很多时间,因为您已经知道哪个行有问题。

还要注意,三角形实际上不包含三角形计数,而是顶点的数量。

第一个问题是glBufferData的第二个参数是Bytes 中缓冲区的大小。进一步的operator &返回并非指向std::vector的数据。您必须使用std::vector::data()

GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,
   cube.size()*sizeof(GLfloat),
   cube.data(),
   GL_STATIC_DRAW);  
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER,
    cube_colors.size()*sizeof(GLfloat),
    cube_colors.data(),
    GL_STATIC_DRAW);

进一步的glDisableVertexAttribArray,禁用通用顶点属性数组。这必须在图纸之后完成。size参数 glVertexAttribPointer指定每个通用顶点属性的组件数,必须为1、2、3、4:

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);  
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glDrawArrays(GL_TRIANGLES, 0, triangleCount);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);