【问题标题】:OpenGL - vertices/triangles not renderedOpenGL - 未渲染的顶点/三角形
【发布时间】:2019-01-28 12:20:19
【问题描述】:

所以我最近一直在尝试学习 OpenGL,学习了几个文本和视频教程。

我无法绘制三角形,我已经两次和三次检查我是否按照正确的顺序执行所有必要的步骤,但我显然遗漏了一些东西

在添加一些代码之前,我应该说明我使用的是 glfw、glad 和 ogl 4.6。

Main.cpp

//while debugging ive add extra unnecessary call to UseProgram and bindvertexarray every frame to be sure
static void Render(GLFWwindow* window)
{
    glfwMakeContextCurrent(window);
    gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
    glfwSwapInterval(1);
    glClearColor(.98f, .5f, .5f, 1);

    std::vector<Vertex> vertsTri = {
        {
            Vertex(0.0f,1.0f,0.0f,0,0,0,0,0)
        },
        {
            Vertex(-1.0f,-1.0f,0.0f,0,0,0,0,0)
        },
        {
            Vertex(1.0f,-1.0f,0.0f,0,0,0,0,0)
        }
    };
    Model tri(vertsTri, "basic");
    tri.UseProgram();
    glBindVertexArray(tri.getVAO());

    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);

        // rendering here
        tri.UseProgram();
        glBindVertexArray(tri.getVAO());
        glDrawArrays(GL_TRIANGLES, 0, tri.size());

        glfwSwapBuffers(window);
    }
}

int main()
{
    glfwSetErrorCallback(errorCallback);
    if (!glfwInit())
        exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "Title", nullptr, nullptr);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwSetFramebufferSizeCallback(window, windowResizeCallback);
    glfwSetKeyCallback(window, keyCallback);

    // Resource loading and creation in here


    std::thread renderThread(Render, window);

    while (!glfwWindowShouldClose(window))
    {
        // Realtime game mechanics here


        glfwPollEvents();
    }

    if (renderThread.joinable())
        renderThread.join();

    glfwDestroyWindow(window);

    glfwTerminate();
    return 0;
}

模型.cpp

//Gets called in the constructor with a Vertex vector, p_shader is created in Model constructor
void Model::Create()
{
    // Generate a vertex array object and bind it
    glGenVertexArrays(1, &p_vaoId);
    glBindVertexArray(p_vaoId);
    // Generate a vertex buffer object and bind it
    glGenBuffers(1, &p_vboId);
    glBindBuffer(GL_ARRAY_BUFFER, p_vboId);
    glBufferData(GL_ARRAY_BUFFER, p_vertices.size()*sizeof(Vertex), &(p_vertices[0]), GL_STATIC_DRAW);
    // Define attributes and enable them
    glEnableVertexArrayAttrib(p_vaoId, 0);
    glVertexAttribPointer(0, sizeof(Vertex::position) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::position), (void*)offsetof(Vertex, position));
    glEnableVertexArrayAttrib(p_vaoId, 1);
    glVertexAttribPointer(1, sizeof(Vertex::normal) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::normal), (void*)offsetof(Vertex, normal));
    glEnableVertexArrayAttrib(p_vaoId, 2);
    glVertexAttribPointer(2, sizeof(Vertex::uv) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::uv), (void*)offsetof(Vertex, uv));
}

着色器.cpp

// p_v/fShaderSource is set in LoadSource, while debugging ive made sure the source is gotten correctly
void Shader::Create()
{
    int errorResult = 0;

    // Load shader sources into memory before anything else
    LoadSource();

    // Creating shader objects
    p_vShaderId = glCreateShader(GL_VERTEX_SHADER);
    p_fShaderId = glCreateShader(GL_FRAGMENT_SHADER);

    // Compile the shaders
    Compile(p_vShaderId, p_vShaderSource);
    Compile(p_fShaderId, p_fShaderSource);

    // Create a program object
    p_programId = glCreateProgram();

    // Attach shaders to the program
    glAttachShader(p_programId, p_vShaderId);
    glAttachShader(p_programId, p_fShaderId);

    //Link the program and handle errors
    glLinkProgram(p_programId);
    glGetProgramiv(p_programId, GL_LINK_STATUS, &errorResult);
    if (!errorResult)
    {
        int length;
        glGetShaderiv(p_programId, GL_INFO_LOG_LENGTH, &length);
        char* log = new char[length];
        glGetProgramInfoLog(p_programId, length, &length, log);
        std::cout << "[Link Error] Failed to link program" << std::endl;
        std::cout << log << std::endl;
        delete log;
        glDeleteShader(p_vShaderId);
        glDeleteShader(p_fShaderId);
    }

    // Validate the program and handle errors
    glValidateProgram(p_programId);
    glGetProgramiv(p_programId, GL_VALIDATE_STATUS, &errorResult);
    if (!errorResult)
    {
        int length;
        glGetShaderiv(p_programId, GL_INFO_LOG_LENGTH, &length);
        char* log = new char[length];
        glGetProgramInfoLog(p_programId, length, &length, log);
        std::cout << "[Validate Error] Failed to validate program" << std::endl;
        std::cout << log << std::endl;
        delete log;
        glDeleteShader(p_vShaderId);
        glDeleteShader(p_fShaderId);
        glDeleteProgram(p_programId);
    }

    // Cleanup shaders after linking and validating
    glDetachShader(p_programId, p_vShaderId);
    glDetachShader(p_programId, p_fShaderId);
    glDeleteShader(p_vShaderId);
    glDeleteShader(p_fShaderId);
}

void Shader::Compile(unsigned int& shaderId, std::string source)
{
    int compileResult = 0;
    const char* csource = (const char*)source.c_str();
    glShaderSource(shaderId, 1, &csource, 0);
    glCompileShader(shaderId);
    glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compileResult);
    if (!compileResult)
    {
        int length;
        glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);
        char* log = new char[length];
        glGetShaderInfoLog(shaderId, length, &length, log);
        std::cout << "[Compile Error] Failed to compile shader - \"" + source + "\""<<  std::endl;
        std::cout << log << std::endl;
        delete log;
    }
}

basic.vert

#version 460 core

layout(location = 0) in vec3 position;
out vec4 fColor;

void main()
{
    gl_Position.xyz = position;
    gl_Position.w = 1.0;
    fColor = vec4(gl_Position.xyz, 1.0);
}

basic.frag

#version 460 core

in vec4 fColor;

layout(location = 0) out vec4 diffuseColor;

void main()
{
    diffuseColor = vec4(1,0,0,0);
}

我删除了一些不执行任何 ogl 调用的特定于类的代码, 如果这使诊断变得太难,我可以添加整个代码,因为它还不错。 我已经在片段着色器中尝试了多种样式的外颜色,但我尝试过的都没有奏效,尽管如此,如果您认为问题确实出在片段着色器中,请告诉我。

【问题讨论】:

  • 是的,为什么会有这样的问题?在发生任何事情之前,上下文被重置到渲染线程,据我了解,它可以在不同的线程上渲染(我在使用 ogl 的 sfml 中完成)
  • 我确实使上下文成为当前的,并且它确实用 glClear 清除了。我也刚刚修改它以在主线程上渲染,结果很遗憾是一样的。
  • 在 glVertexAttribPointer 参数中使用 sizeof 运算符看起来很奇怪。
  • 确实问题出在 vertexattrib 中,特别是步幅错误,应该是 sizeof(Vertex) 而不是 sizeof(Vertex::attrib) - 谢谢

标签: c++ opengl


【解决方案1】:

@datemwolf 指出: 问题在于传递给 glVertexAttribPointer 的 stride 参数

发件人:

glVertexAttribPointer(0, sizeof(Vertex::position) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::position), (void*)offsetof(Vertex, position));
glVertexAttribPointer(1, sizeof(Vertex::normal) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::normal), (void*)offsetof(Vertex, normal));
glVertexAttribPointer(2, sizeof(Vertex::uv) / sizeof(float), GL_FLOAT, false, sizeof(Vertex::uv), (void*)offsetof(Vertex, uv));

收件人:

glVertexAttribPointer(0, sizeof(Vertex::position) / sizeof(float), GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, position));
glVertexAttribPointer(1, sizeof(Vertex::normal) / sizeof(float), GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, normal));
glVertexAttribPointer(2, sizeof(Vertex::uv) / sizeof(float), GL_FLOAT, false, sizeof(Vertex), (void*)offsetof(Vertex, uv));

【讨论】:

    猜你喜欢
    • 2021-04-08
    • 1970-01-01
    • 2020-04-05
    • 2017-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多