Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android OpenGL ES 3.1计算着色器的最小工作示例_Android_C++_Opengl Es_Glsl_Shader - Fatal编程技术网

Android OpenGL ES 3.1计算着色器的最小工作示例

Android OpenGL ES 3.1计算着色器的最小工作示例,android,c++,opengl-es,glsl,shader,Android,C++,Opengl Es,Glsl,Shader,我想使用opengles进行通用计算 到目前为止,我所了解的是,我需要创建一个SSBO,并在那里传输数据,将缓冲区绑定到着色器中的特殊点,运行着色器并获取数据 到目前为止,我有3个问题: 代码未编译:错误:未定义对“glDispatchCompute”的引用。我已经包括了GLES3/gl31.h,函数就在那里。正确导入open gl es的其他功能 我不明白如何从缓冲区取回数据 代码中可能还有其他一些错误。我还没有在web上找到OpenGL ES 3.1计算着色器代码的示例,因此我尝试将常用的O

我想使用opengles进行通用计算

到目前为止,我所了解的是,我需要创建一个SSBO,并在那里传输数据,将缓冲区绑定到着色器中的特殊点,运行着色器并获取数据

到目前为止,我有3个问题:

  • 代码未编译:错误:未定义对“glDispatchCompute”的引用。我已经包括了GLES3/gl31.h,函数就在那里。正确导入open gl es的其他功能
  • 我不明白如何从缓冲区取回数据
  • 代码中可能还有其他一些错误。我还没有在web上找到OpenGL ES 3.1计算着色器代码的示例,因此我尝试将常用的OpenGL ES代码(我是这方面的新手)和上面链接中的计算着色器代码结合起来
  • 另外,我正在编写从Android应用程序启动的代码,因此从这方面可能会出现一些问题。我的最终任务是在着色器上计算一些东西,然后返回到Android应用程序。现在它只返回用于调试的固定字符串

    这是我的密码:

    #include <jni.h>
    #include <string>
    
    
    #include <GLES3/gl31.h>
    //#include <GLES/egl.h>
    
    
    static const char COMPUTE_SHADER[] =
            "#version 310 es\n"
                    "layout(local_size_x = 128) in;\n"
                    "layout(std430) buffer;\n"
                    "layout(binding = 0) writeonly buffer Output {\n"
                    "vec4 elements[];\n"
                    "} output_data;\n"
                    "layout(binding = 1) readonly buffer Input0 {\n"
                    "vec4 elements[];\n"
                    "} input_data0;\n"
                    "void main()\n"
                    "{\n"
                    "    uint ident = gl_GlobalInvocationID.x;\n"
                    "output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
                    "}";
    
    GLuint LoadShader(const char *shaderSrc)
    {
    
        GLuint shader;
        GLint compiled;
    
        // Create the shader object
        shader = glCreateShader(GL_COMPUTE_SHADER);
        if(shader == 0)
            return shader;
    
        // Load the shader source
        glShaderSource(shader, 1, &shaderSrc, NULL);
    
        // Compile the shader
        glCompileShader(shader);
        // Check the compile status
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        if(!compiled)
        {
            GLint infoLen = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
    
            if(infoLen > 1)
            {
                char* infoLog = (char*)malloc(sizeof(char) * infoLen);
                glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
                //esLogMessage("Error compiling shader:\n%s\n", infoLog);
                free(infoLog);
            }
            glDeleteShader(shader);
            return 0;
        }
        return shader;
    }
    
    extern "C" JNIEXPORT jstring
    
    JNICALL
    Java_appname_MainActivity_stringFromJNI(
            JNIEnv *env,
            jobject /* this */) {
        // Maybe create a shader straight here
        //prepare_data();
        //GLuint tex[2];
        char hello[100] = "hello";
    
        GLuint data_buffer;
        GLuint output_buffer;
    
        uint32_t data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
        glGenBuffers(1, &data_buffer);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, data_buffer);
        glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uint32_t) * 10, (void*)data, GL_STREAM_COPY);
        glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 1, data_buffer);
    
        glGenBuffers(0, &output_buffer);
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, output_buffer);
        //glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(uint32_t) * 10, (void*)calc_data, GL_STREAM_COPY);
        glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 0, output_buffer);
    
        GLuint program = glCreateProgram();
        GLuint shader = LoadShader(COMPUTE_SHADER);
    
        glAttachShader(program, shader);
        glLinkProgram(program);
    
        glUseProgram(program);
        glDispatchCompute(10,1,1);
    
        GLuint *ptr = (GLuint *) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 10, GL_READ_ONLY );
        GLuint info = ptr[ 0 ];
        glUnmapBuffer( GL_SHADER_STORAGE_BUFFER );
        sprintf(hello, "%d ", info);
    
        glMemoryBarrier( GL_SHADER_STORAGE_BARRIER_BIT );
    
        return env->NewStringUTF(hello);
    }
    
    #包括
    #包括
    #包括
    //#包括
    静态常量char COMPUTE_着色器[]=
    “#版本310 es\n”
    “布局(本地大小=128)英寸;\n”
    “布局(std430)缓冲区;\n”
    “布局(绑定=0)可写缓冲区输出{\n”
    “vec4元素[];\n”
    “}输出\u数据;\n”
    “布局(绑定=1)只读缓冲区输入0{\n”
    “vec4元素[];\n”
    “}输入数据0;\n”
    “void main()\n”
    “{\n”
    “uint ident=gl\u globalinovationid.x;\n”
    “输出数据.elements[ident]=输入数据0.elements[ident]*输入数据0.elements[ident];\n”
    "}";
    GLuint LoadShader(常量字符*shaderSrc)
    {
    GLuint着色器;
    闪烁编译;
    //创建着色器对象
    着色器=glCreateShader(GL_计算_着色器);
    如果(着色器==0)
    返回着色器;
    //加载着色器源
    glShaderSource(着色器,1,&shaderSrc,NULL);
    //编译着色器
    glCompileShader(着色器);
    //检查编译状态
    glGetShaderiv(着色器、GL\u编译状态和编译状态);
    如果(!编译)
    {
    闪烁信息=0;
    glGetShaderiv(着色器、GL\u INFO\u LOG\u LENGTH和infoLen);
    如果(infoLen>1)
    {
    char*infoLog=(char*)malloc(sizeof(char)*infoLen);
    glGetShaderInfoLog(着色器,infoLen,NULL,infoLog);
    //esLogMessage(“编译着色器时出错:\n%s\n”,信息日志);
    免费(信息日志);
    }
    glDeleteShader(着色器);
    返回0;
    }
    返回着色器;
    }
    外部“C”JNIEXPORT jstring
    JNICALL
    Java_appname_Main Activity_stringFromJNI(
    JNIEnv*env,
    jobject/*此*/){
    //也许直接在这里创建一个着色器
    //准备_数据();
    //GLuint-tex[2];
    char hello[100]=“hello”;
    GLuint数据缓冲区;
    胶合输出缓冲区;
    uint32_t数据[10]={1,2,3,4,5,6,7,8,9,10};
    glGenBuffers(1和数据缓冲区);
    glBindBuffer(GL_着色器_存储_缓冲区、数据_缓冲区);
    glBufferData(GL\u着色器\u存储\u缓冲区,大小(uint32\u t)*10,(void*)数据,GL\u流\u副本);
    glBindBufferBase(GL_着色器_存储_缓冲区,1,数据_缓冲区);
    glGenBuffers(0和输出缓冲区);
    glBindBuffer(GL_着色器_存储_缓冲区、输出_缓冲区);
    //glBufferData(GL\u着色器\u存储\u缓冲区,大小(uint32\u t)*10,(void*)计算数据,GL\u流\u副本);
    glBindBufferBase(GL_着色器_存储_缓冲区,0,输出_缓冲区);
    GLuint程序=glCreateProgram();
    GLuint着色器=LoadShader(计算着色器);
    glAttachShader(程序、着色器);
    glLinkProgram(program);
    glUseProgram(程序);
    glDispatchCompute(10,1,1);
    GLuint*ptr=(GLuint*)glMapBufferRange(GL_着色器_存储_缓冲区,0,10,GL_只读);
    GLuint info=ptr[0];
    glUnmapBuffer(GL_着色器_存储_缓冲区);
    sprintf(你好,“%d”,信息);
    glMemoryBarrier(GL_着色器_存储_屏障_位);
    return env->NewStringUTF(你好);
    }
    
    第一个问题是,必须在缓冲区对象的规范中使用正确的数据类型(
    uint
    ):

    layout(binding = 0) writeonly buffer Output
    {
        uint elements[];
    } output_data;
    
    layout(binding = 1) readonly buffer Input0
    {
        uint elements[];
    } input_data0;
    
    此外,您还可以通过以下方式创建和初始化缓冲区对象的数据存储:

    执行此操作时,如果使用
    GL\u MAP\u READ\u位
    (而不是enum常量
    GL\u READ\u ONLY
    ,则缓冲区的映射将起作用,在这种情况下根本没有意义):

    glGenBuffers(0, &output_buffer);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, output_buffer);
    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 0, output_buffer);
    
    glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * 10, nullptr, GL_DYNAMIC_READ);
    
    GLuint *ptr = (GLuint*)glMapBufferRange(
        GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint) * 10, GL_MAP_READ_BIT );