没有获得 OpenGL 的输出以使用鼠标单击打印行
Not getting an output for OpenGL to print line using mouse click
我的目标是用鼠标点击画一条线。当您单击第一次单击时,它会读取坐标,然后当进行嵌套单击时,它将使用 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() 函数吗?为什么?
首先,您实际上并没有绘制任何东西 - 函数 drawl
仅在您每隔两次单击时才会被调用。要绘制一条线(或任何东西),需要在每一帧调用绘图例程,例如调用 Display
函数。
其次,mouse
回调函数中给出的位置不适合在 3D 中定义点。必须将它们转换到适当的坐标(通常范围从 -1 到 1)才能将它们用作绘图数据。否则 GL 会尝试在视图之外绘制一些线,这意味着什么都不会绘制。
我会稍微重新组织应用程序结构 - 当您收到 mouse
调用而不是每隔一次调用 drawl
时,存储 mouse
函数提供的正确翻译的位置你在一些全局变量中并在 Display
例程中进行绘图。另外 gluOrtho2D
通常也应该在每一帧都被调用。在您调用它时您的参数有误 - 请参阅 reference page 了解详细信息。
为了这个答案,我将我对问题 的答案从 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 轴,以使视图 space 与鼠标坐标相匹配:
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();
}
查看预览:
我的目标是用鼠标点击画一条线。当您单击第一次单击时,它会读取坐标,然后当进行嵌套单击时,它将使用 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() 函数吗?为什么?
首先,您实际上并没有绘制任何东西 - 函数 drawl
仅在您每隔两次单击时才会被调用。要绘制一条线(或任何东西),需要在每一帧调用绘图例程,例如调用 Display
函数。
其次,mouse
回调函数中给出的位置不适合在 3D 中定义点。必须将它们转换到适当的坐标(通常范围从 -1 到 1)才能将它们用作绘图数据。否则 GL 会尝试在视图之外绘制一些线,这意味着什么都不会绘制。
我会稍微重新组织应用程序结构 - 当您收到 mouse
调用而不是每隔一次调用 drawl
时,存储 mouse
函数提供的正确翻译的位置你在一些全局变量中并在 Display
例程中进行绘图。另外 gluOrtho2D
通常也应该在每一帧都被调用。在您调用它时您的参数有误 - 请参阅 reference page 了解详细信息。
为了这个答案,我将我对问题
你必须把鼠标事件和绘图函数分开。
在鼠标 (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 轴,以使视图 space 与鼠标坐标相匹配:
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();
}
查看预览: