OpenGL正方形根本不渲染(如果我向着色器添加错误,则渲染为黑色)

pokxtpni  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(106)

我很难弄明白为什么我的Glew/GLFW应用程序不能呈现一个简单的正方形,所以我将其分解到一个文件中,试图找出缺少了什么。

下面的代码成功地打开了一个窗口,清除为我设置的关闭的绿色/蓝色,但没有渲染正方形。如果我在Frag着色器中添加了一个错误,它会在应该绘制正方形的地方将像素渲染为黑色(但令人惊讶的是,它没有导致程序崩溃)。

我没有收到从render_func()中的glGetError()调用返回的错误。

这是我正在运行的代码,除了着色器编译代码(我直接从另一个运行良好的项目中提取),以减少我共享的示例代码。


# ifndef GLEW_STATIC

# define GLEW_STATIC

# endif

# include "GL/glew.h"

# ifndef GLFW_INCLUDE_NONE

# define GLFW_INCLUDE_NONE

# endif

# include "GLFW/glfw3.h"

# ifndef GLM_FORCE_CTOR_INIT

# define GLM_FORCE_CTOR_INIT

# endif

# include "glm/glm.hpp"

# include <array>

# include <memory>

constexpr static std::array<glm::vec3, 4> vertices {{ {-0.5, -0.5, 0.0}, {-0.5, 0.5, 0.0}, {0.5, 0.5, 0.0}, {0.5, -0.5, 0.0} }};
constexpr static std::array<uint32_t , 6> indices {{  0, 1, 2,  2, 3, 0  }};

const std::string vertex_shader_source = R"(
    #version 460 core
    layout (location = 0) in vec3 attrib_pos;

    out vec3 frag_pos;

    void main()
    {
        frag_pos = attrib_pos;
    }
)";

const std::string fragment_shader_source = R"(
    #version 460 core

    in vec3 frag_pos;
    out vec4 o_frag_colour;

    void main()
    {
        o_frag_colour = vec4(1.0, 0.5, 0.0, 1.0);
    }
)";

GLFWwindow* init_window()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
    GLFWwindow* window = glfwCreateWindow(800, 600, "GLFW Window", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height){ glViewport(0, 0, width, height); });

    glfwSetErrorCallback([](int error, const char* description){
        std::cout << "nodget::App::init_glfw() - ERROR - " << std::to_string(error) << ":n" << description << std::endl;
        throw;
    });

    glewExperimental = GL_TRUE;
    glewInit();
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glFrontFace(GL_CW);
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);

    return window;
}

uint32_t init_vertex_array()
{
    using VERTEX_ELEMENT_TYPE = decltype(vertices)::value_type;
    using INDEX_ELEMENT_TYPE = decltype(indices)::value_type;

    uint32_t VAO, VBO, EBO;

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);

    std::cout << "vertices.size() * sizeof(Vertex) " << vertices.size() * sizeof(VERTEX_ELEMENT_TYPE) << std::endl;
    std::cout << "indices.size() * sizeof(uint32_t) " << indices.size() * sizeof(INDEX_ELEMENT_TYPE) << std::endl;

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(VERTEX_ELEMENT_TYPE), vertices.data(), GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(INDEX_ELEMENT_TYPE), indices.data(), GL_STATIC_DRAW);

    enum {
        VERTEX_POSITION_ATTRIB_INDEX = 0
    };

    glEnableVertexAttribArray(VERTEX_POSITION_ATTRIB_INDEX);
    glVertexAttribPointer(VERTEX_POSITION_ATTRIB_INDEX, 3, GL_FLOAT, false, sizeof(glm::vec3), (void*)0);

    glBindVertexArray(0);

    return VAO;
}

void render_func(GLFWwindow* window, uint32_t vao_id, uint32_t shader_id)
{
    auto error = glGetError();
    if (error != GL_NO_ERROR) {
        std::cout << "Pre Loop Error: " << error << std::endl;
    }

    while(true) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shader_id);

        glBindVertexArray(vao_id);
        glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr);
        glBindVertexArray(0);

        glfwSwapBuffers(window);
        glfwPollEvents();

        error = glGetError();
        if (error != GL_NO_ERROR) {
            std::cout << "Mid Loop Error: " << error << std::endl;
        }
    }
}

int main()
{
    auto window = init_window();
    auto vao_id = init_vertex_array();

    const std::shared_ptr<nodget::Shader> shader = std::make_shared<nodget::Shader>(std::move(vertex_shader_source), std::move(fragment_shader_source));
    shader->init_func();

    render_func(window, vao_id, shader->id);
}
w6lpcovy

w6lpcovy1#

必须将剪裁空间坐标写入gl_Positiongl_Position用于基元组装:


# version 460 core

layout (location = 0) in vec3 attrib_pos;

out vec3 frag_pos;

void main()
{
    frag_pos = attrib_pos;
    gl_Position = vec4(attrib_pos, 1.0);
}

相关问题