OpenGL实现仅立方体移动、坐标平面固定的矩阵操作问题
问题原因与修改方案
你当前的写法是直接在按键回调中修改全局的GL_MODELVIEW矩阵,这个修改会一直保留,后续所有绘制的元素(包括立方体和坐标平面)都会应用这个平移变换,所以两个元素会一起移动。
核心修改思路
- 用独立变量存储立方体的位移状态,不要直接持久修改全局模型视图矩阵
- 绘制不同元素时隔离变换:固定元素用初始单位矩阵绘制,仅在绘制可移动立方体时应用位移变换
- 遵循GLUT的重绘规范,不要手动调用
Display(),用glutPostRedisplay()触发重绘
修改后完整代码
#include <glut.h> void Reshape(int w, int h); void Display(); void ProcessNormalKeys(unsigned char key, int x, int y); void ProcessSpecialKeys(int key, int x, int y); // 新增:存储立方体的偏移量 float cubeOffsetX = 0, cubeOffsetY = 0; int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(800, 600); glutCreateWindow("Move Cube Demo"); // 补全原代码缺失的窗口创建调用 glutReshapeFunc(Reshape); glutDisplayFunc(Display); glutKeyboardFunc(ProcessNormalKeys); glutSpecialFunc(ProcessSpecialKeys); glutMainLoop(); return 0; } void Reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1000, 1000, -1000, 1000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void Display() { glClearColor(1, 1, 1, 0); glClear(GL_COLOR_BUFFER_BIT); // 先绘制固定的坐标平面,此时模型视图矩阵是单位矩阵,不会偏移 glBegin(GL_LINES); glColor3f(0, 0, 0); glVertex2i(-10000, 0); glVertex2i(10000, 0); glVertex2i(0, -10000); glVertex2i(0, 10000); glEnd(); // 用矩阵栈隔离立方体的变换,避免影响其他元素 glPushMatrix(); glTranslatef(cubeOffsetX, cubeOffsetY, 0); // 仅应用立方体的偏移 glBegin(GL_QUADS); glColor3f(1.0, 1.0, 1.0); glVertex2i(350, 550); glColor3f(0.0, 0.0, 1.0); glVertex2i(350, 150); glColor3f(0.0, 1.0, 0.0); glVertex2i(650, 150); glColor3f(1.0, 0.0, 0.0); glVertex2i(650, 550); glEnd(); glPopMatrix(); // 绘制完立方体后恢复矩阵为单位矩阵 glutSwapBuffers(); } void ProcessNormalKeys(unsigned char key, int x, int y) { if (key == 27) { exit(0); } if (key == 65) { cubeOffsetX += 80; cubeOffsetY += 80; glutPostRedisplay(); // 触发重绘 } } void ProcessSpecialKeys(int key, int x, int y) { switch (key) { case GLUT_KEY_UP: cubeOffsetY += 80; glutPostRedisplay(); break; case GLUT_KEY_DOWN: cubeOffsetY -= 80; glutPostRedisplay(); break; case GLUT_KEY_LEFT: cubeOffsetX -= 80; glutPostRedisplay(); break; case GLUT_KEY_RIGHT: cubeOffsetX += 80; glutPostRedisplay(); break; } }
内容的提问来源于stack exchange,提问作者Omberg
相关产品推荐
相关产品推荐

