OpenGL 着色器编译问题 - 意外的 EOF

标签 opengl shader jogl

因此,我决定尝试使用 Java 编写一个简单的 OpenGL 应用程序,只是为了看看它与我的其他工作相比如何,但我遇到了一个问题,即我的着色器拒绝编译。它们确实简单得不能再简单了,这是我的顶点着色器来演示我的意思:

//Minimal vertex shader

#version 330

in vec3 in_Position;
in vec3 in_Color;
out vec3 var_Color;

void main(void)
{
    gl_Position = vec4(in_Position, 1.0);
    var_Color = in_Color;
}

片段着色器也很简单,所以除非有人要求,否则我不会费心发布它。当我检查日志时,我收到以下错误(对于两个着色器):

(0) : error C0000: syntax error, unexpected $end at token "<EOF>"

我不确定这是否相关...但我正在使用 Java 在 Linux (Ubuntu 11.04) 上进行开发。我使用的唯一库是 JOGL(用于 openGL 绑定(bind))和标准 Java 库(如果这也算的话……)我的显卡是 Nvidia GeForce 9600M GS,我检查了扩展,它完全支持OpenGL 3.3。

帮助我 Stack Overflow,你是我唯一的希望。

编辑:

根据要求,这里是负责加载和编译着色器源的函数。另外,当谈到 GLSL 时,我是一个 super 专家,所以我真的不知道要寻找什么来确保内容的格式适合 OpenGL。如果能提供有关该主题的最新教程(即处理 OpenGL 3.x)的链接,我们将不胜感激。

private int CreateCompiledShader(File source, int shader, GL3 gl){
        int shaderloc = gl.glCreateShader(shader);

        BufferedReader input = null;
        ArrayList<String> lines = new ArrayList<String>();
        ArrayList<Integer> lengths = new ArrayList<Integer>();
        try{
            input = new BufferedReader(new FileReader(source));
            String buffer;

            while(input.ready()){
                buffer = input.readLine();
                lines.add(buffer);
                lengths.add(buffer.length());
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(input != null){
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        int[] iLengths = new int[lengths.size()];
        for(int i = 0; i < lengths.size(); i++){
        iLengths[i] = lengths.get(i).intValue();
        }

        gl.glShaderSource(shaderloc, lines.size(), lines.toArray(new String[0]), iLengths, 0);
        gl.glCompileShader(shaderloc);

        int error = gl.glGetError();
        if(error != GL3.GL_NO_ERROR){
            Logger.log(new GLU().gluErrorString(error), Logger.ERROR, "Shader compilation");
        }

        return shaderloc;
    }

顺便说一句,我检查 glGetError() 的 if 语句实际上并不是捕获错误的地方,直到执行返回到调用函数并且我才发生这种情况检查着色器日志。可能是相关的,但话又说回来,我也可能是漫无目的的。

最佳答案

好的,现在我明白了问题所在。您的加载代码不起作用。但别担心;当很多人看到 glShaderSource 接受一个字符串数组时,他们会感到困惑。我猜您看到有人用 C/C++ 编写着色器,如下所示:

const char *myShader[] = {
    "#version 330\n",
    "\n",
    "in vec3 in_position;\n",
    ...
};

他们上传了着色器,glShaderSource(shader, ARRAY_COUNT(myShader), myShader, NULL, 0);

虽然这是合法的,但这并不是该功能的真正用途。因为GLSL没有#include机制,所以glShaderSource可以采用多个字符串。每个字符串都旨在成为一个着色器文件。然后,着色器编译器将字符串有效地连接在一起,就像编译前的 #include 所做的那样。

现在,因此,您可以将每一行作为一个单独的字符串。然而,回顾一下 C/C++ 代码。看看每一行的末尾是什么?那个“\n”字符。

这就是您正在加载的行末尾的内容。因为我非常确定 BufferedReader.readline 不会保留行尾字符。所以你的着色器看起来像:

//Minimal vertex shader#version 330in vec3 in_Position;in vec3 in_Color;out vec3 var_Color;...

您的整个着色器被视为一个大的单行注释。因此出现了意外的 EOF:OpenGL 从未看到任何可编译的内容;)

您不应该逐行读取文件。只需将整个内容加载到一个字符串中即可。然后将其传递给OpenGL。或者,您可以查看 this previous answer关于JOGL;它应该向您展示如何正确执行此操作(尽管我希望 BufferedReader 能够通过某种方式将整个文件作为字符串而不是逐行读取。

关于OpenGL 着色器编译问题 - 意外的 EOF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6400985/

相关文章:

opengl - 如何实现地面雾 GLSL 着色器

javascript - 老派电视翘边效应?

c++ - 奇怪的 ATI vs Nvidia TRIANGLE_STRIP 问题

unity3d - 在 Unity 中使用 Sprite mask 3D 对象

java - JOGL/OPENGL 中的大型线带管理...?

c++ - 基于 Java openGL 和 GTK 的应用程序搞砸了 C++ openGL?

c++ - 如何从 SuperBible 获取 GLTools 库以在 Ubuntu 中工作?还是另一种选择?

c++ - glDrawPixels 输出一些不完全符合预期 RGB 值的像素

java - JOGL 校正球体中的光线和反射

java - 如何优化我的 JOGL 应用程序?