OpenGL:glAccum 错误 1282(无效操作)
编辑:添加了一些错误检查代码,发现当我执行 glAccum(..) 时抛出错误“1282”。
Edit2:我在另一台计算机上尝试了完全相同的代码,它在那里完美运行。
Edit3:“解决方案”ATI HD4xxx 及以上卡不再支持累积缓冲区:*(
因此它无法在具有 HD4850 和最新驱动程序的 Windows 7 64 位上运行 它可以在带有 Intel 系列 4 IGP 的 Windows 7 32 位上运行。 (GL_ACCUM_RED_BITS = 16)。 我还在一台基于 Linux 的机器上非常快速地尝试过它,我不知道该机器的确切规格,但它也在那里工作。所以我想这确实与我的计算机中的某些东西有关:(。虽然我不知道是什么,所以欢迎任何提示。
这是原来的问题。
我正在尝试使用 glAccum 生成 DOF 效果,但是调用glAccum 似乎没有任何效果。我已将问题简化为一个简单的测试用例,其中在 for 循环中我沿 x 轴平移一些球体,如您所见,当我尝试复制时报告了错误。 另外,当我检查累积缓冲区
中可用的红色位数时,结果是 0。这意味着它没有初始化?!
我已经设置了这样的显示模式:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_ACCUM | GLUT_DEPTH);
glClearAccum(0.0, 0.0, 0.0, 0.0);
所以累积 我
我的显示方法如下所示:
void display(void)
{
int i;
GLint test[1];
float weigth = 1.0/(float)apertureSamples;
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
HandleKeyboardInput();
glLoadIdentity();
UpdateCamera();
glClear(GL_ACCUM_BUFFER_BIT);
glGetIntegerv(GL_ACCUM_RED_BITS, test);
//No errors here but the number of red bits is 0!?
for(i = 0; i < apertureSamples; i++)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(10*i, 0, 0);
DrawScene(); //draw a couple of spheres
glPopMatrix();
//Still no errors here
glAccum(GL_ACCUM, weigth);
//If I check for errors here I get error 1282
glFlush();
}
glAccum(GL_RETURN, 1.0);
glutSwapBuffers();
}
现在希望看到球体的模糊轨迹,移动到右侧,但我没有,相反,我只看到 forloop 的最后一次迭代(所有球体)在 x 轴上翻译为 10*appertureSamples)。
为了测试 glAccum 是否做了任何事情,我将权重变量更改为 0.00001,这应该会影响每个帧都被绘制得非常“薄”(我的英语词汇)把我留在这里)。但这似乎没有任何影响。然后我将 glAccum(GL_RETURN, 1.0) 更改为 gl_Accum(GL_RETURN, 0.0001);这又什么也没做(但应该使整个输出图片更薄。
我已经从这里遵循了 DOF 和 JITTER 下的所有步骤: http://glprogramming.com/red/chapter10.html 我找不到任何我丢失的东西。有人有任何提示吗?
(顺便说一句,我是在 Windows 7 上执行此操作的)配备 Radeon HD4850 GPU 的计算机)。
Edit: added some error checking code and found error '1282' is being thrown when I do glAccum(..)
Edit2: I've tried the exact same code on a different computer, it works perfectly there.
Edit3: 'Solution' ATI HD4xxx and up cards dont support accumulation buffers anymore :*(
So it doesn't work on Windows 7 64bit with a HD4850 and up-to-date drivers
It does work on Windows 7 32bit with an Intel series 4 IGP. (GL_ACCUM_RED_BITS = 16).
I also tried it really really quick on a Linux based machine of which I don't know the exact specs, it worked there too. So I guess it really has todo with something in my computer :(. I dont know what though, so any tips are welcome.
Here is the original question.
I'm trying to use glAccum to generate a DOF effect, but the calls to glAccum don't seem to have any effect. I've reduced the problem to a simple test case where in a for loop I translate some spheres along the x-axis. As you can see an error is reported when I try to copy the colour buffer data to the accumulation buffer.
Additionally when I check the number of red bits available in the accumulation buffer, the result is 0. Which would mean that its not initialized?!
I've setup the display mode like this:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_ACCUM | GLUT_DEPTH);
glClearAccum(0.0, 0.0, 0.0, 0.0);
So the accumulation buffer should be available.
My display method looks like this:
void display(void)
{
int i;
GLint test[1];
float weigth = 1.0/(float)apertureSamples;
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
HandleKeyboardInput();
glLoadIdentity();
UpdateCamera();
glClear(GL_ACCUM_BUFFER_BIT);
glGetIntegerv(GL_ACCUM_RED_BITS, test);
//No errors here but the number of red bits is 0!?
for(i = 0; i < apertureSamples; i++)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(10*i, 0, 0);
DrawScene(); //draw a couple of spheres
glPopMatrix();
//Still no errors here
glAccum(GL_ACCUM, weigth);
//If I check for errors here I get error 1282
glFlush();
}
glAccum(GL_RETURN, 1.0);
glutSwapBuffers();
}
I would now expect to see a blurred trail of the spheres, moved to the right, but I don't, instead I only see the last iteration of the forloop (all the spheres translated on the x-axis by 10*appertureSamples).
To test if glAccum was doing anything at all, I've changed the weigth variable to 0.00001 which should have as affect that the each frame is drawn very 'thin' (my English vocabulary left me here). But this doesnt seem to have any affect. Then I changed glAccum(GL_RETURN, 1.0) to gl_Accum(GL_RETURN, 0.0001); which again did nothing (but should've made the entire output picture thinner.
I've followed all the steps under DOF and JITTER from here: http://glprogramming.com/red/chapter10.html and I cant find anything that I'm missing. Does anybody have any tips?
(Btw I'm doing this on a Windows 7 computer with a Radeaon HD4850 GPU).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果 GL_ACCUM_RED_BITS 为零,则意味着您没有累加缓冲区,您的 GL 实现至少应在软件中支持它。 glAccum 处的错误还表明不存在累积缓冲区。
你为什么首先使用累积缓冲区?您可以使用着色器、帧缓冲区对象和浮点纹理来实现相同的效果,并且它还与现代 OpenGL 实现兼容。
If the GL_ACCUM_RED_BITS is zero, it means you don't have a accumlation buffer, your GL implementation should support it at least in software. The error at glAccum suggests also suggests that no accumulation buffer exists.
Why are you using the accumulation buffer in the first place? You can do the same effect using Shaders, Framebuffer Objects and Floating point textures, and it's also compatible with modern OpenGL implementations.
您可能没有累积缓冲区。但无论如何你都不需要一个。景深效果现在使用着色器完成。累积缓冲方式需要多次渲染同一张图片;效率不太高。着色器景深是一种后处理效果,它使用 Z 缓冲区值来选择模糊内核的大小。这个想法是收集当前片段周围的值,并通过 Z 值确定的模糊内核大小添加每个相邻片段。为了保持内部循环较小,您通常会以几个内核大小模糊整个图像,并将它们放入 3D 纹理层中。然后,该 3D 纹理用于快速获取所需的模糊强度。
You probably don't have an accumulation buffer. But you don't need one anyway. Depth of Field effects are now done using shaders. The accumulation buffer method requires to render the same picture multiple times; not quite efficient. Shader Depth of Field is a postprocessing effect, that used the Z-buffer values to select the size of a blurring kernel. The idea is to do gather the values around the current fragment and add each neighbour fragment by the blurring kernel size determined by the Z-value. To keep the inner loop small you normally blur the whole image at several kernel sizes and put those into layers of a 3D texture. Then this 3D texture is used for a quick fetch of the desired blurring intensity.