OpenGL GLSL expecting “::” at token “<int-const>” when adding clamp() to fragment shader
以下GLSL片段着色器可以按预期方式编译和运行:
1 2 3 4 5 6 7 8 9 10 11 | #version 330 core out vec3 color; in float U; in vec4 vertexNormal_worldSpace; uniform sampler1D TextureSampler; uniform vec4 LightPos; void main() { float cosT = dot(normalize(vertexNormal_worldSpace.xyz),normalize(LightPos.xyz)); color = cosT * texture(TextureSampler,U).rgb; } |
但是,当我更改第9行以将" cosT"的值限制在0到1之间时:
1 | float cosT = clamp(dot(normalize(vertexNormal_worldSpace.xyz),normalize(LightPos.xyz)),0.0,1.0); |
我得到了错误:
1 2 | 0(1) : error C0000: syntax error, unexpected integer constant, expecting"::" at token"<int-const>" 0(10) : error C7532: global function texture requires"#version 130" or later |
这似乎表示错误出现在第一行,但该处什么都没有改变。此外,第二个错误表明我正在使用的GLSL版本存在问题,但是由于错误消息指出,#version 330内核应该比#version 130更高。
编辑:
这是我在着色器中加载的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | static GLuint LoadShaders(const char* vertex_file_path, const char* frag_file_path){ GLuint VertID = glCreateShader(GL_VERTEX_SHADER); GLuint FragID = glCreateShader(GL_FRAGMENT_SHADER); char const* VertPointer = ReadShaderFile(vertex_file_path); char const* FragPointer = ReadShaderFile(frag_file_path); glShaderSource(VertID,1,&VertPointer,NULL); glCompileShader(VertID); GLint Result = GL_FALSE; int InfoLogLength; glGetShaderiv(VertID, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){ std::vector<char> VertexShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(VertID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); printf("%s\ ", &VertexShaderErrorMessage[0]); } glShaderSource(FragID,1,&FragPointer,NULL); glCompileShader(FragID); glGetShaderiv(FragID, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){ std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(FragID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); printf("%s\ ", &FragmentShaderErrorMessage[0]); } GLuint ProgramID = glCreateProgram(); glAttachShader(ProgramID,VertID); glAttachShader(ProgramID,FragID); glLinkProgram(ProgramID); glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){ std::vector<char> ProgramErrorMessage(InfoLogLength+1); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); printf("%s\ ", &ProgramErrorMessage[0]); } return ProgramID; } static char const* ReadShaderFile(const char* path){ std::string ShaderCode; std::ifstream ShaderStream(path,std::ios::in); if(ShaderStream.is_open()){ std::string line =""; while (std::getline(ShaderStream,line)){ ShaderCode +="\ "+line; } ShaderStream.close(); return ShaderCode.c_str(); }else{ return 0;} } |
这基本上是我所链接的教程的直接内容,唯一的变化是将文件读取放入ReadShaderFile函数中。
编辑2:
我的OpenGL上下文是使用以下版本创建的:
1 2 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3); |
问题确实是着色器加载器。您正在添加此语句
1 2 | ShaderCode +="\ "+line; |
换行符(\\\\
)在每行之前,与您的输入相比,所有内容都向下移动了一行。
由于version语句必须位于着色器的第一行中,而您将其移至第二行,因此驱动程序似乎忽略了该语句。例如,我的NVIDIA驱动程序指出:
1 | error C0204: version directive must be first statement and may not be repeated |
一个简单的解决方法是在每行之后而不是之前添加换行符,但是我强烈建议您不要逐行读取整个文件,因为这会给您带来糟糕的性能。例如,将为每行调整
编辑:
另一个问题是您正在返回局部变量的
解决方案:返回std :: string对象,而不是指向其内容的const char指针。