OpenGL绝对坐标
我对创建游戏(以及一般在 OpenGL 中工作)非常陌生。我正在尝试制作 2D 游戏,但在尝试解决碰撞检测问题时遇到了一个障碍。
比方说,我平移当前矩阵,再次旋转和平移,然后绘制一个点。我如何知道该点与我可能绘制的其他任何点的关系在哪里?
有没有办法从当前矩阵计算“绝对”坐标?
请尽可能简单地解释一下!谢谢 :)
I'm very new to creating games (and working in OpenGL in general). I'm trying to make a 2D game but have come upon a stumbling point when trying to get my head around collision detection.
Lets say for example I translate the current matrix, the rotate and translate again and then draw a point. How do I know where that point is in relation to anything else I might have drawn?
Is there a way of calculating "absolute" coordinates from the current matrix?
Please explain as simply as possible! thanks :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
OpenGL 不是游戏引擎,而是渲染库。另一方面,碰撞检测是游戏逻辑的函数。因此,它应该与 OpenGL 无关,OpenGL 只是在屏幕上放置视觉表示的查看机制 - 它对您的游戏对象一无所知,也不保存任何有用的持久数据。如果您确实尝试将对象的位置存储在矩阵中并通过转换移动它,那么您最终可能会受到累积浮点错误的影响,从而导致不可预测的行为。
相反,您应该做的是手动维护所有对象的位置(以及方向、速度等)。所有对象的移动都应该由您在应用程序代码中执行。当需要渲染对象时,您可以读取它们的当前值并将其传递给 OpenGL。通常,您获取要渲染的每种类型对象的多边形数据,按对象实例的方向旋转它,按其位置平移它,然后渲染。每帧重复一次。
如果您完全熟悉 模型视图-Controller范例那么你的游戏对象就是Model,而OpenGL提供了一个View。因此,您应该根据需要操作模型,并在需要时让视图从中读取。
OpenGL isn't a game engine but a rendering library. Collision detection on the other hand is a function of your game logic. Therefore, it should have nothing to do with OpenGL, which is just the viewing mechanism for putting a visual representation on the screen - it knows nothing about your game objects nor does it hold any useful persistent data on them. If you do try to store an object's position in a matrix and move it via transformations then you can eventually suffer from the effects of cumulative floating point errors leading to unpredictable behaviour.
What you should do instead is maintain all your object's positions (and orientations, velocities, etc) manually. All movement of objects should be performed by you in the application code. When it comes time to render the objects, you read their current values and pass those in to OpenGL. Typically you take the polygon data for each type object you want to render, rotate it by the object instance's orientation, translate it by its position, then render. Repeat once per frame.
If you're at all familiar with the Model-View-Controller paradigm then your game objects are the Model, and OpenGL provides a View. As such you should manipulate your Model as needed and just have the View read from it when needed.
最好只跟踪每个对象的绝对位置。
It's best to just keep track of every objects absolute position.
令人沮丧,不是吗?所有 OpenGL 和图形编程初学者都有与您类似的问题。跟踪各种参考系可能很困难。
我建议的第一件事是从亚马逊或其他零售商处获取 OpenGL SuperBible 的副本。它从绝对的起点开始,并从那里逐步构建。之前推荐 NeHe 网站的发帖者也给出了很好的建议。
至于你的问题本身,当你创建一个 OpenGL 程序时,你可以将“modelview”矩阵设置为身份(有关更多信息,请参阅 SuperBible),并且你在 glPoint() 调用中设置的所有坐标将相对于该矩阵定义为参考框架。如果从现在开始除了调用 glPoint() 之外不做任何事情,那么所有对象都将位于相同的绝对坐标系中。
当您开始调用 glTranslate 、 glRotate 和 glLoadMatrix 时,事情会变得很棘手,因为这些函数会转换参考系。当这种情况发生时,所有后续的 glPoint() 调用都与该新的参考系相关。
(正如另一张海报所提到的,如果您想返回到先前的参考系,则必须在转换模型视图矩阵之前将其保存在堆栈上,然后您可以“弹出”堆栈并返回到之前的位置.)
很难在支持网站上描述这一点,但可以将其视为牙医椅子上的一系列机械臂。他可以将托盘移至您的下巴下方,然后将其旋转一定角度以托住您的下巴。每个独立的运动都可以被认为是一个变换,在 OpenGL 中作为矩阵实现。
就像我说的,很难在网上正确描述这一点。拿起《超级圣经》这本书,它会更有意义。祝你好运!
Frustrating, isn't it? All OpenGL and graphics programming beginners have questions similar to yours. Keeping track of the various frames of reference can be tough.
The first thing I would recommend is getting a copy of the OpenGL SuperBible from Amazon or another retailer. It starts at the absolute beginning and progressively builds from there. The earlier poster who recommended the NeHe site is giving good advice too.
As for your question itself, when you create an OpenGL program you can set the "modelview" matrix to be the identity (see the SuperBible for more info) and all coordinates you set in glPoint() calls will be defined relative to that matrix as the frame of reference. If you don't do anything besides call glPoint() from here on out all your objects will be in the same, absolute coordinate system.
It gets tricky when you start calling glTranslate and glRotate and glLoadMatrix, as those functions transform the frame of reference. When that happens all subsequent glPoint() calls are then relative to that new frame of reference.
(As mentioned by another poster, if you want to go back to the earlier frame of reference you have to save the modelview matrix on a stack before transforming it, and then you can "pop" the stack and get back to where you were before.)
It's hard to describe this on a support site, but think of it as a series of mechanical arms in a dentists chair. He can move the tray to be under your chin, then rotate it at an angle to cup your chin. Each independent motion can be thought of as a transformation, implemented in OpenGL as a matrix.
Like I said, it's hard to describe this properly online. Grab the SuperBible book and it'll make a lot more sense. Good luck!
当我学习 OpenGL 时,我使用了以下 2 个资源来完成所有事情。
看来 gametutorials 已付费,出售CD,但写得很好,所以可能值得购买。
然而,NeHe仍然是网络上的免费教程,包括这个用于碰撞检测。
http://www.gamedev.net/reference/list.asp?categoryid= 31
When I learned OpenGL, I used the following 2 resources for everything.
It appears the gametutorials has gone paid-for, selling a CD, but they were well written so it might be worth buying it.
However, NeHe are still free tutorials on the web, including this one for collision detection.
http://www.gamedev.net/reference/list.asp?categoryid=31
你所说的“绝对”是什么意思?
如果您希望您的点相对于先前的点,您可以反转您刚刚所做的变换:按第二个平移的负值平移,绕同一轴沿相反方向旋转相同的量,然后按第一个平移的负值平移翻译。这将使您从新坐标转换到旧系统。
或者,您可以使用已有的变换将旧点放入新的坐标系中。
What do you mean by "absolute"?
If you want your point relative to the prior points you can reverse the transforms you just did: translate by the negative of the second translation, rotate in the opposite direction around the same axis by the same amount, then translate by the negative of the first translation. This will give you a transform from your new coordinates to the old system.
Alternatively you could use the transform you already have to take your old points into the new coordinate system.
跟踪世界坐标中的对象位置,并直接比较它们。
要进行显示,请使用相机模型,并将所有转换应用于它。
Keep track of the object positions in world coordinates, and compare them directly.
To do the display, use a camera model, and apply all your transformations to it.