【问题标题】:How to avoid restarting the polygon when redraw?重绘时如何避免重新启动多边形?
【发布时间】:2021-07-18 09:04:42
【问题描述】:

我正在编写一个持续绘制多边形的程序,直到用户单击右键,但是当我继续在屏幕上绘制其他东西时,多边形消失了,我该如何避免这种情况?这是我的程序:

float mouseX, mouseY;
vector<float> vecX(40);
vector<float> vecY(40);
int numPoints = 0;
int closed = 0;

void mouse(int button, int state, int x, int y)
{
    mouseX = x;
    mouseY = y;

    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        if (closed || numPoints > 40)
             numPoints = 0;
        closed = 0;
        vecX[numPoints] = mouseX;
        vecY[numPoints] = mouseY;
        numPoints++;
    }
    if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
        closed = 1;
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    if (numPoints)
    {
        glBegin(GL_LINE_STRIP);
        for (int i = 0; i < numPoints; ++i)
            glVertex2f(vecX[i], vecY[i]);
        if (closed)
            glVertex2f(vecX[0], vecY[0]);
        else
            glVertex2f(mouseX, mouseY);
        glEnd();
    }
    glFlush();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(600, 400);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Testing");
    gluOrtho2D(0, 600, 400, 0);

    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMainLoop();
}

vecXvecY用于存储鼠标点击的坐标。

【问题讨论】:

  • 调试时间。
  • 提示:不要使用两个不相关的向量,而是使用std::vector&lt;std::tuple&lt;float, float&gt;&gt; 或类似的东西。您甚至可能想要制作自己的简单 point 结构,您可以使用它来代替。
  • 这只能处理 40 个样本,在 60FPS 下可以真正快速通过。提示:如果您确实需要像 40 这样的常量或限制,请不要对其进行硬编码,添加 const int LIMIT = 40
  • @tadman,谢谢你的提示,我会改的。
  • 但是每当我绘制另一个形状时,之前的形状就会消失。好吧:if (closed || numPoints &gt; 40) numPoints = 0; 可能是造成这种情况的原因。而且,请记住 OpenGL 中的渲染以glClear(GL_COLOR_BUFFER_BIT); 开头。所以,它总是从一个清晰的“屏幕”开始(实际上是一个清晰的帧缓冲区),这就是它在常见情况下的使用方式。

标签: c++ opengl glut


【解决方案1】:

折线完成后,您需要将其存储到容器中。使用std::vector 的折线。折线的类型是std::vector&lt;float&gt;。一开始,容器中只有 1 条空折线:

std::vector<std::vector<float>> polylines(1);

当您左键单击时,一个新的顶点坐标将添加到容器中的最后一条折线。右键单击时,会在容器中添加一条新的折线:

void mouse(int button, int state, int x, int y)
{
    mouseX = x;
    mouseY = y;

    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        polylines.back().push_back(mouseX);
        polylines.back().push_back(mouseY);
    }
    if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
    {
        polylines.push_back(std::vector<float>());
    }
}

在嵌套循环中绘制折线:

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    for (auto i=0; i < polylines.size(); ++ i)
    {
        bool is_last = i == polylines.size() - 1;
        const auto& polyline = polylines[i];
        glBegin(is_last ? GL_LINE_STRIP : GL_LINE_LOOP);
        for (auto j = 0; j < polyline.size(); j += 2)
            glVertex2f(polyline[j], polyline[j+1]);
        if (is_last)
            glVertex2f(mouseX, mouseY);
        glEnd();
    }

    glutSwapBuffers();
}

【讨论】:

  • 为什么在向量的末尾插入坐标? polylines.back().push_back(mouseX);polylines.back().push_back(mouseY);
  • polylines 是向量的向量。您需要将新点添加到折线列表(矢量)中的最后一条折线。最后一条多段线是您将要绘制的形状。其他形状已闭合并完成。
  • 在gif中,点击屏幕时如何让光标周围出现黄色的东西?
  • @user 这只是我用来创建 gif 的工具的效果。 (screentogif.com)
猜你喜欢
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
相关资源
最近更新 更多