Opengl 将gl_图元ID输出到自定义帧缓冲区对象(FBO)时出现问题

Opengl 将gl_图元ID输出到自定义帧缓冲区对象(FBO)时出现问题,opengl,glsl,gpgpu,opengl-3,Opengl,Glsl,Gpgpu,Opengl 3,我有一个非常基本的片段着色器,我想将“gl_PrimitiveID”输出到我定义的片段缓冲区对象(FBO)。下面是我的片段着色器: #version 150 uniform vec4 colorConst; out vec4 fragColor; out uvec4 triID; void main(void) { fragColor = colorConst; triID.r = uint(gl_PrimitiveID); } 我的FBO设置如下: GLuint re

我有一个非常基本的片段着色器,我想将“gl_PrimitiveID”输出到我定义的片段缓冲区对象(FBO)。下面是我的片段着色器:

#version 150

uniform vec4 colorConst;

out vec4 fragColor;
out uvec4 triID;

void main(void)
{ 
   fragColor = colorConst;
   triID.r = uint(gl_PrimitiveID);
}
我的FBO设置如下:

  GLuint renderbufId0;
  GLuint renderbufId1;
  GLuint depthbufId;
  GLuint framebufId;


  // generate render and frame buffer objects
  glGenRenderbuffers( 1, &renderbufId0 );
  glGenRenderbuffers( 1, &renderbufId1 );
  glGenRenderbuffers( 1, &depthbufId   );
  glGenFramebuffers ( 1, &framebufId   );


  // setup first renderbuffer (fragColor)
  glBindRenderbuffer(GL_RENDERBUFFER, renderbufId0);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA,    gViewWidth, gViewHeight);


  // setup second renderbuffer (triID)
  glBindRenderbuffer(GL_RENDERBUFFER, renderbufId1);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB32UI, gViewWidth, gViewHeight);


  // setup depth buffer
  glBindRenderbuffer(GL_RENDERBUFFER, depthbufId);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, gViewWidth, gViewHeight);


  // setup framebuffer
  glBindFramebuffer(GL_FRAMEBUFFER, framebufId);  
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbufId0);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, renderbufId1);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,  GL_RENDERBUFFER, depthbufId  );


  // check if everything went well
  GLenum stat = glCheckFramebufferStatus(GL_FRAMEBUFFER);  
  if(stat != GL_FRAMEBUFFER_COMPLETE) { exit(0); }


  // setup color attachments
  const GLenum att[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
  glDrawBuffers(2, att);


  // render mesh
  RenderMyMesh()


  // copy second color attachment (triID) to local buffer
  glReadBuffer(GL_COLOR_ATTACHMENT1);
  glReadPixels(0, 0, gViewWidth, gViewHeight, GL_RED, GL_UNSIGNED_INT, data);
出于某种原因,glReadPixels会给我一个“GLU无效操作”错误?但是,如果我将renderbufId1的内部格式从“GL_RGB32UI”更改为“GL_RGB”,并且在glReadPixels中使用“GL_FLOAT”而不是“GL_UNSIGNED_INT”,那么一切都可以正常工作。有人知道我为什么会出现“GL_无效_操作”错误以及我如何解决它吗

是否有另一种输出“gl_PrimitiveID”的方法

PS:我想像这样输出“gl_PrimitiveID”的原因如下所述:

glReadPixels(0,0,gViewWidth,gVIEWWIGHT,GL_红色,GL_无符号整数,数据)

如上所述,传输真实整数数据时需要使用
GL\u RED\u INTEGER
。否则,OpenGL将尝试在其上使用浮点转换


顺便说一句,请确保您使用设置这些片段着色器输出的缓冲区。或者,如果您使用的是GLSL 3.30或更高版本,您也可以这样做。

非常感谢。这就成功了。您是否知道如何(如果可能)在单个“uint”中输出“gl_PrimitiveID”,而不是“vec3”的颜色分量?@WesDec:如果您想写入
uint
,那么只需写入
uint
。没有规定输出(或输入)必须是向量类型。并且没有规则规定输出图像需要全部四个值;GL_RUI32是一个完全有效的。而且,没有“vec3”的颜色成分。“.r”与“.x”的意思相同,后者与“.s”的意思相同。所有swizzle掩码的含义都是一样的。谢谢,我在上面的第二个“glRenderbufferStorage”调用中尝试使用GL_R32UI而不是GL_RGB32UI,但是我得到了一个GL_INVALID_ENUM错误?可能是我的OpenGL驱动程序(linux上的Im)不支持它吗?我知道swizzle遮罩的意思是相同的,但“glReadPixels”参数使您将其视为“颜色”、“深度”或“模具”(GL_RED、GL_RGBA、GL_depth_stencil等),这就是为什么我将其称为“vec3”的颜色组件的原因。@WesDec:如果您的驱动程序可以使用
GL_RGB32UI
,然后他们应该能够使用
GL\u R32UI
。听起来你需要更新你的驱动程序,真奇怪。。我使用最新的ATI FGLRX驱动程序,使用GLR32UI时出现上述错误。