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?
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: