OpenGL 片段着色器无法正常工作 - 无法绘制白色以外的任何颜色

OpenGL Fragment Shader not working correctly - Unable to draw any color other than white

问题的基本描述

我好像不会用白色以外的任何颜色画三角形。

这是我的片段着色器代码。

#version 330 core
out vec3 color;

void main()
{
    color = vec3(1.0, 0.0, 0.0);
}

为了清楚起见,我没有包含任何其他代码。我的顶点着色器有效 - 我可以在屏幕上看到一个白色三角形。

我不熟悉使用 OpenGL 的可编程流水线方式。

更多详细信息和main.cpp代码

有人建议故障可能是我的程序回退到固定管道做事的方式,所以这里是我的 main.cpp 代码,它可能包含问题而不是着色器代码。

#include <GL/glew.h>
#include <GL/glut.h>

#include <iostream>
#include <fstream>


GLuint LoadShaders(const char *vertex_shader_path, const char *fragment_shader_path)
{
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);

    std::ifstream vertex_shader_file;
    vertex_shader_file.open(vertex_shader_path, std::ios::in | std::ios::ate);
    if(vertex_shader_file.is_open())
    {
        unsigned long long vertex_shader_code_size = vertex_shader_file.tellg();
        char *vertex_shader_code = new char[vertex_shader_code_size];
        vertex_shader_file.seekg(0, std::ios::beg);
        vertex_shader_file.read(vertex_shader_code, vertex_shader_code_size);
        vertex_shader_file.close();

        GLint Result = GL_FALSE;
        int InfoLogLength;

        std::cout << "Compiling Vertex Shader: " << vertex_shader_path << std::endl;
        glShaderSource(VertexShaderID, 1, (const GLchar**)(&vertex_shader_code), (const GLint*)(&vertex_shader_code_size));
        glCompileShader(VertexShaderID);

        glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        char *VertexShaderErrorMessage = new char[InfoLogLength];
        glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]);
        std::cout.write(VertexShaderErrorMessage, InfoLogLength);
        std::cout.flush();

        delete [] VertexShaderErrorMessage;
        delete [] vertex_shader_code;

        std::cout << "Done" << std::endl;
    }
    else
    {
        std::cout << "Error: Could not open vertex shader source: " << vertex_shader_path << std::endl;
        exit(-1);
    }

    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    std::ifstream fragment_shader_file;
    fragment_shader_file.open(fragment_shader_path, std::ios::in | std::ios::ate);
    if(fragment_shader_file.is_open())
    {
        unsigned long long fragment_shader_code_size = fragment_shader_file.tellg();
        char *fragment_shader_code = new char[fragment_shader_code_size];
        fragment_shader_file.seekg(0, std::ios::beg);
        fragment_shader_file.read(fragment_shader_code, fragment_shader_code_size);
        fragment_shader_file.close();

        GLint Result = GL_FALSE;
        int InfoLogLength;

        std::cout << "Compiling Fragment Shader: " << fragment_shader_path << std::endl;
        glShaderSource(FragmentShaderID, 1, (const GLchar**)(&fragment_shader_code), (const GLint*)(&fragment_shader_code_size));
        glCompileShader(FragmentShaderID);

        glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        char *FragmentShaderErrorMessage = new char[InfoLogLength];
        glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]);
        std::cout.write(FragmentShaderErrorMessage, InfoLogLength);
        std::cout.flush();

        delete [] FragmentShaderErrorMessage;
        delete [] fragment_shader_code;

        std::cout << "Done" << std::endl;
    }
    else
    {
        std::cout << "Error: Could not open fragment shader source: " << fragment_shader_path << std::endl;
    }

}

GLuint vertexbuffer;

void display()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    gluLookAt(0.0, 0.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDisableVertexAttribArray(0);

    //glFlush();
    glutSwapBuffers();
}

void reshape(int width, int height)
{
    glViewport(0, 0, (GLint)width, (GLint)height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, (GLdouble)width/(GLdouble)height, 0.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
    if(key == 27)
    {
        exit(0);
    }
}

int main(int argc, char argv[])
{

    glutInit(&argc, &argv);

    glutInitDisplayMode(GLUT_DOUBLE);

    glutInitWindowSize(800, 600);
    glutCreateWindow("window");

    glewExperimental = true;
    glewInit();

    GLuint vertexarrayID;
    glGenVertexArrays(1, &vertexarrayID);
    glBindVertexArray(vertexarrayID);

    static const GLfloat gvertexbufferdata[] = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f};

    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(gvertexbufferdata), gvertexbufferdata, GL_STATIC_DRAW);


    glutKeyboardFunc(keyboard);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);


    GLuint programID = LoadShaders("vertexshader.glsl", "fragmentshader.glsl");

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(programID);

    glutMainLoop();

    return 0;
}

编译信息

如果相关,这里有一些关于编译过程的信息:

我在代码块内编译,并与 -lGL -lGLU -lGLEW -lglut 链接。优化级别为 -O3--std=c++11.

替换LoadShaders()功能,不完整。

GLuint LoadShaders(const char *vertex_shader_path, const char *fragment_shader_path)
{
    // Load and Compile Vertex Shader
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);

    std::ifstream vertex_shader_file;
    vertex_shader_file.open(vertex_shader_path, std::ios::in | std::ios::ate);
    if(vertex_shader_file.is_open())
    {
        unsigned long long vertex_shader_code_size = vertex_shader_file.tellg();
        char *vertex_shader_code = new char[vertex_shader_code_size];
        vertex_shader_file.seekg(0, std::ios::beg);
        vertex_shader_file.read(vertex_shader_code, vertex_shader_code_size);
        vertex_shader_file.close();

        GLint Result = GL_FALSE;
        int InfoLogLength;

        std::cout << "Compiling Vertex Shader: " << vertex_shader_path << std::endl;
        glShaderSource(VertexShaderID, 1, (const GLchar**)(&vertex_shader_code), (const GLint*)(&vertex_shader_code_size));
        glCompileShader(VertexShaderID);

        glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        char *VertexShaderErrorMessage = new char[InfoLogLength];
        glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]);
        std::cout.write(VertexShaderErrorMessage, InfoLogLength);
        std::cout.flush();

        delete [] VertexShaderErrorMessage;
        delete [] vertex_shader_code;

        std::cout << "Done" << std::endl;
    }
    else
    {
        std::cout << "Error: Could not open vertex shader source: " << vertex_shader_path << std::endl;
        exit(-1);
    }

    // Load and Compile Fragment Shader
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    std::ifstream fragment_shader_file;
    fragment_shader_file.open(fragment_shader_path, std::ios::in | std::ios::ate);
    if(fragment_shader_file.is_open())
    {
        unsigned long long fragment_shader_code_size = fragment_shader_file.tellg();
        char *fragment_shader_code = new char[fragment_shader_code_size];
        fragment_shader_file.seekg(0, std::ios::beg);
        fragment_shader_file.read(fragment_shader_code, fragment_shader_code_size);
        fragment_shader_file.close();

        GLint Result = GL_FALSE;
        int InfoLogLength;

        std::cout << "Compiling Fragment Shader: " << fragment_shader_path << std::endl;
        glShaderSource(FragmentShaderID, 1, (const GLchar**)(&fragment_shader_code), (const GLint*)(&fragment_shader_code_size));
        glCompileShader(FragmentShaderID);

        glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        char *FragmentShaderErrorMessage = new char[InfoLogLength];
        glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]);
        std::cout.write(FragmentShaderErrorMessage, InfoLogLength);
        std::cout.flush();

        delete [] FragmentShaderErrorMessage;
        delete [] fragment_shader_code;

        std::cout << "Done" << std::endl;
    }
    else
    {
        std::cout << "Error: Could not open fragment shader source: " << fragment_shader_path << std::endl;
    }

    // Link Shaders
    std::cout << "Linking Shaders" << std::endl;

    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID, VertexShaderID);
    glAttachShader(ProgramID, FragmentShaderID);
    glLinkProgram(ProgramID);

    GLint Result = GL_FALSE;
    int InfoLogLength;
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if(InfoLogLength == 0) InfoLogLength = 1;
    char *ProgramErrorMessage = new char[InfoLogLength];
    glGetProgramInfoLog(ProgramID, InfoLogLength, nullptr, ProgramErrorMessage);
    std::cout.write(ProgramErrorMessage, InfoLogLength);

    glDeleteShader(VertexShaderID);
    glDeleteShader(FragmentShaderID);

    return ProgramID;

}

本质上重要的变化是着色器之前没有链接。