Problem mit OpenGl und VSYNC
-
Guten Tag,
programmiere derzeit eine Pendelsimulation, die ich mit OpenGl (glut) darstelle.
Wenn nun VSYNC während der Animation aktiviert ist, verschwimmt das sich bewegende Pendel etwas und es entsteht ein Flackern der Animation ab einer bestimmten Darstellungsgeschwindigkeit. Wenn nun VSYNC während der Animation deaktiviert ist, tritt das Flackern und die Unschärfe nicht mehr auf, jedoch "stockt" die Animation an bestimmten Stellen. Wie kann ich es schaffen, dass die Animation ruckelfrei abläuft?Hier der Quelltext. Bitte nicht über das völlige Chaos im Programmcode aufregen
der wird noch beseitigt
.
Danke schonmal im Vorraus
#include <string.h> #include <GL/glui.h> #include <GL/glut.h> #include <math.h> #include <GL/gl.h> #include <GL/glu.h> #include <stdio.h> #include <windows.h> int main_window; int winIdSub; float faktor = 0.0; float faktor2 = 1.0; const double pi2 = 6.28318530718; float omega = 1.0; static char label[100]; float laenge = 0.75; float winkel = 1; double tic = 0.025; static double time = 0.0; float alpha =1.0; double xcenter , ycenter; float epot,masse,hoehe,ortsfaktor; double current_angle ; void myGlutIdle( void ) { glutSetWindow(main_window); glutPostRedisplay (); time += tic; glutSetWindow (winIdSub); glutPostRedisplay (); } void winInit(void){ gluOrtho2D(-1.0, 1.0, -1.5, 0.5); glDisable(GL_DEPTH_TEST); glEnable (GL_TEXTURE_2D); } void stop(int) { tic=0.0; } void start(int) { tic=0.025; faktor=0.1; } void ausgangsstellung(int) { tic=0.0; current_angle = 0.0; } void display( void ) { static double radius = 0.03; const double delta_theta = pi2/20; double x, y; double theta = 0.0; /* Pot Engergie */ epot = ycenter*masse*ortsfaktor; glClear(GL_COLOR_BUFFER_BIT); /* if (faktor==0) { current_angle = (cos(omega * (time*(faktor/5)))- alpha); } else { */ current_angle = (cos(omega * (time*(faktor/5))- (alpha/12.85)));/*+cos(time*(faktor/5)));*/ /* } hintergrund glBegin (GL_QUADS); glColor3f(0.0, 0.0, 0.0); glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left glEnd (); */ glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINES); glVertex2f(0.0, 0.0); xcenter = (-1)*laenge * sin(current_angle); ycenter = (-1)*laenge * cos(current_angle); glVertex2f(xcenter,ycenter); glEnd(); glBegin(GL_LINES); glVertex2f(1.0, 0.0); glEnd(); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); while (theta <= pi2) { x = xcenter + radius * sin(theta); y = ycenter + radius * cos(theta); glVertex2f(x, y); theta += delta_theta; }; glEnd(); glutSwapBuffers(); } void drawString (char *s) { unsigned int i; for (i = 0; i < strlen (s); i++) glutBitmapCharacter (GLUT_BITMAP_HELVETICA_10, s[i]); }; void subDisplay () { /* unterfenster löschen */ glutSetWindow (winIdSub); glClearColor (0.25, 0.25, 0.25, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* zeichnen */ glColor3f (255.0F, 255.0F, 255.0F); glBegin (GL_LINE_LOOP); glVertex2f (0.0F, 0.0F); glVertex2f (0.0F, 0.99F); glVertex2f (0.999F, 0.99F); glVertex2f (0.999F, 0.0F); glEnd (); /* sub-fenster inhalt */ glColor3f (1.0F, 1.0F, 1.0F); sprintf (label, "v = %8.3f ", xcenter ); glRasterPos2f (0.05F, 0.75F); drawString (label); glColor3f (1.0F, 1.0F, 1.0F); sprintf (label, "a = %8.3f", ortsfaktor); glRasterPos2f (0.05F, 0.5F); drawString (label); glColor3f (1.0F, 1.0F, 1.0F); sprintf (label, "E(kin) = "); glRasterPos2f (0.05F, 0.25F); drawString (label); glColor3f (1.0F, 1.0F, 1.0F); sprintf (label, "E(pot) = %8.3f", epot); glRasterPos2f (0.2F, 0.75F); drawString (label); glutSwapBuffers (); }; void subReshape (int w, int h) { glViewport (0, 0, w, h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D (0.0F, 1.0F, 0.0F, 1.0F); }; /**************************************** main() ********************/ int main(int argc, char* argv[]) { /*Fenster initialisieren und GLUT aufrufen*/ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); ortsfaktor = 9.81; masse = 1; glutInitWindowPosition(5,5); glutInitWindowSize(640,640); main_window = glutCreateWindow( "Pendel" ); winInit(); glEnable(GL_LINE_SMOOTH); glutDisplayFunc(display); glutIdleFunc(myGlutIdle); GLUI * glui_window; winIdSub = glutCreateSubWindow (main_window, 5, 5, 630, 70); glutDisplayFunc (subDisplay); glutReshapeFunc (subReshape); GLUI *glui = GLUI_Master.create_glui( "Menü" ); GLUI_Spinner *segment_spinner = glui->add_spinner( "Animationsgeschwindigkeit:", GLUI_SPINNER_FLOAT, &faktor ); GLUI_Spinner *segment_spinner2 = glui->add_spinner( "l:", GLUI_SPINNER_FLOAT, &laenge ); GLUI_Spinner *segment_spinner3 = glui->add_spinner( "alpha:", GLUI_SPINNER_FLOAT, &alpha); GLUI_Spinner *segment_spinner4 = glui->add_spinner( "Masse (kg):", GLUI_SPINNER_FLOAT, &masse); GLUI_Spinner *segment_spinner5 = glui->add_spinner( "Normalfallbeschleunigung (m/s^2):", GLUI_SPINNER_FLOAT, &ortsfaktor); glui->add_button("Stop", 0, stop); glui->add_button("Start", 0, start); glui->add_button("Ausgangsstellung", 0, ausgangsstellung); segment_spinner->set_int_limits( 0, 100 ); segment_spinner2->set_int_limits( 0, 100 ); segment_spinner3->set_int_limits( 0, 180 ); segment_spinner4->set_int_limits( 0, 1000000 ); glui->set_main_gfx_window( main_window ); /* IDLE mit glui aufrufen*/ GLUI_Master.set_glutIdleFunc( myGlutIdle); glutMainLoop(); return 0; }