You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:36:04