Click to See Complete Forum and Search --> : problem with glutKeyboardFunc(keyboard);


dathatreya
April 17th, 2008, 04:25 AM
I'm using opengl with MFC for developing the 3d application.Here the problem is if I use glutKeyboardFunc(keyboard) both the objects(room and cube)are moving but I want to make move for onlly cube.Here I'm giving the code can anyone suggest how to make movement for only cube.



void MFCOpenGL:isplay(void)
{

glDrawBuffer(GL_FRONT_LEFT);
//glColor3f(1, 1, 1);
glClearColor(1,1,1,1);//set the background color to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

glBegin(GL_QUADS);
glColor3d(1.0, 0.0, 0.0);
glVertex2d(0.0, 0.0);
glVertex2d(2.4, -0.35);
glVertex2d(2.45, 2.5);
glVertex2d(0.0, 2.7);
glEnd();


glBegin(GL_QUADS);
glColor3d(0.0, 0.0, 1.0);
glVertex2d(-2.5, -0.;
glVertex2d(0.0, 0.0);
glVertex2d(0.0, 2.7);
glVertex2d(-2.5, 2.0);
glEnd();


glBegin(GL_QUADS);
glColor3d(0.0, 0.0, 0.0);
glVertex2d(-2.5, -0.;
glVertex2d(-0.3, -2.0);
glVertex2d(2.4, -0.35);
glVertex2d(0.0,0.0);
glEnd();

glColor3f(0.0, 1.0, 1.0);
glutSolidCube(0.5);
glutSwapBuffers();
glutPostRedisplay();//end of insertion
}

void MFCOpenGL::Resize(int width,int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)width / (float)height, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set the viewing position and orientation
gluLookAt(
0.0, 0.0,10.0, // eye location
0.0, 0.0, 1.0, // center location
0.0, 1.0, 0.0); // up vector
}

void MFCOpenGL::keyboard(int key, int x, int y)
{
switch (key)
{
case 'a':
case 'A':
glTranslatef(-1.0, 0.0, 0.0);

break;

case 'd':
case 'D':
glTranslatef(1.0, 0.0, 0.0);
break;

case 'w':
case 'W':
glTranslatef(0.0, 0.0, 1.0);
break;

case 's':
case 'S':
glTranslatef(0.0, 0.0, -1.0);
break;
}
}

Zachm
April 28th, 2008, 09:13 AM
1st, please use [ code ] [ /code] tags in the future to post your code.

What you maybe fail to realize is that openGL is a state machine. openGL has 2 matrices that are always kept the same unless changed by your code.
glTranslate / glRotate / glScale change the Model-View matrix.

When your scene is drawn, each vertex, when positioned in the "world", is multiplied by the current matrix, and thus gets a new world position.

Since in your keyboard function you call glTranslatef, you change the current matrix, and affect the position of all vertices since the matrix is not reset before drawing the room (or before drawing the cube).

If you want the cube to render at the correct position each time, you should keep track of it's position, so keep a vector variable for it's position (or 3 variables x,y and z).

Now, your isplay func should look something like this:

struct vector3
{
float x, y, z;
} cubePos;

void MFCOpenGL:isplay(void)
{
//first reset the model-view matrix to identity glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDrawBuffer(GL_FRONT_LEFT);
//glColor3f(1, 1, 1);
glClearColor(1,1,1,1);//set the background color to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);

glBegin(GL_QUADS);
glColor3d(1.0, 0.0, 0.0);
glVertex2d(0.0, 0.0);
glVertex2d(2.4, -0.35);
glVertex2d(2.45, 2.5);
glVertex2d(0.0, 2.7);
glEnd();


glBegin(GL_QUADS);
glColor3d(0.0, 0.0, 1.0);
glVertex2d(-2.5, -0.;
glVertex2d(0.0, 0.0);
glVertex2d(0.0, 2.7);
glVertex2d(-2.5, 2.0);
glEnd();


glBegin(GL_QUADS);
glColor3d(0.0, 0.0, 0.0);
glVertex2d(-2.5, -0.;
glVertex2d(-0.3, -2.0);
glVertex2d(2.4, -0.35);
glVertex2d(0.0,0.0);
glEnd();

glColor3f(0.0, 1.0, 1.0);
glPushMatrix();
glTranslatef(cubePos.x, cubePos.y, cubePos.z);
glutSolidCube(0.5);
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();//end of insertion
}


and your keyboard func should look something like this:

void MFCOpenGL::keyboard(int key, int x, int y)
{ switch (key)
{
case 'a':
case 'A':
cubePos.x -= 1.0f;
break;
case 'd':
case 'D':
cubePos.x += 1.0f;
break;
case 'w':
case 'W':
cubePos.z += 1.0f;
break;
case 's':
case 'S':
cubePos.z -= 1.0f;
break;
}
}


glPushMatrix() and glPopMatrix() are used to store and retrieve the current matrix, so when calling it just before translating the cube, and just after drawing the cube, you actually retrieve the matrix to it's state just before calling glTranslatef.

I hope this makes sense. There are loads of openGL tutorials that cover all of this issues with plenty of examples.

Regards,
Zachm