Skip to main content
gamedev.net
🔒 Locked

Sleep() problem

Started by napacan Mar 6, 2007 at 2:17 PM 11 replies 1.7k views
Original Post
napacan
napacan
Hello, in my application I have several meshes that i show them one after another to get an animation. When I do this using keyboard, (by pressing '.' several times) it shows the animation but when I try to automate this by using such a code: for(int i = 0; i < 10; i ++) { Sleep( 500 ); key('.'); post_redraw(); } it waits freezed for like 5 secs and then shows the last mesh. What can I do to correct this?
tstrimp
tstrimp
Don't sleep so long.
LessBread
LessBread
5 seconds? Double check your code to make certain that you're calling Sleep(500) and not Sleep(5000).
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
napacan
napacan
I'm calling Sleep(500) for 10 times so that's equal to Sleep(5000) or a little more :)
jouley
jouley
Does post_redraw( ) actually cause all the drawing code to be called, or just alert the drawing manager that it could use a redraw? I suspect the latter. A fix for this is to use a proper timer, rather than relying on Sleep. This way, your update loop can keep updating, and the mesh will change/update when it needs to (when the value of current_time >= next_mesh_time).
napacan
napacan
I tried checking current time in a while() loop but it loops so many times that the program gets into not responding state. Just a call to key('.'); updates the mesh successfully but i need to do it after doing nothing for a while, like 0.5s. The Sleep function waits but it doesn't update mesh when I call key('.'); after sleep. Btw thanks for the answers.
jouley
jouley
Quote:
Original post by napacan
I tried checking current time in a while() loop but it loops so many times that the program gets into not responding state. Just a call to key('.'); updates the mesh successfully but i need to do it after doing nothing for a while, like 0.5s. The Sleep function waits but it doesn't update mesh when I call key('.'); after sleep. Btw thanks for the answers.

Simply check the time whenever you draw your mesh. If the correct time hasn't passed, don't do anything; if it has, update your mesh before you draw it. It shouldn't block anything else from happening.

If you still can't get it, toss some code up and I can point to where it should go.
napacan
napacan
here's the code for play:

void Pane::play() {	_ftime( &timebuffer );		double initialTime = (double)timebuffer.time + (double)timebuffer.millitm*0.001;	for(int i = 1; i <= 10; i ++)	{		Sleep(500);		currentTime = (double)timebuffer.time + (double)timebuffer.millitm*0.001;		if (currentTime > initialTime + (0.5*i))		{			key('.');		}			}}


key('.'); does the following:

if (currentFrame == (numFrames - 1)){	currentFrame = 0;}else{currentFrame++;}switchToFrame(currentFrame);


switchToFrame just changes the pointers to the current model to next model

i used sleep to not to do anything but it's not showing the model. the class Pane inherits from CFrameWnd and has some functions like:
private:    HGLRC gl_context;    int pixel_format;    CDC *active_dc;    bool set_pixel_format(HDC);    bool create_glcontext(HDC);    void handle_mouse(int kind, UINT flags, CPoint point);    void do_redraw(CDC& dc);protected:  // MFC virtual function overrides    BOOL PreCreateWindow(CREATESTRUCT& cs);protected:  // MFC event handlers    afx_msg void OnPaint();    afx_msg BOOL OnEraseBkgnd(CDC *);    afx_msg int  OnCreate(LPCREATESTRUCT lpCreateStruct);    afx_msg void OnDestroy();    afx_msg void OnSize(UINT nType, int cx, int cy);    afx_msg void OnLButtonDown(UINT flags, CPoint point);    afx_msg void OnLButtonUp(UINT flags, CPoint point);    afx_msg void OnRButtonDown(UINT flags, CPoint point);    afx_msg void OnRButtonUp(UINT flags, CPoint point);    afx_msg void OnMButtonDown(UINT flags, CPoint point);    afx_msg void OnMButtonUp(UINT flags, CPoint point);    afx_msg void OnMouseMove(UINT flags, CPoint point);    afx_msg void OnChar(UINT ch, UINT repcount, UINT flags);    afx_msg void OnTimer(UINT timer_id);    DECLARE_MESSAGE_MAP ()public:    void create(char *name);    inline void make_current(HDC dc) { wglMakeCurrent(dc, gl_context); }    inline void finish(HDC dc) { SwapBuffers(dc); }    void get_canvas_geometry(int *x, int *y, int *w, int *h);    void draw_string(int x, int y, const char *str);    void snapshot_ppm(const char *name=NULL);    void snapshot_tiff(const char *name=NULL);    virtual void gl_init();    virtual void begin_redraw();    virtual void end_redraw();    void post_redraw();    void require_redraw();    virtual void redraw();    virtual void illustrate();    virtual void key(char);    virtual void button(int kind, int which, int x, int y);    virtual void size(int width, int height);    unsigned int add_timer(unsigned int id, unsigned int millisecs);    bool remove_timer(unsigned int id);    virtual void timer(unsigned int);
napacan
napacan
Actually key('.') is called when . key is pressed. Any character is sent to key()and if the character is . then it draws the next mesh. It's listening for input all the time and does something if the input has some corresponding code in the
key(char c)
function.

By not responding I mean it crashes, i don't know it stops responding.
jouley
jouley
What it seems like you want to have happen is that when some trigger is triggered, this "play( )" animation will run its course. How you handle it will depend on whether or not you want anything else to happen while the animation is going on. If you don't want anything else to go on, I imagine simply switching the post_redraw( ) in your original post with a redraw( ) will handle that. In most cases, post_redraw( ) simply adds a "draw me!" message to the window's message queue; the actual drawing is done when it gets around to it. If you're stuck in a for loop, it won't get around to it until afterwards.

If, however, you want to be able to handle input and render other things, you'll need to do some more work. Inside of your redraw( ) function, I'll assume you have something set up like this:
void redraw( ){  model.draw(currentFrame);}

Taking the animation into account, though, will give you something like this:
void redraw( ){  if (animating)  {    //  determine which frame to use    currentTime = (double)timebuffer.time + (double)timebuffer.millitm*0.001;    if (currentTime > initialTime + (0.5*i))    {      if (currentFrame == (numFrames - 1))      {        currentFrame = 0;      }      else      {currentFrame++;}      switchToFrame(currentFrame);    }  }    model.draw(currentFrame);}


When the animation trigger happens, just set animating to true, and record the initialTime.

Which one is closer to what you're looking for?
napacan
napacan
I liked the second one and tried it. Good news is it shows the animation but only when i input with mouse. I checked the mouse handling functions and they use post_redraw() and post_redraw() uses InvalidateRect(NULL, FALSE); When I added post_redraw() to the if in redraw() it didn't work. Currently the redraw contains:

    if (isPlaying)    {		_ftime( &timebuffer );			 		currentTime = (double)timebuffer.time + (double)timebuffer.millitm*0.001;		if (currentTime > (initialTime + 0.1))		{			if (currentFrame == (numFrames - 1))			{				currentFrame = 0;			}			else			{currentFrame++;}			switchToFrame(currentFrame);			post_redraw();			initialTime = currentTime;		}		    }


napacan
napacan
Ok i was calling the post_redraw() in a wrong place. It works now.
if (isPlaying){	_ftime( &timebuffer );			 	currentTime = (double)timebuffer.time + (double)timebuffer.millitm*0.001;	if (currentTime > (initialTime + 0.1))	{		if (currentFrame == (numFrames - 1))		{			currentFrame = 0;		}		else		{currentFrame++;}		switchToFrame(currentFrame);		initialTime = currentTime;	}	post_redraw();}


Thank you very much for all :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.