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

前端之家收集整理的这篇文章主要介绍了c – OpenGL glLinkProgram返回false但信息日志为空;检查一切前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我必须承认这是我第一次实现着色器,以前我只使用过固定功能管道;但是,尽管我确信我所做的一切都是正确的 – 但一定有错误.

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

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

我很难过,请有人帮忙!我已经失去了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,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);
}

片段着色器:

void main()
{
    gl_FragColor = vec4(1.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,errorLog);
    Log::error(std::string() + "error linking program: " + errorLog);
    return NULL;
}

success = GL_FALSE;
glValidateProgram(program);
glGetProgramiv(program,GL_VALIDATE_STATUS,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”)读取时,问题消失了,文件被完全读取.我确实尝试了几个替代实现,并且它们在链接期间都产生了相同的错误(并且我在读取文件之后立即将着色器源打印到控制台以确保它看起来正确,它确实如此.).

解决方法

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

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

我经历了几次驱动程序重新安装,强烈的调试和配置研究,我不得不推测并绝对猜测一切!太可怕了,不希望我的最坏的敌人.很抱歉打扰所有人,但如果有另外一个像我这样的哑巴***,欢迎你:)

猜你在找的C&C++相关文章