无法在 android 中编译 opengl 片段着色器 - 错误:0:7:'gl_GlobalInvocationID':未声明的标识符 [英] Unable to compile opengl fragment shader in android - ERROR: 0:7: 'gl_GlobalInvocationID' : undeclared identifier

查看:148
本文介绍了无法在 android 中编译 opengl 片段着色器 - 错误:0:7:'gl_GlobalInvocationID':未声明的标识符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Unable to compile the following opengl fragment shader code in android.The GLES31.glGetString(GL_VERSION) shows the opengl version to be 3.2 and the device also seems to supports this version.

错误:-

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)

JavaCodehaderHelper.java):-

JavaCodehaderHelper.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 插件并且代码存储在原始文件夹中.无论如何,我能够使用应用程序 @ (https://github.com/yulu/GLtext).

NB: Using the glsl plugin in android and code is stored inside raw folder.Anyway, i'am able to compile and run some other sample glsl shader codes (< 3.0) using the app @ (https://github.com/yulu/GLtext).

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

I changed the old shader codes to opengl v3; but now it throws new error Error compiling program: Error: Compute shader is linked with other shader(s)

推荐答案

gl_GlobalInvocationID 是一个 计算着色器特殊变量,并且只能在计算着色器中使用:

gl_GlobalInvocationID is a Compute Shader Special Variables and can only be use in compute shaders:

来自 OpenGL ES 着色语言 3.20 规范

内置变量 gl_GlobalInvocationID 是一个计算着色器输入变量,包含当前工作项的全局索引.该值与当前 DispatchCompute 调用发起的所有工作组中的所有其他调用唯一地标识此调用.计算如下:

The built-in variable gl_GlobalInvocationID is a compute shader input variable containing the global index of the current work item. This value uniquely identifies this invocation from all other invocations across all workgroups initiated by the current DispatchCompute call. This is computed as:

gl_GlobalInvocationID =
     gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID;

在顶点着色器中有内置变量gl_VertexIDgl_InstanceID,它们可以传递到片段着色器阶段.请参阅 顶点着色器特殊变量.

In the vertex shader there are the built-in variables gl_VertexID and gl_InstanceID, which can be passed to the fragment shader stage. See Vertex Shader Special Variables.

这篇关于无法在 android 中编译 opengl 片段着色器 - 错误:0:7:'gl_GlobalInvocationID':未声明的标识符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆