Animation Problem (in dire need of help)

I have been given the following requirements:
·Take a file name from the command line, or if there is none, prompt the user for the file name. Draw the world
·The function draw_tri will draws a white triangle which has its apex at the origin of the triangle coordinate system The triangle should start with its apex at (0,0) pointing in the direction (1,1).
·From a stationary position, hitting the up arrow key should start the triangle moving forward at a slow speed. Hitting up arrow again should speed the motion. Hitting the down arrow works as a brake and slows you down. Hitting it again slows you more. Hitting it from a stopped position should allow you to back the triangle up.
·Right and left arrow keys turn your direction of motion to the right and left, respectively, by a couple of degrees.
·a menu attached to the right mouse button that has options for resetting the triangle to the original position

·Use the glut timer callback to control the speed of updates. Run double buffered at between 25 and 30 updates per second.
I am unable to make the triangle move. This is my first OpenGL program and I am very frustrated. Please assist. here is my code:

 void draw_tri( void ) {

  glColor3f( 1.0, 1.0, 1.0 );
  glBegin( GL_POLYGON );
    glVertex2f( 0.0, 0.0 );
    glVertex2f( .5, -1.0 );
    glVertex2f( -.5, -1.0 );
  glEnd();

}

void add_node_at_end()
  {  
	node *temp, *temp2;   // Temporary pointers
	
     


   while (! inputFile.eof() )
  {
	temp = new node;
	int i = 0;

	inputFile >> temp->simpleworld;

i++;
	temp->nxt = NULL;
  
  
	// Set up link to this node
     if (start_ptr == NULL)
       { start_ptr = temp;
	     current = start_ptr;
       }
     else
       { temp2 = start_ptr;
         // We know this is not NULL - list not empty!
         while (temp2->nxt != NULL)
           {  temp2 = temp2->nxt;
              // Move to next link in chain
           }
         temp2->nxt = temp;
				
       }
 }

}



void get_list()
  {   node *temp;
     temp = start_ptr;
   
	float f, g, h, j, a, b, c, d ; //variables used to calculate coordinates

     if (temp == NULL)
       cout << "The list is empty!" << endl;
     else 
       { while (temp != NULL)
	 { //color
	 
		 if ((temp->simpleworld[0] == 'w') && (temp->simpleworld[1] == NULL))
		 { 
			 temp=temp ->nxt; 
			 
			f = atof(temp->simpleworld); // convert char* to a float
			temp = temp ->nxt;
			g = atof(temp->simpleworld);
		

			glColor3f (0.5, 0.5, 0.5);  //50% gray
	//draw world
			glBegin(GL_POLYGON);
				glVertex2f(0.0,0.0);
				glVertex2f(0.0,g);
				glVertex2f(f,g);
				glVertex2f(f,0.0);
			glEnd();

	 
			
		 }	
	   
		else if  ((temp->simpleworld[0] == 'c') && (temp->simpleworld[1] == NULL))
		 {  
			 temp=temp ->nxt; 
		     f = atof(temp->simpleworld); // convert char* to a float
			 temp = temp ->nxt;
			 g = atof(temp->simpleworld);
			 temp = temp ->nxt;
			 h = atof(temp->simpleworld);
			 
                 //color
                glClearColor(0.0, 0.0, 0.0, 0.0);
				glColor3f(f, g, h);
				
		 }

		 else if  ((temp->simpleworld[0] == 'b') && (temp->simpleworld[1] == NULL))

		 {  

			 temp=temp ->nxt; 
		     f = atof(temp->simpleworld); // convert char* to a float
			 temp = temp ->nxt;
			 g = atof(temp->simpleworld);
			 temp = temp ->nxt;
			 temp = temp ->nxt;
			 h = atof(temp->simpleworld);
			 temp = temp ->nxt;
			 j = atof(temp->simpleworld);

			a = f - (h*.5);
			b = f + (h*.5);
			c = g - (j*.5);
			d = g + (j* .5);

			//draw Rectangle

			glBegin(GL_POLYGON);
				glVertex2f(a,c);
				glVertex2f(b,c);
				glVertex2f(b,d);
				glVertex2f(a,d);
			glEnd();

			
		 }

		 else if  ((temp->simpleworld[0] == 's') && (temp->simpleworld[1] == NULL))
		 {  
			 temp=temp ->nxt; 
		     f = atof(temp->simpleworld); // convert char* to a float
			 temp = temp ->nxt;
			 g = atof(temp->simpleworld);
			 temp = temp ->nxt;
			 h = atof(temp->simpleworld);
			 temp = temp ->nxt;
			 j = atof(temp->simpleworld);
	
			
			quadratic=gluNewQuadric();
			glPushMatrix();
			glLoadIdentity();
			glTranslatef(f,g,0.0);
			gluDisk(quadratic,0.0,j,20.0,1.0);
			glPopMatrix();

			  
		 }
		 
	      temp = temp->nxt;

	   }
	 
       }

	 
  }

	 



void myinit (void)
{
   //attributes

	glClearColor (0.0, 0.0, 0.0, 1.0);
   
	glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-2.0, 2.0, -2.0, 2.0);
    glMatrixMode(GL_MODELVIEW);
    glClearColor (0.0, 0.0, 0.0, 0.0); //black background

}




void myReshape(int w, int h)
{
    glViewport(1, 1, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-2.5, 22.5, -2.5, 32.5);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity ();
}



void display(void)
{

	get_list();
	glTranslatef(0.0, 0.0, 0.0);
	glRotatef(-45.0,0.0,0.0,0.5);
    draw_tri();
    glutSwapBuffers ();
	glFlush(); //clear buffers
	glClear(GL_COLOR_BUFFER_BIT);


}


void animate(int value){
	
	glutPostRedisplay();
if (step < 1.0e3)
	{//step++;
	step *=sqrt(2.0);
		}
	/* call animate again in 200 mili-Secs */
	//glTranslatef(step, 0.0, 0.0);
//	glutTimerFunc(200,animate,step);
}


void specialKeyPressed(int key, int x, int y)
{
	if (key == GLUT_KEY_UP )
	{
		
		//glutTimerFunc();
		//glTranslatef(0.0, 0.0, 5.0);
		//move();
		
	//glTranslatef(0.0, step, 5.0);
		//glutTimerFunc(200,animate,step);
		animate(step);
		glClear(GL_COLOR_BUFFER_BIT);

		cout << "triangle moving forward" << endl;
	}
	else if (key == GLUT_KEY_DOWN)
	{
		
animate(-step);
		
		//glutTimerFunc();
		cout << "triangle slowing down" << endl;
	}
	else if (key == GLUT_KEY_LEFT)
	{
		//turn_left();
		glTranslatef(0.0, 0.0, 0.0);
	    glRotatef(-45.0,0.0,0.0,0.5);
		cout << "triangle moving left" << endl;
	}
	else if (key == GLUT_KEY_RIGHT)
	{
		glTranslatef(0.0, 0.0, 0.0);
	    glRotatef(-45.0,0.0,0.0,0.5);
		cout << "triangle moving right" << endl;
glutPostRedisplay();	} 
}

  
void keyPressed(unsigned char key, int x, int y) 
{
    if ((key == ESCAPE) | (key == 'q') | (key == 'Q')) 
    { 
      glutDestroyWindow(window); 
      
      exit(0);                   
    }
    else if (key == 'a' )
	{
		
		//glutTimerFunc();
		
		cout << "triangle moving forward" << endl;
	}
	else if (key == 's')
	{
	
	
		//glutTimerFunc();
		cout << "triangle slowing down" << endl;
	}
	else if (key == 'l') 
	{
		
		cout << "triangle moving left" << endl;
	}
	else if (key =='k') 
	{
		cout << "triangle moving right" << endl;
	}

    
}     



void main_menu (int option)
{
	switch (option)
	{
		case 1:
			glutDestroyWindow(window);
			exit(0);
			break;
		default:
			break;
	}
}



int main (int argc, char *argv[])
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
	glutInitWindowSize(300,500);
	glutInitWindowPosition(0,0);
	window = glutCreateWindow("Tiffanie Gladden - CSE 7382 - Program 1");
    myinit ();

	if (argc == 2) // they've given a filename on the command line
     fileName = string(argv[1]);  // argv[0] is program name, argv[1]
                                  // is the input file name
   else {
     cout << "Enter the name of the input file." << endl;
     cin >> fileName;
   }
   inputFile.open(fileName.c_str());

   if(inputFile.good() == false)
   {
      cerr << "Error opening file for reading: " << fileName << endl;  // output errors to the cerr stream
      return 1;  
   }
	add_node_at_end(); 	//read from data file to linked list
	
    glutDisplayFunc(display);
	glutReshapeFunc (myReshape);
	
	//Exit thru right mouse button
	glutCreateMenu(main_menu);
	glutAddMenuEntry("Quit", 1);
	glutAddMenuEntry("Original Position", 2);
	glutAttachMenu(GLUT_RIGHT_BUTTON);

	//Exit when escape key is pressed.
	glutKeyboardFunc(&keyPressed);
    glutSpecialFunc(&specialKeyPressed);

	glutTimerFunc(200,animate,step);
    glutMainLoop();

return 0;

}
 

Hi !

You should not put OpenGL function calls in your keyboard callback function, you need to fetch the keys and update some variable to keep information about the triangles position (transformation), after a key is pressed call glutPostReDeisplay() to force an update of the rendering (the display callback will be called) and use the updated variables to render the triangles in the correct position there instead.

If you want to do the updates from a timer you call postReDisplay()) from the timer callback instead, but you already have the keyboard repeat timer.

Mikael