Reputation: 65
I never got the concept down on how to get an animation working in OpenGL. I was working on his project trying to get it to work but never got the skier to move. Trying to figure out how to get this fixed.
#include "../shared/gltools.h" // OpenGL toolkit
#define PI 3.14159265
float a = -5;//maybe
float b = 29;
float c = 27;
float d = 28.25;
float e = 28.5;
bool lookUp;
bool setback;
bool lookDown;
bool lookLeft;
bool lookRight;
bool walkForward;
bool walkBackward;
bool strafeLeft;
bool strafeRight;
float xTranslation;
float yTranslation;
float zTranslation;
float yRotationAngle;
float zRotationAngle;
float xRotationAngle;
int mouseLastx;
int mouseLasty;
float sunRotationAngle=0;
float sunRadius = 150.0;
float day=0;
float dusk=1;
// Light values and coordinates
GLfloat lightPos[] = { 0.0f, 30.0f, 0.0f, 1.0f };
GLfloat lightPos2[] = { 0.0f, 0.0f, 40.0f, 1.0f };
GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat specular2[] = { 0.0f, 1.0f, 0.0f, 1.0f};
GLfloat diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat diffuse2[] = { 0.0f, 0.3f, 0.0f, 1.0f};
GLloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f};
GLfloat spotDir[] = { 0.0f, 0.0f, -1.0f };
void mouseMovement(int x, int y)
{
int mouseDiffx=x-mouseLastx;
int mouseDiffy=y-mouseLasty;
mouseLastx=x;
mouseLasty=y; //set lasty to the current y position
xRotationAngle += (GLfloat) mouseDiffy;
yRotationAngle += (GLfloat) mouseDiffx;
if (xRotationAngle>=90)
xRotationAngle=90;
if (xRotationAngle<=-90)
xRotationAngle=-90;
//cout << "x:" << x << "y:" << y << endl;
}
void drawcabin()
{
glColor3ub(0, 0, 0);
glBegin(GL_TRIANGLES);
//glTranslatef(0,-5,0); // move view left
//glNormal3f(-3,0.7,-1.7);
//glutSolidCube(5.0f);
glNormal3d(0,0.7,0.7);
glVertex3d(0,6,0);
glVertex3d(-3,3.5,-2);
glVertex3d(2,3.5,-2);
glNormal3d(2,-1,1);
glVertex3d(0,6,0);
glVertex3d(-3,3.5,-2);
glVertex3d(2,3.5,-2);
glTranslatef(0,-5,0); // move view left
glNormal3d(-3,0.7,-1.7);
glEnd();
glColor3ub(185, 0, 0);
glutSolidCube(5.0f);
}
void drawskislope()
{
glColor3ub(0, 0, 0);
glBegin(GL_QUADS);
glTranslatef(0,-5,90); // move view left
glColor3ub(185, 122, 87);
glNormal3d(0,5,1);
glVertex3d(10,0,5);
glVertex3d(10,.5,5);
glVertex3d(15,.5,5);
glVertex3d(15,0,5);//small square
glColor3ub(201, 192, 187);
glVertex3d(11.5,.5,5);
glVertex3d(13.5,.5,5);
glVertex3d(13.5,-10,5);
glVertex3d(11.5,-10,5);
//slope start
glTranslatef(0,-5,0); // move view left
// glNormal3d(-3,0.7,-1.7);
glEnd();
}
void drawskier()
{
float a = -5;//maybe
float b = 29;
float c = 27;
float d = 28.25;
float e = 28.5;
glBegin(GL_QUADS);
glTranslatef(0,-5,0); // move view
glColor3ub(185, 122, 87);
glNormal3d(0,5,1);
//Do While loop
// do
// {
// to move skier do a loop and update a in the translate
glTranslatef(0,a,0); // move view
glVertex3d(c,0,5);//10
glVertex3d(c,.1,5);//10
glVertex3d(b,.1,5);//15
glVertex3d(b,0,5);//skis on skier
glNormal3d(0,5,1);
glVertex3d(d,0,5);
glVertex3d(d,1.35,5);
glVertex3d(e,1.35,5);
glVertex3d(e,0,5);//body on skier
glutSwapBuffers;
// }while(b>15); //try to animate
glEnd();
glFlush();
b=b-1;
c=c-1;
d=d-1;
e=e-1;
glutPostRedisplay();
glTranslatef(30,3,0); // move view left
glColor3ub(168, 220, 109);
glutSolidSphere(.5,7,8); //sphere-head
glPushMatrix();
glTranslatef(3.5,-100,2);
glutSolidSphere(25,15,15); //sphere
glPopMatrix();
}
void updatescene()
{
}
///////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
{
GLUquadricObj *pObj; // Quadric Object
pObj = gluNewQuadric();
gluQuadricNormals(pObj, GLU_SMOOTH);
GLfloat horizontalMovement=1;
GLfloat verticalMovement=0;
horizontalMovement=cos(xRotationAngle*PI/180);
verticalMovement=-sin(xRotationAngle*PI/180);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
horizontalMovement=cos(xRotationAngle*PI/180);
verticalMovement=-sin(xRotationAngle*PI/180);
if (lookDown)
{
xRotationAngle+=1;
if (xRotationAngle>=90)
xRotationAngle=90;
}
if (lookUp)
{
xRotationAngle-=1;
if (xRotationAngle<=-90)
xRotationAngle=-90;
}
if (lookRight)
{
yRotationAngle+=1;
if (yRotationAngle>=360)
yRotationAngle=0;
}
if (lookLeft)
{
yRotationAngle-=1;
if (yRotationAngle<=-360)
yRotationAngle=0;
}
if (walkForward)
{
zTranslation+=cos(yRotationAngle*PI/180)*horizontalMovement;
xTranslation-=sin(yRotationAngle*PI/180)*horizontalMovement;
yTranslation-=verticalMovement;
}
if (walkBackward)
{
zTranslation-=cos(yRotationAngle*PI/180)*horizontalMovement;
xTranslation+=sin(yRotationAngle*PI/180)*horizontalMovement;
yTranslation+=verticalMovement;
}
if (strafeRight)
{
zTranslation+=cos((yRotationAngle+90)*PI/180);
xTranslation-=sin((yRotationAngle+90)*PI/180);
}
if (strafeLeft)
{
zTranslation-=cos((yRotationAngle+90)*PI/180);
xTranslation+=sin((yRotationAngle+90)*PI/180);
}
if (setback)
{
zTranslation=0;
xTranslation=0;
yTranslation=0;
}
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(xRotationAngle,1,0,0);
glRotatef(zRotationAngle,0,0,1);
glRotatef(yRotationAngle,0,1,0);
glTranslatef(xTranslation,yTranslation,zTranslation);
//glRotatef(-15,1,0,0);
//glRotatef(90,0,1,0);
glTranslatef(0,-0.50,-10);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
sunRotationAngle++;
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(0,0,0);
glLineWidth(2);
//snow
glColor3ub(255, 255, 255);
glBegin(GL_QUADS);
glNormal3f(0,1,0);
for (int i=-100;i<=200;i+=10) //x
for (int j=-100;j<=200;j+=10)//z
{
float y1=(-j)*.25;
float y2=(-j+10)*.25;
glVertex3d(i+10,y2,-100);
glVertex3d(i,y2,-100);
glVertex3d(i,y1,-100);
glVertex3d(i+10,y1,-100);
}
glEnd();
glPushMatrix();
glTranslatef(-10,14,-50);
drawcabin();
drawskislope();
drawskier();
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
glutPostRedisplay();
//GLfloat horizontalMovement=1;
// GLfloat verticalMovement=0;
}
void TimerFunction(int value)
{
// Redraw the scene with new coordinates
glutPostRedisplay();
updatescene();
glutTimerFunc(16,TimerFunction, 1);
}
///////////////////////////////////////////////////////////
// Setup the rendering context
void SetupRC(void)
{
lookUp=false;
lookDown=false;
lookLeft=false;
lookRight=false;
walkForward=false;
walkBackward=false;
strafeLeft=false;
strafeRight=false;
yRotationAngle=0;
xRotationAngle=0;
zRotationAngle=0;
xTranslation=0;
yTranslation=0;
zTranslation=0;
// White background
glClearColor(0.5f,0.95f, 1.0f, 1.0f );
// Set drawing color to green
glColor3f(0.0f, 1.0f, 0.0f);
// Set color shading model to flat
glShadeModel(GL_SMOOTH);
// Clock wise wound polygons are front facing, this is reversed
// because we are using triangle fans
glFrontFace(GL_CCW);
glEnable (GL_DEPTH_TEST);
}
void ChangeSize(int w, int h)
{
//GLfloat nRange = 100.0f;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
GLfloat fAspect;
fAspect = (GLfloat)w / (GLfloat)h;
//glOrtho(-10,10,-10,10,0,1000);
gluPerspective(45,fAspect,0.1,1000);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Respond to arrow keys by moving the camera frame of reference
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
lookUp=true;
if(key == GLUT_KEY_DOWN)
lookDown=true;
if(key == GLUT_KEY_LEFT)
lookLeft=true;
if(key == GLUT_KEY_RIGHT)
lookRight=true;
// Refresh the Window
glutPostRedisplay();
}
void SpecialKeysUp(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
lookUp=false;
if(key == GLUT_KEY_DOWN)
lookDown=false;
if(key == GLUT_KEY_LEFT)
lookLeft=false;
if(key == GLUT_KEY_RIGHT)
lookRight=false;
// Refresh the Window
glutPostRedisplay();
}
void keyboardFunc(unsigned char key, int x, int y)
{
switch(key)
{
case 'w':
walkForward=true;
break;
case 's':
walkBackward=true;
break;
case 'a':
strafeLeft=true;
break;
case 'd':
strafeRight=true;
break;
case 'r':
setback=true;
break;
default:
break;
}
}
void keyboardUpFunc(unsigned char key, int x, int y)
{
switch(key)
{
case 'w':
walkForward=false;
break;
case 's':
walkBackward=false;
break;
case 'a':
strafeLeft=false;
break;
case 'd':
strafeRight=false;
break;
default:
break;
}
}
///////////////////////////////////////////////////////////
// Main program entry point
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500,500);
glutCreateWindow("Assignment 2");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpecialKeys);
glutSpecialUpFunc(SpecialKeysUp);
glutKeyboardUpFunc(keyboardUpFunc);
glutKeyboardFunc(keyboardFunc);
glutPassiveMotionFunc(mouseMovement);
SetupRC();
glutMainLoop();
return 0;
}
Upvotes: 1
Views: 501
Reputation: 52082
My general approach is to use a glutTimerFunc()
callback to post a redisplay event every 16 milliseconds or so (~60 FPS).
Then in the glutDisplayFunc()
callback you can grab the new GLUT_ELAPSED_TIME
to calculate a delta-time (dt
) from the last frame.
With dt
in hand you can update any number of variables such as angles or translation offsets. You'll want to use dt
instead of fixed increment values to decouple your animation speed from your framerate.
Then back in the glutDisplayFunc()
callback you draw a new frame using the updated state variables.
This is an example that uses the method above to rotate a square at about 30 degrees per second:
#include <GL/glut.h>
float angle = 0;
void update( const double dt )
{
// in degrees per second
const float SPEED = 30.0f;
// update angle
angle += ( SPEED * dt );
}
void display()
{
// GLUT_ELAPSED_TIME is in milliseconds
static int prvMs = glutGet( GLUT_ELAPSED_TIME );
const int curMs = glutGet( GLUT_ELAPSED_TIME );
// dt is in seconds
const double dt = ( curMs - prvMs ) / 1000.0;
prvMs = curMs;
// update world state
update( dt );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// reset projection/modelview matrices each frame;
// this makes sure we have a known-good matrix
// stack each time through display()
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -2, 2, -2, 2, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// draw rotated square
glRotatef( angle, 0, 0, 1 );
glBegin( GL_QUADS );
glColor3ub( 255, 0, 0 );
glVertex2i( -1, -1 );
glVertex2i( 1, -1 );
glVertex2i( 1, 1 );
glVertex2i( -1, 1 );
glEnd();
glutSwapBuffers();
}
void timer( int value )
{
glutPostRedisplay();
glutTimerFunc( 16, timer, 0 );
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}
Upvotes: 1