为什么在我释放左键单击后,我的绘图会消失



所以我正在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分,如果我一直按左键,它就会画出一条线,如果我松开它,屏幕就会变黑。如果我在其他地方点击,现在我有两行,但前提是我按下左键。如果我释放,所有的都会再次变黑。

是的,这里的方法有很多错误。在几乎所有情况下,绘制函数都应该是数据驱动的(即数据控制绘制的内容,除了数据什么都没有!(。大致如下:

// 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();
}

最新更新