使用鼠标单击未获得 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:尝试绘制线条以可视化鼠标射线投射时出现意外行为