Search code examples
copenglglut

Get mouse click coordinates in OpenGL during animation?


I want to make a game in which when somebody clicks on the moving ball, it bursts. I have added the codes for animation and the mouse click event, but when the animation is going on, the click function is not working. When I tried it without the animation, it worked properly. I want to know why is this happening.

#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();
}

Solution

  • Your code has an infinite loop inside the display function, thus you never give the control back to GLUT. GLUT already has an infinite loop like that inside glutMainLoop.

    Instead you shall render only ONE frame in display, post glutPostRedisplay and return:

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

    Then your mouse function will be called and you'll be able to update the state as necessary.