Sign in to follow this  

Sleep() problem

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


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

Share this post


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

Share this post


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

Share this post


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



Sounds like you need to use other input methods than 'key', which sounds like it sits and waits for a keyboard character....

look into Polling and Interrupts if you don't know what they are...

more details needed on what you mean by 'not responding'

Share this post


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

Share this post


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

Share this post


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

Share this post


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

}



Share this post


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

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

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