在OpenGL中用鼠标绘制多条直线

Drawing Multiple Lines with Mouse in OpenGL

本文关键字:绘制 鼠标 OpenGL      更新时间:2023-10-16

我正在OpenGL和C++程序中尝试用鼠标绘制多条线段。现在我可以画一个,一旦我开始画另一个,上一个就消失了。

下面是我的代码,它与鼠标绘图相关。关于如何画多条线,有什么建议吗?

LineSegment seg;
void mouse(int button, int state, int x, int y) {
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {                 // if left button is clicked, that is the start point
        seg.x1 = seg.x2 = x;
        seg.y1 = seg.y2 = y;
    }
    if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {                   // once they lift the mouse, thats the finish point
        seg.x2 = x;
        seg.y2 = y;
    }
}
void motion(int x, int y) {
    seg.x2 = x;
    seg.y2 = y;
    glutPostRedisplay();                                                    // refresh the screen showing the motion of the line
}
void display(void) {
    glClear(GL_COLOR_BUFFER_BIT);                                           // clear the screen
    glBegin(GL_LINES);                                                          // draw lines
    glVertex2f(seg.x1, seg.y1);
    glVertex2f(seg.x2, seg.y2);
    glEnd();
    glutSwapBuffers();
}
void display(void) {
    glClear(GL_COLOR_BUFFER_BIT);                                           // clear the screen
    glBegin(GL_LINES);                                                          // draw lines
    glVertex2f(seg.x1, seg.y1);
    glVertex2f(seg.x2, seg.y2);
    glEnd();
    glutSwapBuffers();
}

您需要在数据结构中保存以前的线段,并在每次单击鼠标时将其添加到数据结构中。然后drawloop需要遍历该数据结构,并绘制每个保存的线段。

std::vector<LineSegment> segmentvector;
//Each time you release the mouse button, add the current line segment to this vector
/*...*/
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
for(const LineSegment & seg : segmentvector) {
    glVertex2f(seg.x1, seg.y1);
    glVertex2f(seg.x2, seg.y2);
}
glVertex2f(currseg.x1, currseg.y1);
glVertex2f(currseg.x2, currseg.y2);
glEnd();

我还强烈建议在学习OpenGL时不要使用固定函数管道函数。网上有很多学习现代OpenGL的教程。

您需要设置一些逻辑来保存您已经绘制的线的状态。目前,您从未开始绘制另一条线,只需重置当前行的起始位置。

以下是您正在寻找的可能解决方案:

std::vector<LineSegment> segs;
LineSegment currentSeg;
void mouse(int button, int state, int x, int y) {
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {                 
        LineSegment newSeg; // Make a new segment
        newSeg.x1 = newSeg.x2 = x;
        newSeg.y1 = newSeg.y2 = y;
        segs.insert(newSeg); // Insert segment into segment vector
        currentSeg = newSeg;
    }
    if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {  
        currentSeg.x2 = x;
        currentSeg.y2 = y;
    }
}
void motion(int x, int y) {
    currentSeg.x2 = x;
    currentSeg.y2 = y;
    glutPostRedisplay();                          
}
void display(void) {
    glClear(GL_COLOR_BUFFER_BIT);  
    glBegin(GL_LINES);                                                          
    // Iterate through segments in your vector and draw each
    for(const auto& seg : segs) {
      glVertex2f(seg.x1, seg.y1);
      glVertex2f(seg.x2, seg.y2);
    }
    glEnd();
    glutSwapBuffers();
}