我试着用这些键将这两个自动旋转的多边形向左右,上下和前后移动:对于金字塔是键('a','w','s','d','+','-'),对于立方体是键('','','','','','Page Up‘,'Page Down'),多边形确实会移动,但它们的移动方式很奇怪,不是我想要的,尤其是当我试着将它们向上,向下移动时,我想知道它们为什么会移动,以及我应该做什么改变才能使它们正常移动。
这是代码:
#include <GL\glew.h>
#include <SOIL.h>
#include <GL/glut.h>
float pyramid_x = 0, pyramid_y = 0, pyramid_z = 0;
float cube_x = 0, cube_y = 0, cube_z = 0;
float pyramid_angle = 0.0;
float cube_angle = 0.0;
int refresh = 10;//ms
float degree = 0;
void cube_right(void)
{
glLoadIdentity();
cube_x += 0.1;
}
void cube_left(void)
{
glLoadIdentity();
cube_x -= 0.1;
}
void cube_up(void)
{
glLoadIdentity();
cube_y += 0.1;
}
void cube_down(void)
{
glLoadIdentity();
cube_y -= 0.1;
}
void cube_front(void)
{
glLoadIdentity();
cube_z -= 0.1;
}
void cube_back(void)
{
glLoadIdentity();
cube_z += 0.1;
}
void pyramid_right(void)
{
glLoadIdentity();
pyramid_x += 0.1;
}
void pyramid_left(void)
{
glLoadIdentity();
pyramid_x -= 0.1;
}
void pyramid_up(void)
{
glLoadIdentity();
pyramid_y += 0.1;
}
void pyramid_down(void)
{
glLoadIdentity();
pyramid_y -= 0.1;
}
void pyramid_front(void)
{
glLoadIdentity();
pyramid_z -= 0.1;
}
void pyramid_back(void)
{
glLoadIdentity();
pyramid_z += 0.1;
}
void keyboard(int buttons, int x, int y)
{
switch (buttons)
{
case GLUT_KEY_LEFT:cube_left(); break;
case GLUT_KEY_RIGHT:cube_right(); break;
case GLUT_KEY_UP:cube_up(); break;
case GLUT_KEY_DOWN:cube_down(); break;
case GLUT_KEY_PAGE_UP:cube_front(); break;
case GLUT_KEY_PAGE_DOWN:cube_back(); break;
}
glutPostRedisplay();
}
void keyboard(unsigned char buttons, int x, int y)
{
switch (buttons)
{
case 'w':pyramid_front(); break;
case'a':pyramid_left(); break;
case's':pyramid_down(); break;
case'd':pyramid_right(); break;
case '+':pyramid_front(); break;
case'-':pyramid_back(); break;
}
glutPostRedisplay();
}
void settings()
{
glClearColor(1, 1, 1, 0);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void drawing_function()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //reset
glTranslatef(2.0f, 0.0f, -7.0f);
glRotatef(pyramid_angle, 1.0f, 0.0f, 0.0f);
glColor3f(1.0, 0.0, 0.0);
glTranslatef(pyramid_x, pyramid_y, pyramid_z);
glBegin(GL_TRIANGLES);
// front
glTexCoord3f(1, 0, 0);
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(1.0f, -1.0f, 1.0f);
// right
glTexCoord3f(0, 0, 0);
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(1.0f, -1.0f, -1.0f);
// back
glTexCoord3f(0, 1, 0);
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(-1.0f, -1.0f, -1.0f);
// left
glTexCoord3f(1, 1, 0);
glColor3f(1.0f, 0.0f, 0.0f); //red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); //blue
glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //green
glVertex3f(-1.0f, -1.0f, 1.0f);
glEnd();
glLoadIdentity();//(Reset model-view matrix)
glTranslatef(-2.0f, 0.0f, -7.0f);
glRotatef(cube_angle, 1.0f, 0.0f, 0.0f);
glTranslatef(cube_x, cube_y, cube_z);
glBegin(GL_QUADS); //cube
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);
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(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, 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.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, 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);
glEnd();
glutSwapBuffers();
pyramid_angle += 1.0f;
cube_angle -= 0.2f;
}
void timer(int deger)
{
glutPostRedisplay();
glutTimerFunc(refresh, timer, 0);
}
void view_setting(GLsizei x, GLsizei y)
{
if (y == 0) y = 1;
GLfloat aspect = (GLfloat)x / (GLfloat)y;
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0f, aspect, 1.0f, 20.0f);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowPosition(50, 50);
glutInitWindowSize(800, 600);
glutCreateWindow("3d");
glutDisplayFunc(drawing_function);
glutReshapeFunc(view_setting);
glutSpecialFunc(keyboard);
glutKeyboardFunc(keyboard);
settings();
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}
更改转换的顺序。 先旋转,然后平移:
glTranslatef(2.0f, 0.0f, -7.0f);
glTranslatef(pyramid_x, pyramid_y, pyramid_z);
glRotatef(pyramid_angle, 1.0f, 0.0f, 0.0f);
glTranslatef(-2.0f, 0.0f, -7.0f);
glTranslatef(cube_x, cube_y, cube_z);
glRotatef(cube_angle, 1.0f, 0.0f, 0.0f);
矩阵乘法是不可交换的。 像glrotote
和gltranslated
这样的操作设置了一个新矩阵,并将当前矩阵乘以新矩阵。 因此,首先需要做的转换必须是代码中的最后一个。
此外,键盘
有一个错误。 当按下w时,金字塔必须向上移动而不是向前移动:
大小写“w”:prymid_front(); 中断;
case 'w':pyramid_up(); break;