PDA

View Full Version : How to display a loading bar



robert_s
03-10-2002, 07:36 AM
Hi!
I am just wonderring how to display a loading bar in the same window where I do all my drawings. For eg. imagine you run a simple demo displaying cube in the middle of a window. The cube is not textured yet!
Now by pressing 't' key the prog. would load eg. 20 or more textures in run time. (this figure is just an example).
Now after pressing the key 't' the program will start loading textures from a disk. Say it would take about 30 seconds to load all texs and therefore I would like to visualize all the loading process by drawing in the same window eg. below the already displayed cube a simple red rectangle which would be initially be very narrow and positioned on -200.0 along X axis. As the texture is being loaded (one by one) the rectangle would stretch to towards right side of the window to 200.0 along X. This would show the user that the program loads all those textures just like in games there are all those loading bars.

the way I can imagine is eg.
counter could be incremented for every texture loaded and automatically should update the main window in order to redraw the rectangle (stretch more an more).
Do u think that thats how its done or I am wrong.
Also I am not sure how to update the window after each texture is loaded which is my main problem. I've tried glutPostRedisplay() coze I am using GLUT but that didnt work. it redisplayed all my drawings in the window after all textures were loaded which is not what I want! I want to update the window everytime a texture is loaded.

The way how I've done now is:
void keyboard(..)
{
case 't': initTex(); load textures...
break;
}

initTex()
{
//load texture 1
++counter
// update window <<--- here I am not sure what to use to update the drawing before the next tex will be loaded (glutPostRedisplay() ???)
//load texture 2
++counter
// update the drawing
etc....
}

void display()
{
//draw a cude
//draw loading bar (simple quad stretching to the right eg. by 1 unit when each texture is loaded) ie.

glBegin(GL_QUADS);
glVertex2s( 0, 0 );
glVertex2s( counter, 0 );
glVertex2s( counter, 20 );
glVertex2s( 0, 20 );
glEnd();

}//end display

Any ideas! Thank you for reading my post and help!! http://www.opengl.org/discussion_boards/ubb/smile.gif


[This message has been edited by robert_s (edited 03-10-2002).]

[This message has been edited by robert_s (edited 03-10-2002).]

zeckensack
03-10-2002, 07:47 AM
Try calling your display function directly, not glutPostRedisplay().
That won't do anything until you return from your function and that won't happen in between texture loads.
If this works anything like the Win32 message pump (I bet it does), nothing happens until you return from the function and go idle.

As for the counter, try scaling it a bit so that the bar gets a little longer than 30 pixels http://www.opengl.org/discussion_boards/ubb/wink.gif

robert_s
03-11-2002, 01:15 AM
hmmmm... for some reason even calling directly the display()function did not help!. I've tried even this: glutDisplayFunc(display); but that didn't work too!
It still creates the window first after the whole init() function is executed. ie. all textures loaded then the window is displayed after.!!! what is it then!??
Does it mean that you can't recall display func to redraw the window even if the you are in the middle of reading init() func? strange! I thought you can! Any other ideas? THX!!

zeckensack
03-11-2002, 02:37 AM
I've just got it working here on my machine.
Try using glutSwapBuffers() at the end of your display function, that may be the problem.



void
initTex()
{
//I just waste lots of time here, you should load your textures instead
unsigned char* bogus=(unsigned char*)malloc(1<<20);

for (int fall_asleep=0;fall_asleep<100;++fall_asleep)
{
//here I waste my time by writing 1 meg of nonsense to memory
for (int woot=0;woot<(1<<20);++woot)
{
bogus[woot]=fall_asleep;
}
//here I increment the size of the bar and call the display function
bar=fall_asleep;
display();
}
free(bogus);
}

void
display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//note: these are coordinates for _my_ projection, you might have to modify this
glBegin(GL_QUADS);
glVertex2s(70,400);
glVertex2s(70,430);
glVertex2s(70+5*bar,430);
glVertex2s(70+5*bar,400);
glEnd();

glutSwapBuffers();
}

robert_s
03-11-2002, 07:33 AM
zeckensack!! This is strange! I've tried your code and it doesn't work.. unless I got it wrong! http://www.opengl.org/discussion_boards/ubb/smile.gif

This is what I tried:

#include <GL/glut.h>
#include <math.h>
#include <iostream.h>
#include <stdlib.h>

int bar = 0;

void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(0.0, 100.0, 0.0, 100.0, -100.0, 100.0);
glMatrixMode( GL_MODELVIEW );
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glColor3f(0.0, 1.0, 0.0);

glBegin(GL_QUADS);
glVertex2s( 10, 10);
glVertex2s( 10+2*bar, 10);
glVertex2s( 10+2*bar, 30);
glVertex2s( 10, 30);
glEnd();
glutSwapBuffers();
}

void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);

//I just waste lots of time here, you should load your textures instead
unsigned char* bogus=(unsigned char*)malloc(1<<20);
for (int fall_asleep=0;fall_asleep<50;++fall_asleep)
{
//here I waste my time by writing 1 meg of nonsense to memory
for (int woot=0;woot<(1<<20);++woot)
{
bogus[woot]=fall_asleep;
}
//here I increment the size of the bar and call the display function cout << "looping";
bar=fall_asleep;
display();
}

free(bogus);

}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (600, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Loading Bar");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}


Is it exactly the same as you have?
In my case the window is displayed after the whole init loop is done so that means when the window appears the bar is already wholy rendered.
I don't know how u managed to get it working!
I am using VC++6 - WinXP...
PLZ let me know if this code works the same as yours on your machine! can't be!
THANK YOU VERY MUCH!! http://www.opengl.org/discussion_boards/ubb/smile.gif



[This message has been edited by robert_s (edited 03-11-2002).]

zeckensack
03-11-2002, 08:17 AM
Actually, the difference is the I did what you said you wanted to do: I called the initTex function from the keyboard function when the user presses 't'.

The problem with your code is, that the initTex function finishes before you enter glutMainLoop.
What you should do, is to take the call to initTex out of your main function and put it into your display function, but beware ...

Try this:



//declare this somewhere at file scope, ie outside of any functions
//we need this flag to check whether textures are already loaded
bool textures_loaded=false;

...

void
display()
{
//we only want to do that once
if (!textures_loaded)
{
//set this flag before calling initTex, or else you'll get an infinite loop !!
textures_loaded=true;
initTex();
}
//rest of your drawing code goes here
}

robert_s
03-12-2002, 04:23 AM
Yes you're right! This was my requirement.. Sorry! http://www.opengl.org/discussion_boards/ubb/smile.gif
Huge thanks for ur help! I ve tried that and it works brilliant! Just the way how I wanted! Thank you! http://www.opengl.org/discussion_boards/ubb/smile.gif

[This message has been edited by robert_s (edited 03-12-2002).]