2014-12-13 98 views
1

我試圖從已經有效編譯和鏈接的程序檢索二進制文件。我收到了GL_PROGRAM_BINARY_LENGTH的長度。該文檔說有兩個GL_INVALID_OPERATION可能發生的實例 - 失敗的鏈接和bufSize小於程序的大小。我讀過一些在鏈接之前無法提供GL_PROGRAM_BINARY_RETRIEVABLE_HINT時出現此錯誤的情況,但這並不適用於我。我也驗證了該程序,以確定...並驗證GL_ARB_get_program_binary是否受支持。glGetProgramBinary導致GL_INVALID_OPERATION

我們連接了一個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); 
} 

我覺得這樣做沒有任何意義,是有什麼我失蹤???

+0

這是一個長遠的,但規格。建議「使用」GLSL計劃。當然,你會認爲'glUseProgram(...)'就是這麼做的,但是從嵌入式實現的經驗來看,有時你必須使用GLSL程序進行一次繪製調用,以便執行某些實現稱爲「預熱」程序的操作。這似乎不太可能在桌面實施,但你永遠不知道... – 2014-12-13 22:47:54

+0

感謝您的建議。不幸的是,我已經這麼做了,很難在發佈的代碼中看到,但是「......模擬渲染」就是發生的地方。 – 2014-12-14 02:24:28

回答

0

所以這是一個非常愚蠢的複製/粘貼錯誤,但有一個微小的機會,它可能是有人在將來有用...

glGetProgramBinary設置爲另一GL功能...