【问题标题】:draw in FrameBuffer but get only black在 FrameBuffer 中绘制但只得到黑色
【发布时间】:2014-09-21 20:55:35
【问题描述】:

窗口

使用 glew

我正在尝试在屏幕外渲染并将渲染的 img opengl 保存到 png 文件中。

我在 stackoverflow 上关注了一个高度评价的答案: How to render offscreen on OpenGL?

但是我得到的png文件只是黑屏。

这是我的相关代码:

glutCreateWindow(argv[0]);
if(GLEW_OK!=glewInit())
{
    return -1;
}

initScene();


GLuint fbo, render_buf;
glGenFramebuffers(1,&fbo);
glGenRenderbuffers(1,&render_buf);
glBindRenderbuffer(GL_RENDERBUFFER,render_buf);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, viewport.w, viewport.h);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,fbo);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, render_buf);


//Before drawing
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,fbo);


glClear(GL_COLOR_BUFFER_BIT);               // clear the color buffer
glMatrixMode(GL_MODELVIEW);                 // indicate we are specifying camera transformations
glLoadIdentity();                       // make sure transformation is "zero'd"

//draw...
//glBegin(GL_POINTS) glColor3f, glVertex2f

//glFlush();
glFinish();

/*glutDisplayFunc(myDisplay);
glutPostRedisplay();*/

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
savePNG(outputPNGName,0,0,viewport.w,viewport.h);

//At deinit:
glDeleteFramebuffers(1,&fbo);
glDeleteRenderbuffers(1,&render_buf);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);

如何解决问题? 谢谢


保存PNG(相关代码):

glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)image);

【问题讨论】:

  • 必须尝试渲染到纹理上并在场景中显示一个四边形?最好确保您的帧缓冲区正常工作。
  • 还确保 - 通过保持系统帧缓冲区处于活动状态 - 你真的绘制任何可见的东西(一直发生......);)如果这个和 @Iggy 的解决方案不能帮助使用例如gDebugger 查看您的渲染缓冲区内容以确保您的 savePNG 不是问题...
  • 谢谢,我已经更新了我的 savePNG 代码...@lggy 你能分享一个关于如何渲染到纹理的链接吗?

标签: opengl framebuffer glew


【解决方案1】:

这段代码至少有两个问题:

  • GL_RGB8 不是渲染缓冲区的有效格式。来自glRenderbufferStorage() man page:

    internalformat 指定用于渲染缓冲区对象存储的内部格式,并且必须是可颜色渲染、可深度渲染或可模板渲染的格式。

    最新规范文档(4.5,可从https://www.opengl.org/registry 下载)中的表 8.13 列出了所有格式,并有一列显示其中哪些是可渲染的。 RGB8 在该列中没有复选标记。您可以改用GL_RGBA8,它是可渲染颜色的。

    您可能还想查看glCheckFramebufferStatus() 函数,它允许您检查帧缓冲区设置是否有效。

  • 虽然我们看不到savePNG() 的代码,但它无法知道您想从 FBO 读取像素数据。它很可能会使用glReadPixels(),它从当前读取的帧缓冲区中读取数据,而您的代码只设置绘制帧缓冲区。在调用 savePNG() 之前,添加此调用以将读取帧缓冲区设置为您的 FBO:

    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    

【讨论】:

  • 谢谢!我已经更新了 savePNG 中的相关代码,我还更正了我关注的网站。我已经更改了GL_RGBA8,但仍然无法正常工作。 glCheckFramebufferStatus(GL_FRAMEBUFFER) 返回 36053
  • @shrekshao:您应该始终以十六进制打印出 OpenGL 枚举值,这将使查找它们变得容易得多。在本例中,它对应于 0x8CD5,即GL_FRAMEBUFFER_COMPLETE。没有人会知道这个数字本身是多少,尤其是在 base-10 中;)
  • 36053 是GL_FRAMEBUFFER_COMPLETE,所以这部分应该没问题。如果设置读取帧缓冲区,则应该获取数据。还要确保您的 viewport.w 和 viewport.h 值正确。
  • 谢谢。 viewport.w = 400 , viewport.h =400,我得到一个 400x400 png 。我认为这部分是对的。但是我的图像仍然是黑色的。问题出在我的绘图部分吗?我只在绘图中使用glBegin(GL_POINT)、glColor3f、glVertex2f@RetoKoradi
  • 尝试使用glClearColor() 将透明颜色设置为黑色以外的颜色。然后,您将无需任何绘图即可查看阅读是否有效。你绑定GL_READ_FRAMEBUFFER了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 2023-03-06
相关资源
最近更新 更多