在 FrameBuffer 中绘制但只得到黑色

shr*_*hao 0 opengl glew framebuffer

视窗

使用 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);
Run Code Online (Sandbox Code Playgroud)

如何解决问题?谢谢


savePNG(相关代码):

glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)image);
Run Code Online (Sandbox Code Playgroud)

Ret*_*adi 5

这段代码至少存在两个问题:

  • GL_RGB8不是渲染缓冲区的有效格式。从glRenderbufferStorage()手册页

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

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

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

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

    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    
    Run Code Online (Sandbox Code Playgroud)