【发布时间】:2012-06-21 12:58:59
【问题描述】:
问题在于,着色器(非常简单的,因为我正在学习 OpenGL)无法以看似随机的方式编译(并给出随机错误消息 * )。 然而,相同的着色器在大约 3 或 4 次尝试后编译。 代码如下:
Shader::Shader(GLenum Type,std::string filename)
{
shader_type = Type;
std::ifstream ifs(filename);
if(!ifs)
throw(std::runtime_error("File:"+filename+" not opened."));
std::ostringstream stream;
stream<<ifs.rdbuf();
const GLchar* data = stream.str().c_str();
handle = glCreateShader(shader_type);
glShaderSource(handle,1,static_cast<const GLchar**>(&data),0);
glCompileShader(handle);
int status;
glGetShaderiv(handle,GL_COMPILE_STATUS,&status);
if(status == GL_FALSE)
{
int loglength;
glGetShaderiv(handle,GL_INFO_LOG_LENGTH,&loglength);
auto data = new char[loglength];
glGetShaderInfoLog(handle,loglength,&loglength,data);
std::string strdata(data);
delete [] data;
throw(std::runtime_error(strdata));
}
}
请注意,着色器最后不会缺少换行符,在最后一个分号后有一个额外的空格,并且使用制表符而不是空格。 (正如互联网上各种旧帖子中所建议的那样!)。
- 这里是由同一个顶点着色器产生的两条错误消息,不是同时产生的:
#version 330
in vec2 Position;
uniform mat4 transform;
void main()
{
gl_Position = transform*vec4(Position,0.0f,1.0f);
}
错误:
0(1) : error C0000: syntax error, unexpected $undefined at token "<undefined>"
0(6) : error C0000: syntax error, unexpected '!', expecting ',' or ')' at token "!"
有时它确实有效! 是我的驱动程序有问题吗? (我在 Arch Linux 64 位上使用最近的 302.x 稳定版 nvidia 二进制驱动程序,并带有一张陈旧的 9600 GSO 卡)
P.S:只要着色器正确编译,代码就会按预期工作,所以我认为它应该是正确的。 如果无法从中找到问题并且有人想看一下,我很乐意将工作(有时!)示例作为 zip 文件发布。
【问题讨论】:
-
着色器编译器很可能看到垃圾字符。确保输入符合您的预期。
-
输入?就像在存储着色器的文本文件中一样?
-
不,你传入glShaderSource的实际数据。可能是因为在
const GLchar* data = stream.str().c_str();之后流被破坏了,您传递给它的数据是垃圾。 -
@Bart 是对的,您需要在提交到 glShaderSource(...) 时记录着色器源并生成错误消息(如果有)。
-
启动调试器。调用
glShaderSource时查看data的内容。大概率是垃圾。
标签: c++ opengl compiler-errors glsl shader