简体   繁体   English

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

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

Basic Description of Problem问题基本描述

I don't seem to be able to draw a triangle in any color other than white.我似乎无法用白色以外的任何颜色绘制三角形。

Here is my fragment shader code.这是我的片段着色器代码。

#version 330 core
out vec3 color;

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

For the sake of clarity, I have not included any other code.为了清楚起见,我没有包含任何其他代码。 My vertex shader works - I can see a white triangle on the screen.我的顶点着色器工作正常 - 我可以在屏幕上看到一个白色三角形。

I am new to the programmable pipeline way of using OpenGL.我是使用 OpenGL 的可编程管道方式的新手。

More Details and main.cpp Code更多细节和 main.cpp 代码

It has been suggested that the fault may be that my program falls back to the fixed pipeline way of doing things, so here is my main.cpp code which perhaps contains the problem rather than the shader code.有人建议错误可能是我的程序回退到固定的管道做事方式,所以这里是我的 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;
}

Compilation Information编译信息

Here is some info on the compilation process if relevant:如果相关,以下是有关编译过程的一些信息:

I am compiling within codeblocks, and linking with -lGL -lGLU -lGLEW -lglut .我正在代码块内编译,并与-lGL -lGLU -lGLEW -lglut Optimization level is -O3 .优化级别为-O3 --std=c++11 . --std=c++11

Replacement LoadShaders() function, which was not complete.替换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;

}

Essentially the important changes are that the shaders were not linked before.本质上,重要的变化是着色器之前没有链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM