OpenGL: glAccum error 1282 (Invalid Operation)

2019-08-21 02:15发布

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).

2条回答
三岁会撩人
2楼-- · 2019-08-21 02:54

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.

查看更多
霸刀☆藐视天下
3楼-- · 2019-08-21 02:58

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.

查看更多
登录 后发表回答