Search code examples
copenglmouseglutmouseclick-event

Not getting an output for OpenGL to print line using mouse click


My aim is to draw a line using mouse click. When you click the first click it reads the coordinates then when for the nest click it will draw the line using GL_LINES with first and second points.

int first, x1, yi, x2, yj, ww = 600, wh = 400;
void drawl()
{
    glClear(GL_COLOR_BUFFER_BIT);  
    glLineWidth(5.00);
    glColor3f(0,1,0);
    glBegin(GL_LINES);
        glVertex2i(x1,yi);
        glVertex2i(x2,yj);
    glEnd();
    glFlush();
}

void Display()
{
    glClearColor(0.5, 0.5, 0.5, 1.0);  
    glColor3f(0.7, 0.4, 0.0);  
    glClear(GL_COLOR_BUFFER_BIT);  
    glFlush();  
}

void mouse(int button, int state, int x, int y)
{
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        if(first == 0)
        {       
            first++;
            x1 = x;
            yi = wh - y;
        }
        else
        {
            x2 = x;
            yj = wh - y;
            drawl();
            printf("%d,%d,%d,%d\n",x1,yi,x2,yj);
            first--;
        }   

    }
}

void main(int argc, char **argv)
{
    first = 0;
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(800,500);
    glutInitWindowPosition(0,0);
    glutCreateWindow("Mouse");
    gluOrtho2D(0,800,0,500);
    glutDisplayFunc(Display);
    glutMouseFunc(mouse);
    glutMainLoop();
} 

Output I got is given below. It is not drawing the line. Should I include myinit() function and why?

enter image description here


Solution

  • For this answer I ported the answer which I had given to the question Draw a polygon in OpenGL GLUT with mouse from C++ to C.


    You have to separate the mouse events and the drawing function.

    In the mouse (void mouse(int button, int state, int x, int y)) event you should just collect the inputs.

    • If the left mouse button is pressed, the following function adds a the X coordinate of the mouse position to the array ptListX and the Y-coordinate to the array ptListY.

    • If the right button is pressed the polygon is marked closed. If the left button is pressed again, the polygon is cleared and the process restarts.

    int wndSizwX = 800, wndSizeY = 500; // size of the window
    int mouseX = 0, mouseY = 0;         // current mouse position
    
    #define MAX_PTS 100
    int ptListX[MAX_PTS]; // X coordinate ot the input points 
    int ptListY[MAX_PTS]; // Y coordinate of the input points
    int noOfPts = 0;      // number of input points
    int closed = 0;       // marke polygon "closed"
    
    void mouse(int button, int state, int x, int y)
    {
        mouseX = x;
        mouseY = y;
    
        if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
        {
            if (closed || noOfPts >= MAX_PTS - 1)
                noOfPts = 0; // restart the polygon
            closed = 0;
            ptListX[noOfPts] = mouseX; 
            ptListY[noOfPts] = mouseY;
            noOfPts ++;
        }
        if ( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
            closed = 1;
    }
    

    In a mouse move event function the current mouse position can be tracked:

    void mouse_move(int x, int y)
    {
        mouseX = x;
        mouseY = y;
        glutPostRedisplay();
    }
    

    In the main loop (Display function), the current list of points is connected to lines and continuously drawn. If the cloesd flag is set, then the polygon is closed. Else a line from the last point in the list to the current mouse position is drawn.

    void Display()
    {
        glClearColor(0.5f, 0.5f, 0.5f, 1.0f);  
        glClear(GL_COLOR_BUFFER_BIT);  
    
        if (noOfPts)
        {
            glLineWidth(5.0);
            glColor3f(0.0f,1.0f,0.0f);
            glBegin(GL_LINE_STRIP);
            for (int i=0; i<noOfPts; ++i )
                glVertex2f( (float)ptListX[i], (float)ptListY[i] );
            if ( closed )
                glVertex2f( (float)ptListX[0], (float)ptListY[0] );
            else
                glVertex2f( (float)mouseX, (float)mouseY );
            glEnd();
        }
    
        glFlush();  
    }
    

    The registration of the mouse move event has to be add to the main program by glutPassiveMotionFunc.
    Further the Y-Axis of the orthographic projection has to be flipped, to match the view space to the mouse coordinates:

    void main(int argc, char **argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
        glutInitWindowSize(wndSizwX,wndSizeY);
        glutInitWindowPosition(0,0);
        glutCreateWindow("Mouse");
    
        gluOrtho2D(0, wndSizwX, wndSizeY, 0); // flip Y 
    
        glutDisplayFunc(Display);
        glutMouseFunc(mouse);
        glutPassiveMotionFunc(mouse_move);
        glutMainLoop();
    }
    

    See the preview:

    enter image description here