如何阻止 GL_Points 删除由 GL_line_loop 创建的行

How to stop GL_Points from removing lines created by GL_line_loop

我正在开发一个应该允许用户创建多边形的程序,然后为程序指定随机点以检查它们是否在多边形内。

GLint vert[100][2];
int width = 400, height = 600, n = 0, type = GL_LINE_STRIP, v;
bool rubberbanding = false;

void display(){
     glClear(GL_COLOR_BUFFER_BIT);
     if(n == 1 && (type == GL_LINE_STRIP)){
          glBegin(GL_POINTS);
          glVertex2iv(vert[0]);
          glEnd();
     }
     glBegin(type);
     for(int i = 0; i < n; i++){
             glVertex2iv(vert[i]);
     }
     glEnd();
     glutSwapBuffers();
}

我在处理下一部分时遇到了问题。用户使用 GL_LINE_STRIP 创建线,然后他们应该单击 'c' 来关闭多边形。然而,在他们关闭多边形之后,我希望他们能够指定随机点。但是当我将类型切换为 GL_POINTS 时,它删除了所有的线,我在顶点处留下了点。

void keyboard(unsigned char key, int x, int y){
     switch(key){
                 case 'r': n = 0; type = GL_LINE_STRIP;  break;

                 case 'c': type = GL_LINE_LOOP; break;
                 //case 'v': type = GL_POINTS; break;
     }
     // type = GL_POINTS;
     glutPostRedisplay();
}

我该如何解决这个问题,以便在用户关闭多边形后,他们可以在多边形不消失的情况下创建点?

编辑:这是点击按钮的代码:

void mouse(int button, int state, int x, int y){
     switch(button){
     case GLUT_LEFT_BUTTON:
                         if(state == GLUT_DOWN){
                                  v = n++;
                                  vert[v][0] = x;
                                  vert[v][1] = height - 1 - y;
                                  rubberbanding = true;
                                  glutPostRedisplay();
                         }
                         else{
                                  rubberbanding = false;
                         }
                         break;
     }
}

我建议执行以下操作:

创建一个显示函数,可以绘制线和点。这些线存储在从索引 0 开始到索引 m-1 结束的顶点数组中。 这些点也存储在顶点数组中。从索引 m 开始到索引 n-1.
结束 这些线条是使用基本类型 GL_LINE_STRIP 绘制的。如果该行已关闭,则使用原始类型 GL_LINE_LOOP
使用 GL_POINTS 绘制点。

GLint vert[100][2];
int n = 0, m = 0;
bool closed = false;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glBegin(closed ? GL_LINE_LOOP : GL_LINE_STRIP);
    for(int i = 0; i < m; i++)
        glVertex2iv(vert[i]);
    glEnd();

    glBegin(GL_POINTS);
    for(int i = m; i < n; i++)
        glVertex2iv(vert[i]);
    glEnd();

    glutSwapBuffers();
    glutPostRedisplay();
}

keybord函数中,状态发生变化:

void keyboard(unsigned char key, int x, int y)
{
    switch(key)
    {
        case 'r': n = 0; m = 0; closed = false; break;
        case 'c': closed = true; break;
    }
}

mouse函数向容器添加一个顶点坐标,并相对于状态closed递增nand/orm

void mouse(int button, int state, int x, int y)
{
    switch(button)
    {
        case GLUT_LEFT_BUTTON:
            if( state == GLUT_DOWN )
            {
                if ( n < 100 )
                {
                    vert[n][0] = x;
                    vert[n][1] = height - 1 - y;
                    n ++;
                    if ( !closed )
                        m = n;
                }
            }
            break;
    }
}

当一个glVertex is called then the color which was set by glColor。 OpenGL是一种状态引擎。如果状态发生变化,它会一直保持到再次发生变化,甚至超出帧范围。

如果你想用一种颜色画线,而用另一种颜色画点,那么你必须在绘制线和点的循环之前设置颜色:

glColor3f(1,1,1);
glBegin(closed ? GL_LINE_LOOP : GL_LINE_STRIP);
for(int i = 0; i < m; i++)
    glVertex2iv(vert[i]);
glEnd();

glColor3f(1,0,0);
glBegin(GL_POINTS);
for(int i = m; i < n; i++)
    glVertex2iv(vert[i]);
glEnd();

即使是橡皮筋也可以轻松实现。实现 glutPassiveMotionFunc 回调并存储当前鼠标位置:

int mx = 0, my = 0;    

void mousemove(int x, int y)
{
    mx = x;
    my = height - 1 - y;
}

glutPassiveMotionFunc(mousemove);

根据绘制状态,在绘制线条时将最终顶点坐标添加到当前鼠标位置:

glBegin(closed ? GL_LINE_LOOP : GL_LINE_STRIP);
for(int i = 0; i < m; i++)
    glVertex2iv(vert[i]);
if (n>0 && !closed)
    glVertex2i(mx, my);
glEnd();