使用鼠标单击未获得 OpenGL 的输出以打印行

Posted

技术标签:

【中文标题】使用鼠标单击未获得 OpenGL 的输出以打印行【英文标题】:Not getting an output for OpenGL to print line using mouse click 【发布时间】:2018-01-10 06:49:10 【问题描述】:

我的目标是用鼠标点击画一条线。当您单击第一次单击时,它会读取坐标,然后在进行嵌套单击时,它将使用 GL_LINES 绘制具有第一点和第二点的线。

int first, x1, yi, x2, yj, ww = 600, wh = 400;
void drawl()

    glClear(GL_COLOR_BUFFER_BIT);  
    glLineWidth(5.00);
    glColor3f(0,1,0);
    glBegin(GL_LINES);
        glVertex2i(x1,yi);
        glVertex2i(x2,yj);
    glEnd();
    glFlush();


void Display()

    glClearColor(0.5, 0.5, 0.5, 1.0);  
    glColor3f(0.7, 0.4, 0.0);  
    glClear(GL_COLOR_BUFFER_BIT);  
    glFlush();  


void mouse(int button, int state, int x, int y)

    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    
        if(first == 0)
               
            first++;
            x1 = x;
            yi = wh - y;
        
        else
        
            x2 = x;
            yj = wh - y;
            drawl();
            printf("%d,%d,%d,%d\n",x1,yi,x2,yj);
            first--;
           

    


void main(int argc, char **argv)

    first = 0;
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(800,500);
    glutInitWindowPosition(0,0);
    glutCreateWindow("Mouse");
    gluOrtho2D(0,800,0,500);
    glutDisplayFunc(Display);
    glutMouseFunc(mouse);
    glutMainLoop();
 

我得到的输出如下。它没有画线。我应该包含 myinit() 函数吗?为什么?

【问题讨论】:

【参考方案1】:

对于这个答案,我将我对问题 Draw a polygon in OpenGL GLUT with mouse 给出的答案从 C++ 移植到 C。

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

在鼠标 (void mouse(int button, int state, int x, int y)) 事件中,您应该只收集输入。

如果按下鼠标左键,以下函数将鼠标位置的 X 坐标添加到数组 ptListX 并将 Y 坐标添加到数组 ptListY

如果按下右键,多边形将被标记为关闭。如果再次按下左键,则多边形被清除并重新开始。

int wndSizwX = 800, wndSizeY = 500; // size of the window
int mouseX = 0, mouseY = 0;         // current mouse position

#define MAX_PTS 100
int ptListX[MAX_PTS]; // X coordinate ot the input points 
int ptListY[MAX_PTS]; // Y coordinate of the input points
int noOfPts = 0;      // number of input points
int closed = 0;       // marke polygon "closed"

void mouse(int button, int state, int x, int y)

    mouseX = x;
    mouseY = y;

    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    
        if (closed || noOfPts >= MAX_PTS - 1)
            noOfPts = 0; // restart the polygon
        closed = 0;
        ptListX[noOfPts] = mouseX; 
        ptListY[noOfPts] = mouseY;
        noOfPts ++;
    
    if ( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
        closed = 1;

在鼠标移动事件函数中,可以跟踪当前鼠标位置:

void mouse_move(int x, int y)

    mouseX = x;
    mouseY = y;
    glutPostRedisplay();

在主循环(Display 函数)中,当前点列表连接到线并连续绘制。如果设置了cloesd 标志,则多边形关闭。否则将绘制从列表中最后一个点到当前鼠标位置的线。

void Display()

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);  
    glClear(GL_COLOR_BUFFER_BIT);  

    if (noOfPts)
    
        glLineWidth(5.0);
        glColor3f(0.0f,1.0f,0.0f);
        glBegin(GL_LINE_STRIP);
        for (int i=0; i<noOfPts; ++i )
            glVertex2f( (float)ptListX[i], (float)ptListY[i] );
        if ( closed )
            glVertex2f( (float)ptListX[0], (float)ptListY[0] );
        else
            glVertex2f( (float)mouseX, (float)mouseY );
        glEnd();
    

    glFlush();  

鼠标移动事件的注册必须通过glutPassiveMotionFunc添加到主程序中。 此外,必须翻转正交投影的 Y 轴,以将视图空间与鼠标坐标匹配:

void main(int argc, char **argv)

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(wndSizwX,wndSizeY);
    glutInitWindowPosition(0,0);
    glutCreateWindow("Mouse");

    gluOrtho2D(0, wndSizwX, wndSizeY, 0); // flip Y 

    glutDisplayFunc(Display);
    glutMouseFunc(mouse);
    glutPassiveMotionFunc(mouse_move);
    glutMainLoop();

查看预览:

【讨论】:

【参考方案2】:

首先,您实际上并没有绘制任何东西 - 函数 drawl 仅在您每第二次单击时才被调用。要绘制一条线(或任何东西),需要在每一帧调用一个绘图例程,例如调用 Display 函数。

第二件事是mouse回调函数中给出的位置不适合在3D中定义一个点。必须将它们转换为适当的坐标(通常范围从 -1 到 1)才能将它们用作绘图数据。否则 GL 会尝试在视野之外绘制一些线,这意味着什么都不会被绘制。

我会稍微重新组织应用程序结构 - 当您收到 mouse 调用而不是每隔一次调用它时调用 drawl 时,将 mouse 函数为您提供的正确翻译位置存储在一些全局变量中并执行在Display 例程中绘图。此外,gluOrtho2D 通常也应该在每一帧都被调用。在您对它的调用中,您的参数错误 - 有关详细信息,请参阅 reference page。

【讨论】:

以上是关于使用鼠标单击未获得 OpenGL 的输出以打印行的主要内容,如果未能解决你的问题,请参考以下文章

在 OpenGL 上单击鼠标时无法旋转和更改对象的颜色

Opengl:尝试绘制线条以可视化鼠标射线投射时出现意外行为

Altium Designer (17.0) 打印输出指定的层

用鼠标单击 OpenGL 拖动 3d 对象

OpenGL用鼠标移动画圆

如何通过鼠标单击获取像素的 rgb 颜色值