跟进:异步屏幕外查询性能

时间:2014-01-28 19:03:29

标签: c++ opengl asynchronous glfw

我最近问过这个问题:

How to perform asynchronous off-screen queries?

我所听到的,但还未能确认的是,渲染窗口比渲染帧缓冲更昂贵。首先,有人可以对此发表评论吗?我可以比窗口更快地将多个场景绘制到帧缓冲区吗?还有其他选择,例如pbuffers还是PBO?

我已经开始使用framebuffers,但我无法让查询工作。这是我到目前为止所设置的一些伪代码:

glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
window = glfwCreateWindow(1, 1, "OpenGL", NULL, NULL);

glfwMakeContextCurrent(window);

glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);

glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);

glEnable(GL_DEPTH_TEST);
glGenQueries(numberOfQueries, queries);

for (scene in scenesToRender)
{
    glClear(GL_DEPTH_BUFFER_BIT);


    glDepthFunc(GL_LESS);
    drawShadingObjects(scene);

    glBeginQuery(GL_SAMPLES_PASSED, queries[index]);

    glDepthFunc(GL_LEQUAL);
    drawShadedObject(scene);

    glEndQuery(GL_SAMPLES_PASSED);

}

collectQueryResults();

deleteBuffers();

到目前为止一切都在运行,但所有查询都返回“0”。在绘制到与绘制到窗口缓冲区时不同的帧缓冲区时,是否有关于查询的内容?

同样,我的两个问题是:

  1. 我可以比窗口更快地将多个场景绘制到帧缓冲区吗?还有其他选择,例如pbuffers还是PBO?
  2. 在绘制到与绘制到窗口缓冲区时不同的帧缓冲区时,是否有关于查询的内容?

1 个答案:

答案 0 :(得分:1)

尝试这样的事情:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <vector>
using namespace std;

const unsigned int sz = 1024;
void drawScene( unsigned int multiplier )
{
    glViewport( 0, 0, sz, sz );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glRotatef( (float)glfwGetTime() * 50.f * multiplier, 0.f, 0.f, 1.f);
    glBegin(GL_TRIANGLES);
    glColor3f(1.f, 0.f, 0.f);
    glVertex3f(-0.6f, -0.4f, 0.f);
    glColor3f(0.f, 1.f, 0.f);
    glVertex3f(0.6f, -0.4f, 0.f);
    glColor3f(0.f, 0.f, 1.f);
    glVertex3f(0.f, 0.6f, 0.f);
    glEnd();
}

bool available( const vector< GLuint >& queries )
{
    for( size_t i = 0; i < queries.size(); ++i )
    {
        GLuint available = 0;
        glGetQueryObjectuiv( queries[i], GL_QUERY_RESULT_AVAILABLE, &available );
        if( GL_FALSE == available )
            return false;
    }
    return true;
}

int main()
{
    glfwInit();
    GLFWwindow* window = glfwCreateWindow( 400, 400, "Simple example", NULL, NULL );
    glfwMakeContextCurrent( window );
    glewInit();

    if( !glewIsSupported( "GL_VERSION_2_1" ) )
        return -1;
    if( !glewIsSupported( "GL_EXT_framebuffer_object" ) )
        return -1;

    GLuint fbo = 0;
    glGenFramebuffersEXT( 1, &fbo );
    glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, fbo );

    GLuint rbo0 = 0;
    glGenRenderbuffersEXT( 1, &rbo0 );
    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbo0 );
    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_RGBA, sz, sz );
    glFramebufferRenderbufferEXT( GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rbo0 );

    GLuint rbo1 = 0;
    glGenRenderbuffersEXT( 1, &rbo1 );
    glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbo1 );
    glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, sz, sz );
    glFramebufferRenderbufferEXT( GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo1 );

    GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
    if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
        return -1;

    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );

    vector< GLuint > queries( 10 );
    glGenQueries( queries.size(), &queries[0] );

    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo );

    for( size_t i  = 0; i < queries.size(); ++i )
    {
        glBeginQuery( GL_SAMPLES_PASSED, queries[i] );
        drawScene( i + 1 );
        glEndQuery( GL_SAMPLES_PASSED );
    }

    glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );

    // wait for queries to become available
    unsigned int cnt = 0;
    while( !available( queries ) )
    {
        cnt++;
    }

    // all queries available, display query results
    cout << "cnt: " << cnt << endl;
    for( size_t i = 0; i < queries.size(); ++i )
    {
        GLuint samples = 0;
        glGetQueryObjectuiv( queries[i], GL_QUERY_RESULT, &samples );
        cout << i << ": " << samples << endl;
    }
    cout << endl;

    glfwDestroyWindow( window );
    glfwTerminate();
    return 0;
}

我系统上的代表性输出:

cnt: 1884
0: 157288
1: 157288
2: 157289
3: 157288
4: 157287
5: 157286
6: 157292
7: 157286
8: 157289
9: 157288