在计算机上使用 OpenGL 绘制 FBO 挂起

Posted

技术标签:

【中文标题】在计算机上使用 OpenGL 绘制 FBO 挂起【英文标题】:Drawing FBO with OpenGL on computer hungs 【发布时间】:2013-03-22 22:56:24 【问题描述】:

我有两台电脑,一台配备 i5 和 ATI Radeon HD 5145 的东芝笔记本电脑,以及一台配备 Pentium D 和 ATI Radeon X1300 系列的旧戴尔台式机。

我使用 LWJGL 创建了一个 Java 应用程序,它创建了一个 FBO。附加到 FBO 的纹理是屏幕的大小(东芝为 1366x768,戴尔为 1024x768)。

我在两台计算机上尝试相同的应用程序,使用名为 MSI Afterburner 的程序查看 CPU 使用率、GPU 使用率和帧率。

在东芝上,它运行完美,在戴尔上它挂起。稍后我会更好地解释。

以下是创建 FBO 的代码:

//Create FBO
DisplayMode display = Display.getDisplayMode();

int fboWidth  = display.getWidth();
int fboHeight = display.getHeight();

int fboTextureID = glGenTextures();
int fboID = glGenFramebuffersEXT(); 

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboID);

glBindTexture(GL_TEXTURE_2D, fboTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fboWidth, fboHeight, 0, GL_RGBA, GL_INT, 
(java.nio.IntBuffer) null);

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, fboTextureID, 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindTexture(GL_TEXTURE_2D, 0);

这是显示 FBO 的 while 循环:

while(true)

    renderFBO();

    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, fboTextureID);
    glBegin(GL_QUADS);

    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

    int x=0; int y=0; //FBO position
    int w=fboWidth; int h=fboHeight; //FBO size

    glTexCoord2f(0, 1);
    glVertex2f(x, y); 
    glTexCoord2f(1, 1);
    glVertex2f(x+w, y);
    glTexCoord2f(1, 0);
    glVertex2f(x+w, y+h);
    glTexCoord2f(0, 0);
    glVertex2f(x, y+h);

    glEnd();
    glBindTexture(GL_TEXTURE_2D, 0);

    glDisable(GL_TEXTURE_2D);
    Display.update(); //Update the screen
    Display.sync(60); //Cap the framerate to 60fps

此方法将一些纹理绘制到 FBO 屏幕外

private void renderFBO()
    
        glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

        //Start FBO drawing
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID );
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        //Here I draw some textures using quads

        //Stop FBO drawing
        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0);
        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    

正如我之前所说,东芝上的应用程序与 Radeon HD 完美结合。 5% CPU 使用率,20% GPU 使用率和 60fps。

在使用 Radeon X1300 的旧戴尔上执行此应用程序时,计算机会挂起; CPU使用率为50%,GPU无法测量,fps为0。

如果我不绘制 FBO,只是将其渲染到屏幕外,那么旧的戴尔不会挂起,我会得到正常结果 5% 的 CPU 使用率、20% 的 GPU 使用率和 60fps。

它在四边形中绘制 FBO 导致计算机挂起。我问,为什么? 为什么会这样?我的代码有问题吗?一开始我以为是电脑太旧了(2006 年的),处理 FBO 有问题,但是为什么在渲染 FBO 屏幕外时它没有挂起?

【问题讨论】:

【参考方案1】:

可能是显卡不支持 OpenGL 的问题,或者至少是您正在使用的功能的问题。

【讨论】:

【参考方案2】:

问题已解决

终于让它在旧戴尔上运行。我必须使用 2 纹理的幂。 ATI HD 显然可以处理 2 纹理的非幂,因此我可以将 1366x768 纹理大小附加到 FBO。但是,我无法使用 ATI X1300 附加 1024x768 纹理。 使用 1024x1024 纹理,我可以让应用程序以 60fps 的速度运行,并且 CPU 使用率很低。

【讨论】:

以上是关于在计算机上使用 OpenGL 绘制 FBO 挂起的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 帧缓冲区 + LibGDX

SDL2 OpenGL C++ 移动使用 VBO 和 FBO 绘制的精灵

FBO:渲染到纹理,绘制渲染纹理时纹理映射错误

基于Qt的OpenGL可编程管线学习- FBO的使用

OpenGL:渲染到 FBO 时是不是支持纹理组合器功能?

OpenGL 片段着色器未写入 fbo 颜色缓冲区