Door animation

Started by
2 comments, last by haegarr 12 years, 8 months ago
Im trying to animate a door so that if i press a button the door will open, at the moment it compiles and when i go to press the button it moves the camera and then i cant control the camera anymore, so i dont know what is wrong with the code, any help would be great
glPushMatrix;
glTranslatef (door_Xpos,0.0, 0.0);
glRotatef (door_Angle, 1,0,0);


glBegin(GL_QUADS);

//door left
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-10.0, 15.0, -25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(0.0, 15.0, -25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(0.0, 0.0, -25.0);

//door right
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(10.0, 15.0, -25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(0.0, 15.0, -25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(0.0, 0.0, -25.0);

glPopMatrix;

void keyboard(unsigned char key, int x, int y)
{

switch (key)
{
case 'a':
case 'A':
glTranslatef(5.0, 0.0, 0.0);
break;
case 'd':
case 'D':
glTranslatef(-5.0, 0.0, 0.0);
break;
case 'w':
case 'W':
glTranslatef(0.0, 0.0, 5.0);
break;
case 's':
case 'S':
glTranslatef(0.0, 0.0, -5.0);
break;
case 't':
case 'T':
if (is_depth)
{
is_depth = 0;
glDisable(GL_DEPTH_TEST);
}
else
{
is_depth = 1;
glEnable(GL_DEPTH_TEST);
}
case 'o':
case 'O':
door_Xpos += 90.0;
break;
}
display();
}
Advertisement
Please edit the OP: Source code snippets shall not be surrounded by [ quote ] but by [ code ] tags. That makes code more readable and doesn't waste so much screen space ;)

Now to the code itself. It is not good to execute the GL transformation immediately during input processing. This intermingles state and rendering. Moreover, because the code snippet doesn't show us the entire program flow, we cannot reproduce how the sequence of transformations actually is. Please refactor the code so that input is working on a state (i.e. position vector of the camera) and concentrate rendering stuff in the draw routine. You do something like that already with door_Xpos.

The branch for the case of 't' / 'T' is not concluded by a break. It instead is immediately followed by the branch for 'o' / 'O' what probably is not intentional.

However, I doubt that the code will work although when the above issues are corrected. I assume that the error is hidden in the code not shown here.

Please edit the OP: Source code snippets shall not be surrounded by [ quote ] but by [ code ] tags. That makes code more readable and doesn't waste so much screen space ;)

Now to the code itself. It is not good to execute the GL transformation immediately during input processing. This intermingles state and rendering. Moreover, because the code snippet doesn't show us the entire program flow, we cannot reproduce how the sequence of transformations actually is. Please refactor the code so that input is working on a state (i.e. position vector of the camera) and concentrate rendering stuff in the draw routine. You do something like that already with door_Xpos.

The branch for the case of 't' / 'T' is not concluded by a break. It instead is immediately followed by the branch for 'o' / 'O' what probably is not intentional.

However, I doubt that the code will work although when the above issues are corrected. I assume that the error is hidden in the code not shown here.


this is my whole code if that helps, iwhere should the gltranslate and glrotate functions go then, thanks

#include <windows.h>

#include <gl\gl.h>
#include <gl\glut.h>
#include <gl\glu.h>
#include <stdio.h>
#include <iostream>

void init(void);
void display(void);
void keyboard(unsigned char, int, int);
void resize(int, int);

GLfloat door_Xpos;
GLfloat door_Angle;
GLint camposz;


int is_depth;


int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(40, 40);
glutCreateWindow("Underground cave");
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(resize);

glutMainLoop();
return 0;
}

void init(void)
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
is_depth = 1;
glMatrixMode(GL_MODELVIEW);


}

void display(void)
{
if (is_depth)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
else
glClear(GL_COLOR_BUFFER_BIT);

GLfloat lightColor0[] = {0.2f, 0.2f, 0.2f, 1.0f};
GLfloat lightPos0[] = {50.0f, 0.0f, 50.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);

GLfloat lightColor1[] = {0.2f, 0.2f, 0.2f, 1.0f};
GLfloat lightPos1[] = {50.0f, 0.0f, -400.0f, 1.0f};
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);
glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);


glPushMatrix;

glTranslatef(door_Xpos,0.0, 0.0);
glRotatef(door_Angle, 1,0,0);


glBegin(GL_QUADS);


//door left
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-10.0, 15.0, -25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(-10.0, 15.0, -15.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(-10.0, 0.0, -15.0);

//door right
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(10.0, 15.0, -25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(0.0, 15.0, -25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(0.0, 0.0, -25.0);

glPopMatrix;

//floor
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-50.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-50.0, 0.0, 25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(50.0, 0.0, 25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(50.0, 0.0, -25.0);

//left wall
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-50.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-50.0, 00.0, 25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(-50.0, 25.0, 25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(-50.0, 25.0, -25.0);

//right wall
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(50.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(50.0, 00.0, 25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(50.0, 25.0, 25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(50.0, 25.0, -25.0);

//roof
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-50.0, 25.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-50.0, 25.0, 25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(50.0, 25.0, 25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(50.0, 25.0, -25.0);

//right panel
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(10.0, 15.0, -25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(50.0, 15.0, -25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(50.0, 0.0, -25.0);

//left panel
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-10.0, 15.0, -25.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(-50.0, 15.0, -25.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(-50.0, 0.0, -25.0);

//top panel
glColor3f(0.2f, 0.2f, 0.2f);
//bottom right
glVertex3f(50.0, 15.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
//top right
glVertex3f(50.0, 25.0, -25.0);
glColor3f(0.6f, 0.6f, 0.6f);
//top left
glVertex3f(-50.0, 25.0, -25.0);
glColor3f(0.8f, 0.8f, 0.8f);
//bottom left
glVertex3f(-50.0, 15.0, -25.0);

// corridor floor
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-10.0, 0.0, -275.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(10.0, 0.0, -275.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(10.0, 0.0, -25.0);

// corridor left wall
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-10.0, 00.0, -275.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(-10.0, 15.0, -275.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(-10.0, 15.0, -25.0);

// corridor right wall
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(10.0, 0.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(10.0, 00.0, -275.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(10.0, 15.0, -275.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(10.0, 15.0, -25.0);

//corridor roof
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-10.0, 15.0, -25.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-10.0, 15.0, -275.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(10.0, 15.0, -275.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(10.0, 15.0, -25.0);

//right panel room 2
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(10.0, 0.0, -275.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(10.0, 15.0, -275.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(50.0, 15.0, -275.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(50.0, 0.0, -275.0);

//left panel room 2
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-10.0, 0.0, -275.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-10.0, 15.0, -275.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(-50.0, 15.0, -275.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(-50.0, 0.0, -275.0);

//top panel room 2
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(50.0, 15.0, -275.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(50.0, 25.0, -275.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(-50.0, 25.0, -275.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(-50.0, 15.0, -275.0);

//right wall room 2
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(50.0, 0.0, -275.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(50.0, 00.0, -325.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(50.0, 25.0, -325.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(50.0, 25.0, -275.0);

//left wall room 2
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-50.0, 0.0, -275.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-50.0, 00.0, -325.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(-50.0, 25.0, -325.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(-50.0, 25.0, -275.0);

//roof room 2
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-50.0, 25.0, -275.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-50.0, 25.0, -325.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(50.0, 25.0, -325.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(50.0, 25.0, -275.0);

//back wall room 2
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(50.0, 0.0, -325.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(50.0, 25.0, -325.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(-50.0, 25.0, -325.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(-50.0, 0.0, -325.0);

//floor room 2
glColor3f(0.2f, 0.2f, 0.2f);
glVertex3f(-50.0, 0.0, -275.0);
glColor3f(0.4f, 0.4f, 0.4f);
glVertex3f(-50.0, 0.0, -325.0);
glColor3f(0.6f, 0.6f, 0.6f);
glVertex3f(50.0, 0.0, -325.0);
glColor3f(0.8f, 0.8f, 0.8f);
glVertex3f(50.0, 0.0, -275.0);



glEnd();


glutSwapBuffers();
}

void keyboard(unsigned char key, int x, int y)
{

switch (key)
{
case 'a':
case 'A':
if(camposz < 50)
{
glTranslatef(5.0, 0.0, 0.0);
camposz= camposz+5;
}
break;
case 'd':
case 'D':
glTranslatef(-5.0, 0.0, 0.0);
break;
case 'w':
case 'W':
glTranslatef(0.0, 0.0, 5.0);
break;
case 's':
case 'S':
glTranslatef(0.0, 0.0, -5.0);
break;
case 't':
case 'T':
if (is_depth)
{
is_depth = 0;
glDisable(GL_DEPTH_TEST);
}
else
{
is_depth = 1;
glEnable(GL_DEPTH_TEST);
}
break;
case 'o':
case 'O':
door_Xpos += 90.0;
break;
}
display();
}

void resize(int width, int height)
{
if (height == 0) height = 1;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

/* note we divide our width by our height to get the aspect ratio */
gluPerspective(45.0, width / height, 1.0, 400.0);

/* set initial position */
glTranslatef(0.0, -5.0, -10.0);

glMatrixMode(GL_MODELVIEW);
}
A cleaner solution would look like:

1. Input is used to manipulate data of the world model (notice that "model" is used here in a broad sense as a scene description, i.e. it includes the camera as well). So use a structure for the camera that stores the position and orientation and whatever else belongs to it. You do something like this already for the door, because door_Xpos and door_Angle are parts of the model of the door.

2. Rendering is a kind of graphical representation of the world model. It interprets the data of the world for its purposes. I.e. at the beginning of render() it switches over to the MODELVIEW matrix if needed and constructs the VIEW matrix portion form the camera's model. It preserves this VIEW portion for all world objects that it renders (e.g. the static geometry like the walls, floor and roof, as well as the dynamic geometry like the door). Hence it iterates over all world objects, computes the respective MODEL matrix, and multiplies it to the saved VIEW portion. Then the geometry is pushed into the pipeline.


void render() {
// prepating rendering
glClear(...);
glMatrixMode( GL_MODELVIEW );
// VIEW portion
glLoadIdentity();
glMultMatrix( camera->inverseOrientation() );
glTranslate( camera->inversePosition() );
// static geometry
glPushMatrix();
glTranslate( staticGeom->position() ); // if not baked into the vertex data
glMultMatrix( staticGeom->orientation() ); // if not baked into the vertex data
glBegin( GL_QUADS );
...
glEnd();
glPopMatrix();
// perhaps some other static geometry
glPushMatrix();
glTranslate( staticGeom2->position() ); // if not baked into the vertex data
glMultMatrix( staticGeom2->orientation() ); // if not baked into the vertex data
glBegin( GL_QUADS );
...
glEnd();
glPopMatrix();
// some dynamic geometry
glPushMatrix();
glTranslate( door->position() );
glMultMatrix( door->orientation() );
glBegin( GL_QUADS );
...
glEnd();
glPopMatrix();
// perhaps some more dynamic geometry
...
}


As you can see, each object should have its own section. (Normally it would be done by iterating some kind of scene graph instead of hard coding, of course.)

Your code uses a glPushMatrix(), but I don't see any glPopMatrix(). That is not good, because it would cause a stack overflow after some time. Notice that in the above example each glPushMatrix() is paired with a glPopMatrix().

3. In summary, input handling and rendering are separated. Both work on / with the model of the world.

This topic is closed to new replies.

Advertisement