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

问题描述 投票:8回答:1

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

glLinkProgram(program) - 在查询GL_FALSE时返回GL_LINK_STATUS。此外,信息日志为空(当我查询日志长度 - 它是1,这是每个文档的空终止符,它检出)。所以链接器错误,没有日志。另外,我刚刚发现链接器问题一旦我在顶点着色器中使用gl_Position变量就会出现,无论是在赋值期间还是我用它进行计算。我尝试了各种各样的着色器变化,它出错但却无法生成日志 - 它似乎只是在触及GL_FALSE时返回gl_Position。有趣的是,片段着色器不会导致任何问题。

片段和顶点着色器都可以正常编译而没有错误。当我引入语法错误时,会检测,打印它们,并在程序创建之前中止该过程(因此它似乎工作正常)。我调试并确保文件正确加载,源为空终止,大小正确,我在附件后检查附加程序的数量,它是2(正确的大声笑)。为清楚起见,它被删除,我有checkForErrors()方法检查和打印opengl错误 - 没有检测到。

我很难过,请有人帮忙!我已经失去了2天的睡眠时间......

这是加载着色器的代码:

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] = '\0';

// 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;
}

通常它甚至没有达到验证程序的程度......我对此非常沮丧,很难不庸俗。

我们需要您的帮助,真诚地感谢您的帮助!

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

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

c++ opengl linker glsl shader
1个回答
15
投票

好吧,我知道当我发帖时这会让人感到尴尬,但是非常糟糕:通常伴随英特尔驱动程序的英特尔图形配置应用程序有3D设置选项卡;现在,未选中“自定义设置”复选框,但“顶点处理”设置下的灰色选项拼写为“启用软件处理”。即使它未经检查且一切都显示为灰色,我只需输入自定义设置并检查所有内容为“应用程序设置”。

修好了!一切都像它应该的链接!不知道是谁想到了那个选项,为什么会有用呢?!它是唯一看起来非常不合适的选择。

我经历了几次驱动程序重新安装,强烈的调试和配置研究,我不得不推测并绝对猜测一切!太可怕了,不希望我的最坏的敌人。

© www.soinside.com 2019 - 2024. All rights reserved.