关于C#:OpenGL GLSL在将clip()添加到片段着色器时,在标记” <int-const>”处期望” ::”

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

一个简单的解决方法是在每行之后而不是之前添加换行符,但是我强烈建议您不要逐行读取整个文件,因为这会给您带来糟糕的性能。例如,将为每行调整ShaderCode变量的大小,这意味着您将获得整个字符串的内存分配和复制操作。看一下有关如何读取完整文件的问题。

编辑:

另一个问题是您正在返回局部变量的c_str()指针。当ReadShaderFile方法结束时,std::string ShaderCode变量超出范围(因此释放其内容),并且返回的指针指向无效的内存地址。

解决方案:返回std :: string对象,而不是指向其内容的const char指针。