【问题标题】:(OpenGL) Rotate object(OpenGL) 旋转对象
【发布时间】:2017-08-24 07:58:36
【问题描述】:

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

  1. 点击鼠标右键:星星旋转
  2. 点击鼠标中键:星星的颜色变化(白→蓝)

我已经应用了代码来旋转一个矩形,但是当我单击鼠标右键时,它不会旋转并且会跳转。

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

请告诉我是什么问题。

/////////////////////////// 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;
}

【问题讨论】:

    标签: opengl rotation mouselistener


    【解决方案1】:

    当我单击鼠标右键时,它不会旋转并会跳跃

    它实际上不是跳来跳去,而是围绕原点(显示屏的左下角)旋转。

    发生这种情况的原因是因为您正在旋转然后翻译。由于您已将 x = 400y = 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);
    

    考虑在别处定义float 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_MIDDLE_BUTTON 然后你切换颜色。

    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_1triangle_2 中记得将glColor3f() 替换为glColor3fv(color1)glColor3fv(color2)

    除此之外,您还可以在mouse 中设置mode 并在triangle_1 中执行类似的操作(在triangle_2 中也可以这样做):

    if (mode == 2)
        glColor3f(0.0, 0.0, 1.0);
    else
        glColor3f(1.0, 1.0, 1.0);
    

    选择当然取决于你。

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

    这也意味着您现在可以删除display_ptriangle_1ptriangle_2p

    【讨论】:

    • 就像我的回答一样,您同样可以拥有另一个mode。让我们称之为spinDirection 并根据您决定旋转的方向。然后您可以通过再次右键单击来切换它。
    • 非常感谢您的回答。但是,我只能在星星旋转时更改颜色(鼠标中键),而在星星停止时我无法更改颜色。我不知道如何处理这部分。
    • 啊...我在 GLUT_MIDDLE_BUTTON 案例中添加了“break”,所以我没有工作。但是,它开始旋转,停止时不会改变颜色。
    猜你喜欢
    • 2012-02-16
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    相关资源
    最近更新 更多