简体   繁体   English

OpenGL累积缓冲区不起作用

[英]OpenGL Accumulation buffer not working

I'm trying to use the accumulation buffer in OpenGL but for some reason the buffer does not appear to be filling. 我正在尝试在OpenGL中使用累积缓冲区,但是由于某些原因,该缓冲区似乎没有被填充。 I constructed a simple test application, a 2D plane being rendered and nothing else. 我构建了一个简单的测试应用程序,正在渲染2D平面,仅此而已。 This renders fine. 这很好。 I then tried doing the simplest possible accumulation buffer operation I could think of, loading the rendered frame into the accumulation buffer, clearing the screen and then returning the accumulation buffer to the screen. 然后,我尝试执行我能想到的最简单的可能的累积缓冲区操作,将渲染的帧加载到累积缓冲区中,清除屏幕,然后将累积缓冲区返回到屏幕。 When I do this it appears that the accumulation buffer contains no information at all, the image is simply the color the screen was cleared to, as though the accumulation buffer was never returned at all. 当我这样做时,似乎累积缓冲区根本不包含任何信息,图像只是清除了屏幕的颜色,就好像根本没有返回累积缓冲区一样。 I've also tried doing a more traditional motion blur setup, making multiple updates to the scene and buffer before returning it and got the same result. 我还尝试过进行更传统的运动模糊设置,对场景和缓冲区进行多次更新,然后再返回并获得相同的结果。

This is the main loop for the simple test: 这是简单测试的主要循环:

SDL_Event eve;
while (true)
{
    //Normal stuff
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    //Accumulation///////////////////////
    glAccum(GL_LOAD, 1.0f);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glAccum(GL_RETURN, 1.0f);
    //Accumulation///////////////////////

    SDL_GL_SwapWindow(window);

    SDL_PollEvent(&eve);
}

And this is the main loop for the motion blur test: 这是运动模糊测试的主要循环:

float x = 0.0f;

int step = 0;
int steps = 4;

SDL_Event eve;
while (true)
{
    //Test stuff
    x += 0.005f;

    GLfloat newVerts[] = {
        -0.5f + x,  0.5f,
        0.5f + x,  0.5f,
        0.5f + x, -0.5f,
        -0.5f + x, -0.5f,
    };

    glBufferData(GL_ARRAY_BUFFER, sizeof(newVerts), newVerts, GL_STATIC_DRAW);

    //Normal stuff
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    //Accumulation///////////////////////
    if (step == 0)
    {
        glAccum(GL_LOAD, 1.0f / steps);
    }
    else
    {
        glAccum(GL_ACCUM, 1.0f / steps);
    }

    step++;

    if (step < steps)
    {
        continue;
    }

    step = 0;
    glAccum(GL_RETURN, 1.0f);
    //Accumulation///////////////////////

    SDL_GL_SwapWindow(window);

    SDL_PollEvent(&eve);
}

This is the full application source (it's only about 100 lines, I'm including it just incase something is wrong with my glEnable or SDL_GL_SetAttribute calls): 这是完整的应用程序源(只有大约100行,我包括了它,以防glEnableSDL_GL_SetAttribute调用出现问题):

#include "tools.h"

static string vertexSource = getFile("D:/test.vsh");
static string fragmentSource = getFile("D:/test.fsh");

int main(int argc, char *argv[])
{
    //SDL///////////////////////////////////////////////
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

    SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8);

    SDL_Window *window = SDL_CreateWindow("Test", 50, 50, 1600, 900, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

    SDL_GLContext context = SDL_GL_CreateContext(window);

    //GLEW///////////////////////////////////////////////
    glewExperimental = GL_TRUE;
    GLint result = glewInit();

    if (result != GLEW_OK)
    {
        cout << glewGetErrorString(result) << "\n";
        cout << "GLEW initialization failed.\n";
    }

    //OpenGL///////////////////////////////////////////////
    glEnable(GL_DEPTH);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
    glClearDepth(1.0f);

    //Object///////////////////////////////////////////

    //Vertex Array
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    //Vertex Buffer
    GLuint vbo;
    glGenBuffers(1, &vbo);

    GLfloat vertices[] = {
        -0.5f,  0.5f,
        0.5f,  0.5f,
        0.5f, -0.5f,
        -0.5f, -0.5f,
    };

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //Element Buffer
    GLuint ebo;
    glGenBuffers(1, &ebo);

    GLuint elements[] = {
        0, 1, 2,
        2, 3, 0
    };

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

    //Shader
    GLuint shaderProgram = createShader(vertexSource, fragmentSource);
    glUseProgram(shaderProgram);

    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

    //Loop///////////////////////////////////////////////
    float x = 0.0f;

    int step = 0;
    int steps = 4;

    SDL_Event eve;
    while (true)
    {
        //Test stuff
        x += 0.005f;

        GLfloat newVerts[] = {
            -0.5f + x,  0.5f,
            0.5f + x,  0.5f,
            0.5f + x, -0.5f,
            -0.5f + x, -0.5f,
        };

        glBufferData(GL_ARRAY_BUFFER, sizeof(newVerts), newVerts, GL_STATIC_DRAW);

        //Normal stuff
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        //Accumulation///////////////////////
        if (step == 0)
        {
            glAccum(GL_LOAD, 1.0f / steps);
        }
        else
        {
            glAccum(GL_ACCUM, 1.0f / steps);
        }

        step++;

        if (step < steps)
        {
            continue;
        }

        step = 0;
        glAccum(GL_RETURN, 1.0f);
        //Accumulation///////////////////////

        SDL_GL_SwapWindow(window);

        SDL_PollEvent(&eve);
    }
}

I'm using GLEW to get access to the OpenGL calls and I'm using SDL for context creation and window management. 我正在使用GLEW来访问OpenGL调用,并且正在使用SDL进行上下文创建和窗口管理。

General specifications of the platform I'm running this on: 我在以下平台上运行的平台的一般规格:

  • OpenGL 4.5 (also tried with 4.3 and 3.3, no difference). OpenGL 4.5(也尝试使用4.3和3.3,没有区别)。
  • Windows 10 64 bit Windows 10 64位
  • AMD FX-9590 @ 4.7 GHz AMD FX-9590 @ 4.7 GHz
  • NVIDIA GTX 970 SC NVIDIA GTX 970 SC
  • ASUS Sabertooth 990FX 华硕Sabertooth 990FX
  • 16GB DDR3 RAM 16GB DDR3内存
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Removed functionality (like accumulation buffers) won't work in a Core context. 删除的功能(例如累积缓冲区)在Core上下文中不起作用。

OpenGL 3.2 Core spec, appendix E, page 329 & 333: OpenGL 3.2核心规范,附录E,第329和333页:

E.2 Deprecated and Removed Features E.2不推荐使用和删除的功能

... ...

Functions which have been removed will generate an INVALID_OPERATION error if called in the core profile or in a forward-compatible context. 如果在核心配置文件中或在前向兼容的上下文中调用,已删除的函数将产生INVALID_OPERATION错误。

... ...

E.2.2 Removed Features E.2.2删除的功能

... ...

Accumulation buffers - ClearAccum , and ACCUM_BUFFER_BIT is not valid as a bit in the argument to Clear (section 4.2.3); 累加缓冲区ClearAccumACCUM_BUFFER_BITClear的参数中无效(第4.2.3节); Accum ; Accum ; the ACCUM_*_-BITS framebuffer state describing the size of accumulation buffer components; ACCUM_*_-BITS帧缓冲器状态,描述累积缓冲器组件的大小; and all associated state. 以及所有相关状态。

Window system-binding APIs such as GLX and WGL may choose to either not expose window configs containing accumulation buffers, or to ignore accumulation buffers when the default framebuffer bound to a GL context contains them. 诸如GLX和WGL之类的窗口系统绑定API可以选择不公开包含累积缓冲区的窗口配置,或者在绑定到GL上下文的默认帧缓冲区包含它们时忽略累积缓冲区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM