簡體   English   中英

OpenGL沒有渲染我的立方體

[英]OpenGL is not rendering my cube

我最近開始使用http://www.opengl-tutorial.org上的教程學習OpenGL。 前幾個教程很順利,我在屏幕上顯示了三角形。 現在我轉到了立方體教程,但我遇到了以下問題。 我只對三角形程序進行了兩次大的更改來渲染我的立方體:

  • 我通過添加更多頂點將三角形更改為立方體
  • 我將所有初始化代碼從我的main函數移動到不同的其他函數中。

問題是,當我運行程序時,它編譯得很好,並向我顯示一個深藍色屏幕(我為清除屏幕設置的顏色),但它不會渲染我的立方體。

我的完整代碼在這里:

#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錯誤,因為size(第二個參數)只允許為1,2,3或4.在你的情況下,triangleCount等於12.大小描述了每個頂點應該消耗多少個元素。 因此,如果屬性是vec3類型,那么它應該是3。

在詢問SO之前,您應該始終檢查glGetError返回任何錯誤。 這節省了大量時間,因為您已經知道哪條線存在問題。

另請注意,triangleCount實際上並不包含三角形計數,而是包含頂點數。

第一個問題是glBufferData的第二個參數是緩沖區大小(以字節為單位) 進一步的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 ,禁用通用頂點屬性數組。 這必須在繪圖后完成。 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