我試圖從已經有效編譯和鏈接的程序檢索二進制文件。我收到了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);
}
我覺得這樣做沒有任何意義,是有什麼我失蹤???
這是一個長遠的,但規格。建議「使用」GLSL計劃。當然,你會認爲'glUseProgram(...)'就是這麼做的,但是從嵌入式實現的經驗來看,有時你必須使用GLSL程序進行一次繪製調用,以便執行某些實現稱爲「預熱」程序的操作。這似乎不太可能在桌面實施,但你永遠不知道... – 2014-12-13 22:47:54
感謝您的建議。不幸的是,我已經這麼做了,很難在發佈的代碼中看到,但是「......模擬渲染」就是發生的地方。 – 2014-12-14 02:24:28