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<char>
或 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着色器编译错误的主要内容,如果未能解决你的问题,请参考以下文章