OpenGL着色器编译错误

Posted

技术标签:

【中文标题】OpenGL着色器编译错误【英文标题】:OpenGL Shader Compile Error 【发布时间】:2010-05-27 17:18:48 【问题描述】:

我的编译着色器代码有点问题,即它们都注册为失败的编译并且没有收到日志。

这是着色器编译代码:

/* Make the shader */

Uint size;
GLchar* file;

loadFileRaw(filePath, file, &size);

const char * pFile = file;
const GLint pSize = size;


newCashe.shader = glCreateShader(shaderType);
glShaderSource(newCashe.shader, 1, &pFile, &pSize); 
glCompileShader(newCashe.shader);

GLint shaderCompiled;

glGetShaderiv(newCashe.shader, GL_COMPILE_STATUS, &shaderCompiled);

if(shaderCompiled == GL_FALSE)

    ReportFiler->makeReport("ShaderCasher.cpp", "loadShader()", "Shader did not compile", "The shader " + filePath + " failed to compile, reporting the error - " + OpenGLServices::getShaderLog(newCashe.shader));


这些是支持功能:

bool loadFileRaw(string fileName, char* data, Uint* size)
    
    if (fileName != "") 
    
        FILE *file = fopen(fileName.c_str(), "rt");

        if (file != NULL) 
        
            fseek(file, 0, SEEK_END);
            *size = ftell(file);
            rewind(file);

            if (*size > 0) 
            
                data = (char*)malloc(sizeof(char) * (*size + 1));
                *size = fread(data, sizeof(char), *size, file);
                data[*size] = '\0';
            

            fclose(file);
        
    

    return data;


string OpenGLServices::getShaderLog(GLuint obj)

    int infologLength = 0;

    int charsWritten  = 0;
    char *infoLog;

    glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);

    if (infologLength > 0)
    
        infoLog = (char *)malloc(infologLength);
        glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);

        string log = infoLog;

        free(infoLog);

        return log;
    

    return "<Blank Log>";

以及我正在加载的着色器:

void main(void)

    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);


void main(void)

    gl_Position = ftransform();

总之我明白了

From: ShaderCasher.cpp, In: loadShader(), Subject: Shader did not compile
Message: The shader Data/Shaders/Standard/standard.vs failed to compile, reporting the error - <Blank Log>

对于我编译的每个着色器。

我尝试用硬编码字符串替换读取的文件,但我得到了同样的错误,所以我编译它们的方式一定有问题。我已经使用着色器运行并编译了示例程序,所以我怀疑我的驱动程序是问题所在,但无论如何我使用的是 Nvidia 8600m GT。

谁能帮忙?

【问题讨论】:

不是完全重复,但您可能会发现这个答案很有帮助:***.com/questions/2795044/… 你是free() - 在loadFileRaw() 之后的任何地方吗?除非我遗漏了什么,否则我会看到内存泄漏。 如果编译失败,我计划在某处缓存或显示着色器源代码,但我目前没有足够复杂的记录器以易于阅读的格式执行此操作。虽然我知道需要释放数据,但是一旦测试编译失败,你就把所有其他的东西扔到一边去寻找问题。 【参考方案1】:

loadFileRaw 中,您通过值传递char *data。然后你分配给它:

data = (char*)malloc(sizeof(char) * (*size + 1));

所以你的电话

loadFileRaw(filePath, file, &size);

不会改变file的值!要更改file,请通过指针传入:

loadFileRaw(filePath, &file, &size);

然后将您的功能更改为

bool loadFileRaw(string fileName, char** data, Uint* size)  ... 

在里面,

*data = (char*)malloc(sizeof(char) * (*size + 1));

等等。 (其余参考data)。

也就是说,既然您使用的是 C++,请考虑使用 std::vector&lt;char&gt;std::string 进行内存管理。为了让您开始,


   std::vector<char> data;
   data.resize(100); // now it has 100 entries, initialized to zero
   silly_C_function_that_takes_a_char_pointer_and_a_size(&data[0], 100); // OK
 // presto, memory freed

另外,您可以考虑使用std::ifstream 来读取文件,而不是使用FILE *

【讨论】:

我的原始函数使用了std::ifstream,但是一旦我遇到这个问题,我就复制了互联网上显示的那个。呃,现在我在 glShaderSource 上的访问权限很差 如果我让读取函数使用std::string,它是否不需要为ifstream函数使用字符? @Tomas,我没有关注你的第二个问题,但看起来你在使用指针时遇到了一些问题,所以你为什么不让着色器暂停片刻,仔细处理一些使用指针(包括但不仅限于 C 风格的字符串)的更简单示例,直到您感觉更舒服为止。 我将函数更改为使用字符串的函数,并且一切正常 - 感谢您的建议。我想说的一个评论是,由于 fstream 的函数都采用指向字符的指针来发送数据,以这种形式获取它然后将其转换为字符串,只是为了将其转换回 opengl 似乎有点多余。无论如何,我在某处使用 stringstream 和 reader->rdbuf() 的文章中找到了一种解决方法——这似乎是在浪费时间,但是嘿,它有效。为建议和所有人干杯【参考方案2】:

尝试:

glShaderSource(newCashe.shader, 1, &pFile, NULL);

这是加载着色器源最常用的调用。

【讨论】:

以上是关于OpenGL着色器编译错误的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL着色器版本编译错误

无法获得简单的 2D 着色器以在 C++ openGL 中绘制红色三角形(无编译器错误)

OpenGL 着色器无法编译

OpenGL着色器无法编译

OpenGL 着色器无法编译但没有给出错误信息

损坏的顶点和片段着色器