Получить координаты щелчка мыши в OpenGL во время анимации? - PullRequest
2 голосов
/ 14 апреля 2019

Я хочу сделать игру, в которой, когда кто-то нажимает на движущийся шар, он лопается. Я добавил коды для анимации и события щелчка мышью, но когда анимация продолжается, функция щелчка не работает. Когда я попробовал это без анимации, это работало правильно. Я хочу знать, почему это происходит.

#include<stdio.h> 
#include<GL/glut.h> 
#include<unistd.h>
#include<math.h> 

int x, y;
float mx, my;
float i, j;

void mouse(int button, int state, int mousex, int mousey)
{
    if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
    {
        mx = mousex;
        my = mousey;
        printf("%f %f\n",mx,my);
        glutPostRedisplay();
    }
}

void init() 
{ 
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glColor3f(0.0, 1.0, 0.0); 
    glPointSize(1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, 1560, 0, 840); 
} 

int randValue()
{
    int i = rand();
    int num = i%1000;
    return num;
}

void blast(int x, int y)
{
    glBegin(GL_POLYGON);
    glColor3f(1.0f,0.0f,0.0f);
    glVertex2i(x-100, y-100);
    glVertex2i(x, y-100);
    glVertex2i(x-22, y-20);
    glVertex2i(x-100, y-30);
    glVertex2i(x-30, y-40);
    glVertex2i(x-150, y-80);
    glVertex2i(x-20, y);
    glVertex2i(x, y-40);
    glVertex2i(x-66, y-125);
    glVertex2i(x-34, y-32);
    glVertex2i(x-32, y-55);
    glVertex2i(x-32, y);
    glVertex2i(x-60, y-57);
    glVertex2i(x-75, y-69);
    glVertex2i(x-100, y);
    glEnd();
    glFlush();
}

void display() 
{
    int j = 0, k = 0, l = 1;
    while(1)
    {
        glClear(GL_COLOR_BUFFER_BIT);

        glColor3f(0.0, 1.0, 0.0);
        glBegin(GL_POINTS);

        for (i = 0;i < 6.29;i += 0.001)
        {
            x = 100 * cos(i);
            y = 100 * sin(i);
            glVertex2i(x / 2 + j, y / 2 + k);
            if((x / 2 + j) >= 1560 || (y / 2 + k) >= 840)
            {
                glEnd();
                glFlush();
                glClear(GL_COLOR_BUFFER_BIT);
                blast(x / 2 + j, y / 2 + k);
                sleep(2);
                j = randValue();
                k = 0;
            }
        }
        j = j + 3;
        k = k + 5;
        glEnd();
        glFlush();
    }
}

int main (int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(1360, 768);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("{Project}");
    init();
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMainLoop();
}

Ответы [ 2 ]

3 голосов
/ 14 апреля 2019

Ваш код имеет бесконечный цикл внутри функции display, поэтому вы никогда не вернете управление GLUT. GLUT уже имеет бесконечный цикл, подобный этому внутри glutMainLoop.

Вместо этого вы должны визуализировать только ОДИН кадр в display, отправить glutPostRedisplay и вернуть:

void display() 
{
    glClear(GL_COLOR_BUFFER_BIT);
    // ... draw the frame here ...

    // for exmaple:
    i += 0.001;
    float x = 100 * cos(i);
    float y = 100 * sin(i);
    glColor3f(0.0, 1.0, 0.0);
    glBegin(GL_POINTS);
    glVertex2f(x, y);
    glEnd();

    glFlush();
    glutPostRedisplay();
}

Тогда будет вызвана ваша функция mouse, и вы сможете при необходимости обновлять состояние.

1 голос
/ 15 апреля 2019

Здесь есть две проблемы:

  • OpenGL сам по себе не поддерживает устройство ввода, вы обычно используете OpenGL для представления информации, но у вас есть что-то еще, прикрепленное к окну, в котором выпредставить информацию, которая дает вам доступ к мыши.для этого необходимо знать, какую другую среду, которую вы используете, которая предлагает вам указательное устройство в области экрана.

  • если у вас есть нужные вам координаты оконной мышичтобы хорошо отобразить окно, вы представляете свои выходные данные OpenGL, но вы должны преобразовать их обратно в какую-то точку вашей сцены, но, вероятно, вашего шара там нет.Существует некоторая двусмысленность при переходе от плоского изображения, представляющего трехмерную сцену, к точке на этой сцене в 3D, поскольку у вас есть все точки на оси Z, имеющие одни и те же координаты экрана на 2D-экране.поэтому вам необходимо проследить до возможного положения мяча с точки зрения (камеры), основываясь на координатах окна мыши.Это геометрическая задача, которая включает в себя обратное преобразование проекции, которая всегда сингулярна.

вы можете решить эту проблему, не догадываясь, поскольку вы знаете, где находится ваш мяч, вы можетеПовторите преобразование, из-за которого оно появилось в двумерном окне, а затем сравните координаты на основе этих.OpenGL позволяет вам узнать фактическое преобразование, которое он выполняет, чтобы представить вашу сцену, и вы можете использовать его, чтобы увидеть, где на экране представлен ваш мяч (вам не нужно делать это для каждой вершины шара, только длянапример, по центру), а затем проверьте, насколько ваш выстрел подобрался достаточно близко, чтобы ударить по мячу.Вам также следует подумать, не мешает ли какой-нибудь другой объект сверху по оси Z, чтобы не убивать никого за стеной.

...