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

 ̄綄美尐妖づ 提交于 2021-02-16 14:59:07

问题


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?


回答1:


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:




回答2:


First of all You do not actually draw anything - function drawl is called only when You click every second time. To draw a line (or anything) one need to call a drawing routine every frame, like the Display function is called.

Second thing is that position given in mouse callback function is not suitable for defining a point in 3D. One have to translate them onto proper coordinates (that is ranging from -1 to 1 usually) to be able to use them as drawing data. Otherwise GL will try to draw some lines out of view, which means nothing will be drawn.

I would reorganize the application structure a bit - when You get mouse call instead of calling drawl every other call to it, store the properly translated positions the mouse function gives You in some global variable and do the drawing in Display routine. Also gluOrtho2D should usually be called every frame as well. In Your call to it You have the parameters wrong - see the reference page for details.



来源:https://stackoverflow.com/questions/48181748/not-getting-an-output-for-opengl-to-print-line-using-mouse-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!