OpenGL 累积缓冲区不工作
OpenGL Accumulation buffer not working
我正在尝试在 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 行,我将其包括在内只是为了防止我的 glEnable
或 SDL_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 进行上下文创建和 window 管理。
我运行这个平台的一般规格:
- OpenGL 4.5(也尝试过 4.3 和 3.3,没有区别)。
- Windows 10 64 位
- AMD FX-9590 @ 4.7 GHz
- 英伟达 GTX 970 SC
- 华硕剑齿虎 990FX
- 16GB DDR3 内存
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
^^^^^^^^^^^^^^^^^^^^^^^^^^^
删除的功能(如累积缓冲区)在核心上下文中不起作用。
OpenGL 3.2 Core spec, appendix E, page 329 & 333:
E.2 Deprecated and Removed Features
...
Functions which have been removed will generate an INVALID_OPERATION
error if called in the core profile or in a forward-compatible context.
...
E.2.2 Removed Features
...
Accumulation buffers - ClearAccum
, and ACCUM_BUFFER_BIT
is not valid as a bit in the argument to Clear
(section 4.2.3); Accum
; the ACCUM_*_-BITS
framebuffer state describing the size of accumulation buffer components; 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.
我正在尝试在 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 行,我将其包括在内只是为了防止我的 glEnable
或 SDL_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 进行上下文创建和 window 管理。
我运行这个平台的一般规格:
- OpenGL 4.5(也尝试过 4.3 和 3.3,没有区别)。
- Windows 10 64 位
- AMD FX-9590 @ 4.7 GHz
- 英伟达 GTX 970 SC
- 华硕剑齿虎 990FX
- 16GB DDR3 内存
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
^^^^^^^^^^^^^^^^^^^^^^^^^^^
删除的功能(如累积缓冲区)在核心上下文中不起作用。
OpenGL 3.2 Core spec, appendix E, page 329 & 333:
E.2 Deprecated and Removed Features
...
Functions which have been removed will generate an
INVALID_OPERATION
error if called in the core profile or in a forward-compatible context....
E.2.2 Removed Features
...
Accumulation buffers -
ClearAccum
, andACCUM_BUFFER_BIT
is not valid as a bit in the argument toClear
(section 4.2.3);Accum
; theACCUM_*_-BITS
framebuffer state describing the size of accumulation buffer components; 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.