So on my hardware, the accumulation buffer idea worked, but incredibly slowly. We’re talking seconds per frame.
I finished off the setup for the texture rendering idea, and here’s the code for anyone who wants to know:
before the first scene:
void Transition::drawInitial(float time)
{
glViewport(0, 0, FADE_TEXTURE_SIZE_X, FADE_TEXTURE_SIZE_Y);
}
between the two scenes:
void Transition::drawBetween(float time)
{
glReadBuffer(GL_BACK);
if(tex == 0)
{
glGenTextures(1, &tex);
externalBind(tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, FADE_TEXTURE_SIZE_X, FADE_TEXTURE_SIZE_Y, 0);
}
else
{
externalBind(tex);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, FADE_TEXTURE_SIZE_X, FADE_TEXTURE_SIZE_Y);
}
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, RESOLUTION_X, RESOLUTION_Y);
}
and finally, after the last scene
void Transition::drawFinal(float time)
{
externalBind(tex);
glBegin(GL_TRIANGLE_FAN);
glColor4f(1, 1, 1, 1.0f-time/length);
glTexCoord2f(0, 1);
glVertex2f(0, 0);
glTexCoord2f(1, 1);
glVertex2f(800, 0);
glTexCoord2f(1, 0);
glVertex2f(800, 600);
glTexCoord2f(0, 0);
glVertex2f(0, 600);
glEnd();
}
The “length” variable is the amount of time that it takes this transition to run, and the passed in “time” variable is the time since the transition started. “tex” is just a GLuint variable in the class that stores the texture when necessary.
RESOLUTION_X and _Y are the size of the screen, and FADE_TEXTURE_SIZE_X and _Y are the size of the texture that the current scene will be drawn to. If it’s too much lower than the resolution you’re working at, then it will look blurry.
I’m using 512x512 for my 800x600 screen, and I’m bogging down to 60fps, which is acceptable. It also looks really nice, and I’m liking the effect.