glGetProgramBinary导致GL_INVALID_OPERATION

时间:2014-12-13 06:27:31

标签: glsl opengl-4

我正在尝试从已经有效编译和链接的程序中检索二进制文件。我用GL_PROGRAM_BINARY_LENGTH收到了它的长度。文档说明有两个实例可以发生GL_INVALID_OPERATION - 一个失败的链接和bufSize小于程序的大小。我已经读过,有些人在链接之前未能提供GL_PROGRAM_BINARY_RETRIEVABLE_HINT时遇到了这个错误,对我来说情况并非如此。我也验证了该程序,确定...并验证了GL_ARB_get_program_binary是否受支持。

我们连接了一个glDebugMessageCallbackARB,它为一些额外的信息提供了这个:“生成了GL_INVALID_OPERATION错误。对象不是程序或着色器对象。”我通过在错误消息中搜索额外的位找不到任何内容。

OGL版本4.2,glsl 1.5。这是在带有最新驱动程序的nVidia GeForce GTX 660上。 Windows 7。

以下是相关代码:

GLuint compileShaderBlock(GLenum type, const char* shaderCode, const int shaderSize) 
{
    GLuint shaderId = 0;

    if (shaderCode != NULL)
    {
        shaderId= glCreateShader(type);
        glShaderSource(shaderId, 1, &shaderCode, &shaderSize);
        glCompileShader(shaderId);
    }

    return shaderId;
};

static GLchar errBuff[4096];
bool validateShader(GLuint shaderID)
{
    GLint compiled;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compiled);

    GLsizei length = 0;

    glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &length);

    char* buffer = new char[length];

    if (!compiled && length > 0)
    {
        GLsizei outputlen;    
        glGetShaderInfoLog(shaderID, length, &outputlen, buffer);
        GLsizei size = 0;
        glGetShaderSource(shaderID, 4096, &size, errBuff);
    }

    assert(compiled == GL_TRUE, "Shader compile error: \n%s", buffer);
    delete[] buffer;

    return compiled == GL_TRUE;
}

bool validateLink(GLuint programID)
{
    GLint linkResult = GL_TRUE;
    glGetProgramiv(programID, GL_LINK_STATUS, &linkResult);

    if (linkResult == GL_FALSE)
    {
        GLsizei outputlen, length = 0;
        glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &length);

        char* buffer = new char[length];
        glGetProgramInfoLog(programID, length, &outputlen, buffer);

        assert(linkResult == GL_TRUE, "Program %d link error %s", programID, buffer);
        delete[] buffer;
        return GL_FALSE;
    }

    return GL_TRUE;
}

....

shader->vertexShaderId = compileShaderBlock(GL_VERTEX_SHADER, vsDataString.ToChar(), vsDataString.Length());
shader->fragmentShaderId = compileShaderBlock(GL_FRAGMENT_SHADER, fsDataString.ToChar(), fsDataString.Length());

validateShader(shader->vertexShaderId, "");
validateShader(shader->fragmentShaderId, "");

shader->programId = glCreateProgram();
glAttachShader(shader->programId, shader->vertexShaderId);
glAttachShader(shader->programId, shader->fragmentShaderId);

//Care about outputs
glBindFragDataLocation(shader->programId, 0, "outColor0");
glBindFragDataLocation(shader->programId, 1, "outColor1");
glBindFragDataLocation(shader->programId, 2, "outColor2");
glBindFragDataLocation(shader->programId, 3, "outColor3");

// let it know we plan on retrieving a binary
glProgramParameteri(shader->programId, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);

glLinkProgram(shader->programId);

... set attributes and uniforms (removing this doesn't change anything)
... do mock render (removing this doesn't change anything)

validateLink(shader->programId);

glValidateProgram((shader->programID);
GLint validateStatus;
glGetProgramiv((shader->programID, GL_VALIDATE_STATUS, &validateStatus);

glUseProgram(shader->programId);

GLint len = 0;
glGetProgramiv(shader->programId, GL_PROGRAM_BINARY_LENGTH, &len);

if (len > 0)
{
    uint8* binary = new uint8[len];
    GLenum binaryFormat;
    **ERROR** --> glGetProgramBinary(shader->programId, len, NULL, &binaryFormat, binary);
}

我觉得这没有任何意义,有什么我想念的吗?

1 个答案:

答案 0 :(得分:0)

所以这是一个非常愚蠢的复制/粘贴错误,但是对于未来的某个人来说它很可能有用......

glGetProgramBinary设置为另一个gl函数...