LibGDX 游戲開發(fā) 之 各種坐標系

原文鏈接: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的物理實現(xiàn)。如果你熟悉Canvas Graphics或者一些圖像編輯器,那么你應該對此坐標系很熟悉了。你可能甚至想把這個坐標系作為你的默認坐標系,但建議你不要這么做。

每當使用鼠標或觸摸坐標時,您將使用此坐標系。 您通常希望盡快將這些坐標轉換為更方便的坐標系。 例如camera.unproject()viewport.unproject()等方法將它們轉換為世界坐標(見下文)。

Screen,Image 坐標系

這是和OpenGL對應的觸摸坐標系; 即:它用于指定(索引)物理屏幕的某個(或者某一部分)像素。 它也用作內存中圖像的索引器。 同樣,坐標分量必須是整數而不能是分數。
觸摸和屏幕坐標之間的唯一區(qū)別是觸摸坐標是y向下,而屏幕坐標是y-up。 因此,它們之間的轉換是相當容易的:

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

通常使用這個坐標系的目的是需要指定要渲染的屏幕的某一部分。 例如,調用glViewport,glScissor或操縱Pixmap(見下文)。

在大多數情況下,你不需要使用這個坐標系,如果有的話,應該把游戲邏輯和坐標系隔離。camera.project()viewport.project()方法可用于將世界單位轉換為屏幕坐標。

Pixmap 和 texture coordinates

Pixmap坐標比較特殊。 Pixmap通常用于上傳紋理數據。 例如,當將PNG圖像文件加載到紋理時,首先將其解碼(未壓縮)到Pixmap(這是圖像的原始像素數據),然后將作為紋理復制到GPU。 然后可以就使用紋理渲染到屏幕。也可以通過代碼修改或創(chuàng)建Bitmap,例如在上傳為紋理數據之前。

“問題”就是OpenGL希望紋理數據是一個Y軸向上的image坐標系。 然而,大多數圖像格式存儲的時候是Y軸向下的。 LibGDX不會在兩者之間轉換圖像數據(這將涉及逐行復制圖像),而是簡單地復制數據。 這實際上導致從Pixmap加載的紋理上下顛倒。

為了解決此紋理上下顛倒的問題,SpriteBatch會在渲染時在y軸上翻轉紋理(UV)坐標(見下文)。 同樣,fbx-conv也可以在y軸上翻轉紋理坐標。 但是,當您使用一個不是通過Bitmap圖像加載的紋理(例如Framebuffer)時,可能會導致紋理出現(xiàn)在上下顛倒的問題。

歸一化渲染坐標系 Normalized render coordinates

上面提到的坐標系有個很大的問題是:都是和設備強相關的。為了解決這個問題,OpenGL允許你在渲染的時候,使用和設備無關的坐標系,系統(tǒng)將自動映射到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) 坐標系。 唯一的區(qū)別是這些范圍從[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游戲中,您幾乎不需要區(qū)分這兩個matrix,而只需要combined transformation matrix。 您可以將此矩陣傳遞給著色器,例如通過調用spriteBatch.setProjectionMatrix(camera.combined)方法。



您可以擁有多個camera或viewport,同樣,你也可以擁有多個世界坐標系。 一個典型的游戲至少有兩個世界坐標系,分別是:

GUI/HUD 坐標系 GUI/HUD coordinates

按鈕,標簽等固定元素在屏幕上始終可見。 通常它們涉及渲染文本。 例如在超級馬里奧,時鐘總是在屏幕的右上角可見,當馬里奧在游戲世界中移動時,時鐘不會移動。
最常見的是scene2d用于HUD,這意味著您將使用Viewport來定義坐標系。 該坐標系統(tǒng)通常在接近設備分辨率的范圍內,以便在呈現(xiàn)字體時給出最佳結果。 這些坐標稱為banana units。 這個攝像機實際上從來沒有移動或旋轉,它固定在一個位置,使得世界坐標(0,0)位于屏幕的左下角。

Game 坐標系 Game coordinates

這是適合您的游戲最適合,并用于實現(xiàn)游戲邏輯。 保持最佳浮點精度值是一個好的做法。 例如,你的主角高1.8米,樹高10米,如果你正在制作一個單位和距離很高的銀河系游戲,你可能想要使用例如 公里。
相機用于查看您的游戲世界,就像在現(xiàn)實世界中使用攝像機時一樣。 相機可以移動,旋轉和縮放,以在屏幕上顯示世界的另一部分。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容