每当在FBO

时间:2016-12-11 23:28:57

标签: opengl opentk fbo depth-buffer

我想要做的是实际实现对象拾取例程,现在我决定通过使用特定对象颜色将场景渲染到纹理并读取适当的像素来识别对象来做到这一点。

问题在于我使用外部fbo来实现这一点,并且我发现默认情况下,在新的fbo渲染中不使用深度信息。在网上搜索我认为情况是这样的,除非有一些与fbo的深度附件(纹理或渲染缓冲区)有关的东西。

所以我尝试了这两种解决方案,但每当我尝试连接新的渲染缓冲区(使用glFramebufferRenderbuffer)或纹理(使用glFramebufferTexture)时,fbo中都没有写入任何内容。我通过阅读fbo的像素来检查它们,它们都是零...

以下是我的代码(使用OpenTK)尝试使用深度渲染缓冲区并将其附加到fbo

//First of all clear the color buffer
//Create the texture to render to
int tex_w = glControl1.Width;
int tex_h = glControl1.Height;

//Create Frame and renderbuffers
int fb = GL.GenFramebuffer();
int depth_rb = GL.GenRenderbuffer();
//int color_rb = GL.GenRenderbuffer();


GL.BindFramebuffer(FramebufferTarget.Framebuffer, fb);
GL.Viewport(0, 0, tex_w, tex_h);
//Clear the buffer and enable depth test
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.DepthTest);
GL.DepthMask(true);

//Create Color texture
int out_tex = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, out_tex);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, tex_w, tex_h, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);

//Create Depth texture
//int depth_tex = GL.GenTexture();
//GL.BindTexture(TextureTarget.Texture2D, depth_tex);
//GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp);
//GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);
//GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
//GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
//GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent32, tex_w, tex_h, 0, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero);


//Attach Textures to this FBO
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, out_tex, 0);
//GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, depth_tex, 0);

//Bind depth renderbuffer
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depth_rb);
GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent16, tex_w, tex_h);
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depth_rb);


GL.BindFramebuffer(FramebufferTarget.Framebuffer, fb);
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
//Now render objects with the picking program
if (this.mainScene != null) traverse_render(this.mainScene, 2);

//Check
if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
    Debug.WriteLine("FRAMEBUFFER Issues" + GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer));



//Store Framebuffer to Disk
byte[] pixels = new byte[4 * tex_w * tex_h];


//GL.ReadBuffer(ReadBufferMode.None);
//Debug.WriteLine("Saving Picking Buffer. Dimensions: " + tex_w + " " + tex_h);
//GL.ReadPixels(0, 0, tex_w, tex_h, PixelFormat.DepthComponent, PixelType.UnsignedByte, pixels);
//FileStream ds = new FileStream("pickDepthBuffer", FileMode.Create);
//BinaryWriter bw = new BinaryWriter(ds);
//bw.Write(pixels);
//ds.Flush();
//ds.Close();


GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
Debug.WriteLine("Saving Picking Buffer. Dimensions: " + tex_w +" "+ tex_h);
GL.ReadPixels(0, 0, tex_w, tex_h, PixelFormat.Rgba, PixelType.UnsignedByte, pixels);
FileStream fs = new FileStream("pickBuffer", FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(pixels);
fs.Flush();
fs.Close();

//Pick object here :)
GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
Debug.WriteLine("Selecting Object at Position: " + p.X + " " + (tex_h -p.Y));
byte[] buffer = new byte[4];
GL.ReadPixels(p.X, tex_h - p.Y, 1, 1, PixelFormat.Rgba, PixelType.UnsignedByte, buffer);

//Convert color to id
int ob_id = (buffer[1] << 8) | buffer[0];

//Deselect everything first
traverse_oblist_rs(this.mainScene, "selected", 0);

//Try to find object
traverse_oblist_field<int>(this.mainScene, ob_id, "selected", 1);

//Restore Rendering Buffer
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

//Cleanup
GL.DeleteFramebuffer(fb);
//GL.DeleteRenderbuffer(color_rb);
GL.DeleteRenderbuffer(depth_rb);
GL.DeleteTexture(out_tex);
//GL.DeleteTexture(depth_tex);
pixels = null;

评论线

GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depth_rb);

GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, TextureTarget.Texture2D, depth_tex, 0);

解决了问题,但当然没有深度问题。

除此之外,我尝试在代码中的任何地方放置GL.GetErrors来通知我任何问题,但每次调用都会返回NoError ....

我错过了一些明显的东西吗?或者至少还有其他方法可以调试吗?

0 个答案:

没有答案