Implimenting fade into game engine
Just curious how a game 'should' impliment its fading.
Should it be part of the main game loop?
Should it have its own loop?
I do not want to add any more if..then's in the main game loop to simply add a fade. I figured I could maybe add the quad as a unit into the unit pool.
Is there perhaps a way to capture the screen as is, then run a seperate loop and render the screen as you captured it then render quad over it as you fade...
Sure, just slowly increasing a foreground black rectangle's alpha should produce the desired effect.
Not sure if it's the 'right' way though.
I actually implimented fading as a particle system effect in my last project. I'd just create a new particle system, set the effect and move the objects to be faded out into it. That's likely not the right way though :]
Not sure if it's the 'right' way though.
I actually implimented fading as a particle system effect in my last project. I'd just create a new particle system, set the effect and move the objects to be faded out into it. That's likely not the right way though :]
The fading to black (or white) effect is usually done by adjusting the monitor gamma setting. Or at least it used to be, I can't tell you for sure that it's still the most common method.
You'd put it in your game loop btw, to get the nicest result.
You'd put it in your game loop btw, to get the nicest result.
If i'm understanding you properly, you want to fade from one screen to another. Correct? If so, there are several things you could do (assuming you are using a 3D lib, given your wording):
1) simple fade-to-black: freeze the action and start drawing a semi-transparent black quad the size of the screen on top of everything else. Gradually increase the opacity. Tada! Then do the same thing in reverse to fade-into-screen.
2) screen2screen fading is a little trickier. basically what you want to do is change states (i'm assuming you have some kind of state changing logic in your code somewhere to control which screen you are on?) and immediately grab the data out of the screen buffer. Turn it into a texture and use the same trick option #1 uses, only using the textured quad instead of black as you fade into the new screen. I just recently implemented this and it's very cool. Once you have the data from the old screen buffer you can abuse it to your heart's desire. All kinds of slick screenswipe effects are now at your disposal.
If you are using OpenGL, here is some code to grab the screen. I hope you find it helpfull:
As far as where to put it, it probably goes with whatever code you are using to manage the game state (start screen, action mode, highscore list screen, etc). It would be wise to encapsulate the effect in a class of it's own so that you can plug in any number of transition effects.
1) simple fade-to-black: freeze the action and start drawing a semi-transparent black quad the size of the screen on top of everything else. Gradually increase the opacity. Tada! Then do the same thing in reverse to fade-into-screen.
2) screen2screen fading is a little trickier. basically what you want to do is change states (i'm assuming you have some kind of state changing logic in your code somewhere to control which screen you are on?) and immediately grab the data out of the screen buffer. Turn it into a texture and use the same trick option #1 uses, only using the textured quad instead of black as you fade into the new screen. I just recently implemented this and it's very cool. Once you have the data from the old screen buffer you can abuse it to your heart's desire. All kinds of slick screenswipe effects are now at your disposal.
If you are using OpenGL, here is some code to grab the screen. I hope you find it helpfull:
glReadBuffer(GL_FRONT); // create a texture from raw memory GLuint texture_num = 0; GLubyte* texture_pixels = new GLubyte[1024*1024*3]; glGenTextures( 1, &texture_num ); glBindTexture( GL_TEXTURE_2D, texture_num ); glTexImage2D( GL_TEXTURE_2D, 0, 3, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_pixels ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // get the screen contents GLubyte* screenshot_pixels = new GLubyte[800*600*3]; glReadPixels(0,0,800,600, GL_RGB, GL_UNSIGNED_BYTE, screenshot_pixels); // substitute the screen contents into the texture glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 800, 600, GL_RGB, GL_UNSIGNED_BYTE, screenshot_pixels); // delete raw data delete[] texture_pixels; delete[] screenshot_pixels;
As far as where to put it, it probably goes with whatever code you are using to manage the game state (start screen, action mode, highscore list screen, etc). It would be wise to encapsulate the effect in a class of it's own so that you can plug in any number of transition effects.
I didn't review your code much since as soon as I read "grab the screen and copy it to a texture" one of my answers we given.
I am fading the screen using a screen aligned quad and slowly adusting the vertex alpha's from 0 to FF.
Now my last remaining question is how should I impliment this, but I suppose this is a choice of game engine so it is up to me. I want to avoid having to add an if..then into the main game loop, there is no point in checking every frame if a fade should be occuring. Likely the best solution is to freeze the frame, render to a texture, enter a new loop, render that texture as a screen quad and then fade like I already em.
I can likely invoke screen to screen like this very easily like you said.
I am just having problems visioning a simple way for me to fade each time a user does an action that requires fading.
Thanks.
Edit: How come the texture_pixels you allocate are ResX * ResX * 3. I figured it would be ResX * ResY * 3...
I am fading the screen using a screen aligned quad and slowly adusting the vertex alpha's from 0 to FF.
Now my last remaining question is how should I impliment this, but I suppose this is a choice of game engine so it is up to me. I want to avoid having to add an if..then into the main game loop, there is no point in checking every frame if a fade should be occuring. Likely the best solution is to freeze the frame, render to a texture, enter a new loop, render that texture as a screen quad and then fade like I already em.
I can likely invoke screen to screen like this very easily like you said.
I am just having problems visioning a simple way for me to fade each time a user does an action that requires fading.
Thanks.
Edit: How come the texture_pixels you allocate are ResX * ResX * 3. I figured it would be ResX * ResY * 3...
What you're currently doing is probably the easiest/most effective way. Freezing the frame wouldn't allow you to have the scene keep running while its fading.
Whats wrong with having it in your main game loop? Just put it all in a function then call that function at the end of your render function.
[edit]
As far as shaders go, I am probably going to implement fade as part of my post processing system, seeing as i already have that set up.
[/edit]
Whats wrong with having it in your main game loop? Just put it all in a function then call that function at the end of your render function.
void Render(){ . . . UpdateScreenFade();}void UpdateScreenFade(){ if (!fading) return; // render fade polygon over the screen according to current fadeyness . . .}
[edit]
As far as shaders go, I am probably going to implement fade as part of my post processing system, seeing as i already have that set up.
[/edit]
That is what I want to avoid.
I want to be able to call up a fade when necessary and have all game action freeze until the fade is done without having to do something like
while (bGame)
{
UpdateLogic()
if (bfade)
{
UpdateFade()
}
}
thats an extra if..then. I'd rather just add for example if the user desires to go to his status screen, then freeze frame, fade, resume.
How can I use a pixel shader to impliment the frame freeze? I have yet to get to the pixel shader part of my engine yet nor do I know much about them.
I want to be able to call up a fade when necessary and have all game action freeze until the fade is done without having to do something like
while (bGame)
{
UpdateLogic()
if (bfade)
{
UpdateFade()
}
}
thats an extra if..then. I'd rather just add for example if the user desires to go to his status screen, then freeze frame, fade, resume.
How can I use a pixel shader to impliment the frame freeze? I have yet to get to the pixel shader part of my engine yet nor do I know much about them.
I would think that freezing the action first would be the preferred thing to do. Imagine that you enter a door and the screen fades to black as you enter the next room. Just as the screen gets close to full black a bullet you couldn't see catches you in the back. Grrr...
Agreed, I'm thinking the following:
- Enter a door for example
- Stop rendering,
- get a copy of the current front buffer, copy its bits to a texture
- Enter a new Loop to fade with.
- Render the texture onto a quad then render another quad over top as the fader.
- Once fading is done, loop exits, gameLoop carries on.
See you need that frozen frame or else you have to update the rendering still in your gameLoop while you fade since you need the scene to fade.
- Enter a door for example
- Stop rendering,
- get a copy of the current front buffer, copy its bits to a texture
- Enter a new Loop to fade with.
- Render the texture onto a quad then render another quad over top as the fader.
- Once fading is done, loop exits, gameLoop carries on.
See you need that frozen frame or else you have to update the rendering still in your gameLoop while you fade since you need the scene to fade.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement