OpenGL片段着色器无法正常工作-无法绘制除白色以外的任何颜色 [英] OpenGL Fragment Shader not working correctly - Unable to draw any color other than white

查看:139
本文介绍了OpenGL片段着色器无法正常工作-无法绘制除白色以外的任何颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法用白色以外的任何颜色绘制三角形.

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.

我是使用OpenGL的可编程流水线方式的新手.

I am new to the programmable pipeline way of using OpenGL.

有人提出错误可能是我的程序退回到了固定的流水线处理方式,所以这是我的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.

#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:

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

I am compiling within codeblocks, and linking with -lGL -lGLU -lGLEW -lglut. Optimization level is -O3. --std=c++11.

推荐答案

替换LoadShaders()函数,该函数不完整.

Replacement LoadShaders() function, which was not complete.

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.

这篇关于OpenGL片段着色器无法正常工作-无法绘制除白色以外的任何颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆