OpenGL glLinkProgram返回false,但信息日志为空;检查一切

OpenGL glLinkProgram returns false but info log is empty; checked everything

本文关键字:检查 日志 信息 返回 glLinkProgram false OpenGL      更新时间:2023-10-16

我必须承认这是我第一次实现着色器,以前我只使用固定的函数管道;然而,尽管我确信我所做的一切都是正确的,但肯定有一个错误。

glLinkProgram(program) -查询GL_LINK_STATUS时返回GL_FALSE。此外,info日志是空的(当我查询日志长度时-它是1,这是每个文档的空终止符,它检出)。链接器错误,没有日志。此外,我刚刚发现,只要我在顶点着色器中使用gl_Position变量,在分配期间和如果我使用它进行计算,链接器问题就会发生。我尝试了各种各样的着色器变化,它错误,但它无法产生日志-它似乎只是返回GL_FALSE任何时间gl_Position被触摸。有趣的是,片段着色器不会引起任何问题。

片段和顶点着色器编译良好,没有错误。当我引入语法错误时,它们会被检测、打印出来,并在程序创建之前终止该进程(因此它似乎工作得很好)。我调试并确保文件正确加载,源是null终止,大小是正确的,我检查了附件后附加程序的数量,它是2(正确的lol)。为了清晰起见,它被删除了,我有checkForErrors()方法来检查和打印opengl错误-没有检测到。

我被难住了,请人帮帮我!我已经为此失眠两天了…

这是加载着色器的代码:
FILE *file = fopen(fileName.c_str(), "rb");
if(file == NULL)
{
    Log::error("file does not exist: "" + fileName + """);
    return NULL;
}
// Calculate file size
fseek(file , 0 , SEEK_END);
int size = ftell(file);
rewind(file);
// If file size is 0
if(size == 0)
{
    Log::error("file is empty: "" + fileName + """);
    return NULL;
}
char **source = new char*[1];
source[0] = new char[size+1];
source[0][size] = '';
// If we weren't able to read the entire file into memory
int readSize = fread(source[0], sizeof(char), size, file);
if(size != readSize)
{
    int fileError = ferror(file);
    // Free the source, log an error and return false
    delete source[0];
    delete [] source;
    fclose(file);
    Log::error("couldn't load file into memory [ferror(" + toString<int>(fileError) + ")]: "" + fileName + "" (Size: " + toString<int>(readSize) + "/" + toString<int>(size) + " bytes)");
    return NULL;
}
// Close the file
fclose(file);


// Create the shader object

// shaderType is GLenum that is set based on the file extension. I assure you it is correctly set to either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
GLuint shaderID = glCreateShader(shaderType);
// If we could not create the shader object, check for OpenGL errors and return false
if(shaderID == 0)
{
    checkForErrors();
    Log::error("error creating shader "" + name);
    delete source[0];
    delete [] source;
    return NULL;
}
// Load shader source and compile it
glShaderSource(shaderID, 1, (const GLchar**)source, NULL);
glCompileShader(shaderID);
GLint success;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
if(!success)
{
    GLchar error[1024];
    glGetShaderInfoLog(shaderID, 1024, NULL, error);
    Log::error("error compiling shader "" + name + ""n    Log:n" + error);
    delete source[0];
    delete [] source;
    return NULL;
}
else
{
    Log::debug("success! Loaded shader "" + name + """);
}
// Clean up
delete source[0];
delete [] source;

快速注意:glShaderSource -我转换为(const GLchar**),因为GCC抱怨const到非const char指针;否则,我相信我是完全顺从的。

顺便说一下,这里没有错误。下面的着色器编译没有任何错误。

顶点着色器:

void main()
{
    // If I comment the line below, the link status is GL_TRUE.
    gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
}

片段着色器:

void main()
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

下面是创建着色器程序,附加对象和链接等的代码:

// Create a new shader program
GLuint program = glCreateProgram();
if(program == 0)
{
    Log::error("RenderSystem::loadShaderProgram() - could not create OpenGL shader program; This one is fatal, sorry.");
    getContext()->fatalErrorIn("RenderSystem::loadShaderProgram(shader1, shader2)", "OpenGL failed to create object using glCreateProgram()");
    return NULL;
}
// Attach shader objects to program
glAttachShader(program, vertexShaderID);
glAttachShader(program, fragmentShaderID);
// Link the program
GLint success = GL_FALSE;
glLinkProgram(program);
checkForErrors();
glGetProgramiv(program, GL_LINK_STATUS, &success);
if(success == GL_FALSE)
{
    GLchar errorLog[1024] = {0};
    glGetProgramInfoLog(program, 1024, NULL, errorLog);
    Log::error(std::string() + "error linking program: " + errorLog);
    return NULL;
}
success = GL_FALSE;
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &success);
if(success == GL_FALSE)
{
    GLchar errorLog[1024] = {0};
    glGetProgramInfoLog(program, 1024, NULL, errorLog);
    checkForErrors();
    Log::error(std::string() + "error validating shader program; Details: " + errorLog);
    return NULL;
}

通常它甚至不会验证程序…我对此感到很沮丧,很难做到不粗俗。

你的帮助是需要的,任何帮助都是真诚的感谢!

编辑:我在英特尔HD 3000上运行一切(支持OpenGL高达3.1)。我的目标OpenGL版本是2.0。

EDIT2:我还想指出,如果我在fopen中设置"r"或"rt"标志,我在从文本文件读取着色器时遇到了一些问题-读取大小比实际大小小约10字节(在所有文件上一致)-并且feof()将返回true。当我切换到二进制读取("rb")时,问题消失了,文件被完全读取。我确实尝试了几种替代实现,它们都在链接期间产生了相同的错误(并且我在读取文件后立即将着色器源打印到控制台以确保它看起来正确,它确实如此)。

好吧,我知道当我发布这将是尴尬的,但它是相当糟糕的:英特尔图形配置应用程序通常伴随英特尔驱动程序有3D设置选项卡;现在,"自定义设置"复选框被选中,但是在"顶点处理"设置下的灰色选项显示为"启用软件处理"。尽管它是未选中的,所有的东西都是灰色的,我只是进入自定义设置,把所有的东西都选中"应用程序设置"。

这就解决了!所有的链接都像它应该的那样!不知道是谁想出了这个主意,为什么它会有用?这是唯一一个看起来很不合适的选择。

我重新安装了几次驱动程序,进行了大量的调试和配置研究,我不得不对每件事都进行推测和猜测!太可怕了,我可不想让我最坏的敌人也这样。