OpenGL绘图三角形只有白色

时间:2018-01-01 15:54:59

标签: c++ opengl

我尝试用这两个教程学习OpenGL: https://learnopengl.com/#!Getting-started/Hello-Trianglehttps://www.youtube.com/playlist?list=PLEETnX-uPtBXT9T-hD0Bj31DSnwio-ywh

当我绘制一个简单的三角形时,它只是白色。但代码似乎是正确的。 这是碎片Shader:

#version 330 core

out vec4 fragColor;

void main()
{
    fragColor = vec4(0.5, 0.3, 0.1, 1.0);
}

这是ShaderProgram

ShaderProgram::ShaderProgram(std::string fileName)
{
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    if (vertexShader == 0)
        std::cerr << "VertexShader creation failed! " << std::endl;
    const char* vertexShaderSource = (SourceLoader(fileName + ".vs")).c_str();
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    CheckErrorMessages(vertexShader, GL_COMPILE_STATUS, false, "VertexShader Compilation failed! ");

    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    if (fragmentShader == 0)
        std::cerr << "FragmentShader Creation failed! " << std::endl;
    const char* fragmentShaderSource = (SourceLoader(fileName + ".fs")).c_str();
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    CheckErrorMessages(fragmentShader, GL_COMPILE_STATUS, false, "FragmentShader Compilation failed! ");

    program = glCreateProgram();
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
    glLinkProgram(program);
    CheckErrorMessages(program, GL_LINK_STATUS, true, "Program linking failed! ");
    glValidateProgram(program);
    CheckErrorMessages(program, GL_VALIDATE_STATUS, true, "Program validation failed! ");
}

我在ShaderProgram课程中有三种方法: 1.一种加载着色器代码的方法,该方法绝对有效 2.检查错误消息的方法,也是有效的。
3.以及仅使用bind()

glUseProgram(program) Funktion

我还有一个窗口类,由SDL创建

Display::Display(std::string title, unsigned int width, unsigned int height)
{
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    m_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
    m_glcontext = SDL_GL_CreateContext(m_window);

    GLenum status = glewInit();
    if (status != GLEW_OK)
        std::cerr << "GLEW failed to initialize!" << std::endl;

    isClosed = false;
}

Display类有一个更新和清除的方法:

void Display::Update()
{
    SDL_GL_SwapWindow(m_window);

    SDL_Event e;
    while (SDL_PollEvent(&e))
    {
        if (e.type == SDL_QUIT)
            isClosed = true;
    }
}

void Display::Clear(float red, float green, float blue, float alpha)
{
    glClearColor(red, green, blue, alpha);
    glClear(GL_COLOR_BUFFER_BIT);
}

我还有一个名为Mesh的班级来管理VAO和VBO等:

Mesh::Mesh(Vertex* vertices, unsigned int numVertices)
{
    drawCount = numVertices;

    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), (void*)0);
    glEnableVertexAttribArray(0);

}

Mesh有一个Funktion来绘制给定的顶点:

void Mesh::Draw()
{
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, drawCount);
    glBindVertexArray(0);
}

main Funktion由while循环组成:

int main(int argc, char* argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    Display display("Fenster", 1024, 840);

    ShaderProgram shader("./res/Shader");

    Vertex vertices[] = { Vertex(glm::vec3(1, 1, 0)), Vertex(glm::vec3(1, -1, 0)), Vertex(glm::vec3(-1, -1, 0)) };

    Mesh mesh(vertices, 3);

    while (!display.getIsClosed())
    {
        display.Clear(1.0f, 0.0f, 1.0f, 1.0f);
        shader.Bind();
        mesh.Draw();
        display.Update();
    }

    SDL_Quit();
    return 0;
}

问题是我没有得到任何错误,但三角形保持白色。 谢谢你的帮助!

编辑:顶点着色器在这里:

#version 330 core

layout (location = 0) in vec3 position;

void main()
{
    gl_Position = vec4(position.x, position.y, position.z, 1.0);
}

1 个答案:

答案 0 :(得分:1)

如果您检查infoLog,您会发现着色器没有编译。您将着色器源指针指定给在行尾被销毁的临时字符串,并且您正在向着色器编译器发送乱码:

LambdaExpression

SourceLoader返回一个临时字符串,并将fragmentShaderSource指针指定给该字符串。然后,当你将它传递给glShaderSource时,那里有垃圾数据。你可以这样做:

LambdaExpression

您还需要为片段着色器修复相同的问题。 你还画了一个顺时针绕组的三角形,这很好,但默认情况下,OpenGL认为逆时针绕组是正面的。

另一件事,你没有发现错误的原因是因为CheckErrorMessages没有做任何事情,你应该将infoLog写入字符串或其他东西。