(OpenGL)旋转对象

(OpenGL)旋转对象,opengl,rotation,mouselistener,Opengl,Rotation,Mouselistener,我正在制作一个程序,当我点击鼠标按钮时,它可以旋转六点星,两个三角形重叠 单击鼠标右键:星形旋转 单击鼠标中键:星星的颜色变化(白色→ (蓝色) 我已经应用了旋转矩形的代码,但是当我单击鼠标右键时,它不会旋转,而是会跳转 当点击鼠标中键时,颜色改变是成功的,但它是通过旋转星形来初始化的。我想在旋转的同时点击中间的按钮来改变星星的颜色 请告诉我是什么问题 /////////////////////////// Header ///////////////////////////// #includ

我正在制作一个程序,当我点击鼠标按钮时,它可以旋转六点星,两个三角形重叠

  • 单击鼠标右键:星形旋转
  • 单击鼠标中键:星星的颜色变化(白色→ (蓝色)
  • 我已经应用了旋转矩形的代码,但是当我单击鼠标右键时,它不会旋转,而是会跳转

    当点击鼠标中键时,颜色改变是成功的,但它是通过旋转星形来初始化的。我想在旋转的同时点击中间的按钮来改变星星的颜色

    请告诉我是什么问题

    /////////////////////////// Header /////////////////////////////
    #include <stdlib.h>
    #include <GL/glut.h>
    
    float v1[3] = { 365.0, 465.0, 0.0 };
    float v2[3] = { 365.0, 420.0, 0.0 };
    float v3[3] = { 400.0, 485.0, 0.0 };
    float v4[3] = { 400.0, 400.0, 0.0 };
    float v5[3] = { 435.0, 465.0, 0.0 };
    float v6[3] = { 435.0, 420.0, 0.0 };
    
    static GLfloat spin = 0.0;
    
    //////////////////////// Functions ////////////////////////////
    void init(void) {
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glShadeModel(GL_FLAT);
    }
    
    void reshape(int w, int h) {
        glViewport(0, 0, (GLsizei)w, (GLsizei)h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0.0, 500.0, 0.0, 500.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
    
    void spinDisplay(void) {
        spin = spin + 2.0;
    
        if (spin > 360.0) {
            spin = spin - 360.0;
        }
    
        glutPostRedisplay();
    }
    
    void triangle_1(void) {         /////////// first triangle ///////////
        glColor3f(1.0, 1.0, 1.0);
    
        glBegin(GL_TRIANGLE_FAN);
        glVertex3fv(v1);
        glVertex3fv(v4);
        glVertex3fv(v5);
    
        glEnd();
    }
    
    void triangle_2(void) {         ///////// second triangle /////////
        glColor3f(1.0, 1.0, 1.0);
    
        glBegin(GL_TRIANGLE_FAN);
        glVertex3fv(v2);
        glVertex3fv(v3);
        glVertex3fv(v6);
    
        glEnd();
    }
    
    void triangle_1p(void) {       ///// first triangle (color changed) /////
        glColor3f(0.0, 0.0, 1.0);
    
        glBegin(GL_TRIANGLE_FAN);
        glVertex3fv(v1);
        glVertex3fv(v4);
        glVertex3fv(v5);
    
        glEnd();
    }
    
    void triangle_2p(void) {       ///// second triangle (color changed) /////
        glColor3f(0.0, 1.0, 0.0);
    
        glBegin(GL_TRIANGLE_FAN);
        glVertex3fv(v2);
        glVertex3fv(v3);
        glVertex3fv(v6);
    
        glEnd();
    }
    
    void display(void) {            ///////// star display /////////
        glClear(GL_COLOR_BUFFER_BIT);
        glPushMatrix();
        glRotatef(spin, 0.0, 0.0, 1.0);
    
        triangle_1();
        triangle_2();
    
        glPopMatrix();
    
        glutSwapBuffers();
    }
    
    void display_p(void) {         ///// star display (color changed) /////
        glClear(GL_COLOR_BUFFER_BIT);
        glPushMatrix();
        glRotatef(spin, 0.0, 0.0, 1.0);
    
        triangle_1p();
        triangle_2p();
    
        glPopMatrix();
    
        glutSwapBuffers();
    }
    
    /////////////////////// Mouse Click ///////////////////////
    void mouse(int button, int state, int x, int y) {
        switch (button) {
        case GLUT_LEFT_BUTTON:
            if (state == GLUT_DOWN)
                glutIdleFunc(NULL);
            break;
        case GLUT_MIDDLE_BUTTON:
            if (state == GLUT_DOWN)
                glutIdleFunc(display_p);
            break;
        case GLUT_RIGHT_BUTTON:
            if (state == GLUT_DOWN)
                glutIdleFunc(spinDisplay);
            break;
        default:
            break;
        }
    }
    
    //////////////////////////// Main /////////////////////////////
    int main(int argc, char **argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
        glutInitWindowSize(500, 500);
        glutInitWindowPosition(300, 300);
        glutCreateWindow("6-Point Star");
    
        init();
    
        glutDisplayFunc(display);
        glutReshapeFunc(reshape);
        glutMouseFunc(mouse);
        glutMainLoop();
    
        return 0;
    }
    
    //页眉/////////////////////////////
    #包括
    #包括
    浮点v1[3]={365.0465.0,0.0};
    浮点v2[3]={365.0420.0,0.0};
    float v3[3]={400.0,485.0,0.0};
    浮点v4[3]={400.0,400.0,0.0};
    浮点v5[3]={435.0465.0,0.0};
    浮点v6[3]={435.0420.0,0.0};
    静态GLfloat自旋=0.0;
    ////////////////////////功能////////////////////////////
    void init(void){
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GLU平面);
    }
    空洞重塑(整数w,整数h){
    GLVIEW(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_投影);
    glLoadIdentity();
    gluOrtho2D(0.0500.0,0.0500.0);
    glMatrixMode(GLU模型视图);
    glLoadIdentity();
    }
    void显示(void){
    自旋=自旋+2.0;
    如果(旋转>360.0){
    自旋=自旋-360.0;
    }
    再发现();
    }
    空心三角形1(空心){////第一个三角形///////////
    GL3F(1.0,1.0,1.0);
    glBegin(GLU三角形风扇);
    glVertex3fv(v1);
    glVertex3fv(v4);
    glVertex3fv(v5);
    格伦德();
    }
    空心三角形2(空心){///second三角形/////////
    GL3F(1.0,1.0,1.0);
    glBegin(GLU三角形风扇);
    glVertex3fv(v2);
    glVertex3fv(v3);
    glVertex3fv(v6);
    格伦德();
    }
    空心三角形\u 1p(空心){/////第一个三角形(颜色已更改)/////
    GL3F(0.0,0.0,1.0);
    glBegin(GLU三角形风扇);
    glVertex3fv(v1);
    glVertex3fv(v4);
    glVertex3fv(v5);
    格伦德();
    }
    空心三角形(空心){///second三角形(颜色已更改)/////
    GL3F(0.0,1.0,0.0);
    glBegin(GLU三角形风扇);
    glVertex3fv(v2);
    glVertex3fv(v3);
    glVertex3fv(v6);
    格伦德();
    }
    空心显示(空心){//星形显示/////////
    glClear(GLU颜色缓冲位);
    glPushMatrix();
    glRotatef(自旋,0.0,0.0,1.0);
    三角形_1();
    三角形_2();
    glPopMatrix();
    glutSwapBuffers();
    }
    无效显示\u p(无效){///star显示(颜色更改)/////
    glClear(GLU颜色缓冲位);
    glPushMatrix();
    glRotatef(自旋,0.0,0.0,1.0);
    三角形_1p();
    三角形_2p();
    glPopMatrix();
    glutSwapBuffers();
    }
    ///////////////////////鼠标点击///////////////////////
    无效鼠标(int按钮、int状态、int x、int y){
    开关(按钮){
    案例过量左按钮:
    如果(状态==GLUT\U DOWN)
    glutIdleFunc(空);
    打破
    机箱GLUT_中间按钮:
    如果(状态==GLUT\U DOWN)
    glutIdleFunc(显示);
    打破
    案例过量右按钮:
    如果(状态==GLUT\U DOWN)
    glutIdleFunc(旋转显示);
    打破
    违约:
    打破
    }
    }
    ////////////////////////////主要/////////////////////////////
    int main(int argc,字符**argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(500500);
    位置(300300);
    窗口(“6点星”);
    init();
    glutDisplayFunc(显示器);
    GLUTREFORUNC(重塑);
    glutMouseFunc(小鼠);
    glutMainLoop();
    返回0;
    }
    
    当我点击鼠标右键时,它不会旋转,而是会跳来跳去

    它实际上不是在跳跃,而是围绕原点(显示器的左下角)旋转

    之所以会发生这种情况,是因为你在旋转,然后在平移。因为您已将恒星的位置
    x=400
    y=442.5
    硬编码到顶点中。如果您使星形的中心位于
    0x0
    (减去
    400x442.5
    ),则您将在显示屏的左下角看到星形在自转

    float v1[3] = { -35.0f,  22.5f, 0.0f };
    float v2[3] = { -35.0f, -22.5f, 0.0f };
    float v3[3] = {   0.0f,  42.5f, 0.0f };
    float v4[3] = {   0.0f, -42.5f, 0.0f };
    float v5[3] = {  35.0f,  22.5f, 0.0f };
    float v6[3] = {  35.0f, -22.5f, 0.0f };
    
    现在在
    display()

    glTranslatef(x, y, 0.0f);
    glRotatef(spin, 0.0, 0.0, 1.0);
    
    考虑浮动x=400.0f,y=442.5f将在别处定义

    现在你会看到恒星回到了同一个地方,但是绕着自己旋转

    我想在旋转的同时点击中间的按钮来改变星星的颜色

    您可以保留颜色作为变量,而不是复制每个模式的所有代码

    float color1[3] = { 1.0f, 1.0f, 1.0f };
    float color2[3] = { 1.0f, 1.0f, 1.0f };
    
    int mode = 1;
    
    现在,在
    mouse()
    GLUT\u中键上
    然后切换颜色

    case GLUT_MIDDLE_BUTTON:
        if (state == GLUT_DOWN) {
            if (mode == 1) {
                color1[0] = 0.0f, color1[1] = 0.0f, color1[2] = 1.0f;
                color2[0] = 0.0f, color2[1] = 1.0f, color2[2] = 0.0f;
                mode = 2;
            }
            else if (mode == 2) {
                color1[0] = 1.0f, color1[1] = 1.0f, color1[2] = 1.0f;
                color2[0] = 1.0f, color2[1] = 1.0f, color2[2] = 1.0f;
                mode = 1;
            }
        }
    
    然后在
    triangle\u 1
    triangle\u 2
    中,记住将
    glColor3f()
    替换为
    glColor3fv(color1)
    glColor3fv(color2)

    除此之外,您还可以在
    鼠标中设置
    模式
    ,并在
    三角1
    中执行类似操作(在
    三角2
    中也可以执行类似操作):

    选择当然取决于你

    总而言之,现在您应该能够看到恒星围绕自身旋转,并在单击鼠标中键时切换颜色

    这现在也意味着您可以删除
    display\u p
    triangle\u 1p
    triangle\u 2p

    当我点击鼠标右键时,它不会旋转,而是会跳来跳去

    它实际上不是在跳跃,而是围绕原点(显示器的左下角)旋转

    之所以会发生这种情况,是因为你在旋转,然后在平移。因为您已将恒星的位置
    x=400
    y=442.5
    硬编码到顶点中。如果你这样做
    if (mode == 2)
        glColor3f(0.0, 0.0, 1.0);
    else
        glColor3f(1.0, 1.0, 1.0);