用鼠标在OpenGL GLUT中绘制多边形 [英] Draw a polygon in OpenGL GLUT with mouse

查看:346
本文介绍了用鼠标在OpenGL GLUT中绘制多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用鼠标交互在openGL Glut中绘制一个多边形,每做一次左键单击就会成为一个顶点,并在每个顶点之间绘制一条线。当鼠标点击时,多边形将关闭从最后一个顶点到第一个顶点的一条线。

  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;

//如果点击右键在这里画一条线
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; (abs(dx)> abs(dy)){
step = abs(dx);

if
}
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; (abs(dx)> abs(dy)){
step = abs(dx);

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

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


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

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





$ b 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();
返回0;
}

我也想知道如何添加一个函数,当我选择从一个菜单中,我可以从创建这个多边形到编辑它,这样我就可以选择一个顶点,将它移动到四周,并且形状也会相应地改变。 方案

您必须将鼠标事件和绘图功能分开。



在鼠标事件中,您应该收集输入。我建议使用


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.

解决方案

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:

这篇关于用鼠标在OpenGL GLUT中绘制多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆