Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw a polygon in OpenGL GLUT with mouse

i want to draw a polygon in openGL Glut with mouse interaction, every left click that will be made will be a vertex and a line will be drawn between every vertex. when the right mouse will be clicked the polygon will close drawing a line from the last to the first vertex. I have come up with this but it doesnt seem to work.

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

    bool right_pushed = 0;
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POINTS);

    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
        p1.x = x;
        p1.y = 480 - y;

        //if right is clicked draw a line to here
        first.x = x;
        first.y = 480 - y;
    }

    while (right_pushed == false) {

        if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
            p2.x = x;
            p2.y = 480 - y;
        }

        GLfloat dx = p2.x - p1.x;
        GLfloat dy = p2.y - p1.y;

        GLfloat x1 = p1.x;
        GLfloat y1 = p1.y;

        GLfloat step = 0;

        if (abs(dx) > abs(dy)) {
            step = abs(dx);
        }
        else {
            step = abs(dy);
        }

        GLfloat xInc = dx / step;
        GLfloat yInc = dy / step;


        for (float i = 1; i <= step; i++) {
            glVertex2i(x1, y1);
            x1 += xInc;
            y1 += yInc;
        }


        p1.x = p2.x;
        p1.y = 480 - y;

        if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {

            right_pushed = 1;
            p2.x = first.x;
            p2.y = first.y;

            dx = p2.x - p1.x;
            dy = p2.y - p1.y;

            x1 = p1.x;
            y1 = p1.y;

            step = 0;

            if (abs(dx) > abs(dy)) {
                step = abs(dx);
            }
            else {
                step = abs(dy);
            }

            xInc = dx / step;
            yInc = dy / step;


            for (float i = 1; i <= step; i++) {

                glVertex2i(x1, y1);
                x1 += xInc;
                y1 += yInc;

            }

        }
    }

    glEnd();
    glFlush();


}

int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(200, 200);
    glutInitWindowSize(640, 480);
    glutCreateWindow("windows");
    glutDisplayFunc(display);
    glutMouseFunc(draw_polygon);//
    init();
    glutMainLoop();
    return 0;
}

i am also trying to find out how to add a functionallity that when i select from a menu i could go from creating this polygon to editing it in a way that i could select a vertex , move it arround, and the shape changes accordingly.

like image 994
leo_bouts Avatar asked Nov 05 '17 15:11

leo_bouts


People also ask

How do you draw a polygon in OpenGL C++?

glBegin(GL_LINE_LOOP); // Draw A 6 vertex polygon glVertex3f(-0.5f, 1.0f, 0.0f); // Top Left glVertex3f(-1.0f, 0.0f, 0.0f); // Left glVertex3f(-0.5f, 1.0f, 0.0f); // Bottom Left glVertex3f(0.5f, 1.0f, 0.0f); // Top Right glVertex3f(1.0f, 0.0f, 0.0f); // Right glVertex3f(0.5f, 1.0f, 0.0f); // Bottom Right glEnd();

How do I make a pentagon in OpenGL?

ang = v * da; pent[v][0] = cos (ang); pent[v][1] = sin (ang); } glBegin (GL_LINE_LOOP); // Draws pentagon. for (v = 0; v < 5; v++) glVertex2fv(pent[v]); glEnd(); This should draw a pentagon with vertices on the unit circle.

How do you draw a polygon in C graphics?

drawpoly() function in C The header file graphics. h contains drawpoly() function which is used to draw polygons i.e. triangle, rectangle, pentagon, hexagon etc. Syntax : void drawpoly( int number, int *polypoints ); where, number indicates (n + 1) number of points where n is the number of vertices in a polygon.

What is glVertex2f in OpenGL?

The glVertex function commands are used within glBegin/glEnd pairs to specify point, line, and polygon vertices. The current color, normal, and texture coordinates are associated with the vertex when glVertex is called. When only x and y are specified, z defaults to 0.0 and w defaults to 1.0.


1 Answers

You have to separate the mouse events and the drawing function.

In the mouse event you should just collect the inputs. I Suggest to use a std::vector for this. The following function adds a point to the std::vector if the left mouse button is pressed. If the right button is pressed the polygon is marked closed. If the left button is pressed again, the polygon is cleared and the process restarts.

#include <vector>
#include <array>

int vp_width = 640;
int vp_height = 480;

std::array<int, 2> currentPt;
std::vector<std::array<int, 2>> pts;
bool closed = false;

void draw_polygon(int button, int state, int x, int y)
{
    currentPt = std::array<int, 2>{x, vp_height-y}; 

    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        if ( closed )
            pts.clear(); // restart if last action was close
        closed = false;
        pts.push_back( currentPt );
    }
    if ( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
        closed = true;
}

In a mouse move event function you can track the current mouse position:

void mouse_move(int x, int y)
{
    currentPt = std::array<int, 2>{x, vp_height-y};
    glutPostRedisplay();
}

In your main loop you can continuously draw the lines between the current points. The fllowing function draw lines betwwen a list of points. If the "cloesd" flag is set, then the polygon is closed. Else a line from the last point in the list to the current mouse position is drawn.

void display(void)
{
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    if ( !pts.empty() )
    {
        glBegin(GL_LINE_STRIP);
        for ( auto &pt : pts )
            glVertex2f( (float)pt[0], (float)pt[1] );
        auto &endPt = closed ? pts.front() : currentPt;
        glVertex2f( (float)endPt[0], (float)endPt[1] );
        glEnd();
    }

    //glFlush();
    glutSwapBuffers();
}

int main()
{
    ..... 
    glutDisplayFunc(display);
    glutPassiveMotionFunc (mouse_move);
    glutMouseFunc(draw_polygon);

    glMatrixMode( GL_PROJECTION );
    glOrtho(0.0f, (float)vp_width, 0.0f, (float)vp_height, -1.0, 1.0);
    .....
}


Preview:

preview

like image 75
Rabbid76 Avatar answered Sep 24 '22 22:09

Rabbid76