c++ - 计算着色器 Open GL ES 的多个输入

标签 c++ opengl-es glsl opengl-es-3.0

我想在 Open GL ES 中创建一个接受多个 vector 并返回一个 vector 的程序。

我用过 example编写我自己的代码。

如果我有以下代码:

static const char COMPUTE_SHADER[] =
    "#version 310 es\n"
    "layout(local_size_x = 128) in;\n"
    "layout(std430) buffer;\n"
    "layout(binding = 0) buffer Output {\n"
    "uint elements[];\n"
    "} output_data;\n"
    "void main()\n"
    "{\n"
    "    uint ident = gl_GlobalInvocationID.x;\n"
    "output_data.elements[ident] = output_data.elements[ident] * "
    "output_data.elements[ident];\n"
    "}";

...

  GLuint data_buffer;
  glGenBuffers(1, &data_buffer);
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, data_buffer);
  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, data_buffer);
  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * 10, (void*)data,
               GL_DYNAMIC_READ);
  GLuint program = glCreateProgram();
  GLuint shader = LoadShader(COMPUTE_SHADER);
  glAttachShader(program, shader);

  glLinkProgram(program);
  glUseProgram(program);

  glDispatchCompute(10, 1, 1);

  std::vector<uint32_t> ready_data(10);

  GLuint* ptr = (GLuint*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
                                          sizeof(GLuint) * 10, GL_MAP_READ_BIT);
  std::copy(ptr, ptr + 10, ready_data.begin());
  glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

它工作得非常好,并将我需要的所有内容存储在输出 vector 中。

但后来我想按照这个例子,把输入和输出分开。它不起作用:

static const char COMPUTE_SHADER[] =
"   #version 310 es"
"layout(local_size_x = 128) in;"
"layout(std430) buffer;"
"layout(binding = 0) buffer Output {"
"    uint elements[];"
"} output_data;"
"layout(binding = 1) buffer Input0 {"
"    uint elements[];"
"} input_data0;"
"layout(binding = 2) readonly buffer Input1 {"
"uint elements[];"
"} input_data1;"
"void main()"
"{"
"    uint ident = gl_GlobalInvocationID.x;"
"    output_data.elements[ident] = input_data0.elements[ident] * input_data1.elements[ident];"
"}";

uint32_t data1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  uint32_t data2[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
  uint32_t data3[10] = {11, 21, 31, 41, 51, 61, 71, 81, 91, 101};

glGenBuffers(1, &input_buffer1);
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, input_buffer1);
  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, input_buffer1);
  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * 10, (void*)data2,
               GL_STREAM_COPY);

  glGenBuffers(1, &input_buffer2);
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, input_buffer2);
  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, input_buffer2);
  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * 10, (void*)data3,
               GL_STREAM_COPY);

  glGenBuffers(1, &data_buffer);
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, data_buffer);
  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, data_buffer);
  glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * 10, (void*)data1,
               GL_DYNAMIC_READ);

  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,
                                          sizeof(GLuint) * 10, GL_MAP_READ_BIT);
  std::copy(ptr, ptr + 10, ready_data.begin());
  glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

它只输出数字 1 2 3 .. 10 而我希望它们按元素相乘。

最佳答案

第二个计算着色器甚至没有编译,因为缺少换行符。

计算着色器的前两行

static const char COMPUTE_SHADER[] =
"   #version 310 es"
"layout(local_size_x = 128) in;"
.....

结果

   #version 310 eslayout(local_size_x = 128) in;

在第一行的末尾添加一个换行符来解决问题:

static const char COMPUTE_SHADER[] =
"#version 310 es\n"
"layout(local_size_x = 128) in;"
..... 

但我建议使用Raw string literals (C++11):

static const char COMPUTE_SHADER[] = R"(
#version 310 es

layout(local_size_x = 128) in;
layout(std430) buffer;

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

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

layout(binding = 2) readonly buffer Input1 {
    uint elements[];
} input_data1;

void main()
{
    uint ident = gl_GlobalInvocationID.x;
    output_data.elements[ident] = input_data0.elements[ident] * input_data1.elements[ident];
}
)";

关于c++ - 计算着色器 Open GL ES 的多个输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51363516/

相关文章:

c++ - 了解内存分配的工作原理 (LLVM)

c++ - 这两种新语法有什么区别?

c++ - 在只接触深度缓冲区的 openGL 中进行绘制调用

c++ - OpenGL 转换无法按预期在 z 轴上工作

java - GLSL奇怪的编译错误

c++ - QML:带有 "bring your own component"的 C++ 类

c++ - 链接项目 C++ Cygwin

iphone - 如何在 iPhone 上激活 OpenGL ES 中的多重采样?

android - 在 C/C++ 中接收完整的 android unicode 输入

ios - 解决奇怪的行为 re : glsl/metal shader.(无意的坐标翻转)