【问题标题】:Moving objects with mouse click通过鼠标点击移动对象
【发布时间】:2017-04-01 14:00:28
【问题描述】:

我想通过鼠标点击来移动对象(6 点星和 2 个三角形)。 我写了以下代码,但是没有响应。

case GLUT_LEFT_BUTTON:
    if (state == GLUT_DOWN) {
        float x_min = (-x + 500) / 500;
        float x_max = (x - 500) / 500;
        float y_min = (-y + 500) / 500;
        float y_max = (y - 500) / 500;
        gluOrtho2D(x_min, x_max, y_min, y_max);
    }
 glutPostRedisplay();
 break;

在 GLUT_LEFT_BUTTON 的情况下,我放置了最小/最大 x 和 y 位置,但是当我单击鼠标左键时没有任何效果。

这里是完整的代码:

#include <stdlib.h>
#include <GL/glut.h>

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

static GLfloat spin = 0.0;

float x = 400.0f, y = 442.5f;
float x_position;
float y_position;

float color1[3] = { 1.0f, 1.0f, 1.0f };
float color2[3] = { 1.0f, 1.0f, 1.0f };

int mode = 1;
int rotate = 1;

void init(void);
void triangle_1(void);
void triangle_2(void);
void display(void);
void spinDisplay_1(void);
void spinDisplay_2(void);
void reshape(int, int);
void changeColor(int);
void mouse(int, int, int, int);

////////////////////////////////////////////////////////////////////

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

////////////////////////////////////////////////////////////////////

void init(void) {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
}

void triangle_1(void) {          //// triangle_1 and triangle_2 make 6-point star ////
    glColor3fv(color1);

    glBegin(GL_TRIANGLE_FAN);
    glVertex3fv(v1);
    glVertex3fv(v4);
    glVertex3fv(v5);

    glEnd();
}

void triangle_2(void) {
    glColor3fv(color2);

    glBegin(GL_TRIANGLE_FAN);
    glVertex3fv(v2);
    glVertex3fv(v3);
    glVertex3fv(v6);

    glEnd();
}

void display(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();

    glTranslatef(x, y, 0.0f);
    glRotatef(spin, 0.0, 0.0, 1.0);

    triangle_1();
    triangle_2();

    glPopMatrix();

    glutSwapBuffers();
}

void spinDisplay_1(void) {
    spin = spin + 2.0;

    if (spin > 360.0) {
        spin = spin - 360.0;
    }

    glutPostRedisplay();
}

void spinDisplay_2(void) {
    spin = spin - 2.0;

    if (spin < 360.0) {
        spin = spin + 360.0;
    }

    glutPostRedisplay();
}

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 changeColor(int n) {
    if (n == 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;
    }
    else if (n == 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;
    }
}

void mouse(int button, int state, int x, int y) {         /////// mouse event ////////
    switch (button) {
    case GLUT_LEFT_BUTTON:
        if (state == GLUT_DOWN) {
            float x_min = (-x + 500) / 500;
            float x_max = (x - 500) / 500;
            float y_min = (-y + 500) / 500;
            float y_max = (y - 500) / 500;
            gluOrtho2D(x_min, x_max, y_min, y_max);
        }
        glutPostRedisplay();
        break;
    case GLUT_MIDDLE_BUTTON:
        if (state == GLUT_DOWN) {
            if (mode == 1) {
                changeColor(mode);
                mode = 2;
            }
            else if (mode == 2) {
                changeColor(mode);
                mode = 1;
            }
        }
        break;
    case GLUT_RIGHT_BUTTON:
        if (state == GLUT_DOWN)
            if (rotate == 1) {
                glutIdleFunc(spinDisplay_1);
                rotate = 2;
            }
            else if (rotate == 2) {
                glutIdleFunc(spinDisplay_2);
                rotate = 1;
            }
        break;
    default:
        break;
    }
}

【问题讨论】:

标签: c++ opengl


【解决方案1】:

我想通过鼠标点击来移动对象(6 点星和 2 个三角形)

如果您想左键单击并且该位置现在是星星的中心,那么您将事情复杂化了。您已经将星号的位置作为全局变量xy。因此,在mouse() 中,您只需将它们设置为鼠标位置即可。

但是请记住将窗口的高度减去y,因为0x0 在屏幕的左上角,但在OpenGL 的左下角。

if (state == GLUT_DOWN) {
    ::x = x;
    ::y = glutGet(GLUT_WINDOW_HEIGHT) - y;
}

由于mouse()xy 参数会影响您的全局变量xy,因此您必须使用:: 作为前缀。您也可以将mouse() 的参数重命名为mxmy

void mouse(int button, int state, int mx, int my) {
    [...]
    if (state == GLUT_DOWN) {
        x = mx;
        y = glutGet(GLUT_WINDOW_HEIGHT) - my;
    }

这是一个点击窗口上随机位置的 GIF:

【讨论】:

  • 谢谢。但是当星星停止时,点击屏幕不起作用。颜色也没有变化。我无法弄清楚问题出在哪里。 -.-;
  • @BlackJ 你可能只是错过了一些东西。 This is the code I tested, and made the GIF from.
  • 哦,我解决了!我错过了将 glutPostRedisplay() 添加到 LEFT 和 MIDDLE 按钮的情况。无论如何,非常感谢。
猜你喜欢
  • 2019-07-10
  • 2020-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
相关资源
最近更新 更多