PDA

View Full Version : Animation Problem (in dire need of help)



tip
04-05-2005, 07:55 PM
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') &amp;&amp; (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') &amp;&amp; (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') &amp;&amp; (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') &amp;&amp; (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(&amp;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(&amp;keyPressed);
glutSpecialFunc(&amp;specialKeyPressed);

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

return 0;

}

mikael_aronsson
04-06-2005, 12:50 AM
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