Progress Bar in OpenGL

This topic is 4950 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello, I have made a simple progress Bar in OpenGL : - The display Callback calls my progress bar function with un percentage. - This function draws the wanted Progress bar at each frame. I am doing a very heavy computation (lasts several minutes), that is why I need a progress bar. The only way I found to make my progress bar moove with the computation is to make a little bit of computation at each frame ! And that is slowing down my already very heavy computation ! I would like to know if there is other ways of mooving the progress Bar in real time with the complexe computation and not slowing it down. I am hopping to be as clear as possible, Thank you. Erwan

Share on other sites
Three options:

- Exactly what you're doing. Basically do the calculation in increments in your main loop.

- Insert "draw" calls in your calculation function. This is really almost the same as the first option. It is required if the calculation cannot be done in small increments. It also might give slightly greater control.

- Do the calculation in another thread that provides a steps or percentage-complete value to your main thread which does the drawing. This shouldn't even require mutexes. Remember to sleep your main application every few milliseconds between redraws.

The last option has the advantage of both of the first methods, plus it can eliminate pointless redraws (you can eliminate them even more by checking for changes in the percentage value, in cases where the processing is long). It can be tuned to allow maximum time for your calculation.

I use method one myself, at the moment - simple and effective. I plan on moving to method three if my application ever needs to have a better loading system or long loading times.

If threads seems like too much effort, perhaps you may be able to get a quick-and-diry fix by calling the update function more than once per loop?

Share on other sites
Tank you very much for that quick and interesting answer Andrew !
Threads are what I am Looking for I think ! Could provide me a few kew words or places to have a look ?
Because I am a total beginner on that point !

Thank you again.
Erwan

Share on other sites
I had that same problem, what i did is make a fullscreen progress bar mode (in my case console mode), instead of using the draw function you write a seperate function that draws the progress bar and swaps buffers itself, like this:

- do some calculations
- when a part is done (for example after things are calculated for one object or a certain amount of polygons) call the progress bar draw function

the progres bar draw function:

- clear screen
- draw progress bar
- swapbuffers

I think thats clear enough.

Share on other sites
Righto.

The functions you want to look up in the MSDN are:

WaitForSingleObject (for waiting for threads to finish and mutexes to become available)

And probably:
CreateMutex (for creating mutexes)
ReleaseMutex (makes an in-use mutex available)
Sleep (suspend a thread for some number of milliseconds)

Basically the idea is - you write a function that is basically the "main" of your thread. This should do the calculation in a loop. You then use CreateThread on that function to start the thread going.

To interact with your thread, you must either share data and use mutexes to ensure no one reads or writes it at the same time. Or use volatile data (which must be a type where read and write operations are atomic) - see the "volatile" keyword.

In your case, you have two interactions. The first of which is - you want to know when the calculation finishes and you want to be able to stop it from your main thread (this functionality is needed in basically every threaded thing you make). For this have a variable:
volatile bool stop;
You basically want this to tell your main thread if a stop has happened, and your calculation thread that it should stop ASAP. Set it to false before calling CreateThread. Then, in your main thread - check for true to see if the calculation is finished, and set to true to ask the calculation to finish. From your calculation thread - check for true and terminate ASAP if so, and set to true once the calculation has finished.

Once you ask the calculation to terminate, you must call WaitForSingleObject to wait for the calculation thread to terminate.

Whatever you do - don't set it to false except before CreateThread or after WaitForSingleObject (ie: only set to false when the thread is not running). Otherwise it will cause unpredictable behaviour.

The other interaction is simply your "calculation progress". This should be an volatile integer that represents how far you've gone. Because integer reads and writes are atomic, and only one thread is writing and one reading, it's safe to use.

Easy! [smile]

[Edited by - Andrew Russell on May 23, 2005 10:55:59 AM]

Share on other sites
Thanks Tree Pinguin, i'll try that to see if it is faster..

And thanks a lot to Mr Andrew for taking time to explain to me threads. But hum is MSDN Microsoft ? If yes I cannot use it because I am trying to make a multiplatform aplication ! In that case can you tell me a few names for multiplatform threads so I can have a look ?

erwan

Share on other sites
Just to be nice, I've included my own simple thread class here.

Anyone who has used threads already probably has one or you may have seen something similar around on the 'net. Doing it this way seems to be fairly standard:

class AThread{protected:    volatile bool terminateflag;    HANDLE hThread;public:    AThread() : terminateflag(true), hThread(NULL) {}    virtual ~AThread()    {        if(!terminateflag)        {            End();        }    }    virtual bool Start()    {        if(hThread)        {            return true;        }        else        {            terminateflag = false;            DWORD threadid; // needed on 9x based systems            hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)StartProc, this, NULL, &threadid);            if(hThread == NULL)            {                // error - use GetLastError for details                return false;            }            return true;        }    }    virtual void End()    {        if(hThread)        {            terminateflag = true;            WaitForSingleObject(hThread, INFINITE);            if(!CloseHandle(hThread))            {                // error - use GetLastError for details            }            hThread = NULL;        }    }        virtual void ThreadProc()=0;    __forceinline volatile const bool& IsStopped() {return terminateflag;}    private:    static void StartProc(AThread* t) {t->ThreadProc();}};

I just love the fact that I can have a function "__forceinline volatile const bool&" [grin]

Just be aware that I've already spotted three issues with this class just while posting this and glancing at the source. They are small and it will work in normal situations, but the usual disclaimers on warranty apply [wink].

And yes, my own version has comments.

All you have to do is inherit the class and overwrite the ThreadProc function with this:

void MyClass::ThreadProc(){    while(terminateflag)    {        // do your thing    }};

Yay! [smile]

Share on other sites
Ahh, multiplatform - then my code might not help.

MSDN is at msdn.microsoft.com.

Share on other sites
For linux, look at the functions clone and kill. I'm afraid I don't know the functions for mutexes and such, though.

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
13
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• Forum Statistics

• Total Topics
633663
• Total Posts
3013232
×