PDA

View Full Version : Smooth motion not possible > 'micro-shakes'



sticksen
03-24-2009, 08:24 AM
Hi,
i need to do a smooth motion of an object crossing the screen. I now tested with a Triangle and a Sprite in Python and a Triangle in C++, but either way there are some kind of micro-shakes. The object doesn´t scroll smoothly through the screen. What can I do?

Here my code examples:

import pyglet
from pyglet.gl import *
window = pyglet.window.Window(1400,600)
i=0
@window.event
def update(dt):
global i
i=i+3
if i > window.width+80:
i=0
glClear(GL_COLOR_BUFFER_BIT)
glLoadIdentity()
glBegin(GL_TRIANGLES)
glColor3f(1.0,0.0,0.0)
glVertex2f(-80+i,20)
glVertex2f(0+i,20)
glVertex2f(-80+i,100)
glEnd()
pyglet.clock.schedule_interval(update,1/60.0)
def on_draw():
pass
pyglet.app.run()

import pyglet
window = pyglet.window.Window()

ball_image = pyglet.image.load('logo.png')

i=0
@window.event
def update(dt):
global i
i=i+10
if i > window.width:
i=0
window.clear()
ball = pyglet.sprite.Sprite(ball_image, x=i, y=50)
ball.draw()
window.flip()
pyglet.clock.schedule_interval(update,1/30.0)
def on_draw():
#window.clear()
#ball.draw()
pass
pyglet.app.run()

//
// main.m
// test2
//
// Created by stickbook on 24.03.09.
// Copyright __MyCompanyName__ 2009. All rights reserved.
//


#import <GLUT/glut.h>
float d=0.1;

void Timer(void)
{
d=d+0.00025;
if (d>1.2) d=0;
glBegin(GL_TRIANGLES);
glVertex2f (0+d, 0.1);
glVertex2f (-0.1+d, 0.1);
glVertex2f (0+d, 0.2);
glEnd();

/* don't wait!
* start processing buffered OpenGL routines
*/
glFlush ();
glutPostRedisplay();
glutTimerFunc(1/60*1000.0,Timer,0);

}
void display(void)
{
/* clear all pixels */
glClear (GL_COLOR_BUFFER_BIT);

/* draw white polygon (rectangle) with corners at
* (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
*/
glColor3f (1.0, 1.0, 1.0);
}

void init (void)
{
/* select clearing color */
glClearColor (1.0, 0.0, 0.0, 0.0);

/* initialize viewing values */
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}

/*
* Declare initial window size, position, and display mode
* (single buffer and RGBA). Open window with "hello"
* in its title bar. Call initialization routines.
* Register callback function to display graphics.
* Enter main loop and process events.
*/
int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (1400, 600);
glutInitWindowPosition (10, 100);
glutCreateWindow ("hello");
init ();
//glutIdleFunc(idle);
glutTimerFunc(300,Timer,0);
glutDisplayFunc(display);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}


Can somebody help?

Cheers,
Marc

Ilian Dinev
03-24-2009, 01:32 PM
This is what happens:
pyglet.clock.schedule_interval(update,1/60.0)

Nothing on a PC can guarantee exact timing of 16.666666ms. Except for the GPU vsync.
Enable vsync by calling wglSwapIntervalEXT(1)
Then, on window.flip() which internally calls SwapBuffers(hDC) under Win32 , your app will wait nicely while the high-precision GPU counter flips backbuffer to be frontbuffer.

You should remove that pyglet.clock.schedule_interval() call, and rely on SwapBuffers() to block until the next 16.666ms timeslice.

(well, there could be later pitfalls like your app taking more than 16ms to redraw, or you designing for 60Hz while user runs at 75Hz, or user force-disabling vsync in the drivers - you'll get to the easy way of overcoming them later)