如何在屏幕上查看GLuints的渲染缓冲区?

问题描述 投票:0回答:1

为了获得屏幕上绘制的元素的索引,我创建了一个帧缓冲区,它将绘制具有GL_R32UI类型的纯色的对象。

我创建的帧缓冲区附加了两个渲染缓冲区。其中一种颜色和一种深度。这是使用python创建它的方式的示意图:

my_fbo = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, my_fbo)

rbo = glGenRenderbuffers(2) # GL_DEPTH_COMPONENT16 and GL_COLOR_ATTACHMENT0

glBindRenderbuffer(GL_RENDERBUFFER, rbo[0])
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[0])

glBindRenderbuffer(GL_RENDERBUFFER, rbo[1])
glRenderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[1])

glBindRenderbuffer(GL_RENDERBUFFER, 0)        
glBindFramebuffer(GL_FRAMEBUFFER, 0)

我用readpixel读取索引,如下所示:

glBindFramebuffer(GL_FRAMEBUFFER, my_fbo)
glReadPixels(x, y, threshold, threshold, GL_RED_INTEGER, GL_UNSIGNED_INT, r_data)
glBindFramebuffer(GL_FRAMEBUFFER, 0)

代码完美无缺,我对此没有任何问题。

但是对于调试,我想在屏幕上看到索引

使用下面获得的数据,我怎样才能看到在屏幕上绘制索引(unsigned int)的结果?*

active_fbo = glGetIntegerv(GL_FRAMEBUFFER_BINDING)
my_indices_fbo = my_fbo
my_rbo_depth = rbo[0]
my_rbo_color = rbo[1]

## how mix my_rbo_color and cur_fbo??? ##

glBindFramebuffer(gl.GL_FRAMEBUFFER, active_fbo)
opengl-3
1个回答
1
投票

glBlitFramebuffer将一个像素值矩形从读取帧缓冲区的一个区域传输到另一个绘制帧缓冲区域。

 glBindFramebuffer( GL_READ_FRAMEBUFFER, my_fbo  );
 glBindFramebuffer( GL_DRAW_FRAMEBUFFER, active_fbo );
 glBlitFramebuffer( 0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST );

注意,你必须要小心,因为如果读缓冲区包含无符号整数值并且任何绘制缓冲区不包含无符号整数值,则会发生GL_INVALID_OPERATION错误。由于帧缓冲区颜色附件的内部格式是GL_R32UI,并且绘图缓冲区的内部格式通常类似于GL_RGBA8,这可能不起作用,或者它甚至不会达到您所期望的效果。

但是你可以创建一个纹理附加到其颜色平面的帧缓冲区,并使用纹理作为后置传递的输入,在整个画布上绘制四边形。

首先,您必须创建大小为帧缓冲区的纹理:

ColorMap0 = glGenTextures(1);
glBindTexture(GL_TEXTURE_2D, ColorMap0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, width, height, 0, GL_R, GL_UNSIGNED_INT, 0);

您必须将纹理附加到帧缓冲区:

my_fbo = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, my_fbo)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorMap0, 0);

绘制场景后,必须释放帧缓冲区。

glBindFramebuffer(GL_FRAMEBUFFER, 0)

现在,您可以将纹理用作最终传递的输入。只需绑定纹理,启用2D纹理并在整个画布上绘制四边形。四边形的范围应从(-1,-1)到(1,1),纹理坐标的范围从(0,0)到(1,1)。 当然,您可以使用着色器,片段着色器中的纹理采样器均匀。您可以从纹理中读取纹理元素,以您想要的方式写入片段。

Extension to the answer

如果性能不重要,那么在使用glReadPixels读取帧缓冲区后,您可以转换CPU上的缓冲区并在画布上绘制它。 为此,您可以保留代码,并使用glReadPixels读取帧缓冲区,但您必须将缓冲区转换为适合绘图缓冲区的格式。我建议使用内部格式GL_RGBA8GL_RGB8。 您必须使用转换缓冲区数据创建新纹理。

debugTexturePlane = ...; 
debugTexture = glGenTextures(1);
glBindTexture(GL_TEXTURE_2D, debugTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, debugTexturePlane);

从现在开始,你有两种可能性。 您可以创建新的帧缓冲区并将纹理附加到其颜色平面

debugFbo = glGenFramebuffers(1)
glBindFramebuffer(GL_FRAMEBUFFER, debugFbo)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, debugTexture, 0);

并且如上所述使用glBlitFramebuffer从调试帧缓冲区复制到颜色平面。这不应该是任何问题,因为缓冲区的内部格式应该相等。

或者在整个视口上绘制纹理四边形。代码可能看起来像这样(旧学校):

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, debugTexture);

glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex2f(-1.0,  1.0);
glTexCoord2f(1.0, 1.0); glVertex2f( 1.0,  1.0);
glTexCoord2f(1.0, 0.0); glVertex2f( 1.0, -1.0);
glEnd();
© www.soinside.com 2019 - 2024. All rights reserved.