Multi-operation of model and view

Hi, all
what is the case if I mix the three operation: Scale, Translate and Rotate ,
I found that the model and view matrix changed every time during the operation, so when I try to moving my small cube, I found it is not what I want, it seems the matrix stack has impact my translation matrix, and I can’t use glLoadIdentity(), if so, all of my drawing will rollback to the original state.
any idea?

The problem is that when pressing arrow keys on the keyboard, the cube doesn’t move as I want, I want to let it move towards ONLY four directions, UP, DOWN,LEFT and RIGHT. not other directions.
This is a very simple one, please take a look, and give me some advise.
thank you !

keyboard controls:
‘v’ zoom out
‘b’ zoom in
‘w’ up-rotate around x axis
‘s’ down-rotate around x axis
‘a’ left-rotate around y axis
‘d’ right-rotate aound y axis

‘Up’ move up
‘Down’ move down
‘Left’ move left
‘Right’ move right

#include <windows.h>
#include <GL/glut.h>

//Translattion parameters
GLdouble tran_x = 0.0 ;
GLdouble tran_y = 0.0 ;
GLdouble tran_z = 0.0 ;

//Scale parameters
GLboolean flag_scale = true ;


GLdouble scale_x = 1.0 ;
GLdouble scale_y = 1.0 ;
GLdouble scale_z = 1.0 ;

//Rotation parameters
GLdouble angle = 10.0 ;
GLdouble rot_x ;
GLdouble rot_y ;
GLdouble rot_z ;

void init (void)
{
	glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0) ;
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_DEPTH_TEST) ;              
}

void Translate(GLdouble x, GLdouble y, GLdouble z)
{
	glMatrixMode(GL_MODELVIEW) ;
	glTranslatef(x, y, z) ;
}

void InitialScalePara()
{
	scale_x = 1.0 ;
	scale_y = 1.0 ;
	scale_z = 1.0 ;
}

void Scale(GLdouble x, GLdouble y, GLdouble z)
{
	glMatrixMode(GL_MODELVIEW) ;
	glScalef(x, y, z) ;

}

void Rotation( GLdouble rotangle, GLdouble x, GLdouble y, GLdouble z) 
{
	glMatrixMode(GL_MODELVIEW) ;
	glRotatef(rotangle, x, y, z) ;

}
void DrawCube(void)
{
	glBegin(GL_QUADS);		
	glColor3f(0.0f,1.0f,0.0f);	
	glVertex3f( 1.0f, 1.0f,-1.0f);	
	glVertex3f(-1.0f, 1.0f,-1.0f);
	glVertex3f(-1.0f, 1.0f, 1.0f);	
	glVertex3f( 1.0f, 1.0f, 1.0f);
	glColor3f(1.0f,0.5f,0.0f);	
	glVertex3f( 1.0f,-1.0f, 1.0f);	
	glVertex3f(-1.0f,-1.0f, 1.0f);	
	glVertex3f(-1.0f,-1.0f,-1.0f);	
	glVertex3f( 1.0f,-1.0f,-1.0f);	
	glColor3f(1.0f,0.0f,0.0f);	
	glVertex3f( 1.0f, 1.0f, 1.0f);	
	glVertex3f(-1.0f, 1.0f, 1.0f);	
	glVertex3f(-1.0f,-1.0f, 1.0f);	
	glVertex3f( 1.0f,-1.0f, 1.0f);	
	glColor3f(1.0f,1.0f,0.0f);	
	glVertex3f( 1.0f,-1.0f,-1.0f);	
	glVertex3f(-1.0f,-1.0f,-1.0f);	
	glVertex3f(-1.0f, 1.0f,-1.0f);	
	glVertex3f( 1.0f, 1.0f,-1.0f);	
	glColor3f(0.0f,0.0f,1.0f);
	glVertex3f(-1.0f, 1.0f, 1.0f);	
	glVertex3f(-1.0f, 1.0f,-1.0f);	
	glVertex3f(-1.0f,-1.0f,-1.0f);	
	glVertex3f(-1.0f,-1.0f, 1.0f);	
	glColor3f(1.0f,0.0f,1.0f);	
	glVertex3f( 1.0f, 1.0f,-1.0f);	
	glVertex3f( 1.0f, 1.0f, 1.0f);	
	glVertex3f( 1.0f,-1.0f, 1.0f);	
	glVertex3f( 1.0f,-1.0f,-1.0f);
	glEnd();	
}

void display(void) 
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) ;
	DrawCube() ;	
	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h) ;
	glMatrixMode(GL_PROJECTION) ;
	glLoadIdentity() ;
	if(w<=h)
		glOrtho(-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w,
		1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0) ;
	else
		glOrtho(-1.5*(GLfloat)w/(GLfloat)h, 
		1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0) ;	
}


void keyboard( unsigned char key, int x, int y)
{
	int zoomout = 1.0 ;
	switch(key)
	{
	case 'w':
	case 'W':
		Rotation(angle, 1.0, 0.0, 0.0) ;
		break ;
	case 'S':
	case 's':
		Rotation(-angle, 1.0, 0.0, 0.0) ;
		break ;
	case 'a':
	case 'A':
		Rotation(-angle, 0.0, 1.0, 0.0) ;
		break ;
	case 'd':
	case 'D':
		Rotation(angle, 0.0, 1.0, 0.0) ;
		break ;
	case 'b':
	case 'B':
		while(flag_scale)
		{
			InitialScalePara() ;
			flag_scale = !flag_scale ;
		}

		Scale(scale_x, scale_y, scale_z) ;
		scale_x += 0.001 ;
		scale_y += 0.001 ;
		scale_z += 0.001 ;
		break ;
	case 'v':
	case 'V':
		while(!flag_scale)
		{
			InitialScalePara() ;
			flag_scale =!flag_scale ;
		}

		Scale(scale_x, scale_y, scale_z) ;
		scale_x -= 0.001 ;
		scale_y -= 0.001 ;
		scale_z -= 0.001 ;
		break ;
	case 'i':
	case 'I':
		glLoadIdentity() ;
		break ;
	case 27:
		exit(1) ;
		break ;
	default:
		break ;	
	}
	glutPostRedisplay() ;
}
void specialkey(int key, int x, int y)
{
	
	switch(key)
	{
	case GLUT_KEY_LEFT:
		tran_x -= 0.2 ;
		break ;

	case GLUT_KEY_RIGHT:
		tran_x += 0.2 ;
		break ;

	case GLUT_KEY_UP:
		tran_y += 0.2 ;
		break ;

	case GLUT_KEY_DOWN:
		tran_y -= 0.2 ;
		break ;

	default:
		break ;
	}
	glTranslatef(0.0, 0.0, 0.0) ;
	Translate(tran_x, tran_y, 0) ;
	glutPostRedisplay();
}

int main(int argc, char** argv) 
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
	glutCreateWindow("Cube") ;
	init();
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
	glutSpecialFunc(specialkey) ;
	glutReshapeFunc(reshape);
	glutMainLoop();

	return 0;
}

There seems to be a lot of confusion over basic math lately. My best advice to you is to hunker down and learn the math (linear algebra).

For you convenience, here’s a free book on the subject:
http://joshua.smcvt.edu/linearalgebra/

And here’s a good overview of basic transformations in OpenGL:
http://www.rush3d.com/reference/opengl-redbook-1.1/chapter03.html

Working through some of the examples is often helpful.

I hope it helps.

What you are doing wrong is that every time you want do move something you change the matrix.
However in openGL matrix modifications happen in the reverse order.

So what you do is that you store the position, rotation and scale is separate variables.
When you press the keys you modify these values directly.
When rendering call glLoadIdentity() and only then just before rendering you call glTranslate, rotate and scale in the proper order.

Oh, it seems a little intractable to me.
but why it is no problem when i mix Scale and Rotate? the issue comes only when i ues Translate, continue investigating…

Because mixing scale and rotate alone is order-independant.
When you add translation, it becomes order dependant.
Try simply reversing the initial order of your operations, often it is enough to make it work.