OpenGL累积缓冲区不工作

OpenGL Accumulation buffer not working

本文关键字:工作 缓冲区 OpenGL      更新时间:2023-10-16

我试图在OpenGL中使用累积缓冲区,但由于某些原因,缓冲区似乎没有填充。我构建了一个简单的测试应用程序,一个正在渲染的2D平面,其他什么都没有。这渲染良好。然后,我尝试做我能想到的最简单的累积缓冲区操作,将渲染的帧加载到累积缓冲区,清除屏幕,然后将累积缓冲区返回到屏幕。当我这样做时,累积缓冲区似乎根本不包含任何信息,图像只是屏幕被清除到的颜色,就好像累积缓冲区根本没有返回一样。我还尝试了一种更传统的运动模糊设置,在返回之前对场景和缓冲区进行多次更新,得到了相同的结果。

这是简单测试的主循环:

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

这是运动模糊测试的主要循环:

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

这是完整的应用程序源代码(只有大约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);
    }
}

我使用GLEW来访问OpenGL调用,并使用SDL来创建上下文和管理窗口。

我正在运行的平台的一般规范:

  • OpenGL 4.5(也尝试过4.3和3.3,没有区别)
  • Windows 10 64位
  • AMD FX-9590@4.7 GHz
  • NVIDIA GTX 970 SC
  • 华硕Sabertoth 990FX
  • 16GB DDR3内存
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^

删除的功能(如累积缓冲区)在Core上下文中不起作用。

OpenGL 3.2核心规范,附录E,第329页;333:

E.2弃用和删除的功能

已删除的函数将生成INVALID_OPERATION如果在核心配置文件或前向兼容上下文中调用,则出错。

E.2.2删除了功能

累积缓冲区-ClearAccumACCUM_BUFFER_BIT作为Clear自变量中的一个位无效(第4.2.3节);Accum;CCD_ 8帧缓冲器状态描述累积缓冲器分量的大小;以及所有相关联的状态。

GLX和WGL等窗口系统绑定API可以选择不公开包含累积缓冲区的窗口配置,或者在绑定到GL上下文的默认帧缓冲区时忽略累积缓冲区。