Sign in to follow this  
Halsafar

Implimenting fade into game engine

Recommended Posts

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

Share this post


Link to post
Share on other sites
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 :]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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:

	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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.


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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.


Share this post


Link to post
Share on other sites
Here is the exact way that i do it for a screen2screen "swap fade" (topmost picture here under "transitions"):

First let me explain that i have a layered object processor. You can insert objects for updating onto any of the layers (background, sprite, foreground, GUI, etc). One of the layers is a dedicated "transition layer". All of the layers can be "frozen" (they treat the frame delta-time as zero).

So:
- we are on the title screen
- user presses enter to start "action mode"
- on the next game loop start, the state manager changes states, deletes all objects associated with the previous state. We are now in action mode, technically. The world is created as well as the player.
- all layers are frozen except the "transition layer"
- a new TransitionEffect object is created and given to the object procesor
- The TransitionEffect object grabs the backbuffer (a rendering of the previous Title Screen - we still haven't started rendering the first frame of Action Mode yet) and creates a texture out of it.
- each trip though the game loop, the only active object is the TransitionEffect which renders the screenshot on top of the new world and object contained by it, created by the Action Mode. ALthough all the other objects are frozen, they still render.
- When the TransitionEffect draws the old screenshot at 100% transparency (you can't see it and only the new screen is visible now), it gets removed from the list of update objects and all the normal layers are thawed.
- Action continues.

Somewhere in there you also want to block player input as well. You could hit the "fire" button several times before the new screen fades in and you fire several shots as soon as player control resumes.

Share this post


Link to post
Share on other sites
I implemented a fade-between-screens effect in a previous incarnation of my previous project, and you can see it (albeit on momentarily) in these video clips:

Clip 1
Clip 2

The way I implemented it is pretty much what everyone else has suggested and that was I had one function that would be called, accepting a float that indicated the duration of the fade in seconds. It would then copy the framebuffer into a number of textures, this number of course depending on the maximum size texture of the user's hardware. At that point the video subssytem kept an internal timer on how long it had been since the fade was invoked and every subsequent frame was automatically rendered with an appropriate alpha setting while the stored frame data was rendered with a complementary alpha value. When the time ran out the fade counter was reset, the textures (or rather, their contents) were discarded and everything proceeded normally.

The fade effect occurs in the first video between the main menu and the "new game" menu, and when the big white flash occurs; in the second it just occurs between the "new game" menu and the main menu.

Share this post


Link to post
Share on other sites
Quote:
Original post by leiavoia
Your effects look pretty good. Off topic: how did you record it? "Camera aimed at the screen" or is there really some software way to do it?


I used the exceedingly useful program FRAPS. I only have version 1, version 2 allows sound recording (I dubbed the explosion sound effect back into the video before compressing it, tricky tricky!) but of course it costs money.

Also if you look at this clip you hear that there's actually a sound effect leading into the main explosion, although the one in this video has since been replaced.

But of course that entire version of the program has been replaced too, so oh well; although the effects will probably remain very similar since they worked so well.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this