在动画期间获取 OpenGL 中的鼠标点击坐标?
Get mouse click coordinates in OpenGL during animation?
我想制作一个游戏,当有人点击移动的球时,它会爆炸。我已经添加了动画和鼠标点击事件的代码,但是当动画进行时,点击功能不起作用。当我在没有动画的情况下尝试时,它工作正常。我想知道为什么会这样。
#include<stdio.h>
#include<GL/glut.h>
#include<unistd.h>
#include<math.h>
int x, y;
float mx, my;
float i, j;
void mouse(int button, int state, int mousex, int mousey)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
mx = mousex;
my = mousey;
printf("%f %f\n",mx,my);
glutPostRedisplay();
}
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glColor3f(0.0, 1.0, 0.0);
glPointSize(1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1560, 0, 840);
}
int randValue()
{
int i = rand();
int num = i%1000;
return num;
}
void blast(int x, int y)
{
glBegin(GL_POLYGON);
glColor3f(1.0f,0.0f,0.0f);
glVertex2i(x-100, y-100);
glVertex2i(x, y-100);
glVertex2i(x-22, y-20);
glVertex2i(x-100, y-30);
glVertex2i(x-30, y-40);
glVertex2i(x-150, y-80);
glVertex2i(x-20, y);
glVertex2i(x, y-40);
glVertex2i(x-66, y-125);
glVertex2i(x-34, y-32);
glVertex2i(x-32, y-55);
glVertex2i(x-32, y);
glVertex2i(x-60, y-57);
glVertex2i(x-75, y-69);
glVertex2i(x-100, y);
glEnd();
glFlush();
}
void display()
{
int j = 0, k = 0, l = 1;
while(1)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POINTS);
for (i = 0;i < 6.29;i += 0.001)
{
x = 100 * cos(i);
y = 100 * sin(i);
glVertex2i(x / 2 + j, y / 2 + k);
if((x / 2 + j) >= 1560 || (y / 2 + k) >= 840)
{
glEnd();
glFlush();
glClear(GL_COLOR_BUFFER_BIT);
blast(x / 2 + j, y / 2 + k);
sleep(2);
j = randValue();
k = 0;
}
}
j = j + 3;
k = k + 5;
glEnd();
glFlush();
}
}
int main (int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(1360, 768);
glutInitWindowPosition(0, 0);
glutCreateWindow("{Project}");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
}
您的代码在 display
函数内有一个无限循环,因此您永远不会将控制权交还给 GLUT。 GLUT 已经有一个像 glutMainLoop
.
里面那样的无限循环
相反,您应在 display
、post glutPostRedisplay
和 return:[=16= 中仅渲染 ONE 帧]
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
// ... draw the frame here ...
// for exmaple:
i += 0.001;
float x = 100 * cos(i);
float y = 100 * sin(i);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
glFlush();
glutPostRedisplay();
}
然后您的 mouse
函数将被调用,您将能够根据需要更新状态。
这里有两个问题:
OpenGL 本身不支持输入设备,您通常使用 OpenGL 来显示信息,但您在显示信息的 window 上附加了其他东西你鼠标访问。这涉及了解您正在使用的 other 环境,它为您提供指向屏幕区域的定点设备。
如果你有 window 鼠标坐标,你需要在 window 上很好地映射你的 OpenGL 输出,但你必须将它们转换回某个点你的场景,但可能你的球不在那里。从表示 3D 场景的平面图像传递到 3D 场景中的点时会出现一些歧义,因为 Z 轴上的所有点在 2D 屏幕中共享相同的屏幕坐标。所以你必须根据鼠标的 window 坐标从视点(相机)追溯到球的可能位置。这是一个几何问题,涉及投影的逆变换,投影总是奇异的。
你不用猜测就可以解决这个问题,因为你知道你的球在哪里,你可以重做使它出现在二维空间中的变换window,然后根据这些来比较坐标。 OpenGL 允许您了解它为表示您的场景所做的实际转换,并且您可以使用它来查看您的球在屏幕中的哪个位置表示(您不需要对球的每个顶点都这样做,只需对中心,例如),然后检查你的 shot 是否已经足够接近击球。您还应该考虑 Z 轴上方是否有其他物体挡路,这样您就不会杀死墙后的任何人。
我想制作一个游戏,当有人点击移动的球时,它会爆炸。我已经添加了动画和鼠标点击事件的代码,但是当动画进行时,点击功能不起作用。当我在没有动画的情况下尝试时,它工作正常。我想知道为什么会这样。
#include<stdio.h>
#include<GL/glut.h>
#include<unistd.h>
#include<math.h>
int x, y;
float mx, my;
float i, j;
void mouse(int button, int state, int mousex, int mousey)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
mx = mousex;
my = mousey;
printf("%f %f\n",mx,my);
glutPostRedisplay();
}
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glColor3f(0.0, 1.0, 0.0);
glPointSize(1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1560, 0, 840);
}
int randValue()
{
int i = rand();
int num = i%1000;
return num;
}
void blast(int x, int y)
{
glBegin(GL_POLYGON);
glColor3f(1.0f,0.0f,0.0f);
glVertex2i(x-100, y-100);
glVertex2i(x, y-100);
glVertex2i(x-22, y-20);
glVertex2i(x-100, y-30);
glVertex2i(x-30, y-40);
glVertex2i(x-150, y-80);
glVertex2i(x-20, y);
glVertex2i(x, y-40);
glVertex2i(x-66, y-125);
glVertex2i(x-34, y-32);
glVertex2i(x-32, y-55);
glVertex2i(x-32, y);
glVertex2i(x-60, y-57);
glVertex2i(x-75, y-69);
glVertex2i(x-100, y);
glEnd();
glFlush();
}
void display()
{
int j = 0, k = 0, l = 1;
while(1)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POINTS);
for (i = 0;i < 6.29;i += 0.001)
{
x = 100 * cos(i);
y = 100 * sin(i);
glVertex2i(x / 2 + j, y / 2 + k);
if((x / 2 + j) >= 1560 || (y / 2 + k) >= 840)
{
glEnd();
glFlush();
glClear(GL_COLOR_BUFFER_BIT);
blast(x / 2 + j, y / 2 + k);
sleep(2);
j = randValue();
k = 0;
}
}
j = j + 3;
k = k + 5;
glEnd();
glFlush();
}
}
int main (int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(1360, 768);
glutInitWindowPosition(0, 0);
glutCreateWindow("{Project}");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
}
您的代码在 display
函数内有一个无限循环,因此您永远不会将控制权交还给 GLUT。 GLUT 已经有一个像 glutMainLoop
.
相反,您应在 display
、post glutPostRedisplay
和 return:[=16= 中仅渲染 ONE 帧]
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
// ... draw the frame here ...
// for exmaple:
i += 0.001;
float x = 100 * cos(i);
float y = 100 * sin(i);
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
glFlush();
glutPostRedisplay();
}
然后您的 mouse
函数将被调用,您将能够根据需要更新状态。
这里有两个问题:
OpenGL 本身不支持输入设备,您通常使用 OpenGL 来显示信息,但您在显示信息的 window 上附加了其他东西你鼠标访问。这涉及了解您正在使用的 other 环境,它为您提供指向屏幕区域的定点设备。
如果你有 window 鼠标坐标,你需要在 window 上很好地映射你的 OpenGL 输出,但你必须将它们转换回某个点你的场景,但可能你的球不在那里。从表示 3D 场景的平面图像传递到 3D 场景中的点时会出现一些歧义,因为 Z 轴上的所有点在 2D 屏幕中共享相同的屏幕坐标。所以你必须根据鼠标的 window 坐标从视点(相机)追溯到球的可能位置。这是一个几何问题,涉及投影的逆变换,投影总是奇异的。
你不用猜测就可以解决这个问题,因为你知道你的球在哪里,你可以重做使它出现在二维空间中的变换window,然后根据这些来比较坐标。 OpenGL 允许您了解它为表示您的场景所做的实际转换,并且您可以使用它来查看您的球在屏幕中的哪个位置表示(您不需要对球的每个顶点都这样做,只需对中心,例如),然后检查你的 shot 是否已经足够接近击球。您还应该考虑 Z 轴上方是否有其他物体挡路,这样您就不会杀死墙后的任何人。