使用GLFW的累积缓冲液

时间:2014-06-02 08:35:32

标签: opengl buffer glfw

我必须在我的openGL项目中使用累积缓冲区(DOF渲染),但它似乎不适用于GLFW库。 我在圆圈上正确移动相机,拍摄21张“镜头”(左边10张,正常位置1张,右边10张),将所有照片添加到累积缓冲区(乘以1/21),然后我处于“正常”位置,我显示缓冲区。然而,图像仍然没有被遮盖,但渲染速度比以前慢21倍。 主循环是:

    int _tmain(int argc, _TCHAR* argv[]) {

    // GLFW initialisation
    if (!glfwInit()) {
        return -1;
    }
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);
    glfwWindowHint(GLFW_SAMPLES, 16);
    GLFWwindow* window;
    window = glfwCreateWindow( 800, 600, "DOF", NULL, NULL);
    if ( !window ) {
        glfwTerminate();
        return -1;
    }   
    glfwMakeContextCurrent(window);

    // check for errors
    GLenum err = glGetError(); 
    if( err ) {
        fprintf( stderr, "ERROR: %s\n", glewGetErrorString( err ) );
        exit(EXIT_FAILURE);
    }

    // GLEW init
    glewExperimental = GL_TRUE;
    GLenum GlewInitResult;
    GlewInitResult = glewInit();
    if (GLEW_OK != GlewInitResult) {
        fprintf( stderr, "ERROR: %s\n", glewGetErrorString(GlewInitResult));
        exit(EXIT_FAILURE);
    }

    // main loop
    Game game;
    game.Init();
    Keyboard::KeyboardInit();
    glEnable(GL_DEPTH_TEST);
    glClear(GL_ACCUM_BUFFER_BIT);
    while (!glfwWindowShouldClose(window))
    {
        glAccum(GL_ACCUM, 1 / (game.getSteps() * 2 + 1)); // steps = 10
        game.nextStep(); //increments step by one
        game.Update();
        game.Redraw();
        if (game.getStep() == 1) {
            glAccum(GL_RETURN, 1);
            glfwSwapBuffers(window);
        }

        glfwPollEvents();

        calcFPS(2.0, "DOF", window);
    }

    glfwTerminate();

    return 0;
}

1 个答案:

答案 0 :(得分:2)

请注意,积累缓冲是过去的事情,并且在大多数具有现代OpenGL配置文件的消费卡上都没有加速;它更有可能得到专业级卡的支持。

无论如何,你必须要求一个累积缓冲区来获得一个。但是,您要求提供 OpenGL-3.3核心配置文件,这为您提供了比累积缓冲区更好的功能:Framebuffer Objects。这些被广泛支持(如果使用FBO扩展,即使是可追溯到2000年之前的非常旧的硬件)并且允许更大的灵活性。

通常的做法是:

  1. 将场景渲染为纹理
  2. 将此纹理与glBlendFunc(GL_SRC_ALPHA, GL_ONE)混合绘制为具有HDR格式(GL_RGB16或类似)且alpha值为1 / n且n为累积步骤量的累积纹理
  3. 您通常会为此创建两个单独的FBO。伪代码

    for step in DOF:
        glBindFramebuffer(scenedraw_FBO)
        draw_scene()
    
        glBindFramebuffer(accumulation_FBO)
        glBindTexture(…, scenedraw_texture)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE)
        glColor4f(1.,1.,1., 1./(float)count(DOF) )
        draw_fullscreen_textured_quad()
        glBindTexture(…, 0)
    

    您可以使用浮动纹理格式并使用glBlendFunc(GL_ONE, GL_ONE)混合,而不是使用Alpha值进行缩放。但浮动纹理并不受广泛支持。