无法在android中编译opengl片段着色器 - 错误:0:7:'gl_GlobalInvocationID':未声明的标识符

问题描述 投票:1回答:1

无法在android中编译以下opengl片段着色器代码.GLES31.glGetString(GL_VERSION)显示opengl版本为3.2,设备似乎也支持此版本。

错误:-

Error compiling shader: ERROR: 0:7: 'gl_GlobalInvocationID' : undeclared identifier 
    ERROR: 0:7: 'xy' :  field selection requires structure, vector, or matrix on left hand side 
    ERROR: 2 compilation errors.  No code generated.
03-31 10:39:17.822 23849-23887/com.research.gltest E/AndroidRuntime: FATAL EXCEPTION: GLThread 1686
    Process: com.research.gltest, PID: 23849
    java.lang.RuntimeException: Error creating shader.
        at com.research.gltest.ShaderHelper.compileShader(ShaderHelper.java:45)
        at com.research.gltest.GLLayer.onDrawFrame(GLLayer.java:325)

着色器代码: -

    #version 310 es
    precision mediump float;
    layout(binding = 0) uniform sampler2D u_Texture1;
    layout(std430) buffer;
    layout(binding = 1) buffer Output { float elements[]; } output_data;
    void main() {
    ivec2 gid = ivec2(gl_GlobalInvocationID.xy);
    if (gid.x >= 257 || gid.y >= 257) return;
    vec3 pixel = texelFetch(u_Texture1, gid, 0).xyz;
    int linear_index = 3 * (gid.y * 224 + gid.x);
    output_data.elements[linear_index + 0] = pixel.x; output_data.elements[linear_index + 1] = pixel.y;
    output_data.elements[linear_index + 2] = pixel.z;
    }

错误发生在以下行: -

final int fragmentShaderHandle = ShaderHelper.compileShader(
            GLES31.GL_FRAGMENT_SHADER, fragmentShader)

JavasodehaderHelper.Java): -

public class ShaderHelper
    {
        private static final String TAG = "ShaderHelper";

        /** 
         * Helper function to compile a shader.
         * 
         * @param shaderType The shader type.
         * @param shaderSource The shader source code.
         * @return An OpenGL handle to the shader.
         */
        public static int compileShader(final int shaderType, final        String shaderSource) 
        {
            int shaderHandle = GLES31.glCreateShader(shaderType);

            if (shaderHandle != 0) 
            {
                // Pass in the shader source.
                GLES31.glShaderSource(shaderHandle, shaderSource);

                // Compile the shader.
                GLES31.glCompileShader(shaderHandle);

                // Get the compilation status.
                final int[] compileStatus = new int[1];
                GLES31.glGetShaderiv(shaderHandle, GLES31.GL_COMPILE_STATUS, compileStatus, 0);

                // If the compilation failed, delete the shader.
                if (compileStatus[0] == 0) 
                {
                    Log.e(TAG, "Error compiling shader: " + GLES31.glGetShaderInfoLog(shaderHandle));
                    GLES31.glDeleteShader(shaderHandle);
                    shaderHandle = 0;
                }
            }

            if (shaderHandle == 0)
            {           
                throw new RuntimeException("Error creating shader.");
            }

            return shaderHandle;
        }

        /**
         * Helper function to compile and link a program.
         * 
         * @param vertexShaderHandle An OpenGL handle to an already-compiled vertex shader.
         * @param fragmentShaderHandle An OpenGL handle to an already-compiled fragment shader.
         * @param attributes Attributes that need to be bound to the program.
         * @return An OpenGL handle to the program.
         */
        public static int createAndLinkProgram(final int vertexShaderHandle, final int fragmentShaderHandle, final String[] attributes) 
        {
            int programHandle = GLES31.glCreateProgram();

            if (programHandle != 0) 
            {
                // Bind the vertex shader to the program.
                GLES31.glAttachShader(programHandle, vertexShaderHandle);

                // Bind the fragment shader to the program.
                GLES31.glAttachShader(programHandle, fragmentShaderHandle);

                // Bind attributes
                if (attributes != null)
                {
                    final int size = attributes.length;
                    for (int i = 0; i < size; i++)
                    {
                        GLES31.glBindAttribLocation(programHandle, i, attributes[i]);
                    }                       
                }

                // Link the two shaders together into a program.
                GLES31.glLinkProgram(programHandle);

                // Get the link status.
                final int[] linkStatus = new int[1];
                GLES31.glGetProgramiv(programHandle, GLES31.GL_LINK_STATUS, linkStatus, 0);

                // If the link failed, delete the program.
                if (linkStatus[0] == 0) 
                {               
                    Log.e(TAG, "Error compiling program: " + GLES31.glGetProgramInfoLog(programHandle));
                    GLES31.glDeleteProgram(programHandle);
                    programHandle = 0;
                }
            }

            if (programHandle == 0)
            {
                throw new RuntimeException("Error creating program.");
            }

            return programHandle;
        }
    }

注意:在android中使用glsl插件,代码存储在raw文件夹中。无论如何,我能够使用app @(https://github.com/yulu/GLtext)编译并运行一些其他样本glsl着色器代码(<3.0)。

编辑:我将旧的着色器代码更改为opengl v3;但现在它抛出新错误错误编译程序:错误:计算着色器与其他着色器链接

java android opengl-es glsl shader
1个回答
2
投票

gl_GlobalInvocationIDCompute Shader Special Variables,只能在计算着色器中使用:

来自OpenGL ES Shading Language 3.20 Specification

内置变量gl_GlobalInvocationID是一个计算着色器输入变量,包含当前工作项的全局索引。此值唯一地标识来自当前DispatchCompute调用启动的所有工作组中的所有其他调用的此调用。计算方法如下:

gl_GlobalInvocationID =
     gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID;

在顶点着色器中有内置变量gl_VertexIDgl_InstanceID,它们可以传递给片段着色器阶段。见Vertex Shader Special Variables

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