LibGDX 游戏开发 之 各种坐标系

原文链接:https://github.com/libgdx/libgdx/wiki/Coordinate-systems
译者:重庆好爸爸 game4kids@163.com
谢绝转载

坐标系对比表 (译者注:为了方便查阅,因此译者做了个汇总表)

参数 Touch coordinates Screen or image coordinates Pixmap and texture coordinates Normalized render coordinates Normalized texture (UV) coordinates World coordinates
Unit 像素 像素 不知道 1 1 应用相关, e.g. SI Units
System Y轴向下 Y轴向上 不知道 Y轴向上 Y轴向上 application specific,一般Y轴向上
Type 整数 整数 不知道 浮点数 浮点数 浮点数
Range 左上角(0,0); 右下角(Gdx.graphics.getWidth()-1, Gdx.graphics.getHeight()-1) 左下角(0,0); 右上角(Gdx.graphics.getWidth()-1, Gdx.graphics.getHeight()-1) 不知道 (-1,-1) (左下角) to (+1,+1) (右上角) (0,0) (左下角) to (1,1) (右上角) 应用相关
Usage 触摸/鼠标坐标系 viewport, scissors & pixmap 不知道 shaders shaders, mesh, texture region, sprite 游戏逻辑
Dependence 设备相关 device/resource/asset specific 不知道 game/application

触摸坐标系Touch coordinates

从物理屏幕(应用程序窗口)的左上角像素开始,坐标系的尺寸和物理屏幕(应用程序窗口)相同。



每个坐标(x,y)其实是一个2维数组元素的索引,每个坐标都表示屏幕上的一个物理像素。既然是索引,那么每个坐标(x,y)都是整数,而不能是分数。这个坐标系通常也最接近于设备和OS的物理实现。如果你熟悉Canvas Graphics或者一些图像编辑器,那么你应该对此坐标系很熟悉了。你可能甚至想把这个坐标系作为你的默认坐标系,但建议你不要这么做。

每当使用鼠标或触摸坐标时,您将使用此坐标系。 您通常希望尽快将这些坐标转换为更方便的坐标系。 例如camera.unproject()viewport.unproject()等方法将它们转换为世界坐标(见下文)。

Screen,Image 坐标系

这是和OpenGL对应的触摸坐标系; 即:它用于指定(索引)物理屏幕的某个(或者某一部分)像素。 它也用作内存中图像的索引器。 同样,坐标分量必须是整数而不能是分数。
触摸和屏幕坐标之间的唯一区别是触摸坐标是y向下,而屏幕坐标是y-up。 因此,它们之间的转换是相当容易的:

y = Gdx.graphics.getHeight() - 1 - y;

通常使用这个坐标系的目的是需要指定要渲染的屏幕的某一部分。 例如,调用glViewportglScissor或操纵Pixmap(见下文)。

在大多数情况下,你不需要使用这个坐标系,如果有的话,应该把游戏逻辑和坐标系隔离。camera.project()viewport.project()方法可用于将世界单位转换为屏幕坐标。

Pixmap 和 texture coordinates

Pixmap坐标比较特殊。 Pixmap通常用于上传纹理数据。 例如,当将PNG图像文件加载到纹理时,首先将其解码(未压缩)到Pixmap(这是图像的原始像素数据),然后将作为纹理复制到GPU。 然后可以就使用纹理渲染到屏幕。也可以通过代码修改或创建Bitmap,例如在上传为纹理数据之前。

“问题”就是OpenGL希望纹理数据是一个Y轴向上的image坐标系。 然而,大多数图像格式存储的时候是Y轴向下的。 LibGDX不会在两者之间转换图像数据(这将涉及逐行复制图像),而是简单地复制数据。 这实际上导致从Pixmap加载的纹理上下颠倒。

为了解决此纹理上下颠倒的问题,SpriteBatch会在渲染时在y轴上翻转纹理(UV)坐标(见下文)。 同样,fbx-conv也可以在y轴上翻转纹理坐标。 但是,当您使用一个不是通过Bitmap图像加载的纹理(例如Framebuffer)时,可能会导致纹理出现在上下颠倒的问题。

归一化渲染坐标系 Normalized render coordinates

上面提到的坐标系有个很大的问题是:都是和设备强相关的。为了解决这个问题,OpenGL允许你在渲染的时候,使用和设备无关的坐标系,系统将自动映射到screen坐标系。该坐标系在[-1,-1]和[+ 1,+ 1]范围内.(0,0)精确地在屏幕或framebuffer(渲染目标)的中心。


Vertex shader在此坐标系中输出(gl_Position)其坐标。 但除此之外,你不应该在实际的应用中使用这个坐标系。 它有时候在教学中使用。
值得注意的是:归一化的时候长宽比。 也就是说:X方向的刻度不会与Y方向的刻度成比例。 它们都在-1的范围内到+1,无论屏幕的长宽比。
应用程序决定如何处理各种宽高比(见下文world unit)。
坐标是浮点数,不再是索引器。 设备(GPU)将使用rasterisation将这些坐标映射到实际的屏幕像素。 一个很好的文章(虽然针对DirectX也适用于OpenGL)有关可以找到的更多信息这里.

Normalized texture (UV) coordinates

如果normalized render 坐标系一样,
Likewise to the normalized render coordinates, OpenGL也使用Normalized texture (UV) 坐标系。 唯一的区别是这些范围从[0,0]到[1,1]。 根据指定的wrap 功能,该范围之外的值将被映射到该范围内。



这些坐标也称为** UV坐标**。 在许多用例中,你不必处理它们。 通常这些值存储在 mesh或者TextureRegion中。

normalized texture 坐标系的使用非常重要, 因为它使它们独立于资产大小。 或者换句话说:它允许您使用缩小或缩放版本替换您的资产,而无需修改UV坐标。 使用这个例子的是mipmap.

当渲染时,GPU将UV坐标转换为纹理像素(纹理像素)。 这被称为“纹理采样”,并且基于纹理过滤。

世界坐标系 World coordinates

一般来说,你的游戏逻辑应该使用一个最适合于游戏逻辑的坐标系。这个坐标系应该和设备或者资源的尺寸无关。比如:通常使用的单位是。世界坐标在顶点着色器中转换为归一化渲染坐标。Camera or Viewport用来做这件事的。比如:

为了保持长宽比例,可能需要加上黑边。Camera用来计算Matrix,Matrix的作用是将世界坐标系转换为camera相关的坐标系,还会考虑camera的位置和旋转考虑进去。
它还计算投影matrix,它将世界坐标转换为[-1,-1]到[+ 1,+ 1]范围内的Normalized render坐标系。 在2D游戏中,您几乎不需要区分这两个matrix,而只需要combined transformation matrix。 您可以将此矩阵传递给着色器,例如通过调用spriteBatch.setProjectionMatrix(camera.combined)方法。



您可以拥有多个camera或viewport,同样,你也可以拥有多个世界坐标系。 一个典型的游戏至少有两个世界坐标系,分别是:

GUI/HUD 坐标系 GUI/HUD coordinates

按钮,标签等固定元素在屏幕上始终可见。 通常它们涉及渲染文本。 例如在超级马里奥,时钟总是在屏幕的右上角可见,当马里奥在游戏世界中移动时,时钟不会移动。
最常见的是scene2d用于HUD,这意味着您将使用Viewport来定义坐标系。 该坐标系统通常在接近设备分辨率的范围内,以便在呈现字体时给出最佳结果。 这些坐标称为banana units。 这个摄像机实际上从来没有移动或旋转,它固定在一个位置,使得世界坐标(0,0)位于屏幕的左下角。

Game 坐标系 Game coordinates

这是适合您的游戏最适合,并用于实现游戏逻辑。 保持最佳浮点精度值是一个好的做法。 例如,你的主角高1.8米,树高10米,如果你正在制作一个单位和距离很高的银河系游戏,你可能想要使用例如 公里。
相机用于查看您的游戏世界,就像在现实世界中使用摄像机时一样。 相机可以移动,旋转和缩放,以在屏幕上显示世界的另一部分。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容