简体   繁体   English

OpenGL没有渲染我的立方体

[英]OpenGL is not rendering my cube

I have recently started learning OpenGL with the tutorial on http://www.opengl-tutorial.org . 我最近开始使用http://www.opengl-tutorial.org上的教程学习OpenGL。 The first few tutorials went fine, and I got my triangle on the screen. 前几个教程很顺利,我在屏幕上显示了三角形。 Now I moved on to the cube tutorial, but I got stuck on the following problem. 现在我转到了立方体教程,但我遇到了以下问题。 I only made 2 big changes to the triangle program to render my cube: 我只对三角形程序进行了两次大的更改来渲染我的立方体:

  • I changed the triangle to a cube by adding more vertices 我通过添加更多顶点将三角形更改为立方体
  • I moved all of the initializing code from my main function into different other functions. 我将所有初始化代码从我的main函数移动到不同的其他函数中。

The problem is that when I run the program, it compiles fine and shows me a dark blue screen (the color I had set for clearing the screen), but it doesn't render my cube. 问题是,当我运行程序时,它编译得很好,并向我显示一个深蓝色屏幕(我为清除屏幕设置的颜色),但它不会渲染我的立方体。

My full code is here: 我的完整代码在这里:

#include "common/shader/loadShader.h"
#include "common/logpp/log++.h"

#include <GL\glew.h>
#include <GL\glfw3.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:\Users\michi_000\Desktop\C++\OpenGL\A Colored Cube\x64\Debug\)");

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

One last note, if I remove the color attribute and just set the entire cube to be red, it still gives the same dark blue screen. 最后一点,如果我删除了颜色属性并将整个立方体设置为红色,它仍会提供相同的深蓝色屏幕。

There are several problems in the code: 代码中有几个问题:

You are disabling all vertex attributes before drawing. 您在绘制之前禁用所有顶点属性。 The calls to glDisableVertexAttribArray have to go after glDrawArrays , otherwise no data is attached when drawing. glDisableVertexAttribArray的调用必须在glDrawArrays之后,否则在绘制时不会附加任何数据。

The even better solution would be to move the VAO setup before the main-loop and never call glDisableVertexAttribArray at all. 更好的解决方案是在主循环之前移动VAO设置,从不调用glDisableVertexAttribArray The pointers never change anyway, and storing the vertex attribute setup is exactly what a VAO is made for. 无论如何,指针永远不会改变,存储顶点属性设置正是VAO的制作方式。 Seems that the tutorial is very suboptimal in explaining/using them. 似乎教程在解释/使用它们时非常不理想。

Another problem is that this line: 另一个问题是这一行:

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

should generate a GL_INVALID_VALUE error since the size (second parameter) is only allowed to be 1, 2, 3 or 4. In your case triangleCount equals 12. The size describes how many elements each of the vertices should consume. 应该生成GL_INVALID_VALUE错误,因为size(第二个参数)只允许为1,2,3或4.在你的情况下,triangleCount等于12.大小描述了每个顶点应该消耗多少个元素。 So if the attributes is of type vec3, then it should be 3. 因此,如果属性是vec3类型,那么它应该是3。

You should always check if glGetError returns any errors before asking on SO. 在询问SO之前,您应该始终检查glGetError返回任何错误。 That saves a lot of time because you already know which line is problematic. 这节省了大量时间,因为您已经知道哪条线存在问题。

Also note, that triangleCount does not actually contain the triangle count but the number of vertices. 另请注意,triangleCount实际上并不包含三角形计数,而是包含顶点数。

The first issue is that the 2nd paramter of glBufferData is the size of the buffer in bytes . 第一个问题是glBufferData的第二个参数是缓冲区大小(以字节为单位) Further operator & returns not a pointer to the data of a std::vector . 进一步的operator &返回不是指向std::vector数据的指针。 You have to use std::vector::data() : 你必须使用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);

Further glDisableVertexAttribArray , disables the generic vertex attribute array. 进一步的glDisableVertexAttribArray ,禁用通用顶点属性数组。 This has to be done after the drawing. 这必须在绘图后完成。 The size parameter of glVertexAttribPointer specifies the number of components per generic vertex attribute and must be 1, 2, 3, 4: glVertexAttribPointersize参数指定每个通用顶点属性的组件数,并且必须为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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM