编译着色器和链接失败,但着色器的验证成功(Compiling a shader and linkin

2019-09-20 04:33发布

我搞糊涂了什么我的着色器在做什么。 我有一个着色器类包装了阴影OpenGL的部分我。 我建立我的代码::块应用程序并运行它,编译FASE失败,连接一阶段失败,但与验证GL_VALIDATE_STATUS成功,并且着色器实际工作。

当我运行它的代码块外IDE编译和链接阶段成功也是如此验证。 当在IDE中运行ProgramLog和信息日志是空的甚至没有警告,但在IDE外部运行时编译和链接成功当InfoLogs确实显示警告。

我真搞不清楚这一点,这是我的编译阶段:

GLuint handle = glCreateShader(a_Type);
glShaderSource(handle, 1, &a_Source, NULL); 
glCompileShader(handle); 

a_Type可以GL_VERTEX_SHADERGL_FRAGMENT_SHADERGL_GEOMETRY_SHADERa_Sourceconst char*从文件中加载我的着色器代码。

然后我去检查编译状态:

glGetShaderiv(handle, GL_COMPILE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{

这是一个逻辑检查和将GL_TRUE从终端运行,但是当GL_FALSE从IDE运行时。

链接检查如下:

glGetProgramiv(m_ProgramHandle, GL_LINK_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{

和验证

glValidateProgram(m_ProgramHandle); OGLCHECK
glGetProgramiv(m_ProgramHandle, GL_VALIDATE_STATUS, &success); OGLCHECK
if(success != GL_TRUE)
{

总结这一切,从withing IDE中的着色器编译和链接状态失败,但验证通过,并且着色的作品,但在信息日志是空的。 当从终端上运行的编译和链接状态的成功也是如此核查和着色器的工作原理。 而从终端中运行时,我也有一个充满信息日志,例如,警告。

:我做了一些调查,我的问题从这里来后,形成这个问题在Linux上GLSL着色器编译

这里的着色器类的源

#include "Shader.h"

Shader::Shader():m_FragmentHandle(0),m_GeometryHandle(0),m_VertexHandle(0),m_ProgramHandle(0),m_CurrentTexture(0)
{

}

Shader::~Shader()
{
    if(m_GeometryHandle != 0)
    {
        glDeleteShader(m_GeometryHandle);
        m_GeometryHandle = 0;
    }

    if(m_VertexHandle != 0)
    {
        glDeleteShader(m_VertexHandle);
        m_VertexHandle = 0;
    }

    if(m_FragmentHandle != 0)
    {
        glDeleteShader(m_FragmentHandle);
        m_FragmentHandle = 0;
    }
}

bool Shader::Load(const char* a_FileName)
{
    printf( "Loading shader: %s\n", a_FileName );

    char* shaderFile = new char[strlen(a_FileName) + 6]; //(char*)calloc(custom::strlen(a_FileName) + 6, sizeof(char));
    char* source = NULL;

    strcpy(shaderFile, a_FileName);
    strcat(shaderFile, ".geom");

    source = GetShaderSource(shaderFile);
    if(source != NULL)
    {
        printf( "Compiling geometry shader...\n" );
        m_GeometryHandle = Compile(GL_GEOMETRY_SHADER, source);

        free(source);
        source = 0;

        if(m_GeometryHandle == 0)
        {
            printf( "Geometry shader compiling failed.\n" );
            delete[] shaderFile;
            shaderFile = 0;

            return false;
        }
    }

    strcpy(shaderFile, a_FileName);
    strcat(shaderFile, ".vert");

    source = GetShaderSource(shaderFile);
    if(source != NULL)
    {
        printf( "Compiling vertex shader...\n" );
        m_VertexHandle = Compile(GL_VERTEX_SHADER, source);

        free(source);
        source = 0;

        if(m_VertexHandle == 0)
        {
            printf( "Vertex shader compiling failed.\n" );
            delete[] shaderFile;
            shaderFile = 0;

            return false;
        }
    }
    else
    {
        printf("No vertex shader found. A vertex and fragment shader are required!\n");
    }

    strcpy(shaderFile, a_FileName);
    strcat(shaderFile, ".frag");

    source = GetShaderSource(shaderFile);
    if(source != NULL)
    {
        printf( "Compiling fragment shader...\n" );
        m_FragmentHandle = Compile(GL_FRAGMENT_SHADER, source);

        free(source);
        source = 0;

        if(m_FragmentHandle == 0)
        {
            printf( "Fragment shader compiling failed.\n" );
            delete[] shaderFile;
            shaderFile = 0;

            return false;
        }
    }
    else
    {
        printf("No fragment shader found. A vertex and fragment shader are required!\n");
    }

    delete[] shaderFile;
    shaderFile = 0;

    CreateProgram();

    if(!Link())
    {
        printf( "Linking of shader \"%s\" failed!\n", a_FileName );
        return false;
    }

    printf( "Shader build succesfully!\n" );
    return true;
}

// WARNING: YOU NEED TO FREE THE RETURNED SOURCE YOURSELF!! free(buffer);
char* Shader::GetShaderSource(const char* a_FileName)
{
    FILE* f;
    f = fopen(a_FileName, "rb");

    if(f != NULL)
    {
        // Shader is available

        char* buffer;
        long size;

        fseek(f, 0L, SEEK_END);
        size = ftell(f);
        rewind(f);

        buffer = (char*)calloc(1, size+1);
        if(!buffer)
        {
            fclose(f);
            return NULL;
        }

        if(fread(buffer, size, 1, f) != 1)
        {
            fclose(f);
            return NULL;
        }

        fclose(f);
        return buffer;
    }

    return NULL;
}

GLuint Shader::Compile(const GLuint a_Type, const char* a_Source)
{
    if(a_Source == NULL)
        return 0;

    GLuint handle = glCreateShader(a_Type); OGLCHECK
    glShaderSource(handle, 1, &a_Source, NULL); OGLCHECK
    glCompileShader(handle); OGLCHECK

    int bufflen = 0;
    GLint success = GL_FALSE;

    glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &bufflen); OGLCHECK
    if(bufflen > 1)
    {
        GLchar* logString = new GLchar[bufflen + 1];
        glGetShaderInfoLog(handle, bufflen, 0, logString); OGLCHECK
        printf( "Shader compile output:\n%s\n", logString );

        delete logString;
        logString = 0;
    } else {
        glGetShaderiv(handle, GL_PROGRAM_LOG_LENGTH, &bufflen); OGLCHECK
    }

    glGetShaderiv(handle, GL_COMPILE_STATUS, &success); OGLCHECK
    if(success != GL_TRUE)
    {
        printf( "Failed to compile shader!\n" );

        glDeleteShader(handle); OGLCHECK
        //handle = 0;
    }

    return handle;
}

void Shader::CreateProgram()
{
    m_ProgramHandle = glCreateProgram(); OGLCHECK

    if(m_GeometryHandle != 0)
    {
        glAttachShader(m_ProgramHandle, m_GeometryHandle); OGLCHECK
        printf( "Attaching geometry shader...\n" );
    }
    if(m_VertexHandle != 0)
    {
        glAttachShader(m_ProgramHandle, m_VertexHandle); OGLCHECK
        printf( "Attaching vertex shader...\n" );
    }
    if(m_FragmentHandle != 0)
    {
        glAttachShader(m_ProgramHandle, m_FragmentHandle); OGLCHECK
        printf( "Attaching fragment shader...\n" );
    }
}

bool Shader::Link()
{
    glLinkProgram(m_ProgramHandle);

    GLint bufflen = 0;
    glGetProgramiv(m_ProgramHandle, GL_INFO_LOG_LENGTH, &bufflen); OGLCHECK
    if(bufflen > 1)
    {
        GLchar *logString = new GLchar[bufflen + 1];
        glGetProgramInfoLog(m_ProgramHandle, bufflen, 0, logString);

        printf( "Shader linking output:\n%s\n", logString );

        delete logString;
        logString = 0;
    }

    GLint success = GL_FALSE;
    glGetProgramiv(m_ProgramHandle, GL_LINK_STATUS, &success); OGLCHECK
    if(success != GL_TRUE)
    {
        printf( "Shader failed to link!\n" );
        return false;
    }

    glValidateProgram(m_ProgramHandle); OGLCHECK
    glGetProgramiv(m_ProgramHandle, GL_VALIDATE_STATUS, &success); OGLCHECK
    if(success != GL_TRUE)
    {
        printf( "Shader program was not validated.!\n" );
    }

    GLint activeCount = 0;
    GLint maxNameLength = 0;
    glGetProgramiv(m_ProgramHandle, GL_ACTIVE_UNIFORMS, &activeCount); OGLCHECK
    glGetProgramiv(m_ProgramHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); OGLCHECK

    GLchar* name = new GLchar[maxNameLength];
    GLsizei length = 100;
    GLenum type = GL_INVALID_ENUM;
    GLint size = 0;

    for(int i=0; i<activeCount; ++i)
    {
        glGetActiveUniform(m_ProgramHandle, i, maxNameLength, &length, &size, &type, name); OGLCHECK
        GLint handle = glGetUniformLocation(m_ProgramHandle, name); OGLCHECK

        m_Parameters.insert(ParameterPair(name, handle));
    }

    glGetProgramiv(m_ProgramHandle, GL_ACTIVE_ATTRIBUTES, &activeCount); OGLCHECK
    glGetProgramiv(m_ProgramHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); OGLCHECK

    delete name;
    name = new GLchar[maxNameLength];

    for(int i=0; i<activeCount; ++i)
    {
        glGetActiveAttrib(m_ProgramHandle, i, maxNameLength, &length, &size, &type, name); OGLCHECK
        GLint handle = glGetAttribLocation(m_ProgramHandle, name); OGLCHECK

        m_Attributes.insert(ParameterPair(name, handle));
    }

    delete name;
    name = 0;

    return true;
}

当我创建的着色器我做的:

Shader gShader;
gShader.load("data/shaders/myshader");

加载器加载数据/着色器/ myshader.frag数据/着色器/ myshader.vert等,您可以在装载功能看到这一点。

更新1:我发现eventhough着色器似乎从IDE工作,我不能绑定的属性的位置。但我可以在片段着色器改变颜色,这将显示。 从属性做工精细的终端,我试图绑定2个均匀地点2个纹理和做了一些混合,工作得很好。

文章来源: Compiling a shader and linking fail but verification of the shader succeeds