سؤال

I recently asked this question:

How to perform asynchronous off-screen queries?

What I've heard, but haven't been able to confirm yet, is that rendering to the window is more expensive than rendering to a framebuffer. First of all, can anyone comment on this? Can I draw multiple scenes to framebuffers faster than I can to the window? Are there other options, e.g., pbuffers or PBOs?

I have started playing around with framebuffers, but I have not been able to get the query to work. Here's some psuedo code for what I have set up so far:

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();

So far everything runs, but all of the queries return "0". Is there something about querying when drawing to a framebuffer that is different than when drawing to the window buffer?

Again, my two questions are:

  1. Can I draw multiple scenes to framebuffers faster than I can to the window? Are there other options, e.g., pbuffers or PBOs?
  2. Is there something about querying when drawing to a framebuffer that is different than when drawing to the window buffer?
هل كانت مفيدة؟

المحلول

Try something like this:

#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;
}

Representative output on my system:

cnt: 1884
0: 157288
1: 157288
2: 157289
3: 157288
4: 157287
5: 157286
6: 157292
7: 157286
8: 157289
9: 157288
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top