OpenGL es、Android中编译Fragment Shader程序出错

问题描述 投票:0回答:3

我是 OpenGL 新手,今天我尝试编译一些着色器程序,以便在 Android 操作系统中使用 OpenGL 的 GPGPU。 我有两个问题: 1)我只想编写片段着色器,是否也需要编写顶点着色器? 2)我在编译着色器源代码时遇到一些错误。 我的源代码定义为:

final String src = "#version 310 es\n" +
            "uniform sampler2D texUnit;\n" +
            "uniform int sequence;\n" +
            "void main(void)\n" +
            "{\n" +
            "const vec3 DotValue = {0.299f , 0.587f , 0.114f};\n" +
            "vec2 texCoord = gl_TexCoord[0].xy;\n" +
            "vec4 CurrentPixelData  = texture2D(texUnit, texCoord);\n" +
            "float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
            "vec4 result = {temp,temp,temp,CurrentPixelData.w};\n" +
            "gl_FragColor = result;\n" +
            "}\n";

创建着色器的代码是:

int fragment = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fragment,src);
        GLES20.glCompileShader(fragment);



        int[] compiled = new int[1];
        GLES20.glGetShaderiv(fragment, GLES20.GL_COMPILE_STATUS, compiled, 0);	//compile[0] != 0 : compiled successfully
        if (compiled[0] == 0) {
            Log.e(TAG, "Could not compile shader: ");
            Log.e(TAG, GLES20.glGetShaderInfoLog(fragment));
            GLES20.glDeleteShader(fragment);
            fragment = 0;
        } else {
            Log.i(TAG, "Compiled shader with source length " + src.length());
        }

但是当我尝试调试我的应用程序时,logcat 中出现了几个有关着色器编译的错误:

    0:6: L0001: Expected token ';', found '{'
    0:7: L0002: Undeclared variable 'gl_TexCoord'
    0:8: L0002: No matching function for call to 'texture2D'
    0:9: L0002: Undeclared variable 'CurrentPixelData'
    0:10: L0001: Expected token ';', found '{'
    0:11: L0002: Undeclared variable 'gl_FragColor'

任何人都可以帮助我我的代码有什么问题吗? 提前致谢。

android opengl-es glsl gpgpu
3个回答
5
投票

您确实需要顶点着色器和片段着色器。

您捕获的着色器编译日志已突出显示语法错误。提供有关它们的更多详细信息:

  1. 您需要使用构造函数语法来初始化向量:

    const vec3 DotValue = vec3(0.299 , 0.587, 0.114);
    
  2. gl_TexCoord
    不是内置变量。您可能已经在桌面 OpenGL 的代码示例中看到过它,它曾经存在于其中。但即使在那里它也已被弃用,并且从未出现在 OpenGL ES 中。您需要自己将纹理坐标传递到着色器中。

  3. texture2D()
    不是内置函数。用于采样 2D 纹理的函数在旧的 GLSL 版本中曾经这样命名,但现在以名称
    texture()
    :

    的名义为各种采样器类型重载
    vec4 CurrentPixelData  = texture(texUnit, texCoord);
    
  4. 看起来只是上一个错误的后续错误。

  5. 与错误1相同:

    vec4 result = vec4(temp, temp, temp, CurrentPixelData.w);
    
  6. gl_FragColor
    曾经是旧版 GLSL 版本中的内置变量,但现在已弃用并删除。您需要使用限定符
    out
    定义自己的变量,以定义用作着色器输出的变量。


2
投票

您必须编写一个顶点着色器。必须为 gl_Position 赋值以创建三角形,然后创建像素(片段)。 如果您使用纹理映射,则需要分配一个可变变量,并将纹理坐标分配给顶点。 随后,为每个片段插入这些坐标。 最基本的顶点着色器是:

    const char* simpleVertexShader=
    "attribute vec4 position;"
    "attribute vec4 inputTextureCoordinate;
    "varying   vec2 textureCoordinate;"
    "void main(){"
    "gl_Position = position;"
    "textureCoordinate = inputTextureCoordinate.xy;"
    "}";

在您的片段着色器中,vec3 和 vec4 init 中有语法错误。 应该这样做:

  "const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n"

  "vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n"

注意浮点文字不需要 glsl 中的“f”后缀。

您的固定代码:

  final String src = "#version 310 es\n" +
        "precision   highp float;"
        "uniform sampler2D texUnit;\n" +
    "varying   vec2 textureCoordinate" +
        "void main(void)\n" +
        "{\n" +
        "const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n" +
        "vec2 texCoord = textureCoordinate;\n" +
        "vec4 CurrentPixelData  = texture2D(texUnit, texCoord);\n" +
        "float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
        "vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n" +
        "gl_FragColor = result;\n" +
        "}\n";

如果您从一个好的 openGL 教程开始,这对您来说会容易得多。

祝你好运!


0
投票

final String src = "#version 310 es\n" +
            "uniform sampler2D texUnit;\n" +
            "uniform int sequence;\n" +
            "void main(void)\n" +
            "{\n" +
            "const vec3 DotValue = {0.299f , 0.587f , 0.114f};\n" +
            "vec2 texCoord = gl_TexCoord[0].xy;\n" +
            "vec4 CurrentPixelData  = texture2D(texUnit, texCoord);\n" +
            "float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
            "vec4 result = {temp,temp,temp,CurrentPixelData.w};\n" +
            "gl_FragColor = result;\n" +
            "}\n";

© www.soinside.com 2019 - 2024. All rights reserved.