片段着色器无法编译

时间:2015-07-23 01:33:59

标签: java opengl compilation glsl lwjgl

我正在尝试让本教程中的着色器工作: https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/discard.php

我将源代码复制到两个文件中,但都不会编译。

这是我的代码:

    shaderProgram = glCreateProgram();
    vertexShader  = glCreateShader(GL_VERTEX_SHADER);
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    StringBuilder vertexShaderSource   = new StringBuilder();
    StringBuilder fragmentShaderSource = new StringBuilder();

    try{
        BufferedReader reader = new BufferedReader(new FileReader("src/shader.vert"));
        String line;
        line = reader.readLine();

        while(line != null){
            line = reader.readLine();

            if(line != null){
                vertexShaderSource.append(line).append('\n');
            }
        }
        reader.close();


    } catch (IOException e) {
        System.err.println("Vertex no load.");
        Display.destroy();
        System.exit(1);
    }

    try{
        BufferedReader reader = new BufferedReader(new FileReader("src/shader.frag"));
        String line;
        line = reader.readLine();

        while(line != null){
            line = reader.readLine();

            if(line != null){
                fragmentShaderSource.append(line).append('\n');
            }
        }
        reader.close();


    } catch (IOException e) {
        System.err.println("Frag no load.");
        Display.destroy();
        System.exit(1);
    }
    System.out.println(fragmentShaderSource);


    glShaderSource(vertexShader, vertexShaderSource);
    glCompileShader(vertexShader);
    if(glGetShader(vertexShader, GL_COMPILE_STATUS) == GL_FALSE){
        System.err.println("Vertex no compile");
    }
    glShaderSource(fragmentShader, fragmentShaderSource);
    glCompileShader(fragmentShader);
    if(glGetShader(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE){
        System.err.println("frag no compile");
    }


    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glValidateProgram(shaderProgram);

我之前有着色器工作,所以它不是设置(我知道)但是当我复制并粘贴时,两个文件都不会再编译。

我的设置是否有问题?

编辑>>>

我似乎无法导入glGetShaderiv

我正在使用LWJGL并从那里导入所有内容。我可以错过JAR文件吗?

编辑>>>

相关问题:

I get error "Exception in thread "main" org.lwjgl.opengl.OpenGLException: Invalid operation (1282)", what it is?, how I can fix it?

1 个答案:

答案 0 :(得分:3)

您正在错误地阅读源文件。

line = reader.readLine();

while(line != null){
    line = reader.readLine();

    if(line != null){
        fragmentShaderSource.append(line).append('\n');
    }
}

在这里,您首先阅读该文件的第一行。如果它不为null,则继续读取行并将它们附加到缓冲区。但是,您实际上并未在循环之外的readLine()语句之后追加该行,这意味着它将被丢弃,并且着色器编译器将获取缺少第一行的源文件。因此,它不知道varying vec2 vTexCoord;sampler2D myTexture;,在代码中稍后使用时会引发编译错误。

有几种方法可以解决这个问题:

  1. line = reader.readLine();
    if (line != null) {
        fragmentShaderSource.append(line).append('\n');
    }
    
    while (line != null) {
        // ...
    }
    
  2. while (true) {
        line = reader.readLine();
    
        if (line == null) {
            break;
        }
    
        fragmentShaderSource.append(line).append('\n');
    }
    
  3. while ((line = reader.readLine()) != null) {
        fragmentShaderSource.append(line).append('\n');
    }
    
  4. 使用哪一个取决于您的偏好。 1包含冗余代码,这几乎不是最佳解决方案。 2是读取任意文件的常用方式;虽然3更短,但有些人不喜欢在循环控制语句中分配变量。