我目前正致力于使用JOGL设计我的第一款FPS游戏。 (OpenGL的Java绑定)。
到目前为止,我已经能够生成'世界'(一系列立方体)和一个玩家模型。我在播放器和立方体之间进行了碰撞检测,效果很好。
现在我想加入枪支。我正确地绘制了枪模型并加载到玩家模型上。我试图实现的第一把枪是一把激光枪,无论你瞄准的是什么,它都能射出瞬间的视线激光。在我开始实施敌人模型之前,我想在激光和墙壁之间进行碰撞检测。
目前,我的激光是由一系列小立方体一个接一个地绘制的。第一个立方体在玩家枪的末端绘制,然后从那里连续绘制。我们的想法是继续绘制激光的立方体,直到检测到某些物体的碰撞,即世界上的立方体。
我知道世界上立方体的位置。问题是我必须调用glMatrixPush来绘制我的角色模型。然后在该模型视图中绘制激光。这意味着我失去了旧的坐标系 - 所以我在一个系统中绘制世界,然后在另一个系统中绘制lazer。在这个播放器矩阵中,我已经多次调用glRotate和glTranslate,以便通过相机旋转的方式同步所有内容。然后通过沿着这个新系统的z轴平移来构建激光器。
我的问题是,通过所有这些转换,我不再知道我的激光在地图坐标系中的位置,主要是由于涉及相机的旋转。
有没有人知道如何解决这个问题的方法 - 或者有任何想法?我相信我需要一种方法将激光的新坐标转换为地图的旧坐标,但我不确定如何撤消已经完成的所有转换。 OpenGL也可能提供一些功能来处理我不知道的这类问题。
答案 0 :(得分:4)
你不应该把激光视为射击它的角色的空间孩子。一旦它被激发,激光就是它自己的实体,所以你应该渲染如下:
glPushMatrix(viewMatrix);
glPushMatrix(playerMatrix);
DrawPlayer();
glPopMatrix();
glPushMatrix(laserMatrix);
DrawLaser();
glPopMatrix();
glPopMatrix();
另外,请确保不要将渲染转换逻辑与游戏逻辑混合使用。无论当前的OpenGL矩阵堆栈如何,都应始终存储对象的世界空间位置,以便能够测试交叉点。
请记住要注意空间的父母/子女关系。在实践中,它们并不常见。有关更多信息,请谷歌了解场景图的问题。
答案 1 :(得分:3)
第一个答案中提到的一点是,你不应该依赖于矩阵来首先定位对象。在考虑绘制激光之前,您应该记录激光的位置和旋转。然后使用translate和rotate命令将它放在你应该知道的位置。
你试图向后做事,是的,这确实意味着你将不得不进行矩阵数学运算,并且OpenGL没有跟踪它,因为ModelView矩阵是OpenGL确实跟踪的唯一事情关于对象位置。 OpenGL没有“世界空间”或“相机空间”的概念。只有所有输入乘以的矩阵。它非常简单......但在某些情况下,我更喜欢DirectX具有独立视图矩阵和模型矩阵的方式。
所以,如果你没有矩阵数学就不知道对象的位置,那么我会认为这是一个基本的设计问题。如果你不需要知道对象的位置,那么矩阵变换到你的心灵内容,但如果你确实需要它的位置,开始与位置。
(几乎是第一个答案所说的,只是以不同的方式......)