Loading screen

Started by
12 comments, last by mpipe 16 years, 10 months ago
Hey all, I was wondering how to make a loading screen for my game. Sometimes when I start my game up I have to wait there a couple seconds for it to load all the textures and everything. I'm thinking it would be more user friendly if I could put a loading screen on there while the player is waiting. A simple "loading..." text would work, but I think it would be really cool to have one of the progress bars to. I'm using C++ and OpenGL with win32 (probably going to be ported to SDL later on), so what should I do for this kind of problem? Thanks a bunch, --Nathan --
Advertisement
Oddly, I just got done implementing a progress control in my windowing UI, so...

The easiest way to do it is to draw two rectangles; one for the progress control box, and one for the actual meter.

The outer rectangle is your "control" that contains the meter.

You'll need a "position" value. Clamp it to the range 0.0f to 1.0f (I'll show why in a sec).

The second rectangle should be the same size or close to the same size as the first box. This is your actual progress meter. Draw this inner box inside of the original box. Here's where the clamped position value comes in. To easily do the inner box, use glScalef and set the x parameter of the call as your position value. This will grow the box horizontally as the position value counts up to 1.0f

You'll end up with something like the following ProgrammerArt(tm):
0.0f+----------------------+|                      ||                      ||                      |+----------------------+0.25f+----------------------+| +-----+              || |     |              || +-----+              |+----------------------+0.5f+----------------------+| +----------+         || |          |         || +----------+         |+----------------------+0.75f+----------------------+| +---------------+    || |               |    || +---------------+    |+----------------------+1.0f+----------------------+| +------------------+ || |                  | || +------------------+ |+----------------------+


And for some code (untested and uncompiled...):

glPushMatrix();glBegin(GL_QUADS);    glVertex3f(-10.0f, -1.0f, 0.0f);    glVertex3f( 10.0f, -1.0f, 0.0f);    glVertex3f( 10.0f,  1.0f, 0.0f);    glVertex3f(-10.0f,  1.0f, 0.0f);glEnd();glTranslate(0.0f, 0.0f, -0.1f); // so it's in front of the other boxglScalef(position, 1.0f, 1.0f); // scaled to the progress positionglBegin(GL_QUADS);    glVertex3f(-9.0f, -0.9f, 0.0f);    glVertex3f( 9.0f, -0.9f, 0.0f);    glVertex3f( 9.0f,  0.9f, 0.0f);    glVertex3f(-9.0f,  0.9f, 0.0f);glEnd();glPopMatrix()


Now for the obligatory warnings... the position must never be outside of the range 0.0f to 1.0f. If it's less than 0.0f, the inner box will spread to the left of the container box. If it's larger than 1.0f, the inner box will extend past the right side of the container box.

Hope that works out for you. The one I did was a lot more complicated, but that's essentially what I started with as a proof of concept.

Good luck!

vr
Honestly, if you're having trouble with this, then loading progress bars are the least of your worries.

I would suggest that you takes things one step at a time and not try to jump ahead. Leaping to the end before you've made your first step, will only lead to frustration and abandoned projects.

Once you have an idea of how to animate things, progress bars will look easy and obvious.
Programming since 1995.
I don't think his problem lies in drawing the progress bar; anyone could do that.

I think his problem is in knowing when stuff is being updated behind the scenes so he knows when and how to update the progress bar.

In my game, I just load the font I'll need, and then start drawing the loading screen; to update my progress bar, I have a method which forces a redraw and adds onto the progress bar percentage. I call this method after each "step." So my code would look something like this (albeit a lot cleaner, and probably in a ton more classes without global variables):
main() {  font = loadFont("data/font");  loadingSequence();  runGame();}doLoadingScreen(percentage : float, explanation : string) {  renderer.clear();  font.write(0,0,explanation);  drawBar(percentage);  flip();}loadingSequence() {  doLoadingScreen(0, "Loading...");  initSprites("data/sprites");  doLoadingScreen(0.25, "Loading sounds");  initSounds("data/sounds");  doLoadingScreen(0.50, "Loading meshes");  initMeshes("data/meshes");  doLoadingScreen(1.0, "Done loading");  return;}
You could probably make this more fine grained inside your initialization functions if you wanted to make the progress bar more smooth and accurate; mine is sort of choppy but it's to be expected.
I do it in a similar way, except instead of constants, I pass my progress bar the number of items loaded and the total number of items to load. items loaded / toal items = the exact width of the bar. Of course, I decided to be a bit crazy with mine and have it change colors [grin], but that is just a style thing.
There was a saying we had in college: Those who walk into the engineering building are never quite the same when they walk out.
@ Ravuya,
how do I set a value to test if my game is loading or not? since my intiliazation code is called before the loop and is only called once, how can I draw anything, since it would only be drawn once and then would immediately disappear?

@virtuallyrandom and t1Oracle,
sorry that I made my question unclear. I already know how to animate stuff, I was trying to figure out how to know when my game is loading data so that I could know when to display a loading screen and when to not.

Thanks a bunch,
--Nathan

--
Stuff only disappears from your window once you 'present' over it, so you can afford to render to it only so often.

You have to do some work before you can put up the loading screen (such as loading fonts and such) and then you can do the actual loading and present the new frames of the loading screen when you have time.
To make sure I understand the question, do you want to know how to sectionalize your game so you could have, for instance, a loading screen followed by an intro screen and then the game? I use structures of function pointers for that (if you want to see code, let me know and I'll post some.)

Much like medevilenemy, I track the position of the progress bar by how much I've done divided by how much I need to do, and update it as I go along.

Usually, I end up with something like this:

int tot_step = 43;
int cur_step = 0;

// do something
cur_step++;

// do something
cur_step++;

On each update frame, I then set the position of the progress bar to cur_step/(float)tot_step.

vr
Idea: grab the size of each stuff you are loading and calculate the progress using it, instead of number of things to load. You will avoid that kind of loading that takes 10 seconds before 30% and then load the rest in less than half a second.
Size doesn't always relate directly to the amount of time is required to load something. Sure, loading the actual data is size-based, but a lot of data needs processed, which is a step that can add significantly to the amount of time required to load a particular resource. For example, creating the graph to use for navigation when loading map data. It's not always practical to precompute those, and it's not always possible to predict exactly how complicated the graph will turn out [to predict how long it will take to generate].

Good news is that people won't generally fault you for your loading bar being a bit jerky, since these things are generally understood.

This topic is closed to new replies.

Advertisement