opengl 片段着色器编译并链接,但没有任何效果[已关闭]

66bbxpm5  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(138)

**已关闭。**此问题需要debugging details。当前不接受答案。

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
昨天关门了。
Improve this question
我刚开始学习OpenGL的时候,是按照https://learnopengl.com/Getting-started/Hello-Triangle来学习的,按照教程我根据自己的理解编写了代码,编译后确实给予了我一个输出,但不是橙色的三角形,而是一个白色的三角形。如果我用https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/2.1.hello_triangle/hello_triangle.cpp的代码替换shaderProgram(),它就可以工作了。(显示橙子三角形),所以我认为我把问题缩小到了着色器程序编译,我只是找不到它有什么问题,下面是我的代码。

// Local Headers
#include "glitter.hpp"

// System Headers
#include <glad/glad.h>
#include <GLFW/glfw3.h>

// Standard Headers
#include <cstdio>
#include <cstdlib>

#include <stdexcept>
#include <iostream>
#include <memory>

void _delete_shader(const GLuint *shader)
{
    if (!shader) return;
    glDeleteShader(*shader);
    delete shader;
}

using shader_t = std::unique_ptr<GLuint, decltype(&_delete_shader)>;

// window resize callback
void framebuffer_size_callback(GLFWwindow* , int width, int height)
{
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    {
        glfwSetWindowShouldClose(window, true);
    }
}

shader_t compileShader(const char *source, GLenum shaderType)
{
    auto shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, &source, nullptr);
    glCompileShader(shader);

    int success;
    char log[512];
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(shader, sizeof(log), nullptr, log);
        throw std::runtime_error(log);
    }

    return shader_t(new GLuint {shader}, &_delete_shader);
}

shader_t vertexshader() try
{
    static const char *source = R"(
        #version 330 core
        layout (location = 0) in vec3 aPos;
        void main()
        {
            gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
        }
    )";

    return compileShader(source, GL_VERTEX_SHADER);
}
catch(const std::exception& e)
{
    printf("error in vertex shader, %s\n", e.what());
    exit(-1);
}

shader_t fragmentShader() try
{
    static const char *source = R"(
        #version 330 core
        out vec4 FragColor;
        void main()
        {
            FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
        }
    )";

    return compileShader(source, GL_FRAGMENT_SHADER);
}
catch(const std::exception &e)
{
    printf("error in fragment shader, %s\n", e.what());
    exit(-1);
}

uint32_t shaderProgram() try
{
    uint32_t program = glCreateProgram();

    const auto vertexShader = ::vertexshader();
    glAttachShader(program, *vertexShader);

    const auto fragmentShader = ::fragmentShader();
    glAttachShader(program, *fragmentShader);

    glLinkProgram(program);

    int success;
    glGetProgramiv(program, GL_LINK_STATUS, &success);
    if (!success)
    {
        char log[512];
        glGetProgramInfoLog(program, 512, nullptr, log);
        throw std::runtime_error(log);
    }
}
catch(const std::exception &e)
{
    printf("error in shader program, %s\n", e.what());
    exit(-1);
}

int main(int , char * [])
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow *window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
    if (window == nullptr)
    {
        printf("Failed to create window\n");
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        puts("Failed to initialize GLAD\n");
        glfwTerminate();
        return -1;
    }

    glViewport(0, 0, 800, 600);

    float vertices[] =
    {
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        0.0f,  0.5f, 0.0f
    };

    const auto shaderProgram = ::shaderProgram();

    unsigned int VAO, VBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
    glBindVertexArray(VAO);

    // copy vertices into gpu memory
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // how data should be interpreted
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
    glEnableVertexAttribArray(0);

    // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
    glBindBuffer(GL_ARRAY_BUFFER, 0);

     // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
    glBindVertexArray(0);

    while (!glfwWindowShouldClose(window))
    {
        // inputs
        processInput(window);

        // paint color
        glClearColor(.2f, .3f, .3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // draw triangle
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // final rendering step
        glfwSwapBuffers(window);

        // check for events
        glfwPollEvents();
    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);

    glfwTerminate();
    return 0;
}
voj3qocg

voj3qocg1#

shaderProgram()从来没有return s任何东西,所以你的GL程序对象的名称只是丢失了,而你的shaderProgram局部变量只包含一些 undefined 值,因此你从来没有使用过那个程序。
请注意,几乎每一个像样的编译器都会发现这样的错误,只需启用(并阅读)警告...

相关问题