Geometry Shader中Shader Storage Buffer的所有值都是0

All values of the Shader Storage Buffer are 0 in Geometry Shader

在我的应用程序中,Shader Storage Buffer 的所有值似乎都是 0 在 Geometry Shader 中。

这是我简单的Geometry Shader来测试值:

#version 430
#extension GL_ARB_shader_storage_buffer_object : enable

layout (points) in;
layout(invocations = 20) in;
layout (points, max_vertices = 256) out;

uniform mat4x4 matModel;
uniform mat4x4 matView;
uniform mat4x4 matProjection;
uniform mat4x4 matLightView;


struct Info {  
  vec4 position;
  vec4 normal;
  vec4 color;
};

layout(std430, binding=0) buffer pointData 
{
    Info pointElements[];
};

void main() {
  if( pointElements[0].position.x == 0 ) {
    gl_Position =  matProjection * matView * matModel *  gl_in[0].gl_Position;
    EmitVertex();
  }

  EndPrimitive();
}

只为 pointElements[0].position.x == 0 渲染点(pointElements[0].position.x > 0 不渲染任何东西)。 缓冲区的设置是这样完成的:

struct PointData {
  float px, py, pz, pw;
  float nx, ny, nz, nw;
  float r, g, b, a;
}


void setupSSBO() {
  std::vector<PointData> data;
  int count = 15;
  for (int x = 0; x< count; x++) {
    for (int y = 0; y< count; y++) {
      PointData pt;
      pt.px = 1;
      pt.py = 2;
      pt.pz = 3;
      pt.pw = 4;
      pt.nx = 5;
      pt.ny = 6;
      pt.nz = 7;
      pt.nw = 8;
      pt.r = 9;
      pt.g = 10;
      pt.b = 11;
      pt.a = 12;
      data.push_back(pt);
    }
  }

  GLuint ssbo = 0;
  std::cout << "errors bnefore: " << glGetError() << std::endl;
  glGenBuffers(1, &m_pointData);
  std::cout << "glGenBuffers: " << m_pointData  << " " << glGetError() << std::endl;
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_pointData);
  std::cout << "glBindBuffer: " << glGetError() << std::endl;
  glBufferData(GL_SHADER_STORAGE_BUFFER, data.size()*sizeof(PointData), NULL, GL_STATIC_DRAW/*GL_DYNAMIC_COPY*/);
  std::cout << "glBufferData: " << glGetError() << std::endl;
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  std::cout << "glBindBuffer: " << glGetError() << std::endl;


  glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_pointData);
  PointData* p = (PointData*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, data.size() *sizeof(PointData), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
  std::cout << "glMapBufferRange: " << glGetError() << std::endl;
  memcpy(p, &data[0], data.size()*sizeof(PointData));
  glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
  std::cout << "glUnmapBuffer: " << glGetError() << std::endl;
  glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  std::cout << "glBindBuffer: " << glGetError() << std::endl;
}

着色器的绑定是这样完成的:

GLuint block_index = glGetProgramResourceIndex(progamId, GL_SHADER_STORAGE_BLOCK, "pointData");
glShaderStorageBlockBinding(progamId, block_index, m_pointData);

glGetError() 调用不会 return 出错。着色器被执行,因为我在测试 pointElements[0].position.x == 0 时看到了点。值保持 0 的原因可能是什么? (问题也存在于 xyw 以及 normalcolor

问题似乎是

glShaderStorageBlockBinding(progamId, block_index, m_pointData);

当我将其替换为:

时一切正常
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, block_index, m_pointData);

编辑

根据我的观察和再次阅读规范后,glGetProgramResourceIndexglBindBufferBase 的组合也不正确。将 glBindBufferBaselayout(std430, binding=0) 定义的绑定一起使用是正确的,但 glGetProgramResourceIndex 不会 return 该绑定而是资源索引。