Почему мои рисунки исчезают после того, как я отпускаю свой левый щелчок? - PullRequest
0 голосов
/ 07 ноября 2019

Итак, я пытаюсь нарисовать линии в OpenGL между точками, где я нажимаю. Рисунок отображается на экране, если я нажимаю левую кнопку, но он исчезает, если я отпускаю левый щелчок:

struct Vector {
    float x, y;
    Vector(float x = 0, float y = 0) : x(x), y(y) {}

} last_mouse_pos;

void onInitialization() {
    glClearColor(0, 0, 0, 0); // A hatterszin beallitasa.
    glClear(GL_COLOR_BUFFER_BIT); // A kepernyo torlese, az uj hatterszinnel.
}

void onDisplay() {
    glutSwapBuffers();
}

Vector convertToNdc(float x, float y) {
    Vector ret;
    ret.x = (x - kScreenWidth / 2) / (kScreenWidth / 2);
    ret.y = (kScreenHeight / 2 - y) / (kScreenHeight / 2);
    return ret;
}

int i = 0;

void onMouse(int button, int state, int x, int y) {

    if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
        glClear(GL_COLOR_BUFFER_BIT); 
        glutPostRedisplay(); 
    }
    else if (button == GLUT_LEFT_BUTTON) {
        if (state == GLUT_DOWN) {
            i++;
            if (i == 1) last_mouse_pos = convertToNdc(x, y);
            if (i > 1) {
                Vector pos = convertToNdc(x, y);
                glBegin(GL_LINES);  
                glVertex2f(last_mouse_pos.x, last_mouse_pos.y);
                glVertex2f(pos.x, pos.y);
                glEnd();
                glutPostRedisplay();
                last_mouse_pos = pos; 
            }
        }
    }
}

Таким образом, я делаю 2 точки, он рисует линию, если я продолжаю нажимать левую кнопку. нажмите, если я отпущу, экран станет черным. Если я нажимаю в другом месте, теперь у меня есть 2 строки, но только если я нажимаю левой кнопкой мыши. Если я отпущу, все это снова станет черным.

1 Ответ

0 голосов
/ 07 ноября 2019

Да, с вашим подходом здесь много неправильного. Почти во всех случаях ваша функция рисования должна управляться данными (т. Е. Данные контролируют то, что рисуется, и ничего кроме данных!) . Что-то вроде этого:

// 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;

Далее ваша функция мыши теперь будет делать следующее:

  1. Когда нажата левая кнопка, добавьте новую вершину в массив точек.
  2. Когда отпущена левая кнопка, обновите положение последней точки в массиве
  3. Когда нажата правая кнопка (а левая кнопка не нажата), очистите массив точек.
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();
}
...