Да, с вашим подходом здесь много неправильного. Почти во всех случаях ваша функция рисования должна управляться данными (т. Е. Данные контролируют то, что рисуется, и ничего кроме данных!) . Что-то вроде этого:
// use this vector to store all of the point clicks
std::vector<Vector> points;
void onDisplay() {
// now just render each vertex making up the lines
glBegin(GL_LINES);
for(auto p : points)
glVertex2f(p.x, p.y);
glEnd();
glutSwapBuffers();
}
Далее вам нужно будет отслеживать состояние мыши, поэтому с целью максимально упростить это (вы можете отслеживать мышьположение и другие состояния кнопок, но это минимальный пример) .
bool leftHeld = false;
Далее ваша функция мыши теперь будет делать следующее:
- Когда нажата левая кнопка, добавьте новую вершину в массив точек.
- Когда отпущена левая кнопка, обновите положение последней точки в массиве
- Когда нажата правая кнопка (а левая кнопка не нажата), очистите массив точек.
void onMouse(int button, int state, int x, int y) {
switch(button) {
case GLUT_LEFT_BUTTON:
{
leftHeld = state == GLUT_DOWN;
if(leftHeld)
{
points.push_back(convertToNdc(x, y)); // add new point
}
else
points.back() = convertToNdc(x, y); // update last point
}
break;
// on right click, empty the array
// (but only if the left mouse button isn't currently pressed!)
case GLUT_RIGHT_BUTTON:
if(!leftHeld && state == GLUT_DOWN)
points.clear();
break;
}
glutPostRedisplay();
}
Наконец, если вы хотите, чтобы линии обновлялись при нажатии и перетаскивании по экрану, вам нужно зарегистрировать функцию движения мыши, чтобы обновить последнюю точку в массиве
// register with glutMotionFunc.
// code updates last coordinate whilst mouse is moving, and
// the left button is held.
void onMouseMove(int x, int y) {
if(leftHeld)
{
points.back() = convertToNdc(x, y);
}
glutPostRedisplay();
}