Open GL ES 3.1 计算着色器的最小工作示例

2023-12-27

我想使用 Open GL ES 进行通用计算。

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

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

  1. 该代码无法编译:错误:未定义对“glDispatchCompute”的引用。我已经包含了GLES3/gl31.h,该函数就在那里。 open gl es 的其他函数已正确导入;
  2. 我不明白如何从缓冲区取回数据;
  3. 代码中可能还有其他一些错误。我没有在网上找到 Open GL ES 3.1 计算着色器代码的示例,因此我尝试将常用的 Open GL 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);
}

第一个问题是,您必须使用正确的数据类型(uint)在缓冲区对象的规范中:

layout(binding = 0) writeonly buffer Output
{
    uint elements[];
} output_data;

layout(binding = 1) readonly buffer Input0
{
    uint elements[];
} input_data0;

此外,您还通过以下方式创建并初始化了缓冲区对象的数据存储glBufferData https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferData.xhtmll:

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);

当你这样做时,缓冲区的映射通过glMapBufferRange https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glMapBufferRange.xhtml会起作用,如果你使用GL_MAP_READ_BIT(而不是枚举常量GL_READ_ONLY,在这种情况下根本没有意义):

GLuint *ptr = (GLuint*)glMapBufferRange(
    GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint) * 10, GL_MAP_READ_BIT );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Open GL ES 3.1 计算着色器的最小工作示例 的相关文章

随机推荐

  • 使用python将某个网站的HTML保存在txt文件中

    我需要将任何网站的 HTML 代码保存在 txt 文件中 这是一个非常简单的练习 但我对此表示怀疑 因为有一个函数可以执行此操作 import urllib request def get html url f open htmlcode
  • MySQL 连接器和许可 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想到 MySQL 连接器 Java 和 NET 是 GPL 许可的 这是否意味着供应商 不是为内部应用程序开发 必须购买通过这些连接器与
  • 如果我设置 min-height 和 max-height,哪一个优先?

    我有一个菜单 有 9 个项目 我希望按钮高度为屏幕尺寸的 40px 或 11 屏幕的 1 9 不管是最大的 现在我有 min height 40px max height 11 并且始终为 40px 即使我的屏幕尺寸比这个大 我可以在 cs
  • min-sdk 大于以前版本的 android

    我有一个应用程序 它已经在 Play 商店中存在多年了 我刚刚进行了更新 该更新利用了 numberpicker 它的 min sdk 为 11 并且 v4 支持库不满足该需求 我倾向于发布我的新版本并在清单中将 min sdk 设置为 1
  • 当枚举无法序列化时,提前失败或明确抛出

    在 WCF 服务返回具有无效值 枚举类型中不存在 int 的枚举成员的 DataContract 的情况下 客户端抛出的异常为The underlying connection was closed The connection was c
  • 在Python中解析SQL查询

    我需要在 python 中构建一个迷你 sql 引擎 所以我需要一个 sql parser 并且我发现了 python sqlparse 但无法理解如何从 SQL 查询中提取列名或表名等 有人可以帮我解决这个问题吗 让我们检查 python
  • 数据框的视觉结构:NA 的位置等等

    我想用颜色编码在单个图上表示数据框 或矩阵 或 data table 等 的结构 我想这对于许多处理各种类型数据的人来说非常有用 可以一目了然地将其可视化 也许有人已经开发了一个包来做到这一点 但我找不到一个 只是this https st
  • Android单行TextView不带点

    是否可以有单线TextView在最近的像素处切断并且不添加三个点
  • 如何停止在 WPF DataVisualization 图表中的 Y 轴上显示小数点

    我正在使用 WPF DataVisualization 图表控件来显示一些示例数据 我的问题是 Y 轴显示小数值 我怎样才能让它只显示整数值 这是我的 XAML 代码
  • Excel计算公式错误

    我的VBA代码是 Function yEval entry As String yEval Evaluate entry Application Volatile End Function 在 Sheet1 的单元格 f4 中我有公式 yE
  • 余弦距离作为 k 均值的向量距离函数

    我有一个 N 个顶点的图 其中每个顶点代表一个地方 我还有向量 每个用户一个 N 个系数中的每一个 其中系数的值是在相应地点花费的持续时间 以秒为单位 如果没有访问该地点则为 0 例如 对于图表 向量 v1 100 50 0 30 0 意味
  • 如何通过 Dialog Flow (API.AI) 获取用户从 Facebook Messenger bot 发送的图像/附件?

    我有由 Dialogflow API AI 提供支持的聊天机器人 它要求用户发送图像 我知道 当用户单击 Messenger 中的 开始 按钮时 同时开始与机器人对话 将触发带有 WELCOME FACEBOOK WELCOME 事件的对话
  • 如何从多索引数据框中删除级别?

    例如 我有 In 1 df pd DataFrame 8 9 index pd MultiIndex from tuples 1 1 1 1 3 2 columns A In 2 df Out 2 A 1 1 1 8 3 2 9 有没有比这
  • [表视图重新加载数据];直到我滚动 tableView 才起作用

    我有一个简单的应用程序 当用户键入时 它会下载 XML 格式的搜索结果UISearchBar 下载 解析是线程化的 一旦完成就会触发NSNotification告诉带有表视图的 ViewController tableView reload
  • 如何使用 ng-model 显示输入元素的不同值?

    在控制器中 如果有一个变量用于跟踪分页表页面的索引 从 0 开始 var page pageNumber 0 问题 我怎样才能显示这个pageNumberhtml 中的变量 但总是增加 1 因为index 0页面显然是第一页 因此应该显示为
  • 使用 Laravel 验证来验证 UUID

    是否有一种内置方法可以使用验证规则来验证 UUID 我在 可用的验证规则 https laravel com docs 5 5 validation available validation rules 文档 实际上 Laravel 5 7
  • 奇怪的 git 案例 - git stash 后跟 git stash apply 丢失了未提交的数据?

    我有一个文件 假设 file txt 我已经完成了 git mv file txt 到 file1 txt 然后我创建了一个名为 file txt 的新文件并对其进行了处理 不幸的是我还没有将该文件添加到 git 中 不管怎样 问题是我做了
  • 如何确定矩形的内半径?

    第一张图片是以下代码的结果 一个具有预期半径的矩形 但我需要一个在右上角有内半径的矩形 就像第二个图像一样
  • Font Awesome 未出现在浏览器中

    我正在为我的项目开发一个网站 我正在使用 Bootstrap 和 Font Awesome 作为字形 但我遇到了一个问题 当我使用 Font Awesome 图标时 某些图标不会显示在浏览器中 但某些图标会显示 例如 fa fa user
  • Open GL ES 3.1 计算着色器的最小工作示例

    我想使用 Open GL ES 进行通用计算 所以到目前为止我所理解的是 我需要创建一个 SSBO 并将数据传输到那里 将缓冲区绑定到着色器中的特殊点 运行着色器并取回数据 到目前为止我有3个问题 该代码无法编译 错误 未定义对 glDis