c++ - OpenGL 没有渲染我的立方体

标签 c++ opengl

我最近通过 http://www.opengl-tutorial.org 上的教程开始学习 OpenGL .前几个教程很顺利,我在屏幕上看到了我的三角形。现在我继续学习多维数据集教程,但我遇到了以下问题。我只对三角形程序进行了 2 次重大更改来渲染我的立方体:

  • 我通过添加更多顶点将三角形变成了立方体
  • 我将所有初始化代码从我的主要函数移到了不同​​的其他函数中。

问题是,当我运行该程序时,它可以正常编译并显示深蓝色屏幕(我为清除屏幕设置的颜色),但它不会渲染我的立方体。

我的完整代码在这里:

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

最后请注意,如果我删除颜色属性并将整个立方体设置为红色,它仍然会显示相同的深蓝色屏幕。

最佳答案

代码中有几个问题:

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

更好的解决方案是在主循环之前移动 VAO 设置并且根本不调用 glDisableVertexAttribArray。指针永远不会改变,存储顶点属性设置正是 VAO 的用途。似乎教程在解释/使用它们方面不是很理想。

另一个问题是这一行:

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

应该生成 GL_INVALID_VALUE 错误,因为大小(第二个参数)只允许为 1、2、3 或 4。在您的情况下,triangleCount 等于 12。大小描述了元素的数量 每个的顶点都应该消耗。所以如果属性的类型是vec3,那么它应该是3。

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

另请注意,triangleCount 实际上并不包含三角形数,而是包含顶点数。

关于c++ - OpenGL 没有渲染我的立方体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48853400/

相关文章:

c++ - 内仿函数概念或接口(interface)

c++ - 从高度图计算纹理坐标

opengl - OpenGL的LookAt函数中的UP向量到底是什么?

c++ - dijkstra 实现给出了错误的输出

c++ - 找到给定整数的邻居之和

c++ - 具有库和意外文件类型的Xcode链接二进制文件

java - 使用纹理对象使用 JOGL 进行基本纹理绘制

c++ - 在 Ubuntu 12.10 下链接 w/Boost 序列化的未解析符号

python - 如何渲染同一列表中的多个多边形

opengl - 如何渲染由三角形组成的网格,其中每个三角形具有相同的颜色,而每个三角形不指定该颜色 3 次